SearchController.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using Common;
  2. using Masuit.MyBlogs.Core.Extensions;
  3. using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
  4. using Masuit.MyBlogs.Core.Models.DTO;
  5. using Masuit.MyBlogs.Core.Models.Entity;
  6. using Masuit.Tools.NoSQL;
  7. using Microsoft.AspNetCore.Mvc;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Diagnostics;
  11. using System.Linq;
  12. using System.Linq.Expressions;
  13. using System.Text.RegularExpressions;
  14. namespace Masuit.MyBlogs.Core.Controllers
  15. {
  16. /// <summary>
  17. /// 站内搜索
  18. /// </summary>
  19. public class SearchController : BaseController
  20. {
  21. /// <summary>
  22. ///
  23. /// </summary>
  24. public ISearchDetailsService SearchDetailsService { get; set; }
  25. private readonly IPostService _postService;
  26. /// <summary>
  27. /// 站内搜索
  28. /// </summary>
  29. /// <param name="searchDetailsService"></param>
  30. /// <param name="postService"></param>
  31. public SearchController(ISearchDetailsService searchDetailsService, IPostService postService)
  32. {
  33. SearchDetailsService = searchDetailsService;
  34. _postService = postService;
  35. }
  36. /// <summary>
  37. /// 搜索页
  38. /// </summary>
  39. /// <param name="wd"></param>
  40. /// <param name="page"></param>
  41. /// <param name="size"></param>
  42. /// <returns></returns>
  43. [Route("s/{wd?}/{page:int?}/{size:int?}"), ResponseCache(VaryByQueryKeys = new[] { "wd", "page", "size" }, Duration = 60)]
  44. public ActionResult Search(string wd = "", int page = 1, int size = 10)
  45. {
  46. var nul = new List<PostOutputDto>();
  47. int count = 0;
  48. ViewBag.Elapsed = 0;
  49. ViewBag.Total = count;
  50. ViewBag.Keyword = wd;
  51. if (Regex.Match(wd, CommonHelper.BanRegex).Length > 0 || Regex.Match(wd, CommonHelper.ModRegex).Length > 0)
  52. {
  53. //ViewBag.Wd = "";
  54. return RedirectToAction("Search");
  55. }
  56. var start = DateTime.Today.AddDays(-7);
  57. using (RedisHelper redisHelper = RedisHelper.GetInstance())
  58. {
  59. string key = HttpContext.Connection.Id;
  60. if (redisHelper.KeyExists(key) && !redisHelper.GetString(key).Equals(wd))
  61. {
  62. var hotSearches = SearchDetailsService.LoadEntitiesFromL2CacheNoTracking(s => s.SearchTime > start, s => s.SearchTime, false).GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(7).Select(g => new KeywordsRankOutputDto()
  63. {
  64. KeyWords = g.FirstOrDefault().KeyWords,
  65. SearchCount = g.Count()
  66. }).ToList();
  67. ViewBag.hotSearches = hotSearches;
  68. ViewBag.ErrorMsg = "10秒内只能搜索1次!";
  69. return View(nul);
  70. }
  71. wd = wd.Trim().Replace("+", " ");
  72. if (!string.IsNullOrWhiteSpace(wd) && !wd.Contains("锟斤拷"))
  73. {
  74. if (page == 1)
  75. {
  76. SearchDetailsService.AddEntity(new SearchDetails()
  77. {
  78. KeyWords = wd,
  79. SearchTime = DateTime.Now,
  80. IP = HttpContext.Connection.RemoteIpAddress.ToString()
  81. });
  82. }
  83. string[] keywords = LuceneHelper.CutKeywords(wd).ToArray();
  84. Stopwatch sw = Stopwatch.StartNew();
  85. var posts = _postService.SearchPage(page, size, out count, keywords, p => p.ModifyDate);
  86. ViewBag.Elapsed = sw.Elapsed.TotalMilliseconds;
  87. ViewBag.Total = count;
  88. SearchDetailsService.SaveChanges();
  89. if (count > 1)
  90. {
  91. redisHelper.SetString(key, wd, TimeSpan.FromSeconds(10));
  92. }
  93. ViewBag.hotSearches = new List<KeywordsRankOutputDto>();
  94. return View(posts);
  95. }
  96. ViewBag.hotSearches = SearchDetailsService.LoadEntitiesFromL2CacheNoTracking(s => s.SearchTime > start, s => s.SearchTime, false).GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(7).Select(g => new KeywordsRankOutputDto()
  97. {
  98. KeyWords = g.FirstOrDefault().KeyWords,
  99. SearchCount = g.Count()
  100. }).ToList();
  101. return View(nul);
  102. }
  103. }
  104. /// <summary>
  105. /// 关键词推荐
  106. /// </summary>
  107. /// <param name="page"></param>
  108. /// <param name="size"></param>
  109. /// <param name="search"></param>
  110. /// <returns></returns>
  111. [Authority, HttpPost]
  112. public ActionResult SearchList(int page = 1, int size = 10, string search = "")
  113. {
  114. if (page <= 0)
  115. {
  116. page = 1;
  117. }
  118. var @where = string.IsNullOrEmpty(search) ? (Expression<Func<SearchDetails, bool>>)(s => true) : s => s.KeyWords.Contains(search);
  119. var list = SearchDetailsService.LoadPageEntities<DateTime, SearchDetailsOutputDto>(page, size, out int total, where, s => s.SearchTime, false).ToList();
  120. var pageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
  121. return PageResult(list, pageCount, total);
  122. }
  123. /// <summary>
  124. /// 热词
  125. /// </summary>
  126. /// <returns></returns>
  127. [Authority, HttpPost]
  128. public ActionResult HotKey()
  129. {
  130. var start = DateTime.Today.AddMonths(-1);
  131. var temp = SearchDetailsService.LoadEntitiesNoTracking(s => s.SearchTime > start, s => s.SearchTime, false).ToList();
  132. var month = temp.GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(30).Select(g => new
  133. {
  134. Keywords = g.FirstOrDefault().KeyWords,
  135. Count = g.Count()
  136. }).ToList();
  137. var week = temp.Where(s => s.SearchTime > DateTime.Today.AddDays(-7)).GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(30).Select(g => new
  138. {
  139. Keywords = g.FirstOrDefault().KeyWords,
  140. Count = g.Count()
  141. }).ToList();
  142. var today = temp.Where(s => s.SearchTime > DateTime.Today).GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(30).Select(g => new
  143. {
  144. Keywords = g.FirstOrDefault().KeyWords,
  145. Count = g.Count()
  146. }).ToList();
  147. return ResultData(new
  148. {
  149. month,
  150. week,
  151. today
  152. });
  153. }
  154. /// <summary>
  155. /// 删除搜索记录
  156. /// </summary>
  157. /// <param name="id"></param>
  158. /// <returns></returns>
  159. [HttpPost, Authority]
  160. public ActionResult Delete(int id)
  161. {
  162. bool b = SearchDetailsService.DeleteByIdSaved(id);
  163. return ResultData(null, b, b ? "删除成功!" : "删除失败!");
  164. }
  165. }
  166. }