Search.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <?php
  2. namespace addons\cms\controller;
  3. use addons\cms\library\FulltextSearch;
  4. use addons\cms\library\Service;
  5. use addons\cms\model\Archives;
  6. use addons\cms\model\SearchLog;
  7. use think\Config;
  8. use think\Session;
  9. /**
  10. * 搜索控制器
  11. * Class Search
  12. * @package addons\cms\controller
  13. */
  14. class Search extends Base
  15. {
  16. public function index()
  17. {
  18. $config = get_addon_config('cms');
  19. $search = $this->request->request("search", $this->request->request("q", ""));
  20. $search = mb_substr($search, 0, 100);
  21. if (!$search) {
  22. $this->error("关键字不能为空");
  23. }
  24. //搜索入库
  25. $token = $this->request->request("__searchtoken__");
  26. if ($search && $token && $token == Session::get("__searchtoken__")) {
  27. $log = SearchLog::getByKeywords($search);
  28. if ($log) {
  29. $log->setInc("nums");
  30. } else {
  31. SearchLog::create(['keywords' => $search, 'nums' => 1]);
  32. }
  33. }
  34. if ($config['searchtype'] == 'xunsearch') {
  35. return $this->xunsearch();
  36. }
  37. $filterList = [];
  38. $orderList = [];
  39. $orderby = $this->request->get('orderby', '');
  40. $orderway = $this->request->get('orderway', '', 'strtolower');
  41. $params = ['q' => $search];
  42. if ($orderby) {
  43. $params['orderby'] = $orderby;
  44. }
  45. if ($orderway) {
  46. $params['orderway'] = $orderway;
  47. }
  48. //默认排序字段
  49. $orders = [
  50. ['name' => 'default', 'field' => 'weigh', 'title' => __('Default')],
  51. ['name' => 'views', 'field' => 'views', 'title' => __('Views')],
  52. ['name' => 'id', 'field' => 'id', 'title' => __('Post date')],
  53. ];
  54. //获取排序列表
  55. list($orderList, $orderby, $orderway) = Service::getOrderList($orderby, $orderway, $orders, $params);
  56. $pageList = Archives
  57. ::where('status', 'normal')
  58. ->whereNull('deletetime')
  59. ->where('title', 'like', "%{$search}%")
  60. ->order($orderby, $orderway)
  61. ->paginate(10, $config['pagemode'] == 'simple', ['type' => '\\addons\\cms\\library\\Bootstrap']);
  62. $pageList->appends(array_filter($params));
  63. $this->view->assign("__FILTERLIST__", $filterList);
  64. $this->view->assign("__ORDERLIST__", $orderList);
  65. $this->view->assign("__PAGELIST__", $pageList);
  66. Config::set('cms.title', __("Search for %s", $search));
  67. return $this->view->fetch('/search');
  68. }
  69. public function typeahead()
  70. {
  71. $search = $this->request->post("search", $this->request->post("q", ""));
  72. $search = mb_substr($search, 0, 100);
  73. $list = Archives
  74. ::where('status', 'normal')
  75. ->whereNull('deletetime')
  76. ->where('title', 'like', "%{$search}%")
  77. ->order('id', 'desc')
  78. ->field('id,title,diyname,channel_id,likes,dislikes,tags,createtime')
  79. ->limit(10)
  80. ->select();
  81. $result = collection($list)->toArray();
  82. $result[] = ['id' => 0, 'title' => __('Search more %s', $search), 'url' => addon_url("cms/search/index", [':search' => $search, 'search' => $search])];
  83. return json($result);
  84. }
  85. /**
  86. * Xunsearch搜索
  87. * @return string
  88. * @throws \think\Exception
  89. */
  90. public function xunsearch()
  91. {
  92. $orderList = [
  93. 'relevance' => '默认排序',
  94. 'createtime_desc' => '发布时间从新到旧',
  95. 'createtime_asc' => '发布时间从旧到新',
  96. 'views_desc' => '浏览次数从多到少',
  97. 'views_asc' => '浏览次数从少到多',
  98. 'comments_desc' => '评论次数从多到少',
  99. 'comments_asc' => '评论次数从少到多',
  100. ];
  101. $q = $this->request->request('q', $this->request->request('search', ''));
  102. $q = mb_substr($q, 0, 100);
  103. $page = $this->request->get('page/d', '1');
  104. $order = $this->request->get('order', '');
  105. $fulltext = $this->request->get('fulltext/d', '1');
  106. $fuzzy = $this->request->get('fuzzy/d', '0');
  107. $synonyms = $this->request->get('synonyms/d', '0');
  108. $total_begin = microtime(true);
  109. $search = null;
  110. $pagesize = 10;
  111. $result = FulltextSearch::search($q, $page, $pagesize, $order, $fulltext, $fuzzy, $synonyms);
  112. // 计算总耗时
  113. $total_cost = microtime(true) - $total_begin;
  114. //获取热门搜索
  115. $hot = FulltextSearch::hot();
  116. $data = [
  117. 'q' => $q,
  118. 'error' => '',
  119. 'total' => $result['total'],
  120. 'count' => $result['count'],
  121. 'search_cost' => $result['microseconds'],
  122. 'docs' => $result['list'],
  123. 'pager' => $result['pager'],
  124. 'corrected' => $result['corrected'],
  125. 'highlight' => $result['highlight'],
  126. 'related' => $result['related'],
  127. 'search' => $search,
  128. 'fulltext' => $fulltext,
  129. 'synonyms' => $synonyms,
  130. 'fuzzy' => $fuzzy,
  131. 'order' => $order,
  132. 'orderList' => $orderList,
  133. 'hot' => $hot,
  134. 'total_cost' => $total_cost,
  135. ];
  136. Config::set('cms.title', __("Search for %s", $q));
  137. $this->view->assign("title", $q);
  138. $this->view->assign($data);
  139. return $this->view->fetch('/xunsearch');
  140. }
  141. public function suggestion()
  142. {
  143. $q = trim($this->request->get('q', ''));
  144. $q = mb_substr($q, 0, 100);
  145. $terms = [];
  146. $config = get_addon_config('cms');
  147. if ($config['searchtype'] == 'xunsearch') {
  148. $terms = FulltextSearch::suggestion($q);
  149. } else {
  150. $terms = SearchLog::where("keywords", "LIKE", "{$q}%")->where("nums", ">", 0)->column("keywords");
  151. }
  152. return json($terms);
  153. }
  154. }