筛选方式(exact/like/date_from/date_to) */ abstract protected function getAllowedFilters(): array; /** 默认排序字段 */ protected function getDefaultSort(): string { return 'created_at'; } /** 默认排序方向 */ protected function getDefaultSortDirection(): string { return 'desc'; } /** * 通用列表方法:分页 + 筛选 + DataScope + 字段选择 */ public function index(): ResponseInterface|array { $model_class = $this->getModelClass(); $query = $model_class::query()->select($this->getListFields()); // DataScope 过滤 $this->applyDataScope($query); // 应用筛选条件 $this->applyFilters($query); // 排序 $query->orderBy($this->getDefaultSort(), $this->getDefaultSortDirection()); // 分页 $per_page = min((int) ($this->request->input('per_page', 15)), 100); $per_page = max($per_page, 1); $page = max((int) ($this->request->input('page', 1)), 1); $total = $query->count(); $items = $query->offset(($page - 1) * $per_page) ->limit($per_page) ->get(); return [ 'code' => 0, 'message' => '获取成功', 'data' => [ 'items' => $items, 'total' => $total, 'page' => $page, 'per_page' => $per_page, ], ]; } /** * 通用详情方法:字段选择 + DataScope 校验 */ public function show(int $id): ResponseInterface|array { $model_class = $this->getModelClass(); $fields = $this->getDetailFields(); $query = $model_class::query(); if ($fields !== ['*']) { $query->select($fields); } // DataScope 过滤(确保只能查看权限范围内的数据) $this->applyDataScope($query); $record = $query->where('id', $id)->first(); if (!$record) { return $this->response->json([ 'code' => 404, 'message' => '数据不存在', ])->withStatus(404); } return [ 'code' => 0, 'message' => '获取成功', 'data' => $record, ]; } /** * 应用 DataScope 过滤 * * 读取 PermissionMiddleware 注入的 scope_type / scope_ids 属性, * 自动添加 WHERE 条件限制查询范围。 */ protected function applyDataScope(Builder $query): void { $scope_type = $this->request->getAttribute('scope_type'); $scope_ids = $this->request->getAttribute('scope_ids', []); if ($scope_type === 'store') { $query->whereIn('store_id', $scope_ids); } elseif ($scope_type === 'platform') { $query->whereIn('platform_id', $scope_ids); } // 'all' → 不附加条件 } /** * 应用筛选条件 * * 根据 getAllowedFilters() 定义的参数名和筛选方式, * 从请求参数中提取值并构建 WHERE 子句。 * * 支持的筛选方式: * - exact: 精确匹配(WHERE col = value) * - like: 模糊搜索(WHERE col ILIKE %value%) * - date_from: 日期下界(WHERE col >= value),参数名需以 _from 结尾 * - date_to: 日期上界(WHERE col <= value 23:59:59),参数名需以 _to 结尾 */ protected function applyFilters(Builder $query): void { foreach ($this->getAllowedFilters() as $param => $type) { $value = $this->request->input($param); if ($value === null || $value === '') { continue; } match ($type) { 'exact' => $query->where($param, $value), 'like' => $query->where($param, 'ilike', "%{$value}%"), 'date_from' => $query->where(str_replace('_from', '', $param), '>=', $value), 'date_to' => $query->where(str_replace('_to', '', $param), '<=', $value . ' 23:59:59'), }; } } }