Browse Source

新增访问记录导出功能

懒得勤快 3 years ago
parent
commit
4a708a9043

+ 10 - 4
src/Masuit.MyBlogs.Core/Common/CommonHelper.cs

@@ -8,18 +8,18 @@ using Masuit.MyBlogs.Core.Common.Mails;
 using Masuit.MyBlogs.Core.Infrastructure;
 using Masuit.Tools;
 using Masuit.Tools.Media;
+using Masuit.Tools.Systems;
 using MaxMind.GeoIP2;
 using MaxMind.GeoIP2.Exceptions;
 using MaxMind.GeoIP2.Model;
 using MaxMind.GeoIP2.Responses;
 using Polly;
-using System.Collections.Concurrent;
 using System.Drawing;
 using System.Net;
 using System.Net.Sockets;
 using System.Text;
-using Masuit.Tools.Systems;
 using TimeZoneConverter;
+using ArgumentException = System.ArgumentException;
 
 namespace Masuit.MyBlogs.Core.Common
 {
@@ -166,9 +166,15 @@ namespace Masuit.MyBlogs.Core.Common
             return Policy<CityResponse>.Handle<AddressNotFoundException>().Fallback(new CityResponse()).Execute(() => MaxmindReader.City(ip));
         }
 
-        public static IPLocation GetIPLocation(this string ips)
+        public static IPLocation GetIPLocation(this string ip)
         {
-            return GetIPLocation(IPAddress.Parse(ips));
+            var b = IPAddress.TryParse(ip, out var ipAddress);
+            if (b)
+            {
+                return GetIPLocation(ipAddress);
+            }
+
+            throw new ArgumentException("不能将" + ip + "转换成IP地址");
         }
 
         public static IPLocation GetIPLocation(this IPAddress ip)

+ 20 - 1
src/Masuit.MyBlogs.Core/Controllers/AdvertisementController.cs

@@ -1,4 +1,5 @@
 using AutoMapper.QueryableExtensions;
+using EFCoreSecondLevelCacheInterceptor;
 using Masuit.MyBlogs.Core.Common;
 using Masuit.MyBlogs.Core.Extensions;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
@@ -6,7 +7,11 @@ using Masuit.MyBlogs.Core.Models.DTO;
 using Masuit.MyBlogs.Core.Models.Entity;
 using Masuit.MyBlogs.Core.Models.Enum;
 using Masuit.MyBlogs.Core.Models.ViewModel;
+using Masuit.Tools.AspNetCore.Mime;
+using Masuit.Tools.AspNetCore.ResumeFileResults.Extensions;
 using Masuit.Tools.Core.Net;
+using Masuit.Tools.Database;
+using Masuit.Tools.Excel;
 using Masuit.Tools.Linq;
 using Masuit.Tools.Models;
 using Microsoft.AspNetCore.Mvc;
@@ -16,7 +21,6 @@ using System.ComponentModel.DataAnnotations;
 using System.Linq.Expressions;
 using System.Net;
 using System.Text.RegularExpressions;
-using EFCoreSecondLevelCacheInterceptor;
 
 namespace Masuit.MyBlogs.Core.Controllers
 {
@@ -179,6 +183,21 @@ namespace Masuit.MyBlogs.Core.Controllers
             return Ok(pages);
         }
 
+        /// <summary>
+        /// 导出广告访问记录
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <returns></returns>
+        [HttpGet("/partner/{id}/records-export"), MyAuthorize]
+        public IActionResult ExportClickRecords(int id)
+        {
+            using var ms = ClickRecordService.GetQuery<DateTime, AdvertisementClickRecordViewModel>(e => e.AdvertisementId == id, e => e.Time, false).ToList().ToDataTable().ToExcel();
+            var advertisement = AdsService[id];
+            return this.ResumeFile(ms.ToArray(), ContentType.Xlsx, advertisement.Title + "访问记录.xlsx");
+        }
+
         /// <summary>
         /// 广告访问记录图表
         /// </summary>

+ 11 - 2
src/Masuit.MyBlogs.Core/Controllers/PassportController.cs

@@ -1,4 +1,5 @@
 using CacheManager.Core;
+using Hangfire;
 using Masuit.MyBlogs.Core.Common;
 using Masuit.MyBlogs.Core.Configs;
 using Masuit.MyBlogs.Core.Extensions.Firewall;
@@ -17,7 +18,6 @@ using Masuit.Tools.Strings;
 using Microsoft.AspNetCore.Mvc;
 using System.Net;
 using System.Web;
-using Hangfire;
 
 namespace Masuit.MyBlogs.Core.Controllers
 {
@@ -142,7 +142,16 @@ namespace Masuit.MyBlogs.Core.Controllers
                 return ResultData(null, false, "用户名或密码不能为空");
             }
 
-            password = password.RSADecrypt(HttpContext.Session.Get<string>(nameof(RsaKey.PrivateKey)));
+            try
+            {
+                var privateKey = HttpContext.Session.Get<string>(nameof(RsaKey.PrivateKey));
+                password = password.RSADecrypt(privateKey);
+            }
+            catch (Exception e)
+            {
+                LogManager.Info("登录失败,私钥:" + HttpContext.Session.Get<string>(nameof(RsaKey.PrivateKey)));
+                throw;
+            }
             var userInfo = UserInfoService.Login(username, password);
             if (userInfo == null)
             {

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

@@ -19,8 +19,12 @@ using Masuit.MyBlogs.Core.Models.Enum;
 using Masuit.MyBlogs.Core.Models.ViewModel;
 using Masuit.MyBlogs.Core.Views.Post;
 using Masuit.Tools;
+using Masuit.Tools.AspNetCore.Mime;
+using Masuit.Tools.AspNetCore.ResumeFileResults.Extensions;
 using Masuit.Tools.Core.Net;
 using Masuit.Tools.Core.Validator;
+using Masuit.Tools.Database;
+using Masuit.Tools.Excel;
 using Masuit.Tools.Html;
 using Masuit.Tools.Linq;
 using Masuit.Tools.Logging;
@@ -1067,6 +1071,20 @@ namespace Masuit.MyBlogs.Core.Controllers
             return Ok(pages);
         }
 
+        /// <summary>
+        /// 导出文章访问记录
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("/{id}/records-export"), MyAuthorize]
+        [ProducesResponseType(typeof(PagedList<PostVisitRecordViewModel>), (int)HttpStatusCode.OK)]
+        public IActionResult ExportPostVisitRecords(int id)
+        {
+            using var ms = PostVisitRecordService.GetQuery<DateTime, PostVisitRecordViewModel>(e => e.PostId == id, e => e.Time, false).ToList().ToDataTable().ToExcel();
+            var post = PostService[id];
+            return this.ResumeFile(ms.ToArray(), ContentType.Xlsx, post.Title + "访问记录.xlsx");
+        }
+
         /// <summary>
         /// 文章访问记录图表
         /// </summary>

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

@@ -51,6 +51,7 @@
         <PackageReference Include="htmldiff.net-core" Version="1.3.6" />
         <PackageReference Include="IP2Region" Version="1.2.0" />
         <PackageReference Include="Karambolo.AspNetCore.Bundling.NUglify" Version="3.5.1" />
+        <PackageReference Include="Masuit.Tools.Excel" Version="1.1.2.2" />
         <PackageReference Include="MaxMind.GeoIP2" Version="5.1.0" />
         <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.4" />
         <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.4" />

+ 4 - 0
src/Masuit.MyBlogs.Core/Models/ViewModel/AdvertisementViewModel.cs

@@ -1,4 +1,5 @@
 using Masuit.MyBlogs.Core.Models.Entity;
+using System.ComponentModel;
 
 namespace Masuit.MyBlogs.Core.Models.ViewModel
 {
@@ -91,10 +92,13 @@ namespace Masuit.MyBlogs.Core.Models.ViewModel
     {
         public string IP { get; set; }
 
+        [Description("地理位置")]
         public string Location { get; set; }
 
+        [Description("来源页面")]
         public string Referer { get; set; }
 
+        [Description("访问时间")]
         public string Time { get; set; }
     }
 }

+ 7 - 3
src/Masuit.MyBlogs.Core/Models/ViewModel/PostVisitRecordViewModel.cs

@@ -1,17 +1,21 @@
-namespace Masuit.MyBlogs.Core.Models.ViewModel
+using System.ComponentModel;
+
+namespace Masuit.MyBlogs.Core.Models.ViewModel
 {
     public class PostVisitRecordViewModel
     {
         public string IP { get; set; }
 
+        [Description("地理位置")]
         public string Location { get; set; }
 
+        [Description("来源页面")]
         public string Referer { get; set; }
 
+        [Description("请求URL")]
         public string RequestUrl { get; set; }
 
-        public string RequestHeader { get; set; }
-
+        [Description("访问时间")]
         public string Time { get; set; }
     }
 }

+ 1 - 0
src/Masuit.MyBlogs.Core/Views/Advertisement/ClickRecordsInsight.cshtml

@@ -27,6 +27,7 @@
             <input class="layui-input" name="kw" id="kw">
         </div>
         <button class="layui-btn" data-type="reload">搜索</button>
+        <a class="layui-btn" asp-controller="Advertisement" asp-action="ExportClickRecords" asp-route-id="@Model.Id">导出</a>
     </div>
     <table class="layui-hide" id="table" lay-filter="tableEvent"></table>
     <div id="chart" style="height: 500px"></div>

+ 2 - 2
src/Masuit.MyBlogs.Core/Views/Drive/Index.cshtml

@@ -12,13 +12,13 @@
     <title>懒勤网盘</title>
     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@@mdi/font@latest/css/materialdesignicons.min.css">
     <link href="https://cdn.jsdelivr.net/npm/@@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
-    <link href="https://ldqk.rth1.me/chunk-vendors.39ab6aaa.css" rel="stylesheet">
+    <link href="/drive/css/chunk-vendors.39ab6aaa.css" rel="stylesheet">
     <link href="/drive/css/app.377a312e.css" rel="stylesheet">
 </head>
 <body>
     <div id="app"></div>
     <!-- built files will be auto injected -->
-    <script type="text/javascript" src="https://ldqk.rth1.me/chunk-vendors.b37660ae.js"></script>
+    <script type="text/javascript" src="/drive/js/chunk-vendors.b37660ae.js"></script>
     <script type="text/javascript" src="/drive/js/app.8b25141a.js"></script>
 </body>
 </html>

+ 1 - 0
src/Masuit.MyBlogs.Core/Views/Post/PostVisitRecordInsight.cshtml

@@ -27,6 +27,7 @@
 			<input class="layui-input" name="kw" id="kw">
 		</div>
 		<button class="layui-btn" data-type="reload">搜索</button>
+		<a class="layui-btn" asp-controller="Post" asp-action="ExportPostVisitRecords" asp-route-id="@Model.Id">导出</a>
 	</div>
 	<table class="layui-hide" id="table" lay-filter="tableEvent"></table>
 	<div id="chart" style="height: 500px"></div>

+ 1 - 1
src/Masuit.MyBlogs.Core/ueconfig.json

@@ -9,7 +9,7 @@
     "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
     "imageInsertAlign": "none", /* 插入的图片浮动方式 */
     "imageUrlPrefix": "", /* 图片访问路径前缀 */
-    "imagePathFormat": "/images/{yyyy}/{mm}/{dd}/{filename}_{hh}{ii}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+    "imagePathFormat": "/images/{yyyy}/{mm}/{dd}/{filename}_{hh}{ii}{ss}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
     /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
     /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
     /* {time} 会替换成时间戳 */