dcat-admin

dcat-admin


数据仓库

<h1>数据仓库</h1> <p>数据仓库(<code>Repository</code>)是<code>Dcat Admin</code>中对数据增删改查操作接口的具体实现,通过<code>Repository</code>的介入可以让页面的构建不再关心数据读写功能的具体实现,开发者通过实现<code>Repository</code>接口即可对数据进行读写操作。</p> <p>&gt; {tip} 当然为了方便系统也保留了直接使用 <code>Model</code> 的功能,底层会自动把<code>Model</code>转化为数据仓库实例,毕竟大多数时候直接使用 <code>Model</code> 也能满足我们的需求。</p> <p>数据表格<code>Grid</code>、数据表单<code>Form</code>、数据详情<code>Show</code>、<code>Tree</code> 等组件不再直接依赖于<code>Model</code>,而是依赖于提供更简单清晰的接口的数据仓库,下面是<code>Repository</code>的所有接口:</p> <pre><code class="language-php">&amp;lt;?php namespace Dcat\Admin\Contracts; use Dcat\Admin\Form; use Dcat\Admin\Grid; use Dcat\Admin\Show; use Illuminate\Support\Collection; interface Repository { /** * 获取主键名称. * * @return string */ public function getKeyName(); /** * 获取创建时间字段. * * @return string */ public function getCreatedAtColumn(); /** * 获取更新时间字段. * * @return string */ public function getUpdatedAtColumn(); /** * 是否使用软删除. * * @return bool */ public function isSoftDeletes(); /** * 获取Grid表格数据. * * @param Grid\Model $model * * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator|Collection|array */ public function get(Grid\Model $model); /** * 获取编辑页面数据. * * @param Form $form * * @return array|\Illuminate\Contracts\Support\Arrayable */ public function edit(Form $form); /** * 获取详情页面数据. * * @param Show $show * * @return array|\Illuminate\Contracts\Support\Arrayable */ public function detail(Show $show); /** * 新增记录. * * @param Form $form * * @return mixed */ public function store(Form $form); /** * 查询更新前的行数据. * * @param Form $form * * @return array|\Illuminate\Contracts\Support\Arrayable */ public function updating(Form $form); /** * 更新数据. * * @param Form $form * * @return bool */ public function update(Form $form); /** * 删除数据. * * @param Form $form * @param array $deletingData * * @return mixed */ public function delete(Form $form, array $deletingData); /** * 查询删除前的行数据. * * @param Form $form * * @return array|\Illuminate\Contracts\Support\Arrayable */ public function deleting(Form $form); } </code></pre> <p>如果你的数据是多层级结构,则还需要实现以下接口</p> <pre><code class="language-php">&amp;lt;?php namespace Dcat\Admin\Contracts; interface TreeRepository { /** * 获取主键字段名称. * * @return string */ public function getPrimaryKeyColumn(); /** * 获取父级ID字段名称. * * @return string */ public function getParentColumn(); /** * 获取标题字段名称. * * @return string */ public function getTitleColumn(); /** * 获取排序字段名称. * * @return string */ public function getOrderColumn(); /** * 保存层级数据排序. * * @param array $tree * @param int $parentId */ public function saveOrder($tree = [], $parentId = 0); /** * 设置数据查询回调. * * @param \Closure|null $query * * @return $this */ public function withQuery($queryCallback); /** * 获取层级数据. * * @return array */ public function toTree(); }</code></pre> <h2>Repository接口</h2> <h3>getKeyName</h3> <p>此接口要求返回数据的主键字段名称,需要返回<code>string</code>类型值。</p> <pre><code class="language-php"> public function getKeyName() { return 'id'; }</code></pre> <h3>getCreatedAtColumn</h3> <p>此接口要求返回数据的<code>created_at</code>字段名称,如果没有值可以返回空字符串或<code>null</code>值。</p> <pre><code class="language-php"> // 如果没有值可以返回空字符串或`null`值 public function getCreatedAtColumn() { return 'created_at'; }</code></pre> <h3>getUpdatedAtColumn</h3> <p>此接口要求返回数据的<code>updated_at</code>字段名称,如果没有值可以返回空字符串或<code>null</code>值。</p> <pre><code class="language-php"> // 如果没有值可以返回空字符串或`null`值 public function getCreatedAtColumn() { return 'updated_at'; }</code></pre> <h3>isSoftDeletes</h3> <p>此接口要求返回数据是否支持软删除,请返回一个<code>bool</code>类型的值。</p> <pre><code class="language-php"> public function isSoftDeletes() { return true; }</code></pre> <p>&lt;a name=&quot;get&quot;&gt;&lt;/a&gt;</p> <h3>get</h3> <p>此接口要求返回数据表格<code>Grid</code>的数据,用于数据表格展示,要求返回一个<code>array</code>、<code>Illuminate\Support\Collection</code>或<code>LengthAwarePaginator</code>类型值。</p> <h4>分页</h4> <p>当数据需要分页时要求返回一个<code>\Illuminate\Contracts\Pagination\LengthAwarePaginator</code>类型值:</p> <pre><code class="language-php"> public function get(Grid\Model $model) { // 获取当前页数 $currentPage = $model-&amp;gt;getCurrentPage(); // 获取每页显示行数 $perPage = $model-&amp;gt;getPerPage(); // 获取筛选参数 $city = $model-&amp;gt;filter()-&amp;gt;input(Grid\Filter\Scope::QUERY_NAME, '广州'); $start = ($currentPage - 1) * $perPage; $client = new \GuzzleHttp\Client(); $response = $client-&amp;gt;get(&amp;quot;{$this-&amp;gt;api}?{$this-&amp;gt;apiKey}&amp;amp;city=$city&amp;amp;start=$start&amp;amp;count=$perPage&amp;quot;); $data = json_decode((string)$response-&amp;gt;getBody(), true); return $model-&amp;gt;makePaginator( $data['total'] ?? 0, // 传入总记录数 $data['subjects'] ?? [] // 传入数据二维数组 ); }</code></pre> <h4>不分页</h4> <p>如果不需要分页,则直接返回一个<code>array</code>或<code>Illuminate\Support\Collection</code>类型值即可。</p> <pre><code class="language-php"> public function get(Grid\Model $model) { return [ ['id' =&amp;gt; 1, 'name' =&amp;gt; 'n1'], ['id' =&amp;gt; 2, 'name' =&amp;gt; 'n2'] ]; }</code></pre> <p>注意,<code>grid</code>需要禁用分页</p> <pre><code class="language-php">$grid-&amp;gt;disablePagination()</code></pre> <h3>edit</h3> <p>此接口要求返回表单编辑页面的数据,用于显示数据表单编辑页面,需要返回<code>array</code>类型值。</p> <pre><code class="language-php"> public function edit(Form $form): array { // 获取数据主键值 $id = $form-&amp;gt;getKey(); return ['id' =&amp;gt; 1, 'name' =&amp;gt; 'n1']; }</code></pre> <h3>detail</h3> <p>此接口要求返回数据详情页面的数据,用于显示数据详情,需要返回<code>array</code>类型值。</p> <pre><code class="language-php"> public function detail(Show $show): array { // 获取数据主键值 $id = $show-&amp;gt;getId(); return ['id' =&amp;gt; 1, 'name' =&amp;gt; 'n1']; }</code></pre> <h3>store</h3> <p>此接口用于新增一条记录,可以返回<code>int</code>、<code>string</code>或<code>bool</code>类型值。</p> <pre><code class="language-php"> public function store(Form $form) { // 获取待新增的数据 $attributes = $form-&amp;gt;updates(); // 执行你的新增逻辑 // 返回新增记录id或bool值 return 1; }</code></pre> <h3>updating</h3> <p>此接口用于数据表单修改数据时查询原始记录,需要返回<code>array</code>或<code>Model</code>类型值。</p> <p>&gt; {tip} 此接口只有某些特殊字段会用到,如图片、文件上传字段,当更改了图片或文件时可以根据这个接口查出的数据删除旧文件。所以如果你的表单中没有用到此类特殊字段,此接口可以返回一个空数组。</p> <pre><code class="language-phpjie"> public function updating(Form $form) { // 获取数据主键值 $id = $form-&amp;gt;getKey(); return ['id' =&amp;gt; 1, 'name' =&amp;gt; 'n1']; }</code></pre> <h3>update</h3> <p>此接口用于数据表单修改记录,可以返回<code>int</code>、<code>string</code>或<code>bool</code>类型值。</p> <pre><code class="language-php"> public function update(Form $form) { // 获取待编辑的数据 $attributes = $form-&amp;gt;updates(); // 执行你的编辑逻辑 // 返回成功 return true; }</code></pre> <h3>deleting</h3> <p>此接口用于删除数据时查询原始记录,需要返回二维数组,或Collection model。</p> <pre><code class="language-php"> public function deleting(Form $form): array { // 当批量删除时id为多个 $id = explode(',', $form-&amp;gt;getKey()); // 执行你的逻辑 // 注意这里需要返回二维数组 return [ ['id' =&amp;gt; 1, 'name' =&amp;gt; 'h1'], ]; // 也可以返回collection return Modell::find($id); }</code></pre> <h3>destroy</h3> <p>单行/批量删除数据方法,成功返回<code>true</code>,失败返回<code>false</code>。</p> <pre><code class="language-php"> public function destroy(Form $form, array $deletingData) { // 当批量删除时id为多个 $id = explode(',', $form-&amp;gt;getKey()); // $deletingData 是 getDataWhenDeleting 接口返回的数据 // 执行你的逻辑 return true; }</code></pre> <h2>TreeRepository接口</h2> <h3>getPrimaryKeyColumn</h3> <p>此接口用于返回数据的主键字段名称,需要返回<code>string</code>类型值。</p> <pre><code class="language-php"> public function getPrimaryKeyColumn() { return $this-&amp;gt;getKeyName(); }</code></pre> <h3>getParentColumn</h3> <p>此接口用于返回数据的父ID字段名称,需要返回<code>string</code>类型值。</p> <pre><code class="language-php"> public function getParentColumn() { return 'parent_id'; }</code></pre> <h3>getTitleColumn</h3> <p>此接口用于返回数据标题字段名称,需要返回<code>string</code>类型值。</p> <pre><code class="language-php"> public function getTitleColumn() { return 'title'; }</code></pre> <h3>getOrderColumn</h3> <p>此接口用于返回数据排序字段名称,需要返回<code>string</code>类型值。</p> <p>&gt; {tip} 此字段不是必须的,如果你的数据不支持或不需要排序,请返回空值!</p> <pre><code class="language-php"> public function getOrderColumn() { return 'order'; }</code></pre> <h3>saveOrder</h3> <p>此接口用于保存层级数据的排序,并且接收两个参数</p> <ul> <li><code>$tree</code> <code>array</code> 此字段是一个已分好层级的数组</li> <li><code>$parentId</code> <code>int</code> 此字段主要用于递归时传递父ID使用</li> </ul> <p>&gt; {tip} 如果你的数据不支持 <code>MySQL</code>,可参考 <code>Dcat\Admin\Traits\ModelTree::saveOrder</code> 方法自行实现。</p> <pre><code class="language-php">$tree = [ [ 'id' =&amp;gt; 1, 'title' =&amp;gt; 'title', 'parent_id' =&amp;gt; 0, 'children' =&amp;gt; [ [ 'id' =&amp;gt; 2, 'title' =&amp;gt; 'child1', 'parent_id' =&amp;gt; 1, ], [ 'id' =&amp;gt; 3, 'title' =&amp;gt; 'child2', 'parent_id' =&amp;gt; 1, ], ], ] ]; // 保存排序,内层逻辑请自行实现 $repository-&amp;gt;saveOrder($tree); </code></pre> <h3>withQuery</h3> <p>此接口需结合 <code>toTree</code> 接口使用,接收一个参数:主要用于设置数据查询操作的相关回调或参数。</p> <pre><code class="language-php">&amp;lt;?php use Dcat\Admin\Contracts\Repository; use Dcat\Admin\Contracts\TreeRepository; use Dcat\Admin\Support\Helper; class Category implements Repository, TreeRepository { protected $queryCallbacks = []; public function withQuery($queryCallback) { $this-&amp;gt;queryCallbacks[] = $queryCallback; return $this; } public function toTree() { // 这里演示的代码只是为了说明 withQuery 方法的作用 $client = ...; foreach ($this-&amp;gt;queryCallbacks as $callback) { $callback($client); } return Helper::buildNestedArray($client-&amp;gt;get()); } } </code></pre> <h3>toTree</h3> <p>此接口主要用于查询数据并分好层级返回,需要返回 <code>array</code> 类型值。</p> <pre><code class="language-php"> public function toTree() { $client = ...; foreach ($this-&amp;gt;queryCallbacks as $callback) { $callback($client); } return Helper::buildNestedArray($client-&amp;gt;get()); }</code></pre> <h2>模型</h2> <p><code>Dcat Admin</code>已经内置了对<code>Eloquent model</code>的支持,如果你的数据源是支持<code>Model</code>的,那么只需继承<code>Dcat\Admin\Repositories\EloquentRepository</code>类即可实现对数据的<code>CURD</code>操作,如:</p> <pre><code class="language-php">&amp;lt;?php namespace App\Admin\Repositories; use Dcat\Admin\Repositories\EloquentRepository; use App\Models\Movie as MovieModel; class Movie extends EloquentRepository { // 这里设置你的模型类名即可 protected $eloquentClass = MovieModel::class; // 通过这个方法可以指定查询的字段,默认&amp;quot;*&amp;quot; public function getGridColumns() { return [$this-&amp;gt;getKeyName(), 'name', 'title', 'created_at']; } // 通过这个方法可以指定表单页查询的字段,默认&amp;quot;*&amp;quot; public function getFormColumns() { return [$this-&amp;gt;getKeyName(), 'name', 'title', 'created_at']; } // 通过这个方法可以指定数据详情页查询的字段,默认&amp;quot;*&amp;quot; public function getDetailColumns() { return ['*']; } }</code></pre> <h2>QueryBuilder</h2> <p>如果你的数据支持<code>QueryBuilder</code>查询,但不方便建模型类(比如需要动态查表数据),则可以继承<code>Dcat\Admin\Repositories\QueryBuilderRepository</code>类。</p> <p>&gt; {tip} 注意,<code>QueryBuilderRepository</code>默认是不支持<code>Model</code>的关联模型、软删除、模型树以及字段排序等功能,如果需要这些功能,请自定实现上述相关接口即可。</p> <pre><code class="language-php">&amp;lt;?php namespace App\Admin\Repositories; use Dcat\Admin\Repositories\QueryBuilderRepository; class MyRepository extends QueryBuilderRepository { // 设置你的主键名称 protected $keyName = 'id'; // 设置创建时间字段 protected $createdAtColumn = 'created_at'; // 设置更新时间字段 protected $updatedAtColumn = 'updated_at'; // 返回表名 public function getTable() { return 'your_table_name'; } // 返回你的主键名称 public function getKeyName() { return $this-&amp;gt;keyName; } // 通过这个方法可以指定查询的字段,默认&amp;quot;*&amp;quot; public function getGridColumns() { return [$this-&amp;gt;getKeyName(), 'name', 'title', 'created_at']; } // 通过这个方法可以指定表单页查询的字段,默认&amp;quot;*&amp;quot; public function getFormColumns() { return [$this-&amp;gt;getKeyName(), 'name', 'title', 'created_at']; } // 通过这个方法可以指定数据详情页查询的字段,默认&amp;quot;*&amp;quot; public function getDetailColumns() { return ['*']; } }</code></pre>

页面列表

ITEM_HTML