feat(controller): 增加了一个 Rest 风格的 trait

Signed-off-by: 李东云 <dongyu.li@luxcreo.ai>
This commit is contained in:
李东云
2023-07-21 10:54:33 +08:00
parent fd788a7eb8
commit 68844a6132
4 changed files with 92 additions and 49 deletions

12
docs/REST 控制器.md Normal file
View File

@@ -0,0 +1,12 @@
# REST 资源控制器支持
## 列表的筛选、排序
* [**RestfulList**](../src/Traits/RestfulList.php)
### RestfulList
在 AbstractController 中已经默认进行了集成
- parseParameters 用来解析请求
- responseFormatter 用来将 builder 转化成响应
- restSelect 额外的语法糖,调用了上面的两个方法

View File

@@ -21,8 +21,8 @@ use Dont\DontToString;
use Hyperf\Contract\ContainerInterface; use Hyperf\Contract\ContainerInterface;
use Hyperf\Contract\StdoutLoggerInterface; use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Inject; use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface; use Hyperf\HttpServer\Contract\ResponseInterface;
use Singularity\HDK\Core\Traits\RestfulList;
/** /**
* 抽象控制器基类 * 抽象控制器基类
@@ -42,13 +42,11 @@ abstract class AbstractController
use DontSerialise; use DontSerialise;
use DontDeserialise; use DontDeserialise;
use DontToString; use DontToString;
use RestfulList;
#[Inject] #[Inject]
protected ContainerInterface $container; protected ContainerInterface $container;
#[Inject]
protected RequestInterface $request;
#[Inject] #[Inject]
protected ResponseInterface $response; protected ResponseInterface $response;

View File

@@ -1,45 +0,0 @@
<?php
/**
* Paginatable.php@Core
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2023/7/18
*/
namespace Singularity\HDK\Core\Traits;
use Closure;
use Hyperf\Contract\LengthAwarePaginatorInterface;
use Hyperf\Database\Model\Builder;
use Hyperf\Stringable\Str;
trait PaginatorAble
{
public function responseFormatter(
array $options,
Builder $builder,
?Closure $filter = null
) {
$perPage = $options['size'] ?? null;
$order = $options['order'] ?? 'created_at';
$sort = $options['sort'] ?? 'desc';
$pagination = !!($options['page'] ?? $perPage ?? false);
// $group = $options['group'] ?? null;
$builder = $builder->orderBy(Str::snake($order), $sort);
$result = $pagination ? $builder->paginate($perPage) : $builder->get();
if (is_null($filter)) {
return $result;
}
if ($result instanceof LengthAwarePaginatorInterface) {
$collection = $result->getCollection();
$collection = $filter($collection);
return $result->setCollection($collection);
}
return $filter($result);
}
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* Paginatable.php@Core
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2023/7/18
*/
namespace Singularity\HDK\Core\Traits;
use Closure;
use Hyperf\Contract\LengthAwarePaginatorInterface;
use Hyperf\Database\Model\Builder;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Stringable\Str;
use Singularity\HDK\Core\Service\ExtendService;
trait RestfulList
{
#[Inject]
private ExtendService $extend;
#[Inject]
private RequestInterface $request;
public function restSelect(Closure $callback, ?Closure $filter = null)
{
$options = [];
$result = $this->parseParameters(function ($query, $parsedOptions) use ($callback, &$options) {
$options = $parsedOptions;
$callback($query, $parsedOptions);
});
return $this->responseFormatter($options, $result, $filter);
}
public function parseParameters(Closure $callback): mixed
{
$query = $this->request->getQueryParams();
$options = [
'size' => $this->request->query('size'),
'page' => $this->request->query('page'),
'order' => $this->request->query('order', 'created_at'),
'sort' => $this->request->query('sort', 'desc'),
'group' => $this->request->query('group'),
'extends' => $this->extend->getExtends(),
];
unset($query['sort'], $query['page'], $query['size'], $query['order'], $query['group'], $query['extends']);
return $callback(query: $query, options: $options);
}
public function responseFormatter(
array $options,
Builder $builder,
?Closure $filter = null
) {
$perPage = $options['size'] ?? null;
$order = $options['order'] ?? 'created_at';
$sort = $options['sort'] ?? 'desc';
$pagination = !!($options['page'] ?? $perPage ?? false);
// $group = $options['group'] ?? null;
$builder = $builder->orderBy(Str::snake($order), $sort);
$result = $pagination ? $builder->paginate($perPage) : $builder->get();
if (is_null($filter)) {
return $result;
}
if ($result instanceof LengthAwarePaginatorInterface) {
$collection = $result->getCollection();
$collection = $filter($collection);
return $result->setCollection($collection);
}
return $filter($result);
}
}