using Common;
using Masuit.LuceneEFCore.SearchEngine.Interfaces;
using Masuit.MyBlogs.Core.Extensions;
using Masuit.MyBlogs.Core.Infrastructure.Application;
using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
using Masuit.MyBlogs.Core.Models.DTO;
using Masuit.MyBlogs.Core.Models.Entity;
using Masuit.Tools;
using Masuit.Tools.Core.Net;
using Masuit.Tools.NoSQL;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Net.Http.Headers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
namespace Masuit.MyBlogs.Core.Controllers
{
///
/// 站内搜索
///
public class SearchController : BaseController
{
///
///
///
public ISearchDetailsService SearchDetailsService { get; set; }
private readonly IPostService _postService;
private readonly ISearchEngine _searchEngine;
///
/// 站内搜索
///
///
///
///
public SearchController(ISearchDetailsService searchDetailsService, IPostService postService, ISearchEngine searchEngine)
{
SearchDetailsService = searchDetailsService;
_postService = postService;
_searchEngine = searchEngine;
}
///
/// 搜索页
///
///
///
///
///
[Route("s/{wd?}/{page:int?}/{size:int?}"), ResponseCache(VaryByQueryKeys = new[] { "wd", "page", "size" }, VaryByHeader = HeaderNames.Cookie, Duration = 60)]
public ActionResult Search(string wd = "", int page = 1, int size = 10)
{
var nul = new List();
ViewBag.Elapsed = 0;
ViewBag.Total = 0;
ViewBag.Keyword = wd ?? "";
if (Regex.Match(wd, CommonHelper.BanRegex).Length > 0 || Regex.Match(wd, CommonHelper.ModRegex).Length > 0)
{
//ViewBag.Wd = "";
return RedirectToAction("Search");
}
var start = DateTime.Today.AddDays(-7);
using (RedisHelper redisHelper = RedisHelper.GetInstance())
{
string key = HttpContext.Connection.Id;
if (redisHelper.KeyExists(key) && !redisHelper.GetString(key).Equals(wd))
{
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()
{
KeyWords = g.First().KeyWords,
SearchCount = g.Count()
}).ToList();
ViewBag.hotSearches = hotSearches;
ViewBag.ErrorMsg = "10秒内只能搜索1次!";
return View(nul);
}
wd = wd.Trim().Replace("+", " ");
if (!string.IsNullOrWhiteSpace(wd) && !wd.Contains("锟斤拷"))
{
if (!HttpContext.Session.TryGetValue("search:" + wd, out _))
{
SearchDetailsService.AddEntity(new SearchDetails
{
KeyWords = wd,
SearchTime = DateTime.Now,
IP = HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString()
});
HttpContext.Session.Set("search:" + wd, wd);
}
var posts = _postService.SearchPage(page, size, wd);
ViewBag.Elapsed = posts.Elapsed;
ViewBag.Total = posts.Total;
SearchDetailsService.SaveChanges();
if (posts.Total > 1)
{
redisHelper.SetString(key, wd, TimeSpan.FromSeconds(10));
}
ViewBag.hotSearches = new List();
return View(posts.Results);
}
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()
{
KeyWords = g.FirstOrDefault().KeyWords,
SearchCount = g.Count()
}).ToList();
return View(nul);
}
}
///
/// 关键词推荐
///
///
///
///
///
[Authority, HttpPost, ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "page", "size", "search" }, VaryByHeader = HeaderNames.Cookie)]
public ActionResult SearchList(int page = 1, int size = 10, string search = "")
{
if (page <= 0)
{
page = 1;
}
var where = string.IsNullOrEmpty(search) ? (Expression>)(s => true) : s => s.KeyWords.Contains(search);
var list = SearchDetailsService.LoadPageEntities(page, size, out int total, where, s => s.SearchTime, false).ToList();
var pageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
return PageResult(list, pageCount, total);
}
///
/// 热词
///
///
[Authority, HttpPost, ResponseCache(Duration = 600, VaryByHeader = HeaderNames.Cookie)]
public ActionResult HotKey()
{
var start = DateTime.Today.AddMonths(-1);
var temp = SearchDetailsService.LoadEntitiesNoTracking(s => s.SearchTime > start, s => s.SearchTime, false).ToList();
var month = temp.GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(30).Select(g => new
{
Keywords = g.FirstOrDefault().KeyWords,
Count = g.Count()
}).ToList();
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
{
Keywords = g.FirstOrDefault().KeyWords,
Count = g.Count()
}).ToList();
var today = temp.Where(s => s.SearchTime > DateTime.Today).GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(30).Select(g => new
{
Keywords = g.FirstOrDefault().KeyWords,
Count = g.Count()
}).ToList();
return ResultData(new
{
month,
week,
today
});
}
///
/// 删除搜索记录
///
///
///
[HttpPost, Authority]
public ActionResult Delete(int id)
{
bool b = SearchDetailsService.DeleteByIdSaved(id);
return ResultData(null, b, b ? "删除成功!" : "删除失败!");
}
}
}