SearchController.php 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. <?php
  2. namespace App\Http\Controllers\Library;
  3. use App\Http\Controllers\Controller;
  4. use Illuminate\Http\Request;
  5. use App\Services\OpenSearchService;
  6. use App\DTO\Search\SearchDataDTO;
  7. use Carbon\Carbon;
  8. class SearchController extends Controller
  9. {
  10. public function search(Request $request)
  11. {
  12. $query = trim($request->input('q', ''));
  13. $category = $request->input('category', 'all');
  14. $page = max(1, (int) $request->input('page', 1));
  15. $perPage = 10;
  16. $lang = $request->input('language');
  17. $search = app(OpenSearchService::class);
  18. // 组装搜索参数
  19. $params = [
  20. 'query' => $query,
  21. 'pageSize' => $perPage,
  22. 'page' => $page,
  23. 'language' => $lang,
  24. 'resourceType' => $request->input('resource_type'),
  25. ];
  26. $result = $search->search($params);
  27. $dto = SearchDataDTO::fromArray($result);
  28. $results = [];
  29. foreach ($dto->hits->items as $key => $item) {
  30. $data = [
  31. 'id' => $item->resId,
  32. 'title' => $item->title,
  33. 'type' => $item->type,
  34. 'lang' => $item->language,
  35. 'category' => $item->type,
  36. 'quality' => 'featured',
  37. 'snippet' => !empty($item->highlight) ? $item->highlight : $item->content,
  38. 'updated' => Carbon::parse($item->updated)->format('Y-m-d'),
  39. ];
  40. if ($item->type === 'tipitaka') {
  41. $arrId = explode('_', $item->id);
  42. $data['chapter'] = ['id' => $arrId['2'], 'channel' => $arrId['3']];
  43. }
  44. $results[] = $data;
  45. }
  46. $aggregations = $dto->aggregations->toArray();
  47. unset($aggregations['resource_type']);
  48. // 分页对象(兼容 Blade paginator 风格)
  49. $pagination = [
  50. 'total' => $dto->hits->total,
  51. 'per_page' => $perPage,
  52. 'current_page' => $page,
  53. 'last_page' => max(1, (int) ceil($dto->hits->total / $perPage)),
  54. ];
  55. return view('library.search', [
  56. 'lang' => $lang,
  57. 'query' => $query,
  58. 'results' => $results,
  59. 'pagination' => $pagination,
  60. 'category' => 'all',
  61. 'filters' => $aggregations,
  62. 'types' => $this->types(),
  63. 'recentUpdates' => [],
  64. ]);
  65. }
  66. // ── Helpers ──────────────────────────────────────────────────
  67. private function types(): array
  68. {
  69. return [
  70. ['slug' => 'term', 'label' => '百科词条'],
  71. ['slug' => 'tipitaka', 'label' => '巴利三藏'],
  72. ['slug' => 'article', 'label' => '文章文集'],
  73. ['slug' => 'course', 'label' => '课程'],
  74. ['slug' => 'dictionary', 'label' => '字典'],
  75. ];
  76. }
  77. }