65 lines
1.9 KiB
PHP
65 lines
1.9 KiB
PHP
<?php
|
||
|
||
namespace app\mzl\common\utils;
|
||
|
||
class SearchHelper
|
||
{
|
||
public static function parseFiltersAndRelations(array $params, array $mapping): array
|
||
{
|
||
$filters = [];
|
||
$relations = [];
|
||
$hasRelations = [];
|
||
|
||
// 解析过滤条件和关联字段
|
||
foreach ($mapping as $paramKey => $definition) {
|
||
$field = $definition['field'];
|
||
$operator = $definition['operator'];
|
||
$value = $params[$paramKey] ?? null;
|
||
|
||
if (self::isValidValue($value, $operator)) {
|
||
$filters[] = compact('field', 'operator', 'value');
|
||
if (str_contains($field, '.')) {
|
||
$relations[] = self::extractRelationPath($field);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 解析 whereHas 关联字段(如 profile.age)
|
||
foreach ($params as $key => $value) {
|
||
if (str_contains($key, '.')) {
|
||
$relation = explode('.', $key)[0]; // 获取关联名
|
||
$hasRelations[$relation] = function ($query) use ($key, $value) {
|
||
$query->where($key, '=', $value);
|
||
};
|
||
}
|
||
}
|
||
|
||
return [
|
||
'filters' => $filters,
|
||
'relations' => array_unique($relations),
|
||
'hasRelations' => $hasRelations,
|
||
];
|
||
}
|
||
|
||
private static function isValidValue(mixed $value, string $operator): bool
|
||
{
|
||
$operator = strtolower($operator);
|
||
|
||
if (in_array($operator, ['in', 'not_in', 'between'])) {
|
||
return is_array($value) && !empty($value);
|
||
}
|
||
|
||
if (in_array($operator, ['null', 'not_null'])) {
|
||
return true;
|
||
}
|
||
|
||
return $value !== '' && $value !== null;
|
||
}
|
||
|
||
private static function extractRelationPath(string $field): string
|
||
{
|
||
$parts = explode('.', $field);
|
||
array_pop($parts);
|
||
return implode('.', $parts);
|
||
}
|
||
} |