排序
This commit is contained in:
@@ -51,6 +51,12 @@ class Campus extends AetherModel
|
|||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected array $search = [
|
||||||
|
'parent_id' => '=',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected array|bool|string $sortable = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取父级校区.
|
* 获取父级校区.
|
||||||
* @return BelongsTo
|
* @return BelongsTo
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ abstract class AetherModel extends HyperfModel implements CacheableInterface
|
|||||||
* - 字符串: 排序字段(默认升序)
|
* - 字符串: 排序字段(默认升序)
|
||||||
* - 数组: ['field' => '字段名', 'direction' => 'asc/desc'].
|
* - 数组: ['field' => '字段名', 'direction' => 'asc/desc'].
|
||||||
*/
|
*/
|
||||||
protected array|bool|string $sortable = 'sort'; // 默认按sort字段升序
|
protected array|bool|string $sortable = false; // 'sort'; // 默认按sort字段升序
|
||||||
|
|
||||||
public function __construct(array $attributes = [])
|
public function __construct(array $attributes = [])
|
||||||
{
|
{
|
||||||
@@ -140,12 +140,101 @@ abstract class AetherModel extends HyperfModel implements CacheableInterface
|
|||||||
/**
|
/**
|
||||||
* 列表查询.
|
* 列表查询.
|
||||||
*/
|
*/
|
||||||
|
// public function list(array $params = []): array
|
||||||
|
// {
|
||||||
|
// $query = $this->buildQueryFromParams($params);
|
||||||
|
// return $this->listResult($query, $params);
|
||||||
|
// }
|
||||||
|
|
||||||
public function list(array $params = []): array
|
public function list(array $params = []): array
|
||||||
{
|
{
|
||||||
$query = $this->buildQueryFromParams($params);
|
$query = static::query();
|
||||||
return $this->listResult($query, $params);
|
|
||||||
|
// 通过模型配置自动应用所有搜索条件
|
||||||
|
$this->applySearch($query, $params);
|
||||||
|
|
||||||
|
// 动态应用排序
|
||||||
|
if ($this->sortable) {
|
||||||
|
$sortConfig = $this->getSortConfig();
|
||||||
|
$query->orderBy($sortConfig['field'], $sortConfig['direction']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$withDeleted = filter_var($params['with_deleted'] ?? false, FILTER_VALIDATE_BOOLEAN);
|
||||||
|
if ($withDeleted) {
|
||||||
|
$query->withTrashed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 存在分页参数(page或size)则进行分页查询
|
||||||
|
if (isset($params['page']) || isset($params['size'])) {
|
||||||
|
$page = (int) ($params['page'] ?? 1);
|
||||||
|
$size = (int) ($params['size'] ?? 10);
|
||||||
|
// 确保分页参数合法性
|
||||||
|
$page = max(1, $page);
|
||||||
|
$size = max(1, min(100, $size)); // 限制最大页大小为100
|
||||||
|
|
||||||
|
$result = $query->paginate($size, ['*'], 'page', $page);
|
||||||
|
return [
|
||||||
|
'list' => $result->items(),
|
||||||
|
'total' => $result->total(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 无分页参数时返回完整数据集合
|
||||||
|
$items = $query->get()->toArray();
|
||||||
|
|
||||||
|
// 若模型支持树形结构则构建树形,否则返回普通数组
|
||||||
|
if ($this instanceof TreeableInterface) {
|
||||||
|
return $this::buildTree($items, (int) ($params['parent_id'] ?? 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据模型的$search配置,自动应用搜索条件到查询构建器.
|
||||||
|
*/
|
||||||
|
// public function applySearch(Builder $query, array $params): void
|
||||||
|
// {
|
||||||
|
// foreach ($this->search as $field => $rule) {
|
||||||
|
// // 跳过未传递的参数
|
||||||
|
// if (!isset($params[$field])) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// $value = $params[$field];
|
||||||
|
// $this->applySearchRule($query, $field, $value, $rule);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 应用单个搜索规则
|
||||||
|
// */
|
||||||
|
// protected function applySearchRule(Builder $query, string $field, $value, $rule): void
|
||||||
|
// {
|
||||||
|
// // 处理规则格式(支持字符串简写或数组配置)
|
||||||
|
// $config = is_array($rule) ? $rule : ['type' => $rule];
|
||||||
|
// $type = $config['type'];
|
||||||
|
//
|
||||||
|
// switch ($type) {
|
||||||
|
// case '=': // 精确匹配
|
||||||
|
// $query->where($field, $value);
|
||||||
|
// break;
|
||||||
|
// case 'like': // 模糊匹配
|
||||||
|
// $query->where($field, 'like', "%{$value}%");
|
||||||
|
// break;
|
||||||
|
// case 'between': // 范围查询(支持数组或两个参数)
|
||||||
|
// $values = is_array($value) ? $value : [$value, $params[$field . '_end'] ?? $value];
|
||||||
|
// $query->whereBetween($field, $values);
|
||||||
|
// break;
|
||||||
|
// case 'callback': // 自定义回调
|
||||||
|
// if (isset($config['handler']) && is_callable($config['handler'])) {
|
||||||
|
// call_user_func($config['handler'], $query, $value);
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// // 可扩展其他类型:in、>、< 等
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 快捷创建.
|
* 快捷创建.
|
||||||
*/
|
*/
|
||||||
@@ -293,30 +382,6 @@ abstract class AetherModel extends HyperfModel implements CacheableInterface
|
|||||||
return Db::transaction($closure);
|
return Db::transaction($closure);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据参数构建查询.
|
|
||||||
*/
|
|
||||||
protected function buildQueryFromParams(array $params = []): Builder
|
|
||||||
{
|
|
||||||
// 创建查询构建器
|
|
||||||
$query = static::query();
|
|
||||||
|
|
||||||
// 应用搜索条件
|
|
||||||
// if (isset($params['search'])) {
|
|
||||||
// $this->applySearch($query, $params['search']);
|
|
||||||
// }
|
|
||||||
$this->applySearch($query, $params);
|
|
||||||
// 应用排序
|
|
||||||
$this->applySorting($query, $params);
|
|
||||||
|
|
||||||
// 处理软删除
|
|
||||||
if (isset($params['withTrashed']) && $params['withTrashed']) {
|
|
||||||
$query->withTrashed();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用排序.
|
* 应用排序.
|
||||||
*/
|
*/
|
||||||
@@ -527,35 +592,35 @@ abstract class AetherModel extends HyperfModel implements CacheableInterface
|
|||||||
protected function applySearch(Builder $query, array $conditions): void
|
protected function applySearch(Builder $query, array $conditions): void
|
||||||
{
|
{
|
||||||
foreach ($conditions as $field => $value) {
|
foreach ($conditions as $field => $value) {
|
||||||
// 跳过非字符串的字段名(防止索引数组键导致的类型错误)
|
// 基础过滤:非字符串字段名或未设置值的参数直接跳过
|
||||||
if (! is_string($field)) {
|
if (! is_string($field) || ! isset($value)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理嵌套关系查询(如:user.name)
|
// 核心限制:只处理$search数组中定义的字段
|
||||||
|
if (! isset($this->search[$field])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理嵌套关系查询(如:user.name,需在$search中配置完整键名)
|
||||||
if (str_contains($field, '.')) {
|
if (str_contains($field, '.')) {
|
||||||
[$relation, $relationField] = explode('.', $field, 2);
|
[$relation, $relationField] = explode('.', $field, 2);
|
||||||
$query->whereHas($relation, function ($q) use ($relationField, $value) {
|
$query->whereHas($relation, function ($q) use ($relationField, $value) {
|
||||||
|
// 嵌套查询默认使用精确匹配,如需特殊规则可在$search中自定义处理
|
||||||
$q->where($relationField, $value);
|
$q->where($relationField, $value);
|
||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否有自定义搜索器方法
|
// 优先使用自定义搜索器方法(仅对$search中存在的字段生效)
|
||||||
$searchMethod = 'search' . ucfirst($field);
|
$searchMethod = 'search' . ucfirst($field);
|
||||||
if (method_exists($this, $searchMethod)) {
|
if (method_exists($this, $searchMethod)) {
|
||||||
$this->{$searchMethod}($query, $value);
|
$this->{$searchMethod}($query, $value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 应用搜索规则配置
|
// 应用$search中定义的搜索规则(如=、like等)
|
||||||
if (isset($this->search[$field])) {
|
|
||||||
$this->applySearchRule($query, $field, $value, $this->search[$field]);
|
$this->applySearchRule($query, $field, $value, $this->search[$field]);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 默认精确匹配(仅对$search中允许的字段生效,因已通过白名单过滤)
|
|
||||||
$query->where($field, $value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ class RpcExceptionHandler extends ExceptionHandler
|
|||||||
{
|
{
|
||||||
public function handle(Throwable $throwable, ResponseInterface $response): ResponseInterface
|
public function handle(Throwable $throwable, ResponseInterface $response): ResponseInterface
|
||||||
{
|
{
|
||||||
var_dump($throwable->getMessage());
|
|
||||||
try {
|
try {
|
||||||
// 获取请求ID(用于日志追踪)
|
// 获取请求ID(用于日志追踪)
|
||||||
$requestId = Context::get('request_id', '');
|
$requestId = Context::get('request_id', '');
|
||||||
|
|||||||
Reference in New Issue
Block a user