Ver código fonte

1.dashboard使用highstock渲染
2.一些bug修复
3.全文检索优化

懒得勤快 6 anos atrás
pai
commit
0e676c78c5
30 arquivos alterados com 321 adições e 472 exclusões
  1. 5 0
      src/Masuit.MyBlogs.Core/Common/CommonHelper.cs
  2. 11 0
      src/Masuit.MyBlogs.Core/Common/HangfireHelper.cs
  3. 14 0
      src/Masuit.MyBlogs.Core/Configs/AppConfig.cs
  4. 9 0
      src/Masuit.MyBlogs.Core/Configs/HangfireJobInit.cs
  5. 6 1
      src/Masuit.MyBlogs.Core/Configs/RegisterAutomapper.cs
  6. 12 3
      src/Masuit.MyBlogs.Core/Controllers/BugController.cs
  7. 1 0
      src/Masuit.MyBlogs.Core/Controllers/PostController.cs
  8. 2 0
      src/Masuit.MyBlogs.Core/Controllers/SearchController.cs
  9. 3 0
      src/Masuit.MyBlogs.Core/Extensions/AuthorityAttribute.cs
  10. 15 1
      src/Masuit.MyBlogs.Core/Extensions/ExceptionMiddleware.cs
  11. 5 0
      src/Masuit.MyBlogs.Core/Extensions/FirewallMiddleware.cs
  12. 32 0
      src/Masuit.MyBlogs.Core/Extensions/Hangfire/HangfireBackJob.cs
  13. 27 0
      src/Masuit.MyBlogs.Core/Extensions/Hangfire/IHangfireBackJob.cs
  14. 2 2
      src/Masuit.MyBlogs.Core/Hubs/MyHub.cs
  15. 8 243
      src/Masuit.MyBlogs.Core/Infrastructure/Services/BaseService.cs
  16. 4 2
      src/Masuit.MyBlogs.Core/Infrastructure/Services/CategoryService.cs
  17. 4 2
      src/Masuit.MyBlogs.Core/Infrastructure/Services/CommentService.cs
  18. 0 166
      src/Masuit.MyBlogs.Core/Infrastructure/Services/Interface/IBaseService.cs
  19. 6 2
      src/Masuit.MyBlogs.Core/Infrastructure/Services/Interface/IServices.cs
  20. 4 2
      src/Masuit.MyBlogs.Core/Infrastructure/Services/LeaveMessageService.cs
  21. 4 3
      src/Masuit.MyBlogs.Core/Infrastructure/Services/MenuService.cs
  22. 3 11
      src/Masuit.MyBlogs.Core/Infrastructure/Services/PostService.cs
  23. 35 18
      src/Masuit.MyBlogs.Core/Infrastructure/Services/Services.cs
  24. 3 1
      src/Masuit.MyBlogs.Core/Infrastructure/Services/UserInfoService.cs
  25. 0 1
      src/Masuit.MyBlogs.Core/Masuit.MyBlogs.Core.csproj
  26. 1 1
      src/Masuit.MyBlogs.Core/Models/Entity/BaseEntity.cs
  27. 7 7
      src/Masuit.MyBlogs.Core/Models/Entity/Issue.cs
  28. 5 1
      src/Masuit.MyBlogs.Core/Startup.cs
  29. 3 3
      src/Masuit.MyBlogs.Core/Views/Dashboard/Index.cshtml
  30. 90 2
      src/Masuit.MyBlogs.Core/wwwroot/ng-views/controllers/dashboard.js

+ 5 - 0
src/Masuit.MyBlogs.Core/Common/CommonHelper.cs

@@ -499,6 +499,11 @@ namespace Common
             return (url, success);
             return (url, success);
         }
         }
 
 
+        /// <summary>
+        /// 替换img标签的src属性
+        /// </summary>
+        /// <param name="content"></param>
+        /// <returns></returns>
         public static string ReplaceImgSrc(string content)
         public static string ReplaceImgSrc(string content)
         {
         {
             var srcs = content.MatchImgSrcs();
             var srcs = content.MatchImgSrcs();

+ 11 - 0
src/Masuit.MyBlogs.Core/Common/HangfireHelper.cs

@@ -5,10 +5,21 @@ using System;
 
 
 namespace Masuit.MyBlogs.Core.Common
 namespace Masuit.MyBlogs.Core.Common
 {
 {
+    /// <summary>
+    /// HangfireHelper
+    /// </summary>
     public static class HangfireHelper
     public static class HangfireHelper
     {
     {
         private static BackgroundJobClient Client { get; set; } = new BackgroundJobClient();
         private static BackgroundJobClient Client { get; set; } = new BackgroundJobClient();
 
 
+        /// <summary>
+        /// 创建任务
+        /// </summary>
+        /// <param name="type">任务类</param>
+        /// <param name="method">调用方法</param>
+        /// <param name="queue">队列名</param>
+        /// <param name="args">调用参数</param>
+        /// <returns></returns>
         public static string CreateJob(Type type, string method, string queue = "", params dynamic[] args)
         public static string CreateJob(Type type, string method, string queue = "", params dynamic[] args)
         {
         {
             var job = new Job(type, type.GetMethod(method), args);
             var job = new Job(type, type.GetMethod(method), args);

+ 14 - 0
src/Masuit.MyBlogs.Core/Configs/AppConfig.cs

@@ -1,9 +1,23 @@
 namespace Masuit.MyBlogs.Core.Configs
 namespace Masuit.MyBlogs.Core.Configs
 {
 {
+    /// <summary>
+    /// 应用程序配置
+    /// </summary>
     public class AppConfig
     public class AppConfig
     {
     {
+        /// <summary>
+        /// 数据库连接字符串
+        /// </summary>
         public static string ConnString { get; set; }
         public static string ConnString { get; set; }
+
+        /// <summary>
+        /// 百度AK
+        /// </summary>
         public static string BaiduAK { get; set; }
         public static string BaiduAK { get; set; }
+
+        /// <summary>
+        /// Redis连接字符串
+        /// </summary>
         public static string Redis { get; set; }
         public static string Redis { get; set; }
     }
     }
 }
 }

+ 9 - 0
src/Masuit.MyBlogs.Core/Configs/HangfireJobInit.cs

@@ -12,6 +12,9 @@ namespace Masuit.MyBlogs.Core.Configs
     /// </summary>
     /// </summary>
     public class HangfireJobInit
     public class HangfireJobInit
     {
     {
+        /// <summary>
+        /// hangfire初始化
+        /// </summary>
         public static void Start()
         public static void Start()
         {
         {
             RecurringJob.AddOrUpdate(() => CheckLinks(), Cron.HourInterval(5)); //每5h检查友链
             RecurringJob.AddOrUpdate(() => CheckLinks(), Cron.HourInterval(5)); //每5h检查友链
@@ -25,11 +28,17 @@ namespace Masuit.MyBlogs.Core.Configs
             }
             }
         }
         }
 
 
+        /// <summary>
+        /// 检查友链
+        /// </summary>
         public static void CheckLinks()
         public static void CheckLinks()
         {
         {
             HangfireHelper.CreateJob(typeof(IHangfireBackJob), nameof(HangfireBackJob.CheckLinks), "default");
             HangfireHelper.CreateJob(typeof(IHangfireBackJob), nameof(HangfireBackJob.CheckLinks), "default");
         }
         }
 
 
+        /// <summary>
+        /// 每日任务
+        /// </summary>
         public static void EverydayJob()
         public static void EverydayJob()
         {
         {
             HangfireHelper.CreateJob(typeof(IHangfireBackJob), nameof(HangfireBackJob.EverydayJob), "default");
             HangfireHelper.CreateJob(typeof(IHangfireBackJob), nameof(HangfireBackJob.EverydayJob), "default");

+ 6 - 1
src/Masuit.MyBlogs.Core/Configs/RegisterAutomapper.cs

@@ -6,10 +6,15 @@ using Masuit.MyBlogs.Core.Models.ViewModel;
 using System.Linq;
 using System.Linq;
 
 
 namespace Masuit.MyBlogs.Core.Configs
 namespace Masuit.MyBlogs.Core.Configs
-
 {
 {
+    /// <summary>
+    /// 注册automapper
+    /// </summary>
     public static class RegisterAutomapper
     public static class RegisterAutomapper
     {
     {
+        /// <summary>
+        /// 初始化
+        /// </summary>
         public static void Excute()
         public static void Excute()
         {
         {
             Mapper.Initialize(m =>
             Mapper.Initialize(m =>

+ 12 - 3
src/Masuit.MyBlogs.Core/Controllers/BugController.cs

@@ -67,10 +67,19 @@ namespace Masuit.MyBlogs.Core.Controllers
         public ActionResult PageData([FromBody]PageFilter filter)
         public ActionResult PageData([FromBody]PageFilter filter)
         {
         {
             UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
             UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
-            List<Issue> list = string.IsNullOrEmpty(filter.Kw) ? IssueService.LoadPageEntitiesFromL2CacheNoTracking(filter.Page, filter.Size, out int total, i => i.Level != BugLevel.Fatal || user.IsAdmin, i => i.SubmitTime, false).ToList() : IssueService.SearchPage(filter.Page, filter.Size, out total, new[]
+            List<Issue> list;
+            int total;
+            if (string.IsNullOrEmpty(filter.Kw))
             {
             {
-                filter.Kw
-            }, i => (i.Level != BugLevel.Fatal || user.IsAdmin), i => i.SubmitTime, false).ToList();
+                list = IssueService.LoadPageEntitiesFromL2CacheNoTracking(filter.Page, filter.Size, out total, i => i.Status != Status.Handled || i.Level != BugLevel.Fatal || user.IsAdmin, i => i.SubmitTime, false).ToList();
+            }
+            else
+            {
+                var searchResult = IssueService.SearchPage(filter.Page, filter.Size, filter.Kw);
+                total = searchResult.Total;
+                list = searchResult.Results.Where(i => i.Status != Status.Handled || i.Level != BugLevel.Fatal || user.IsAdmin).ToList();
+            }
+
             var pageCount = Math.Ceiling(total * 1.0 / filter.Size).ToInt32();
             var pageCount = Math.Ceiling(total * 1.0 / filter.Size).ToInt32();
             return PageResult(list.Select(i => new
             return PageResult(list.Select(i => new
             {
             {

+ 1 - 0
src/Masuit.MyBlogs.Core/Controllers/PostController.cs

@@ -62,6 +62,7 @@ namespace Masuit.MyBlogs.Core.Controllers
         /// <param name="hostingEnvironment"></param>
         /// <param name="hostingEnvironment"></param>
         /// <param name="searchEngine"></param>
         /// <param name="searchEngine"></param>
         /// <param name="luceneIndexer"></param>
         /// <param name="luceneIndexer"></param>
+        /// <param name="luceneIndexSearcher"></param>
         public PostController(IPostService postService, ICategoryService categoryService, IBroadcastService broadcastService, ISeminarService seminarService, IPostHistoryVersionService postHistoryVersionService, IHostingEnvironment hostingEnvironment, ISearchEngine<DataContext> searchEngine, ILuceneIndexer luceneIndexer, ILuceneIndexSearcher luceneIndexSearcher)
         public PostController(IPostService postService, ICategoryService categoryService, IBroadcastService broadcastService, ISeminarService seminarService, IPostHistoryVersionService postHistoryVersionService, IHostingEnvironment hostingEnvironment, ISearchEngine<DataContext> searchEngine, ILuceneIndexer luceneIndexer, ILuceneIndexSearcher luceneIndexSearcher)
         {
         {
             PostService = postService;
             PostService = postService;

+ 2 - 0
src/Masuit.MyBlogs.Core/Controllers/SearchController.cs

@@ -28,11 +28,13 @@ namespace Masuit.MyBlogs.Core.Controllers
         public ISearchDetailsService SearchDetailsService { get; set; }
         public ISearchDetailsService SearchDetailsService { get; set; }
         private readonly IPostService _postService;
         private readonly IPostService _postService;
         private readonly ISearchEngine<DataContext> _searchEngine;
         private readonly ISearchEngine<DataContext> _searchEngine;
+
         /// <summary>
         /// <summary>
         /// 站内搜索
         /// 站内搜索
         /// </summary>
         /// </summary>
         /// <param name="searchDetailsService"></param>
         /// <param name="searchDetailsService"></param>
         /// <param name="postService"></param>
         /// <param name="postService"></param>
+        /// <param name="searchEngine"></param>
         public SearchController(ISearchDetailsService searchDetailsService, IPostService postService, ISearchEngine<DataContext> searchEngine)
         public SearchController(ISearchDetailsService searchDetailsService, IPostService postService, ISearchEngine<DataContext> searchEngine)
         {
         {
             SearchDetailsService = searchDetailsService;
             SearchDetailsService = searchDetailsService;

+ 3 - 0
src/Masuit.MyBlogs.Core/Extensions/AuthorityAttribute.cs

@@ -14,6 +14,9 @@ using System.Web;
 
 
 namespace Masuit.MyBlogs.Core.Extensions
 namespace Masuit.MyBlogs.Core.Extensions
 {
 {
+    /// <summary>
+    /// 授权验证过滤器
+    /// </summary>
     public class AuthorityAttribute : ActionFilterAttribute
     public class AuthorityAttribute : ActionFilterAttribute
     {
     {
         /// <summary>在执行操作方法之前由 ASP.NET MVC 框架调用。</summary>
         /// <summary>在执行操作方法之前由 ASP.NET MVC 框架调用。</summary>

+ 15 - 1
src/Masuit.MyBlogs.Core/Extensions/ExceptionMiddleware.cs

@@ -7,13 +7,27 @@ using System.Threading.Tasks;
 
 
 namespace Masuit.MyBlogs.Core.Extensions
 namespace Masuit.MyBlogs.Core.Extensions
 {
 {
+    /// <summary>
+    /// 异常拦截中间件
+    /// </summary>
     public class ExceptionMiddleware
     public class ExceptionMiddleware
     {
     {
         private readonly RequestDelegate _next;
         private readonly RequestDelegate _next;
+
+        /// <summary>
+        /// 异常拦截中间件
+        /// </summary>
+        /// <param name="next"></param>
         public ExceptionMiddleware(RequestDelegate next)
         public ExceptionMiddleware(RequestDelegate next)
         {
         {
             _next = next;
             _next = next;
         }
         }
+
+        /// <summary>
+        /// 执行调用
+        /// </summary>
+        /// <param name="context"></param>
+        /// <returns></returns>
         public async Task Invoke(HttpContext context)
         public async Task Invoke(HttpContext context)
         {
         {
             try
             try
@@ -69,4 +83,4 @@ namespace Masuit.MyBlogs.Core.Extensions
             }
             }
         }
         }
     }
     }
-}
+}

+ 5 - 0
src/Masuit.MyBlogs.Core/Extensions/FirewallMiddleware.cs

@@ -29,6 +29,11 @@ namespace Masuit.MyBlogs.Core.Extensions
             _redisHelper = redisHelper;
             _redisHelper = redisHelper;
         }
         }
 
 
+        /// <summary>
+        /// 执行调用
+        /// </summary>
+        /// <param name="context"></param>
+        /// <returns></returns>
         public async Task Invoke(HttpContext context)
         public async Task Invoke(HttpContext context)
         {
         {
             string httpMethod = context.Request.Method;
             string httpMethod = context.Request.Method;

+ 32 - 0
src/Masuit.MyBlogs.Core/Extensions/Hangfire/HangfireBackJob.cs

@@ -16,6 +16,9 @@ using System.Threading.Tasks;
 
 
 namespace Masuit.MyBlogs.Core.Extensions.Hangfire
 namespace Masuit.MyBlogs.Core.Extensions.Hangfire
 {
 {
+    /// <summary>
+    /// hangfire后台任务
+    /// </summary>
     public class HangfireBackJob : IHangfireBackJob
     public class HangfireBackJob : IHangfireBackJob
     {
     {
         private readonly IUserInfoService _userInfoService;
         private readonly IUserInfoService _userInfoService;
@@ -27,6 +30,17 @@ namespace Masuit.MyBlogs.Core.Extensions.Hangfire
         private readonly IHttpClientFactory _httpClientFactory;
         private readonly IHttpClientFactory _httpClientFactory;
         private readonly IHostingEnvironment _hostingEnvironment;
         private readonly IHostingEnvironment _hostingEnvironment;
 
 
+        /// <summary>
+        /// hangfire后台任务
+        /// </summary>
+        /// <param name="userInfoService"></param>
+        /// <param name="postService"></param>
+        /// <param name="settingService"></param>
+        /// <param name="searchDetailsService"></param>
+        /// <param name="linksService"></param>
+        /// <param name="redisHelper"></param>
+        /// <param name="httpClientFactory"></param>
+        /// <param name="hostingEnvironment"></param>
         public HangfireBackJob(IUserInfoService userInfoService, IPostService postService, ISystemSettingService settingService, ISearchDetailsService searchDetailsService, ILinksService linksService, RedisHelper redisHelper, IHttpClientFactory httpClientFactory, IHostingEnvironment hostingEnvironment)
         public HangfireBackJob(IUserInfoService userInfoService, IPostService postService, ISystemSettingService settingService, ISearchDetailsService searchDetailsService, ILinksService linksService, RedisHelper redisHelper, IHttpClientFactory httpClientFactory, IHostingEnvironment hostingEnvironment)
         {
         {
             _userInfoService = userInfoService;
             _userInfoService = userInfoService;
@@ -39,6 +53,12 @@ namespace Masuit.MyBlogs.Core.Extensions.Hangfire
             _hostingEnvironment = hostingEnvironment;
             _hostingEnvironment = hostingEnvironment;
         }
         }
 
 
+        /// <summary>
+        /// 登录记录
+        /// </summary>
+        /// <param name="userInfo"></param>
+        /// <param name="ip"></param>
+        /// <param name="type"></param>
         public void LoginRecord(UserInfoOutputDto userInfo, string ip, LoginType type)
         public void LoginRecord(UserInfoOutputDto userInfo, string ip, LoginType type)
         {
         {
             var result = ip.GetPhysicsAddressInfo().Result;
             var result = ip.GetPhysicsAddressInfo().Result;
@@ -62,6 +82,10 @@ namespace Masuit.MyBlogs.Core.Extensions.Hangfire
             }
             }
         }
         }
 
 
+        /// <summary>
+        /// 文章定时发布
+        /// </summary>
+        /// <param name="p"></param>
         public void PublishPost(Post p)
         public void PublishPost(Post p)
         {
         {
             p.Status = Status.Pended;
             p.Status = Status.Pended;
@@ -81,6 +105,10 @@ namespace Masuit.MyBlogs.Core.Extensions.Hangfire
             }
             }
         }
         }
 
 
+        /// <summary>
+        /// 文章访问记录
+        /// </summary>
+        /// <param name="pid"></param>
         public void RecordPostVisit(int pid)
         public void RecordPostVisit(int pid)
         {
         {
             Post post = _postService.GetById(pid);
             Post post = _postService.GetById(pid);
@@ -101,6 +129,10 @@ namespace Masuit.MyBlogs.Core.Extensions.Hangfire
             _postService.UpdateEntitySaved(post);
             _postService.UpdateEntitySaved(post);
         }
         }
 
 
+        /// <summary>
+        /// 防火墙拦截日志
+        /// </summary>
+        /// <param name="s"></param>
         public static void InterceptLog(IpIntercepter s)
         public static void InterceptLog(IpIntercepter s)
         {
         {
             using (RedisHelper redisHelper = RedisHelper.GetInstance())
             using (RedisHelper redisHelper = RedisHelper.GetInstance())

+ 27 - 0
src/Masuit.MyBlogs.Core/Extensions/Hangfire/IHangfireBackJob.cs

@@ -4,12 +4,39 @@ using Masuit.MyBlogs.Core.Models.Enum;
 
 
 namespace Masuit.MyBlogs.Core.Extensions.Hangfire
 namespace Masuit.MyBlogs.Core.Extensions.Hangfire
 {
 {
+    /// <summary>
+    /// hangfire后台任务
+    /// </summary>
     public interface IHangfireBackJob
     public interface IHangfireBackJob
     {
     {
+        /// <summary>
+        /// 登陆记录
+        /// </summary>
+        /// <param name="userInfo"></param>
+        /// <param name="ip"></param>
+        /// <param name="type"></param>
         void LoginRecord(UserInfoOutputDto userInfo, string ip, LoginType type);
         void LoginRecord(UserInfoOutputDto userInfo, string ip, LoginType type);
+
+        /// <summary>
+        /// 文章定时发表
+        /// </summary>
+        /// <param name="p"></param>
         void PublishPost(Post p);
         void PublishPost(Post p);
+
+        /// <summary>
+        /// 文章访问记录
+        /// </summary>
+        /// <param name="pid"></param>
         void RecordPostVisit(int pid);
         void RecordPostVisit(int pid);
+
+        /// <summary>
+        /// 每日任务
+        /// </summary>
         void EverydayJob();
         void EverydayJob();
+
+        /// <summary>
+        /// 友链检查
+        /// </summary>
         void CheckLinks();
         void CheckLinks();
     }
     }
 }
 }

+ 2 - 2
src/Masuit.MyBlogs.Core/Hubs/MyHub.cs

@@ -65,7 +65,7 @@ namespace Masuit.MyBlogs.Core.Hubs
         /// <summary>
         /// <summary>
         /// 性能计数器缓存
         /// 性能计数器缓存
         /// </summary>
         /// </summary>
-        public static ConcurrentLimitedQueue<PerformanceCounter> PerformanceCounter { get; set; } = new ConcurrentLimitedQueue<PerformanceCounter>(1000);
+        public static ConcurrentLimitedQueue<PerformanceCounter> PerformanceCounter { get; set; } = new ConcurrentLimitedQueue<PerformanceCounter>(5000);
 
 
         static MyHub()
         static MyHub()
         {
         {
@@ -89,7 +89,7 @@ namespace Masuit.MyBlogs.Core.Hubs
                         Console.ForegroundColor = ConsoleColor.White;
                         Console.ForegroundColor = ConsoleColor.White;
                         errorCount++;
                         errorCount++;
                     }
                     }
-                    Thread.Sleep(5000);
+                    Thread.Sleep(1000);
                 }
                 }
             });
             });
         }
         }

+ 8 - 243
src/Masuit.MyBlogs.Core/Infrastructure/Services/BaseService.cs

@@ -1,8 +1,8 @@
-using AutoMapper.QueryableExtensions;
-using EFSecondLevelCache.Core;
+using EFSecondLevelCache.Core;
+using Masuit.LuceneEFCore.SearchEngine.Interfaces;
+using Masuit.MyBlogs.Core.Infrastructure.Application;
 using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
-using NinjaNye.SearchExtensions;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Data.SqlClient;
 using System.Data.SqlClient;
@@ -19,10 +19,13 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services
     public class BaseService<T> : IBaseService<T> where T : class, new()
     public class BaseService<T> : IBaseService<T> where T : class, new()
     {
     {
         public virtual IBaseRepository<T> BaseDal { get; set; }
         public virtual IBaseRepository<T> BaseDal { get; set; }
-
-        public BaseService(IBaseRepository<T> repository)
+        protected readonly ISearchEngine<DataContext> _searchEngine;
+        protected readonly ILuceneIndexSearcher _searcher;
+        public BaseService(IBaseRepository<T> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher)
         {
         {
             BaseDal = repository;
             BaseDal = repository;
+            _searchEngine = searchEngine;
+            _searcher = searcher;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -531,244 +534,6 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services
             return BaseDal.LoadPageEntitiesFromL2CacheNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc);
             return BaseDal.LoadPageEntitiesFromL2CacheNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc);
         }
         }
 
 
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        public List<TDto> SearchPage<TOrder, TDto>(int page, int size, out int total, string[] keywords, Expression<Func<T, TOrder>> orderBy, bool isAsc = true)
-        {
-            var query = GetAllNoTracking().Search().Containing(keywords);
-            total = query.Count();
-            IOrderedQueryable<T> order = isAsc ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
-            return order.Skip((page - 1) * size).Take(size).ProjectTo<TDto>().ToList();
-        }
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="where">其他条件</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        public List<TDto> SearchPage<TOrder, TDto>(int page, int size, out int total, string[] keywords, Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> orderBy, bool isAsc = true)
-        {
-            var query = LoadEntities(where).Search().Containing(keywords);
-            total = query.Count();
-            IOrderedQueryable<T> order = isAsc ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
-            return order.Skip((page - 1) * size).Take(size).ProjectTo<TDto>().ToList();
-        }
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        public List<T> SearchPage<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, TOrder>> orderBy, bool isAsc = true)
-        {
-            var query = GetAll().Search().Containing(keywords);
-            total = query.Count();
-            IOrderedQueryable<T> order = isAsc ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
-            return order.Skip((page - 1) * size).Take(size).ToList();
-        }
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="where">其他条件</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        public List<T> SearchPage<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> orderBy, bool isAsc = true)
-        {
-            var query = LoadEntities(where).Search().Containing(keywords);
-            total = query.Count();
-            IOrderedQueryable<T> order = isAsc ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
-            return order.Skip((page - 1) * size).Take(size).ToList();
-        }
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        public List<T> SearchPageNotracking<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, TOrder>> orderBy, bool isAsc = true)
-        {
-            var query = GetAllNoTracking().Search().Containing(keywords);
-            total = query.Count();
-            IOrderedQueryable<T> order = isAsc ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
-            return order.Skip((page - 1) * size).Take(size).ToList();
-        }
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="where">其他条件</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        public List<T> SearchPageNotracking<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> orderBy, bool isAsc = true)
-        {
-            var query = LoadEntitiesNoTracking(where).Search().Containing(keywords);
-            total = query.Count();
-            IOrderedQueryable<T> order = isAsc ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
-            return order.Skip((page - 1) * size).Take(size).ToList();
-        }
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        public List<TDto> SearchPageFromCache<TOrder, TDto>(int page, int size, out int total, string[] keywords, Expression<Func<T, TOrder>> orderBy, bool isAsc = true)
-        {
-            var query = GetAllNoTracking().Search().Containing(keywords);
-            total = query.Count();
-            IOrderedQueryable<T> order = isAsc ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
-            return order.Skip((page - 1) * size).Take(size).ProjectTo<TDto>().Cacheable().ToList();
-        }
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="where">其他条件</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        public List<TDto> SearchPageFromCache<TOrder, TDto>(int page, int size, out int total, string[] keywords, Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> orderBy, bool isAsc = true)
-        {
-            var query = LoadEntities(where).Search().Containing(keywords);
-            total = query.Count();
-            IOrderedQueryable<T> order = isAsc ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
-            return order.Skip((page - 1) * size).Take(size).ProjectTo<TDto>().Cacheable().ToList();
-        }
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        public List<T> SearchPageFromCache<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, TOrder>> orderBy, bool isAsc = true)
-        {
-            var query = GetAll().Search().Containing(keywords);
-            total = query.Count();
-            IOrderedQueryable<T> order = isAsc ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
-            return order.Skip((page - 1) * size).Take(size).Cacheable().ToList();
-        }
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="where">其他条件</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        public List<T> SearchPageFromCache<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> orderBy, bool isAsc = true)
-        {
-            var query = LoadEntities(where).Search().Containing(keywords);
-            total = query.Count();
-            IOrderedQueryable<T> order = isAsc ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
-            return order.Skip((page - 1) * size).Take(size).Cacheable().ToList();
-        }
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        public List<T> SearchPageFromCacheNotracking<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, TOrder>> orderBy, bool isAsc = true)
-        {
-            var query = GetAllNoTracking().Search().Containing(keywords);
-            total = query.Count();
-            IOrderedQueryable<T> order = isAsc ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
-            return order.Skip((page - 1) * size).Take(size).Cacheable().ToList();
-        }
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="where">其他条件</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        public List<T> SearchPageFromCacheNotracking<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> orderBy, bool isAsc = true)
-        {
-            var query = LoadEntitiesNoTracking(where).Search().Containing(keywords);
-            total = query.Count();
-            IOrderedQueryable<T> order = isAsc ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
-            return order.Skip((page - 1) * size).Take(size).Cacheable().ToList();
-        }
-
         /// <summary>
         /// <summary>
         /// 根据ID删除实体
         /// 根据ID删除实体
         /// </summary>
         /// </summary>

+ 4 - 2
src/Masuit.MyBlogs.Core/Infrastructure/Services/CategoryService.cs

@@ -1,4 +1,6 @@
-using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
+using Masuit.LuceneEFCore.SearchEngine.Interfaces;
+using Masuit.MyBlogs.Core.Infrastructure.Application;
+using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Models.Entity;
 using Masuit.MyBlogs.Core.Models.Entity;
 
 
@@ -30,7 +32,7 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services
             return b;
             return b;
         }
         }
 
 
-        public CategoryService(IBaseRepository<Category> repository) : base(repository)
+        public CategoryService(IBaseRepository<Category> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }

+ 4 - 2
src/Masuit.MyBlogs.Core/Infrastructure/Services/CommentService.cs

@@ -1,4 +1,6 @@
-using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
+using Masuit.LuceneEFCore.SearchEngine.Interfaces;
+using Masuit.MyBlogs.Core.Infrastructure.Application;
+using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Models.Entity;
 using Masuit.MyBlogs.Core.Models.Entity;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -33,7 +35,7 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services
             return 0;
             return 0;
         }
         }
 
 
-        public CommentService(IBaseRepository<Comment> repository) : base(repository)
+        public CommentService(IBaseRepository<Comment> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }

+ 0 - 166
src/Masuit.MyBlogs.Core/Infrastructure/Services/Interface/IBaseService.cs

@@ -388,172 +388,6 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services.Interface
         /// <returns>还未执行的SQL语句</returns>
         /// <returns>还未执行的SQL语句</returns>
         IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
         IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
 
 
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        List<TDto> SearchPage<TOrder, TDto>(int page, int size, out int total, string[] keywords, Expression<Func<T, TOrder>> orderBy, bool isAsc = true);
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="where">其他条件</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        List<TDto> SearchPage<TOrder, TDto>(int page, int size, out int total, string[] keywords, Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> orderBy, bool isAsc = true);
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        List<T> SearchPage<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, TOrder>> orderBy, bool isAsc = true);
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="where">其他条件</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        List<T> SearchPage<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> orderBy, bool isAsc = true);
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        List<T> SearchPageNotracking<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, TOrder>> orderBy, bool isAsc = true);
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="where">其他条件</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        List<T> SearchPageNotracking<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> orderBy, bool isAsc = true);
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        List<TDto> SearchPageFromCache<TOrder, TDto>(int page, int size, out int total, string[] keywords, Expression<Func<T, TOrder>> orderBy, bool isAsc = true);
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="where">其他条件</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        List<TDto> SearchPageFromCache<TOrder, TDto>(int page, int size, out int total, string[] keywords, Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> orderBy, bool isAsc = true);
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        List<T> SearchPageFromCache<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, TOrder>> orderBy, bool isAsc = true);
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="where">其他条件</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        List<T> SearchPageFromCache<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> orderBy, bool isAsc = true);
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        List<T> SearchPageFromCacheNotracking<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, TOrder>> orderBy, bool isAsc = true);
-
-        /// <summary>
-        /// 搜索
-        /// </summary>
-        /// <typeparam name="TOrder"></typeparam>
-        /// <param name="page">第几页</param>
-        /// <param name="size">页大小</param>
-        /// <param name="total">总条数</param>
-        /// <param name="keywords">关键词</param>
-        /// <param name="where">其他条件</param>
-        /// <param name="orderBy">排序字段</param>
-        /// <param name="isAsc">升序排列?</param>
-        /// <returns></returns>
-        List<T> SearchPageFromCacheNotracking<TOrder>(int page, int size, out int total, string[] keywords, Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> orderBy, bool isAsc = true);
-
         /// <summary>
         /// <summary>
         /// 根据ID删除实体
         /// 根据ID删除实体
         /// </summary>
         /// </summary>

+ 6 - 2
src/Masuit.MyBlogs.Core/Infrastructure/Services/Interface/IServices.cs

@@ -1,4 +1,5 @@
-using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
 
 
 namespace Masuit.MyBlogs.Core.Infrastructure.Services.Interface
 namespace Masuit.MyBlogs.Core.Infrastructure.Services.Interface
 {
 {
@@ -12,7 +13,10 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services.Interface
 
 
     public partial interface IInternalMessageService : IBaseService<InternalMessage> { }
     public partial interface IInternalMessageService : IBaseService<InternalMessage> { }
 
 
-    public partial interface IIssueService : IBaseService<Issue> { }
+    public partial interface IIssueService : IBaseService<Issue>
+    {
+        SearchResult<Issue> SearchPage(int page, int size, string keyword);
+    }
 
 
     public partial interface ILinksService : IBaseService<Links> { }
     public partial interface ILinksService : IBaseService<Links> { }
 
 

+ 4 - 2
src/Masuit.MyBlogs.Core/Infrastructure/Services/LeaveMessageService.cs

@@ -1,4 +1,6 @@
-using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
+using Masuit.LuceneEFCore.SearchEngine.Interfaces;
+using Masuit.MyBlogs.Core.Infrastructure.Application;
+using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Models.Entity;
 using Masuit.MyBlogs.Core.Models.Entity;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -30,7 +32,7 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services
             return 0;
             return 0;
         }
         }
 
 
-        public LeaveMessageService(IBaseRepository<LeaveMessage> repository) : base(repository)
+        public LeaveMessageService(IBaseRepository<LeaveMessage> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }

+ 4 - 3
src/Masuit.MyBlogs.Core/Infrastructure/Services/MenuService.cs

@@ -1,8 +1,9 @@
-using System.Collections.Generic;
+using Masuit.LuceneEFCore.SearchEngine.Interfaces;
+using Masuit.MyBlogs.Core.Infrastructure.Application;
 using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Models.Entity;
 using Masuit.MyBlogs.Core.Models.Entity;
-using System.Linq;
+using System.Collections.Generic;
 
 
 namespace Masuit.MyBlogs.Core.Infrastructure.Services
 namespace Masuit.MyBlogs.Core.Infrastructure.Services
 {
 {
@@ -18,7 +19,7 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services
             return SqlQuery<Menu>("exec sp_getChildrenMenusByParentId " + id);
             return SqlQuery<Menu>("exec sp_getChildrenMenusByParentId " + id);
         }
         }
 
 
-        public MenuService(IBaseRepository<Menu> repository) : base(repository)
+        public MenuService(IBaseRepository<Menu> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }

+ 3 - 11
src/Masuit.MyBlogs.Core/Infrastructure/Services/PostService.cs

@@ -6,6 +6,7 @@ using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Models.DTO;
 using Masuit.MyBlogs.Core.Models.DTO;
 using Masuit.MyBlogs.Core.Models.Entity;
 using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
 using PanGu;
 using PanGu;
 using PanGu.HighLight;
 using PanGu.HighLight;
 using System.Linq;
 using System.Linq;
@@ -14,17 +15,13 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services
 {
 {
     public partial class PostService : BaseService<Post>, IPostService
     public partial class PostService : BaseService<Post>, IPostService
     {
     {
-        private readonly ILuceneIndexSearcher _searcher;
-        private readonly ISearchEngine<DataContext> _searchEngine;
-        public PostService(IPostRepository repository, ILuceneIndexSearcher searcher, ISearchEngine<DataContext> searchEngine) : base(repository)
+        public PostService(IPostRepository repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
-            _searcher = searcher;
-            _searchEngine = searchEngine;
         }
         }
         public SearchResult<PostOutputDto> SearchPage(int page, int size, string keyword)
         public SearchResult<PostOutputDto> SearchPage(int page, int size, string keyword)
         {
         {
             var searchResult = _searchEngine.ScoredSearch<Post>(new SearchOptions(keyword, page, size, typeof(Post)));
             var searchResult = _searchEngine.ScoredSearch<Post>(new SearchOptions(keyword, page, size, typeof(Post)));
-            var posts = searchResult.Results.Select(p => p.Entity.Mapper<PostOutputDto>()).ToList();
+            var posts = searchResult.Results.Select(p => p.Entity.Mapper<PostOutputDto>()).Where(p => p.Status == Status.Pended).ToList();
             var simpleHtmlFormatter = new SimpleHTMLFormatter("<span style='color:red;background-color:yellow;font-size: 1.1em;font-weight:700;'>", "</span>");
             var simpleHtmlFormatter = new SimpleHTMLFormatter("<span style='color:red;background-color:yellow;font-size: 1.1em;font-weight:700;'>", "</span>");
             var highlighter = new Highlighter(simpleHtmlFormatter, new Segment()) { FragmentSize = 200 };
             var highlighter = new Highlighter(simpleHtmlFormatter, new Segment()) { FragmentSize = 200 };
             var keywords = _searcher.CutKeywords(keyword);
             var keywords = _searcher.CutKeywords(keyword);
@@ -62,10 +59,5 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services
                 Total = searchResult.TotalHits
                 Total = searchResult.TotalHits
             };
             };
         }
         }
-
-        public PostService(IBaseRepository<Post> repository, ISearchEngine<DataContext> searchEngine) : base(repository)
-        {
-            _searchEngine = searchEngine;
-        }
     }
     }
 }
 }

+ 35 - 18
src/Masuit.MyBlogs.Core/Infrastructure/Services/Services.cs

@@ -1,124 +1,141 @@
-using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
+using Masuit.LuceneEFCore.SearchEngine;
+using Masuit.LuceneEFCore.SearchEngine.Interfaces;
+using Masuit.MyBlogs.Core.Infrastructure.Application;
+using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
 using Masuit.MyBlogs.Core.Models.Entity;
 using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using System.Linq;
 
 
 namespace Masuit.MyBlogs.Core.Infrastructure.Services
 namespace Masuit.MyBlogs.Core.Infrastructure.Services
 {
 {
     public partial class BroadcastService : BaseService<Broadcast>, IBroadcastService
     public partial class BroadcastService : BaseService<Broadcast>, IBroadcastService
     {
     {
-        public BroadcastService(IBaseRepository<Broadcast> repository) : base(repository)
+        public BroadcastService(IBaseRepository<Broadcast> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class ContactsService : BaseService<Contacts>, IContactsService
     public partial class ContactsService : BaseService<Contacts>, IContactsService
     {
     {
-        public ContactsService(IBaseRepository<Contacts> repository) : base(repository)
+        public ContactsService(IBaseRepository<Contacts> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class DonateService : BaseService<Donate>, IDonateService
     public partial class DonateService : BaseService<Donate>, IDonateService
     {
     {
-        public DonateService(IBaseRepository<Donate> repository) : base(repository)
+        public DonateService(IBaseRepository<Donate> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class FastShareService : BaseService<FastShare>, IFastShareService
     public partial class FastShareService : BaseService<FastShare>, IFastShareService
     {
     {
-        public FastShareService(IBaseRepository<FastShare> repository) : base(repository)
+        public FastShareService(IBaseRepository<FastShare> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class InternalMessageService : BaseService<InternalMessage>, IInternalMessageService
     public partial class InternalMessageService : BaseService<InternalMessage>, IInternalMessageService
     {
     {
-        public InternalMessageService(IBaseRepository<InternalMessage> repository) : base(repository)
+        public InternalMessageService(IBaseRepository<InternalMessage> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class IssueService : BaseService<Issue>, IIssueService
     public partial class IssueService : BaseService<Issue>, IIssueService
     {
     {
-        public IssueService(IBaseRepository<Issue> repository) : base(repository)
+        public IssueService(IBaseRepository<Issue> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
+        public SearchResult<Issue> SearchPage(int page, int size, string keyword)
+        {
+            var searchResult = _searchEngine.ScoredSearch<Issue>(new SearchOptions(keyword, page, size, typeof(Issue)));
+            var posts = searchResult.Results.Select(p => p.Entity).Where(i => i.Status == Status.Handled).ToList();
+            return new SearchResult<Issue>()
+            {
+                Results = posts,
+                Elapsed = searchResult.Elapsed,
+                Total = searchResult.TotalHits
+            };
+        }
     }
     }
 
 
     public partial class LinksService : BaseService<Links>, ILinksService
     public partial class LinksService : BaseService<Links>, ILinksService
     {
     {
-        public LinksService(IBaseRepository<Links> repository) : base(repository)
+        public LinksService(IBaseRepository<Links> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class LoginRecordService : BaseService<LoginRecord>, ILoginRecordService
     public partial class LoginRecordService : BaseService<LoginRecord>, ILoginRecordService
     {
     {
-        public LoginRecordService(IBaseRepository<LoginRecord> repository) : base(repository)
+        public LoginRecordService(IBaseRepository<LoginRecord> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class MiscService : BaseService<Misc>, IMiscService
     public partial class MiscService : BaseService<Misc>, IMiscService
     {
     {
-        public MiscService(IBaseRepository<Misc> repository) : base(repository)
+        public MiscService(IBaseRepository<Misc> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class NoticeService : BaseService<Notice>, INoticeService
     public partial class NoticeService : BaseService<Notice>, INoticeService
     {
     {
-        public NoticeService(IBaseRepository<Notice> repository) : base(repository)
+        public NoticeService(IBaseRepository<Notice> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class PostAccessRecordService : BaseService<PostAccessRecord>, IPostAccessRecordService
     public partial class PostAccessRecordService : BaseService<PostAccessRecord>, IPostAccessRecordService
     {
     {
-        public PostAccessRecordService(IBaseRepository<PostAccessRecord> repository) : base(repository)
+        public PostAccessRecordService(IBaseRepository<PostAccessRecord> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class PostHistoryVersionService : BaseService<PostHistoryVersion>, IPostHistoryVersionService
     public partial class PostHistoryVersionService : BaseService<PostHistoryVersion>, IPostHistoryVersionService
     {
     {
-        public PostHistoryVersionService(IBaseRepository<PostHistoryVersion> repository) : base(repository)
+        public PostHistoryVersionService(IBaseRepository<PostHistoryVersion> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class SearchDetailsService : BaseService<SearchDetails>, ISearchDetailsService
     public partial class SearchDetailsService : BaseService<SearchDetails>, ISearchDetailsService
     {
     {
-        public SearchDetailsService(IBaseRepository<SearchDetails> repository) : base(repository)
+        public SearchDetailsService(IBaseRepository<SearchDetails> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class SeminarService : BaseService<Seminar>, ISeminarService
     public partial class SeminarService : BaseService<Seminar>, ISeminarService
     {
     {
-        public SeminarService(IBaseRepository<Seminar> repository) : base(repository)
+        public SeminarService(IBaseRepository<Seminar> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class SystemSettingService : BaseService<SystemSetting>, ISystemSettingService
     public partial class SystemSettingService : BaseService<SystemSetting>, ISystemSettingService
     {
     {
-        public SystemSettingService(IBaseRepository<SystemSetting> repository) : base(repository)
+        public SystemSettingService(IBaseRepository<SystemSetting> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class SeminarPostService : BaseService<SeminarPost>, ISeminarPostService
     public partial class SeminarPostService : BaseService<SeminarPost>, ISeminarPostService
     {
     {
-        public SeminarPostService(IBaseRepository<SeminarPost> repository) : base(repository)
+        public SeminarPostService(IBaseRepository<SeminarPost> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }
 
 
     public partial class SeminarPostHistoryVersionService : BaseService<SeminarPostHistoryVersion>, ISeminarPostHistoryVersionService
     public partial class SeminarPostHistoryVersionService : BaseService<SeminarPostHistoryVersion>, ISeminarPostHistoryVersionService
     {
     {
-        public SeminarPostHistoryVersionService(IBaseRepository<SeminarPostHistoryVersion> repository) : base(repository)
+        public SeminarPostHistoryVersionService(IBaseRepository<SeminarPostHistoryVersion> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }

+ 3 - 1
src/Masuit.MyBlogs.Core/Infrastructure/Services/UserInfoService.cs

@@ -1,4 +1,6 @@
 using Common;
 using Common;
+using Masuit.LuceneEFCore.SearchEngine.Interfaces;
+using Masuit.MyBlogs.Core.Infrastructure.Application;
 using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Repository.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services;
 using Masuit.MyBlogs.Core.Infrastructure.Services;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
@@ -146,7 +148,7 @@ namespace Service
             return false;
             return false;
         }
         }
 
 
-        public UserInfoService(IBaseRepository<UserInfo> repository) : base(repository)
+        public UserInfoService(IBaseRepository<UserInfo> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
         {
         }
         }
     }
     }

+ 0 - 1
src/Masuit.MyBlogs.Core/Masuit.MyBlogs.Core.csproj

@@ -70,7 +70,6 @@
     <PackageReference Include="Microsoft.AspNetCore.App" />
     <PackageReference Include="Microsoft.AspNetCore.App" />
     <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="2.2.1" />
     <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="2.2.1" />
     <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.1" />
     <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.1" />
-    <PackageReference Include="NinjaNye.SearchExtensions" Version="3.0.0" />
     <PackageReference Include="PanGu.HighLight" Version="1.0.0" />
     <PackageReference Include="PanGu.HighLight" Version="1.0.0" />
     <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" />
     <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" />
     <PackageReference Include="Quartz" Version="3.0.7" />
     <PackageReference Include="Quartz" Version="3.0.7" />

+ 1 - 1
src/Masuit.MyBlogs.Core/Models/Entity/BaseEntity.cs

@@ -9,7 +9,7 @@ namespace Masuit.MyBlogs.Core.Models.Entity
     /// </summary>
     /// </summary>
     public class BaseEntity : LuceneIndexableBaseEntity
     public class BaseEntity : LuceneIndexableBaseEntity
     {
     {
-        [DefaultValue(Status.Default)]
+        [DefaultValue(Status.Default), LuceneIndex]
         public Status Status { get; set; }
         public Status Status { get; set; }
     }
     }
 }
 }

+ 7 - 7
src/Masuit.MyBlogs.Core/Models/Entity/Issue.cs

@@ -1,9 +1,9 @@
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.LuceneEFCore.SearchEngine;
 using Masuit.MyBlogs.Core.Models.Enum;
 using Masuit.MyBlogs.Core.Models.Enum;
 using Masuit.MyBlogs.Core.Models.Validation;
 using Masuit.MyBlogs.Core.Models.Validation;
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
 
 
 namespace Masuit.MyBlogs.Core.Models.Entity
 namespace Masuit.MyBlogs.Core.Models.Entity
 {
 {
@@ -35,19 +35,19 @@ namespace Masuit.MyBlogs.Core.Models.Entity
         /// <summary>
         /// <summary>
         /// 问题标题
         /// 问题标题
         /// </summary>
         /// </summary>
-        [Required(ErrorMessage = "标题不能为空!")]
+        [Required(ErrorMessage = "标题不能为空!"), LuceneIndex]
         public string Title { get; set; }
         public string Title { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// 存在问题的页面链接
         /// 存在问题的页面链接
         /// </summary>
         /// </summary>
-        [Required(ErrorMessage = "链接不能为空!")]
+        [Required(ErrorMessage = "链接不能为空!"), LuceneIndex]
         public string Link { get; set; }
         public string Link { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// 问题的详细描述
         /// 问题的详细描述
         /// </summary>
         /// </summary>
-        [Required(ErrorMessage = "问题描述不能为空!"), SubmitCheck(20, 5000)]
+        [Required(ErrorMessage = "问题描述不能为空!"), SubmitCheck(20, 5000), LuceneIndex(IsHtml = true)]
         public string Description { get; set; }
         public string Description { get; set; }
 
 
         /// <summary>
         /// <summary>

+ 5 - 1
src/Masuit.MyBlogs.Core/Startup.cs

@@ -38,6 +38,7 @@ using Newtonsoft.Json;
 using Newtonsoft.Json.Serialization;
 using Newtonsoft.Json.Serialization;
 using Swashbuckle.AspNetCore.Swagger;
 using Swashbuckle.AspNetCore.Swagger;
 using System;
 using System;
+using System.Collections.Generic;
 using System.Data;
 using System.Data;
 using System.Data.SqlClient;
 using System.Data.SqlClient;
 using System.IO;
 using System.IO;
@@ -201,7 +202,10 @@ namespace Masuit.MyBlogs.Core
             if (!Directory.Exists(lucenePath) || Directory.GetFiles(lucenePath).Length < 1)
             if (!Directory.Exists(lucenePath) || Directory.GetFiles(lucenePath).Length < 1)
             {
             {
                 Console.WriteLine("开始自动创建Lucene索引库...");
                 Console.WriteLine("开始自动创建Lucene索引库...");
-                searchEngine.CreateIndex();
+                searchEngine.CreateIndex(new List<string>()
+                {
+                    nameof(DataContext.Post),nameof(DataContext.Issues)
+                });
                 Console.WriteLine("索引库创建完成!");
                 Console.WriteLine("索引库创建完成!");
             }
             }
 
 

+ 3 - 3
src/Masuit.MyBlogs.Core/Views/Dashboard/Index.cshtml

@@ -34,11 +34,11 @@
     <link href="~/ng-views/css/app.css" rel="stylesheet" />
     <link href="~/ng-views/css/app.css" rel="stylesheet" />
 
 
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/6.2.0/highcharts.js"></script>
+    <script src="https://img.highcharts.com.cn/highstock/highstock.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.1.0/echarts.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.1.0/echarts.min.js"></script>
     <script src="~/Assets/echarts/china.js"></script>
     <script src="~/Assets/echarts/china.js"></script>
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/6.0.3/highcharts-more.js"></script>
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/6.0.3/js/modules/solid-gauge.js"></script>
+    <script src="https://img.highcharts.com.cn/highcharts/highcharts-more.js"></script>
+    <script src="https://img.highcharts.com.cn/highcharts/modules/solid-gauge.js"></script>
     <script src="https://img.hcharts.cn/highcharts-plugins/highcharts-zh_CN.js"></script>
     <script src="https://img.hcharts.cn/highcharts-plugins/highcharts-zh_CN.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.9/angular.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.9/angular.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.9/angular-animate.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.9/angular-animate.min.js"></script>

+ 90 - 2
src/Masuit.MyBlogs.Core/wwwroot/ng-views/controllers/dashboard.js

@@ -87,7 +87,7 @@
 	}
 	}
 	$scope.connectWebsocket();
 	$scope.connectWebsocket();
 	$.post("/system/GetHistoryList", null, function(data) {
 	$.post("/system/GetHistoryList", null, function(data) {
-		$('#cpu').highcharts({
+		Highcharts.stockChart("cpu",{
 			subtitle: {
 			subtitle: {
 				text: document.ontouchstart === undefined ?
 				text: document.ontouchstart === undefined ?
 				'鼠标拖动可以进行缩放' : '手势操作进行缩放'
 				'鼠标拖动可以进行缩放' : '手势操作进行缩放'
@@ -162,6 +162,50 @@
 			scrollbar: {
 			scrollbar: {
 				enabled: false
 				enabled: false
 			},
 			},
+			rangeSelector : {
+				buttons: [{
+					type: 'minute',
+					count: 5,
+					text: '5分钟'
+				}, {
+					type: 'minute',
+					count: 15,
+					text: '15分钟'
+				}, {
+					type: 'minute',
+					count: 30,
+					text: '30分钟'
+				}, {
+					type: 'hour',
+					count: 1,
+					text: '1小时'
+				}, {
+					type: 'hour',
+					count: 2,
+					text: '2小时'
+				}, {
+					type: 'hour',
+					count: 5,
+					text: '5小时'
+				}, {
+					type: 'hour',
+					count: 12,
+					text: '12小时'
+				}, {
+					type: 'day',
+					count: 1,
+					text: '1天'
+				}, {
+					type: 'day',
+					count: 3,
+					text: '3天'
+				}, {
+					type: 'all',
+					text: 'All'
+				}],
+				inputEnabled: false,
+				selected : 1
+			},
 			tooltip: {
 			tooltip: {
 				formatter: function() {
 				formatter: function() {
 					return '时间点:<b>' + Highcharts.dateFormat("%H:%M:%S", this.points[0].x) + '</b><br/>' +
 					return '时间点:<b>' + Highcharts.dateFormat("%H:%M:%S", this.points[0].x) + '</b><br/>' +
@@ -235,7 +279,7 @@
 				},
 				},
 			}]
 			}]
 		});
 		});
-		$('#io').highcharts({
+		Highcharts.stockChart("io",{
 			subtitle: {
 			subtitle: {
 				text: document.ontouchstart === undefined ?
 				text: document.ontouchstart === undefined ?
 				'鼠标拖动可以进行缩放' : '手势操作进行缩放'
 				'鼠标拖动可以进行缩放' : '手势操作进行缩放'
@@ -287,6 +331,50 @@
 			title: {
 			title: {
 				text: '网络状态 和 磁盘I/O'
 				text: '网络状态 和 磁盘I/O'
 			},
 			},
+			rangeSelector : {
+				buttons: [{
+					type: 'minute',
+					count: 5,
+					text: '5分钟'
+				}, {
+					type: 'minute',
+					count: 15,
+					text: '15分钟'
+				}, {
+					type: 'minute',
+					count: 30,
+					text: '30分钟'
+				}, {
+					type: 'hour',
+					count: 1,
+					text: '1小时'
+				}, {
+					type: 'hour',
+					count: 2,
+					text: '2小时'
+				}, {
+					type: 'hour',
+					count: 5,
+					text: '5小时'
+				}, {
+					type: 'hour',
+					count: 12,
+					text: '12小时'
+				}, {
+					type: 'day',
+					count: 1,
+					text: '1天'
+				}, {
+					type: 'day',
+					count: 3,
+					text: '3天'
+				}, {
+					type: 'all',
+					text: 'All'
+				}],
+				inputEnabled: false,
+				selected : 1
+			},
 			xAxis: {
 			xAxis: {
 				type: 'datetime',
 				type: 'datetime',
 				tickPixelInterval: 150
 				tickPixelInterval: 150