排序
This commit is contained in:
@@ -63,7 +63,7 @@ abstract class AetherModel extends HyperfModel implements CacheableInterface
|
||||
* - 字符串: 排序字段(默认升序)
|
||||
* - 数组: ['field' => '字段名', 'direction' => 'asc/desc'].
|
||||
*/
|
||||
protected array|bool|string $sortable = 'sort'; // 默认按sort字段升序
|
||||
protected array|bool|string $sortable = false; // 'sort'; // 默认按sort字段升序
|
||||
|
||||
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
|
||||
{
|
||||
$query = $this->buildQueryFromParams($params);
|
||||
return $this->listResult($query, $params);
|
||||
$query = static::query();
|
||||
|
||||
// 通过模型配置自动应用所有搜索条件
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数构建查询.
|
||||
*/
|
||||
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
|
||||
{
|
||||
foreach ($conditions as $field => $value) {
|
||||
// 跳过非字符串的字段名(防止索引数组键导致的类型错误)
|
||||
if (! is_string($field)) {
|
||||
// 基础过滤:非字符串字段名或未设置值的参数直接跳过
|
||||
if (! is_string($field) || ! isset($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 处理嵌套关系查询(如:user.name)
|
||||
// 核心限制:只处理$search数组中定义的字段
|
||||
if (! isset($this->search[$field])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 处理嵌套关系查询(如:user.name,需在$search中配置完整键名)
|
||||
if (str_contains($field, '.')) {
|
||||
[$relation, $relationField] = explode('.', $field, 2);
|
||||
$query->whereHas($relation, function ($q) use ($relationField, $value) {
|
||||
// 嵌套查询默认使用精确匹配,如需特殊规则可在$search中自定义处理
|
||||
$q->where($relationField, $value);
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查是否有自定义搜索器方法
|
||||
// 优先使用自定义搜索器方法(仅对$search中存在的字段生效)
|
||||
$searchMethod = 'search' . ucfirst($field);
|
||||
if (method_exists($this, $searchMethod)) {
|
||||
$this->{$searchMethod}($query, $value);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 应用搜索规则配置
|
||||
if (isset($this->search[$field])) {
|
||||
$this->applySearchRule($query, $field, $value, $this->search[$field]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 默认精确匹配(仅对$search中允许的字段生效,因已通过白名单过滤)
|
||||
$query->where($field, $value);
|
||||
// 应用$search中定义的搜索规则(如=、like等)
|
||||
$this->applySearchRule($query, $field, $value, $this->search[$field]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user