all(); $list = $this->model->where(function ($query) use ($all) { if (isset($all['filter']) && !empty($all['filter'])) { foreach ($all['filter'] as $condition) { $key = $condition['key'] ?? null; $op = $condition['op'] ?? null; $value = $condition['value'] ?? null; if (!isset($key) || !isset($op) || !isset($value)) { continue; } // 等于 if ($op == 'eq') { $query->where($key, $value); } // 不等于 if ($op == 'neq') { $query->where($key, '!=', $value); } // 大于 if ($op == 'gt') { $query->where($key, '>', $value); } // 大于等于 if ($op == 'egt') { $query->where($key, '>=', $value); } // 小于 if ($op == 'lt') { $query->where($key, '<', $value); } // 小于等于 if ($op == 'elt') { $query->where($key, '<=', $value); } // 模糊搜索 if ($op == 'like') { $query->where($key, 'like', '%' . $value . '%'); } // 否定模糊搜索 if ($op == 'notlike') { $query->where($key, 'not like', '%' . $value . '%'); } // 范围搜索 if ($op == 'range') { list($from, $to) = explode(',', $value); if (empty($from) || empty($to)) { continue; } $query->whereBetween($key, [$from, $to]); } } } })->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc'); if (isset($all['is_export']) && !empty($all['is_export'])) { $list = $list->get()->toArray(); $export_fields = $all['export_fields'] ?? []; // 导出文件名字 $tableName = $this->model->getTable(); $filename = (new CustomForm())->getTableComment($tableName); return Excel::download(new BaseExport($export_fields, $list, $tableName), $filename . date('YmdHis') . '.xlsx'); } else { // 输出 $list = $list->paginate($all['page_size'] ?? 20); } return $this->success($list); } /** * @OA\Get( * path="/api/admin/statistics-config/show", * tags={"动态统计"}, * summary="详情", * description="", * @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"), * @OA\Parameter(name="show_relation", in="query", @OA\Schema(type="string"), required=false, description="需要输出的关联关系数组,填写输出指定数据"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function show() { $all = \request()->all(); $messages = [ 'id.required' => 'Id必填', ]; $validator = Validator::make($all, [ 'id' => 'required' ], $messages); if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } $detail = $this->model->find($all['id']); return $this->success($detail); } /** * @OA\Post( * path="/api/admin/statistics-config/save", * tags={"动态统计"}, * summary="保存统计数据配置", * description="根据传入的id决定是更新现有配置还是新增新的配置。", * @OA\Parameter(name="id", in="query", @OA\Schema(type="integer"), required=false, description="配置ID(存在则更新,不存在则新增)"), * @OA\Parameter(name="name", in="query", @OA\Schema(type="string"), required=true, description="名字"), * @OA\Parameter(name="key", in="query", @OA\Schema(type="string"), required=false, description="标识key"), * @OA\Parameter(name="decimal_places", in="query", @OA\Schema(type="integer"), required=false, description="小数点位数,默认0"), * @OA\Parameter(name="description", in="query", @OA\Schema(type="string"), required=false, description="描述"), * @OA\Parameter(name="config_json", in="query", @OA\Schema(type="string"), required=false, description="配置json,包含数据来源、条件设置、统计方式等配置,详见配置文档"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="认证token"), * @OA\Response( * response="200", * description="操作成功" * ) * ) */ public function save() { $all = \request()->all(); DB::beginTransaction(); try { if (isset($all['id'])) { $model = $this->model->find($all['id']); if (empty($model)) { return $this->fail([ResponseCode::ERROR_BUSINESS, '数据不存在']); } } else { $model = $this->model; $all['admin_id'] = $this->getUserId(); $all['department_id'] = $this->getUser()->department_id; } $original = $model->getOriginal(); $model->fill($all); $model->save(); DB::commit(); return $this->success($model); } catch (\Exception $exception) { DB::rollBack(); return $this->fail([$exception->getCode(), $exception->getMessage()]); } } /** * @OA\Get( * path="/api/admin/statistics-config/destroy", * tags={"动态统计"}, * summary="删除", * description="", * @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function destroy() { return parent::destroy(); } /** * @OA\Get( * path="/api/admin/statistics-config/calculate", * tags={"动态统计"}, * summary="根据配置key执行统计", * description="根据配置的key获取对应的统计配置,然后根据config_json的配置执行统计查询,返回数据列表和统计结果", * @OA\Parameter(name="key", in="query", @OA\Schema(type="string"), required=true, description="配置的key标识"), * @OA\Parameter(name="page", in="query", @OA\Schema(type="integer"), required=false, description="页码,默认1"), * @OA\Parameter(name="page_size", in="query", @OA\Schema(type="integer"), required=false, description="每页显示的条数,默认10"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="认证token"), * @OA\Response( * response="200", * description="返回统计数据" * ) * ) */ public function calculate() { $all = \request()->all(); $messages = [ 'key.required' => 'key必填', ]; $validator = Validator::make($all, [ 'key' => 'required' ], $messages); if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } // 获取分页参数 $page = isset($all['page']) ? (int) $all['page'] : 1; $pageSize = isset($all['page_size']) ? (int) $all['page_size'] : 10; // 根据key查找配置 $config = $this->model->where('key', $all['key'])->first(); if (empty($config)) { return $this->fail([ResponseCode::ERROR_BUSINESS, '配置不存在']); } $configJson = $config->config_json; if (empty($configJson)) { return $this->fail([ResponseCode::ERROR_BUSINESS, '配置数据为空']); } // 如果 config_json 是字符串,尝试解析 if (is_string($configJson)) { $configJson = json_decode($configJson, true); if (json_last_error() !== JSON_ERROR_NONE) { return $this->fail([ResponseCode::ERROR_BUSINESS, '配置 JSON 格式错误:' . json_last_error_msg()]); } } try { // 检查数据结构 if (!isset($configJson['data_source'])) { return $this->fail([ResponseCode::ERROR_BUSINESS, '配置数据缺少 data_source 字段,当前配置键:' . implode(', ', array_keys($configJson))]); } // 获取主模型 $mainModelName = $configJson['data_source']['main_model'] ?? ''; if (empty($mainModelName)) { $dataSourceKeys = isset($configJson['data_source']) ? implode(', ', array_keys($configJson['data_source'])) : '无'; return $this->fail([ResponseCode::ERROR_BUSINESS, '主模型名称未配置,data_source 中的键:' . $dataSourceKeys]); } $mainModel = $this->getModel($mainModelName); if (empty($mainModel)) { return $this->fail([ResponseCode::ERROR_BUSINESS, '主模型不存在:' . $mainModelName . ',可用的模型:user, company, course_sign, course, course_type']); } $query = $mainModel::query(); // 获取主模型表名 $tableName = $mainModel::make()->getTable(); // 加载关联模型 $relations = $configJson['data_source']['relations'] ?? []; if (!empty($relations)) { foreach ($relations as $relation) { $query->with($relation); } } // 应用条件 $conditions = $configJson['conditions'] ?? []; if (!empty($conditions['items'])) { $logic = $conditions['logic'] ?? 'and'; if ($logic === 'or') { $query->where(function ($q) use ($conditions, $tableName) { foreach ($conditions['items'] as $index => $item) { if ($index === 0) { $this->applyCondition($q, $item, 'and', 0, $tableName); } else { $q->orWhere(function ($subQ) use ($item, $tableName) { $this->applyCondition($subQ, $item, 'and', 0, $tableName); }); } } }); } else { foreach ($conditions['items'] as $item) { $this->applyCondition($query, $item, 'and', 0, $tableName); } } } // 执行统计 $statistics = $configJson['statistics'] ?? []; $statisticsType = $statistics['type'] ?? 'count'; $groupBy = $statistics['group_by'] ?? null; // 确保空字符串也被视为不分组 $groupBy = !empty($groupBy) ? $groupBy : null; // 保存原始查询用于获取列表 $listQuery = clone $query; if ($groupBy) { // 分组统计 $groupParts = explode('.', $groupBy); if (count($groupParts) > 1) { // 关联模型字段分组,需要 join $relationName = $groupParts[0]; $fieldName = $groupParts[1]; $relationModel = $this->getRelationModel($mainModel, $relationName); if ($relationModel) { $relationTable = $relationModel::make()->getTable(); $relationKey = $this->getRelationKey($mainModel, $relationName); $query->join($relationTable, $tableName . '.' . $relationKey, '=', $relationTable . '.id'); $selectFields = [$relationTable . '.' . $fieldName . ' as group_value']; } else { $selectFields = [$groupBy . ' as group_value']; } } else { // 主模型字段分组 $selectFields = [$tableName . '.' . $groupBy . ' as group_value']; } // 根据统计类型构建 SQL $statisticsField = $statistics['field'] ?? null; if ($statisticsType === 'sum' && $statisticsField) { // 处理关联模型字段 $fieldParts = explode('.', $statisticsField); if (count($fieldParts) > 1) { $fieldRelationName = $fieldParts[0]; $fieldFieldName = $fieldParts[1]; $fieldRelationModel = $this->getRelationModel($mainModel, $fieldRelationName); if ($fieldRelationModel) { $fieldRelationTable = $fieldRelationModel::make()->getTable(); $fieldRelationKey = $this->getRelationKey($mainModel, $fieldRelationName); // 如果还没有 join,需要 join $query->leftJoin($fieldRelationTable, $tableName . '.' . $fieldRelationKey, '=', $fieldRelationTable . '.id'); $selectFields[] = DB::raw('SUM(' . $fieldRelationTable . '.' . $fieldFieldName . ') as total'); } else { $selectFields[] = DB::raw('SUM(' . $tableName . '.' . $statisticsField . ') as total'); } } else { $selectFields[] = DB::raw('SUM(' . $tableName . '.' . $statisticsField . ') as total'); } } elseif ($statisticsType === 'max' && $statisticsField) { // 处理关联模型字段 $fieldParts = explode('.', $statisticsField); if (count($fieldParts) > 1) { $fieldRelationName = $fieldParts[0]; $fieldFieldName = $fieldParts[1]; $fieldRelationModel = $this->getRelationModel($mainModel, $fieldRelationName); if ($fieldRelationModel) { $fieldRelationTable = $fieldRelationModel::make()->getTable(); $fieldRelationKey = $this->getRelationKey($mainModel, $fieldRelationName); // 如果还没有 join,需要 join $query->leftJoin($fieldRelationTable, $tableName . '.' . $fieldRelationKey, '=', $fieldRelationTable . '.id'); $selectFields[] = DB::raw('MAX(' . $fieldRelationTable . '.' . $fieldFieldName . ') as total'); } else { $selectFields[] = DB::raw('MAX(' . $tableName . '.' . $statisticsField . ') as total'); } } else { $selectFields[] = DB::raw('MAX(' . $tableName . '.' . $statisticsField . ') as total'); } } elseif ($statisticsType === 'min' && $statisticsField) { // 处理关联模型字段 $fieldParts = explode('.', $statisticsField); if (count($fieldParts) > 1) { $fieldRelationName = $fieldParts[0]; $fieldFieldName = $fieldParts[1]; $fieldRelationModel = $this->getRelationModel($mainModel, $fieldRelationName); if ($fieldRelationModel) { $fieldRelationTable = $fieldRelationModel::make()->getTable(); $fieldRelationKey = $this->getRelationKey($mainModel, $fieldRelationName); // 如果还没有 join,需要 join $query->leftJoin($fieldRelationTable, $tableName . '.' . $fieldRelationKey, '=', $fieldRelationTable . '.id'); $selectFields[] = DB::raw('MIN(' . $fieldRelationTable . '.' . $fieldFieldName . ') as total'); } else { $selectFields[] = DB::raw('MIN(' . $tableName . '.' . $statisticsField . ') as total'); } } else { $selectFields[] = DB::raw('MIN(' . $tableName . '.' . $statisticsField . ') as total'); } } elseif ($statisticsType === 'count_distinct' && isset($statistics['distinct_field'])) { // 去重数量统计 $distinctField = $statistics['distinct_field']; // 处理关联模型字段 $fieldParts = explode('.', $distinctField); if (count($fieldParts) > 1) { $fieldRelationName = $fieldParts[0]; $fieldFieldName = $fieldParts[1]; $fieldRelationModel = $this->getRelationModel($mainModel, $fieldRelationName); if ($fieldRelationModel) { $fieldRelationTable = $fieldRelationModel::make()->getTable(); $fieldRelationKey = $this->getRelationKey($mainModel, $fieldRelationName); // 如果还没有 join,需要 join $query->leftJoin($fieldRelationTable, $tableName . '.' . $fieldRelationKey, '=', $fieldRelationTable . '.id'); $selectFields[] = DB::raw('COUNT(DISTINCT ' . $fieldRelationTable . '.' . $fieldFieldName . ') as total'); } else { $selectFields[] = DB::raw('COUNT(DISTINCT ' . $tableName . '.' . $distinctField . ') as total'); } } else { $selectFields[] = DB::raw('COUNT(DISTINCT ' . $tableName . '.' . $distinctField . ') as total'); } } else { // count 统计总数量 $selectFields[] = DB::raw('COUNT(*) as total'); } $query->select($selectFields); if (count($groupParts) > 1) { $query->groupBy($relationTable . '.' . $fieldName); } else { $query->groupBy($tableName . '.' . $groupBy); } } else { // 不分组统计,获取所有数据列表 // 列表查询保持原样,获取所有符合条件的记录 } // 排序(分组统计时对分组结果排序,不分组时对列表排序) if (!empty($statistics['order_by'])) { $orderField = $statistics['order_by']['field'] ?? ($groupBy ? 'total' : 'id'); $orderDirection = $statistics['order_by']['direction'] ?? 'desc'; $query->orderBy($orderField, $orderDirection); if (!$groupBy) { // 不分组时,列表查询也需要排序 $listQuery->orderBy($orderField, $orderDirection); } } else { // 没有指定排序时,不分组情况使用默认排序 if (!$groupBy) { $listQuery->orderBy('id', 'desc'); } } // 获取统计查询的 SQL 语句(在执行查询前) $statisticsSql = $query->toSql(); $statisticsBindings = $query->getBindings(); $statisticsSqlFull = $this->getFullSql($statisticsSql, $statisticsBindings); // 获取分组统计结果列表(分页) // 先获取所有结果用于计算统计结果 $allResults = $query->get(); // 对结果进行分页处理 $totalCount = $allResults->count(); $pagedResults = $allResults->slice(($page - 1) * $pageSize, $pageSize); // 格式化分组统计结果 $data = []; foreach ($pagedResults as $item) { $row = [ 'group_value' => $item->group_value ?? null, 'total' => round($item->total, $config->decimal_places) ]; $data[] = $row; } // 计算统计结果 $statisticsResult = null; $pagination = null; if ($groupBy) { // 分组统计:根据统计类型计算最终结果 $statisticsField = $statistics['field'] ?? null; if ($statisticsType === 'sum' && $statisticsField) { // 分组求和时,统计结果是所有分组的总和 $allTotalValue = 0; foreach ($allResults as $item) { $allTotalValue += $item->total; } $statisticsResult = round($allTotalValue, $config->decimal_places); } elseif ($statisticsType === 'max' && $statisticsField) { // 分组最大值时,统计结果是所有分组中的最大值 $maxValue = null; foreach ($allResults as $item) { if ($maxValue === null || $item->total > $maxValue) { $maxValue = $item->total; } } $statisticsResult = $maxValue !== null ? round($maxValue, $config->decimal_places) : 0; } elseif ($statisticsType === 'min' && $statisticsField) { // 分组最小值时,统计结果是所有分组中的最小值 $minValue = null; foreach ($allResults as $item) { if ($minValue === null || $item->total < $minValue) { $minValue = $item->total; } } $statisticsResult = $minValue !== null ? round($minValue, $config->decimal_places) : 0; } else { // 分组计数时,统计结果是所有分组的计数总和 $allTotalValue = 0; foreach ($allResults as $item) { $allTotalValue += $item->total; } $statisticsResult = $allTotalValue; } // 分页信息 $pagination = [ 'current_page' => $page, 'page_size' => $pageSize, 'total' => $totalCount, 'total_pages' => ceil($totalCount / $pageSize) ]; } else { // 不分组统计:先获取 SQL,再执行查询 // 克隆查询用于获取 SQL(避免执行后无法获取) $calcQuery = clone $listQuery; $listQueryForData = clone $listQuery; // 根据统计类型计算统计值 $statisticsField = $statistics['field'] ?? null; if ($statisticsType === 'sum' && $statisticsField) { // 处理关联模型字段 $fieldParts = explode('.', $statisticsField); if (count($fieldParts) > 1) { $fieldRelationName = $fieldParts[0]; $fieldFieldName = $fieldParts[1]; $fieldRelationModel = $this->getRelationModel($mainModel, $fieldRelationName); if ($fieldRelationModel) { $fieldRelationTable = $fieldRelationModel::make()->getTable(); $fieldRelationKey = $this->getRelationKey($mainModel, $fieldRelationName); $calcQuery->leftJoin($fieldRelationTable, $tableName . '.' . $fieldRelationKey, '=', $fieldRelationTable . '.id'); $statisticsResult = round($calcQuery->sum($fieldRelationTable . '.' . $fieldFieldName), $config->decimal_places); } else { $statisticsResult = round($listQuery->sum($statisticsField), $config->decimal_places); } } else { $statisticsResult = round($listQuery->sum($statisticsField), $config->decimal_places); } } elseif ($statisticsType === 'max' && $statisticsField) { // 处理关联模型字段 $fieldParts = explode('.', $statisticsField); if (count($fieldParts) > 1) { $fieldRelationName = $fieldParts[0]; $fieldFieldName = $fieldParts[1]; $fieldRelationModel = $this->getRelationModel($mainModel, $fieldRelationName); if ($fieldRelationModel) { $fieldRelationTable = $fieldRelationModel::make()->getTable(); $fieldRelationKey = $this->getRelationKey($mainModel, $fieldRelationName); $calcQuery->leftJoin($fieldRelationTable, $tableName . '.' . $fieldRelationKey, '=', $fieldRelationTable . '.id'); $statisticsResult = round($calcQuery->max($fieldRelationTable . '.' . $fieldFieldName), $config->decimal_places); } else { $statisticsResult = round($listQuery->max($statisticsField), $config->decimal_places); } } else { $statisticsResult = round($listQuery->max($statisticsField), $config->decimal_places); } } elseif ($statisticsType === 'min' && $statisticsField) { // 处理关联模型字段 $fieldParts = explode('.', $statisticsField); if (count($fieldParts) > 1) { $fieldRelationName = $fieldParts[0]; $fieldFieldName = $fieldParts[1]; $fieldRelationModel = $this->getRelationModel($mainModel, $fieldRelationName); if ($fieldRelationModel) { $fieldRelationTable = $fieldRelationModel::make()->getTable(); $fieldRelationKey = $this->getRelationKey($mainModel, $fieldRelationName); $calcQuery->leftJoin($fieldRelationTable, $tableName . '.' . $fieldRelationKey, '=', $fieldRelationTable . '.id'); $statisticsResult = round($calcQuery->min($fieldRelationTable . '.' . $fieldFieldName), $config->decimal_places); } else { $statisticsResult = round($listQuery->min($statisticsField), $config->decimal_places); } } else { $statisticsResult = round($listQuery->min($statisticsField), $config->decimal_places); } } elseif ($statisticsType === 'count_distinct' && isset($statistics['distinct_field'])) { // 去重数量统计 $distinctField = $statistics['distinct_field']; // 处理关联模型字段 $fieldParts = explode('.', $distinctField); if (count($fieldParts) > 1) { $fieldRelationName = $fieldParts[0]; $fieldFieldName = $fieldParts[1]; $fieldRelationModel = $this->getRelationModel($mainModel, $fieldRelationName); if ($fieldRelationModel) { $fieldRelationTable = $fieldRelationModel::make()->getTable(); $fieldRelationKey = $this->getRelationKey($mainModel, $fieldRelationName); $calcQuery->leftJoin($fieldRelationTable, $tableName . '.' . $fieldRelationKey, '=', $fieldRelationTable . '.id'); $statisticsResult = $calcQuery->selectRaw('COUNT(DISTINCT ' . $fieldRelationTable . '.' . $fieldFieldName . ') as total')->value('total') ?? 0; } else { $statisticsResult = $listQuery->selectRaw('COUNT(DISTINCT ' . $distinctField . ') as total')->value('total') ?? 0; } } else { $statisticsResult = $listQuery->selectRaw('COUNT(DISTINCT ' . $tableName . '.' . $distinctField . ') as total')->value('total') ?? 0; } } else { // count 统计总数量 $statisticsResult = $listQuery->count(); } // 获取统计查询的 SQL(在计算完统计值之后,确保包含所有修改) $statisticsSqlForCalc = $calcQuery->toSql(); $statisticsBindingsForCalc = $calcQuery->getBindings(); $statisticsSqlFull = $this->getFullSql($statisticsSqlForCalc, $statisticsBindingsForCalc); // 获取列表总数(用于分页) $listTotalCount = $listQueryForData->count(); // 不分组时,获取分页数据作为列表 $listResults = $listQueryForData->skip(($page - 1) * $pageSize)->take($pageSize)->get(); $data = []; foreach ($listResults as $item) { $data[] = $item->toArray(); } // 分页信息 $pagination = [ 'current_page' => $page, 'page_size' => $pageSize, 'total' => $listTotalCount, 'total_pages' => ceil($listTotalCount / $pageSize) ]; } return $this->success([ 'sql' => $statisticsSqlFull, 'list' => $data, 'total' => $statisticsResult, 'pagination' => $pagination, 'config' => $config ]); } catch (\Exception $exception) { return $this->fail([$exception->getCode(), $exception->getMessage()]); } } /** * 获取模型实例 */ private function getModel($modelName) { $models = [ 'user' => User::class, 'company' => Company::class, 'course_sign' => CourseSign::class, 'course' => Course::class, 'course_type' => CourseType::class, ]; return $models[$modelName] ?? null; } /** * 应用查询条件 */ private function applyCondition($query, $condition, $logic, $index, $tableName = null) { $key = $condition['key'] ?? ''; $operator = $condition['operator'] ?? 'eq'; $value = $condition['value'] ?? ''; if (empty($key)) { return; } // 处理关联模型的字段 $keyParts = explode('.', $key); if (count($keyParts) > 1) { // 关联模型字段,使用 whereHas $relationName = $keyParts[0]; $fieldName = $keyParts[1]; $query->whereHas($relationName, function ($q) use ($fieldName, $operator, $value) { $this->applyOperator($q, $fieldName, $operator, $value); }); return; } // 主模型字段,添加表名前缀避免字段歧义 $qualifiedKey = $tableName ? $tableName . '.' . $key : $key; $this->applyOperator($query, $qualifiedKey, $operator, $value); } /** * 获取关联模型 */ private function getRelationModel($mainModel, $relationName) { $model = new $mainModel(); if (method_exists($model, $relationName)) { $relation = $model->$relationName(); return get_class($relation->getRelated()); } return null; } /** * 获取关联键名 */ private function getRelationKey($mainModel, $relationName) { $model = new $mainModel(); if (method_exists($model, $relationName)) { $relation = $model->$relationName(); return $relation->getForeignKeyName(); } return 'id'; } /** * 获取完整的 SQL 语句(包含绑定参数) */ private function getFullSql($sql, $bindings) { if (empty($bindings)) { return $sql; } $fullSql = $sql; foreach ($bindings as $binding) { $value = is_numeric($binding) ? $binding : "'" . addslashes($binding) . "'"; $fullSql = preg_replace('/\?/', $value, $fullSql, 1); } return $fullSql; } /** * 应用操作符 */ private function applyOperator($query, $key, $operator, $value) { switch ($operator) { case 'eq': $query->where($key, $value); break; case 'neq': $query->where($key, '!=', $value); break; case 'gt': $query->where($key, '>', $value); break; case 'egt': $query->where($key, '>=', $value); break; case 'lt': $query->where($key, '<', $value); break; case 'elt': $query->where($key, '<=', $value); break; case 'like': $query->where($key, 'like', '%' . $value . '%'); break; case 'notlike': $query->where($key, 'not like', '%' . $value . '%'); break; case 'in': $array = explode(',', $value); $query->whereIn($key, $array); break; case 'notin': $array = explode(',', $value); $query->whereNotIn($key, $array); break; case 'between': list($from, $to) = explode(',', $value); if (!empty($from) && !empty($to)) { $query->whereBetween($key, [$from, $to]); } break; case 'notbetween': list($from, $to) = explode(',', $value); if (!empty($from) && !empty($to)) { $query->whereNotBetween($key, [$from, $to]); } break; case 'isnull': $query->whereNull($key); break; case 'isnotnull': $query->whereNotNull($key); break; } } }