筛选黑科技

本文介绍了一种基于Laravel框架的智能筛选方案,通过解析YAML配置文件动态生成筛选条件,实现灵活高效的数据库查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于Laravel编写的筛选项黑科技

目录:


FilterController.php

<?php

namespace Modules\Student\Http\Controllers;

use Illuminate\Routing\Controller;
use Mockery\Exception;
use Symfony\Component\Yaml\Yaml;

/**
 * author:yolo
 * 筛选黑科技,通过Filter/*.yaml文件获取筛选列表,
 * 根据路由$request->all()参数,智能匹配指定模型的筛选函数
 *
 * example:
 * 设置筛选文件 Filter/模型名_filter_config.yaml
 *
 * // 获取所有筛选项
 * FilterController::setModule('Student', 'student'); //模块名, 模型名
 * FilterController::getScopeFilters(); // 获取所有筛选项
 *
 * // 构建查询器,进行筛选
 * FilterController::setModule('Student', 'student'); //模块名, 模型名
 * $query = FilterController::QueryBulider($query, $request); // 构建查询器,进行筛选
 *
 * Class FilterController
 * @package Modules\Student\Http\Controllers
 */
class FilterController extends Controller
{
    private static $module;
    private static $model;

    public static function setModule($moduleName, $modelName)
    {
        if (null === static::$module) {
            self::$module = $moduleName;
        }

        if (null === static::$model) {
            self::$model = $modelName;
        }
    }

    public static function getModule()
    {
        return static::$module . static::$model;
    }

    public static function getScopeFilters()
    {
        if (is_null($moduleName = static::$module)) {
            throw new Exception('请使用setModule方法设置模块名称');
        }

        if (is_null($modelName = static::$model)) {
            throw new Exception('请使用setModel方法设置模型名称');
        }

        // 获取当前模型对应的筛选项配置文件
        if (file_exists($filterConfigPath = module_path(ucfirst($moduleName)) . '/' . 'Filters/' . strtolower($modelName) . '_filter_config.yaml')) {
            try {
                $filterContent = Yaml::parse(file_get_contents($filterConfigPath));
            } catch (Exception $e) {
                throw new Exception("{$filterConfigPath}文件格式不规范");
            }
        }

        return self::dataTransfer($filterContent);
    }

    // 对options配置内容进行数据转换
    private static function dataTransfer($data)
    {
        $transfer = function ($item) {
            if (isset($item['options']) && is_string($item['options'])) {
                if (isset($item['modelClass'])) {
                    $optionsMethod = $item['options'];
                    $item['options'] = (new $item['modelClass'])->$optionsMethod();
                    unset($item['modelClass']);
                } else {
                    throw new Exception('请为options选择项指定模型');
                }
            }

            return $item;
        };

        if (isset($data['scopes'])) {
            $data['scopes'] = array_map($transfer, $data['scopes']);
        }
        return $data;
    }

    public static function QueryBulider($query, $request)
    {
        $filterContent = self::getScopeFilters();

        // 对其进行遍历,获得所有的键,根据键判断是否存在,存在则执行筛选查询。
        if (isset($filterContent['scopes'])) {
            foreach ($filterContent['scopes'] as $key => $item) {
                if (isset($request->$key)) {
                    if (isset($item['scope']) && !empty($scopeFunction = lcfirst($item['scope']))) {
                        $query = $query->$scopeFunction($request->$key);
                    } else {
                        $query = $query->where($key, $request->$key);
                    }
                }
            }
        }
        return $query;
    }

}


student_filter_config.yaml

# ===================================
# Filter Scope Definitions
# ===================================
scopes:
    education:
        label: 最高学历
        options:
            本科: 本科
            硕士: 硕士
            博士: 博士
            中专及以下: 中专及以下
        scope: FilterEducation
    age:
        label: 年龄
        modelClass: Modules\Student\Entities\Student
        options: getAgeOptions
        scope: FilterAge

Student.php

<?php

namespace Modules\Student\Entities;

use Illuminate\Database\Eloquent\Model;
use Prettus\Repository\Contracts\Transformable;
use Prettus\Repository\Traits\TransformableTrait;

/**
 *  @SWG\Definition(
 *   definition="StudentList",
 *   type="object",
 *   allOf={
 *       @SWG\Schema(
 *          required={"id"},
 *          @SWG\Property(property="total", format="", type="integer",description="总数"),
 *          @SWG\Property(property="page", format="", type="integer",description="当前页"),
 *          @SWG\Property(property="limit", format="", type="integer",description="页大小"),
 *          @SWG\Property(
 *              property="data",
 *              format="",
 *              type="array",
 *              @SWG\Items(ref="#/definitions/Student")
 *          )
 *       )
 *   }
 * )
 */
class Student extends Model implements Transformable
{
    use TransformableTrait;

    protected $guarded = ['id'];

    protected $table = "students";

    public function edus()
    {
        return $this->hasMany(StudentEdu::class);
    }

    public function jobs()
    {
        return $this->hasMany(StudentJob::class);
    }

    public function exams()
    {
        return $this->hasMany(StudentExam::class);
    }

    public function pays()
    {
        return $this->hasMany(StudentPay::class);
    }

    public function grant()
    {
        return $this->hasOne(StudentGrant::class);
    }

    public function scopeFilterEducation($query, $value)
    {
        return $query->where('education', $value);
    }

    public function getAgeOptions()
    {
        return [
            "本科" => "本科",
            "硕士" => "硕士",
            "博士" => "博士",
            "中专及以下" => "中专及以下",
        ];
    }
}

composer.json需要插入 "symfony/yaml": "^4.0",



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值