《财经》CMS后台查询功能的实现(基于Laravel Repository)

使用 RequestCriteria 统一搜索功能,可自动根据 url 按字段进行搜索,无需写方法

1. 后台搜索框的基本代码:

要求表单中的 name 与数据表中的字段名完全一致。
注意:这里是 button,而不是 submit

2. 在YourModelRepositoryEloquent.php (如FlashRepositoryEloquent.php) 中添加 $fieldSearchable 字段

如:

protected $fieldSearchable = [
    'id',
    'snap_goods_name' => 'like',
    'username',
    'order_status',
    'created_at' => ">=",
    'created_at@' => "<=",
    'source_id',
    'paymentInfo.payment_type'
];

注意:

  • 要列出所有需要进行搜索的字段。
  • 等于的可以省略,
  • 模糊搜索用 like,
  • 范围搜索也直接写。
  • 如果一个字段需要用一次以上,需要对 key 进行重写,加一个@

其中,最后一个功能是在 BaseRepositoryEloquent 中定义的。

默认的键值间的分隔符为:, 如http://prettus.local/users?search=name:John Doe;email:[email protected]
可以进行自定义。
在 BaseRepositoryEloquent.php 的构造方法中,
$this->keyValueSeparator = '|:'

组件中默认不包含范围选择符,即sql中的between用法。我们进行了改写,以支持该用法。

BaseRepositoryEloquent 中,添加解析搜索url的方法。

public function parserSearchData($searchData)
{
    if (!empty($searchData) && is_array($searchData)) {
        foreach ($searchData as $index => $item) {
            $method = sprintf("parser%s4Search", ucfirst(camel_case(str_replace('@', '', $index))));
            $model = $this->getModel();
            if (method_exists($model, $method)) {
                $searchData[$index] = $model->{$method}($item);
            }
        }
    }

    return $searchData;
}

以及解析原始搜索数据的方法

public function parserOriginSearchData($search)
{
    $searchData = [];
    if (stripos($search, $this->keyValueSeparator)) {
        $fields = explode($this->paramSeparator, $search);

        foreach ($fields as $row) {
            try {
                list($field, $value) = explode($this->keyValueSeparator, $row);
                $searchData[trim($field)] = trim($value);
            } catch (\Exception $e) {
                //Surround offset error
            }
        }
    }
    return $searchData;
}

业务需要,添加了整合后的获取搜索参数的方法

public function getSearchData($param = null, $is_origin = true)
{
    $search = $this->request->get(config('repository.criteria.params.search', 'search'), null);
    $searchData = $this->parserOriginSearchData($search);
    if (false == $is_origin) {
        $searchData = $this->parserSearchData($searchData);
    }
    if (!empty($param)) {
        if (isset($searchData[$param])) {
            $searchData = $searchData[$param];
        } else {
            $searchData = null;
        }
    }
    return $searchData;
}

3. js 文件中添加解析url的方法。

// 搜索 按钮
searchWithParams('/magazine/order?page=1');

function searchWithParams(url) {
    $("#btn_search").click(function () {
        var params = {};
        $("#frm_search_info select, #frm_search_info input[type=text], #frm_search_info input[type=hidden]").each(function () {
            var value = $(this).val();
            if ('' != value) {
                params[$(this).attr('name')] = value;
            }
        });

        if (!$.isEmptyObject(params)) {
            url += "&search=" + parserParams2Url(params);
        }

        location.href = url;
    });

}

该方法实现了对所有输入框、下拉框等搜索框内容的收集并处理,生成一个 Repository 可解析的 url。

4. 回显的数据不需要通过控制器获取后回传,在模板中通过 $searchCondition 全局变量获取即可

如何使用?
控制器中的方法会非常简洁:

public function getIndex(Request $request)
{
    $flashes = $this->repositoryInterface->paginate();

    return View::make("flash/index", array(
        "flashes" => $flashes,
        "flashTypes" => Flash::$flashTypes,
    ));
}

第二部分

上述搜索方法只是实现了单表搜索,如果搜索涉及到跨表该怎么处理?

场景:在模型Order的列表页进行搜索,但搜索的关键字是模型Payment的一个字段,模型Payment有一个指向模型Order的外键 order_id。

实现:

1. 在 app/Models/Order 中,建立与 Payment 模型的关联关系。

/**
 * 支付信息关联关系
 * @return \Illuminate\Database\Eloquent\Relations\HasOne
 */
public function paymentInfo()
{
    return $this->hasOne('App\Models\Payment', 'order_id', 'id');
}

2. Order 的模板文件(列表 resources/views/backend/order/index.blade.php)中,搜索相关部分的 name 和字段名都要加上关联关系的方法前缀。

3. 在YourModelRepositoryEloquent.php (如FlashRepositoryEloquent.php) 中添加 $fieldSearchable 字段

如:

protected $fieldSearchable = [
    'paymentInfo.payment_type'
];

要与模板文件的name一致。

你可能感兴趣的:(《财经》CMS后台查询功能的实现(基于Laravel Repository))