diff --git a/WebFirst/database/sqlite.db b/WebFirst/database/sqlite.db
index 25f2976c..b7d7dd70 100644
Binary files a/WebFirst/database/sqlite.db and b/WebFirst/database/sqlite.db differ
diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml
index cef7ad07..5b252db1 100644
--- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml
+++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml
@@ -336,6 +336,14 @@
+
+
+ 动态条件分页查询
+
+
+
+
+
动态条件分页查询
@@ -478,6 +486,13 @@
+
+
+ 操作日志测试
+
+
+
+
用户管理
diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/LoginLogController.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/LoginLogController.cs
new file mode 100644
index 00000000..7c831f84
--- /dev/null
+++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/LoginLogController.cs
@@ -0,0 +1,28 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Yi.Framework.Common.Models;
+using Yi.Framework.Interface;
+using Yi.Framework.Model.Models;
+using Yi.Framework.Repository;
+using Yi.Framework.WebCore;
+using Yi.Framework.WebCore.AttributeExtend;
+using Yi.Framework.WebCore.AuthorizationPolicy;
+
+namespace Yi.Framework.ApiMicroservice.Controllers
+{
+ [ApiController]
+ [Route("api/[controller]/[action]")]
+ public class LoginLogController : BaseCrudController
+ {
+ private ILoginLogService _iLoginLogService;
+ public LoginLogController(ILogger logger, ILoginLogService iLoginLogService) : base(logger, iLoginLogService)
+ {
+ _iLoginLogService = iLoginLogService;
+ }
+ }
+}
diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/OperationLogController.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/OperationLogController.cs
new file mode 100644
index 00000000..86663cba
--- /dev/null
+++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/OperationLogController.cs
@@ -0,0 +1,41 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Yi.Framework.Common.Models;
+using Yi.Framework.Interface;
+using Yi.Framework.Model.Models;
+using Yi.Framework.Repository;
+using Yi.Framework.WebCore;
+using Yi.Framework.WebCore.AttributeExtend;
+using Yi.Framework.WebCore.AuthorizationPolicy;
+
+namespace Yi.Framework.ApiMicroservice.Controllers
+{
+ [ApiController]
+ [Route("api/[controller]/[action]")]
+ public class OperationLogController : BaseSimpleCrudController
+ {
+ private IOperationLogService _iOperationLogService;
+ public OperationLogController(ILogger logger, IOperationLogService iOperationLogService) : base(logger, iOperationLogService)
+ {
+ _iOperationLogService = iOperationLogService;
+ }
+ ///
+ /// 动态条件分页查询
+ ///
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task PageList([FromQuery] OperationLogEntity operationLog, [FromQuery] PageParModel page)
+ {
+ return Result.Success().SetData(await _iOperationLogService.SelctPageList(operationLog, page));
+ }
+
+
+ }
+}
diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/TestController.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/TestController.cs
index c2bb50e6..72f6bb66 100644
--- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/TestController.cs
+++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/TestController.cs
@@ -221,6 +221,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
return Result.Success();
}
+
///
/// 清空数据库
///
@@ -256,5 +257,17 @@ namespace Yi.Framework.ApiMicroservice.Controllers
var rep = _iUserService._repository;
return Result.Success().SetStatus(DbSeedExtend.Invoer(rep._Db));
}
+
+ ///
+ /// 操作日志测试
+ ///
+ ///
+ ///
+ [HttpPost]
+ [Log("测试模块", Common.Enum.OperEnum.Insert)]
+ public Result LogTest(List par)
+ {
+ return Result.Success().SetData(par);
+ }
}
}
diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Program.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Program.cs
index b797f44a..f7674f71 100644
--- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Program.cs
+++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Program.cs
@@ -163,6 +163,11 @@ app.UseStaticFiles();
//Թʻע
#endregion
app.UseLocalizerService();
+
+#region
+//body
+#endregion
+app.UseHttpBodyService();
#region
//HttpsRedirectionע
#endregion
diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Yi.Framework.ApiMicroservice.csproj b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Yi.Framework.ApiMicroservice.csproj
index 5a98ed12..6edd784f 100644
--- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Yi.Framework.ApiMicroservice.csproj
+++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Yi.Framework.ApiMicroservice.csproj
@@ -34,6 +34,9 @@
Always
+
+ Always
+
Always
diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/ip2region.db b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/ip2region.db
new file mode 100644
index 00000000..0fc60e6c
Binary files /dev/null and b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/ip2region.db differ
diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db
index 20cbf7bc..f226bb05 100644
Binary files a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db and b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db differ
diff --git a/Yi.Framework.Net6/Yi.Framework.Common/Enum/OperationEnum.cs b/Yi.Framework.Net6/Yi.Framework.Common/Enum/OperEnum.cs
similarity index 91%
rename from Yi.Framework.Net6/Yi.Framework.Common/Enum/OperationEnum.cs
rename to Yi.Framework.Net6/Yi.Framework.Common/Enum/OperEnum.cs
index 592775f1..ecfd535a 100644
--- a/Yi.Framework.Net6/Yi.Framework.Common/Enum/OperationEnum.cs
+++ b/Yi.Framework.Net6/Yi.Framework.Common/Enum/OperEnum.cs
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace Yi.Framework.Common.Enum
{
- public enum OperationEnum
+ public enum OperEnum
{
Insert=1,
Update=2,
diff --git a/Yi.Framework.Net6/Yi.Framework.Common/Yi.Framework.Common.csproj b/Yi.Framework.Net6/Yi.Framework.Common/Yi.Framework.Common.csproj
index 02122188..78f348dd 100644
--- a/Yi.Framework.Net6/Yi.Framework.Common/Yi.Framework.Common.csproj
+++ b/Yi.Framework.Net6/Yi.Framework.Common/Yi.Framework.Common.csproj
@@ -7,6 +7,7 @@
+
diff --git a/Yi.Framework.Net6/Yi.Framework.Core/JwtInvoker.cs b/Yi.Framework.Net6/Yi.Framework.Core/JwtInvoker.cs
index 74ecfe3c..0bb2f670 100644
--- a/Yi.Framework.Net6/Yi.Framework.Core/JwtInvoker.cs
+++ b/Yi.Framework.Net6/Yi.Framework.Core/JwtInvoker.cs
@@ -38,7 +38,7 @@ namespace Yi.Framework.Core
claims.Add(new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"));
claims.Add(new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddMinutes(minutes)).ToUnixTimeSeconds()}"));
claims.Add(new Claim(JwtRegisteredClaimNames.Sid, user.Id.ToString()));
- claims.Add(new Claim(JwtRegisteredClaimNames.Name, user.UserName));
+ claims.Add(new Claim("userName", user.UserName));
claims.Add(new Claim("deptId", user.DeptId.ToString()));
//-----------------------------以下从user的权限表中添加权限-----------------------例如:
diff --git a/Yi.Framework.Net6/Yi.Framework.Interface/IOperationLogService.cs b/Yi.Framework.Net6/Yi.Framework.Interface/IOperationLogService.cs
new file mode 100644
index 00000000..8e7823c8
--- /dev/null
+++ b/Yi.Framework.Net6/Yi.Framework.Interface/IOperationLogService.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Yi.Framework.Common.Models;
+using Yi.Framework.Model.Models;
+using Yi.Framework.Repository;
+
+namespace Yi.Framework.Interface
+{
+ public partial interface IOperationLogService:IBaseService
+ {
+ Task>> SelctPageList(OperationLogEntity operationLog, PageParModel page);
+ }
+}
diff --git a/Yi.Framework.Net6/Yi.Framework.Interface/IServiceTemplate/ILoginLogService.cs b/Yi.Framework.Net6/Yi.Framework.Interface/IServiceTemplate/ILoginLogService.cs
new file mode 100644
index 00000000..580bba86
--- /dev/null
+++ b/Yi.Framework.Net6/Yi.Framework.Interface/IServiceTemplate/ILoginLogService.cs
@@ -0,0 +1,9 @@
+using Yi.Framework.Model.Models;
+using Yi.Framework.Repository;
+
+namespace Yi.Framework.Interface
+{
+ public partial interface ILoginLogService:IBaseService
+ {
+ }
+}
diff --git a/Yi.Framework.Net6/Yi.Framework.Interface/IServiceTemplate/IOperationLogService.cs b/Yi.Framework.Net6/Yi.Framework.Interface/IServiceTemplate/IOperationLogService.cs
new file mode 100644
index 00000000..54073186
--- /dev/null
+++ b/Yi.Framework.Net6/Yi.Framework.Interface/IServiceTemplate/IOperationLogService.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Yi.Framework.Common.Models;
+using Yi.Framework.Model.Models;
+using Yi.Framework.Repository;
+
+namespace Yi.Framework.Interface
+{
+ public partial interface IOperationLogService : IBaseService
+ {
+
+ }
+}
diff --git a/Yi.Framework.Net6/Yi.Framework.Model/ModelsTemplate/LoginLogEntity.cs b/Yi.Framework.Net6/Yi.Framework.Model/ModelsTemplate/LoginLogEntity.cs
new file mode 100644
index 00000000..d2165318
--- /dev/null
+++ b/Yi.Framework.Net6/Yi.Framework.Model/ModelsTemplate/LoginLogEntity.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json.Serialization;
+using SqlSugar;
+namespace Yi.Framework.Model.Models
+{
+ ///
+ /// 登入日志
+ ///
+ [SugarTable("LoginLog")]
+ public partial class LoginLogEntity:IBaseModelEntity
+ {
+ public LoginLogEntity()
+ {
+ this.CreateTime = DateTime.Now;
+ }
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [SugarColumn(ColumnName="Id" ,IsPrimaryKey = true )]
+ public long Id { get; set; }
+ ///
+ /// 登录用户
+ ///
+ [SugarColumn(ColumnName="LoginUser" )]
+ public string LoginUser { get; set; }
+ ///
+ /// 登录地点
+ ///
+ [SugarColumn(ColumnName="LoginLocation" )]
+ public string LoginLocation { get; set; }
+ ///
+ /// 登录Ip
+ ///
+ [SugarColumn(ColumnName="LoginIp" )]
+ public string LoginIp { get; set; }
+ ///
+ /// 浏览器
+ ///
+ [SugarColumn(ColumnName="Browser" )]
+ public string Browser { get; set; }
+ ///
+ /// 操作系统
+ ///
+ [SugarColumn(ColumnName="Os" )]
+ public string Os { get; set; }
+ ///
+ /// 登录信息
+ ///
+ [SugarColumn(ColumnName="LogMsg" )]
+ public string LogMsg { get; set; }
+ ///
+ /// 创建者
+ ///
+ [SugarColumn(ColumnName="CreateUser" )]
+ public long? CreateUser { get; set; }
+ ///
+ /// 创建时间
+ ///
+ [SugarColumn(ColumnName="CreateTime" )]
+ public DateTime? CreateTime { get; set; }
+ ///
+ /// 修改者
+ ///
+ [SugarColumn(ColumnName="ModifyUser" )]
+ public long? ModifyUser { get; set; }
+ ///
+ /// 修改时间
+ ///
+ [SugarColumn(ColumnName="ModifyTime" )]
+ public DateTime? ModifyTime { get; set; }
+ ///
+ /// 租户Id
+ ///
+ [SugarColumn(ColumnName="TenantId" )]
+ public long? TenantId { get; set; }
+ ///
+ /// 排序字段
+ ///
+ [SugarColumn(ColumnName="OrderNum" )]
+ public int? OrderNum { get; set; }
+ ///
+ /// 描述
+ ///
+ [SugarColumn(ColumnName="Remark" )]
+ public string Remark { get; set; }
+ ///
+ /// 是否删除
+ ///
+ [SugarColumn(ColumnName="IsDeleted" )]
+ public bool? IsDeleted { get; set; }
+ }
+}
diff --git a/Yi.Framework.Net6/Yi.Framework.Model/ModelsTemplate/OperationLogEntity.cs b/Yi.Framework.Net6/Yi.Framework.Model/ModelsTemplate/OperationLogEntity.cs
new file mode 100644
index 00000000..183e60a3
--- /dev/null
+++ b/Yi.Framework.Net6/Yi.Framework.Model/ModelsTemplate/OperationLogEntity.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json.Serialization;
+using SqlSugar;
+namespace Yi.Framework.Model.Models
+{
+ ///
+ /// 操作日志表
+ ///
+ [SugarTable("OperationLog")]
+ public partial class OperationLogEntity:IBaseModelEntity
+ {
+ public OperationLogEntity()
+ {
+ this.CreateTime = DateTime.Now;
+ }
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [SugarColumn(ColumnName="Id" ,IsPrimaryKey = true )]
+ public long Id { get; set; }
+ ///
+ /// 操作模块
+ ///
+ [SugarColumn(ColumnName="Title" )]
+ public string Title { get; set; }
+ ///
+ /// 操作类型
+ ///
+ [SugarColumn(ColumnName="OperType" )]
+ public int? OperType { get; set; }
+ ///
+ /// 请求方法
+ ///
+ [SugarColumn(ColumnName="RequestMethod" )]
+ public string RequestMethod { get; set; }
+ ///
+ /// 操作人员
+ ///
+ [SugarColumn(ColumnName="OperUser" )]
+ public string OperUser { get; set; }
+ ///
+ /// 操作Ip
+ ///
+ [SugarColumn(ColumnName="OperIp" )]
+ public string OperIp { get; set; }
+ ///
+ /// 操作地点
+ ///
+ [SugarColumn(ColumnName="OperLocation" )]
+ public string OperLocation { get; set; }
+ ///
+ /// 操作方法
+ ///
+ [SugarColumn(ColumnName="Method" )]
+ public string Method { get; set; }
+ ///
+ /// 请求参数
+ ///
+ [SugarColumn(ColumnName="RequestParam" )]
+ public string RequestParam { get; set; }
+ ///
+ /// 请求结果
+ ///
+ [SugarColumn(ColumnName="RequestResult" )]
+ public string RequestResult { get; set; }
+ ///
+ /// 创建者
+ ///
+ [SugarColumn(ColumnName="CreateUser" )]
+ public long? CreateUser { get; set; }
+ ///
+ /// 创建时间
+ ///
+ [SugarColumn(ColumnName="CreateTime" )]
+ public DateTime? CreateTime { get; set; }
+ ///
+ /// 修改者
+ ///
+ [SugarColumn(ColumnName="ModifyUser" )]
+ public long? ModifyUser { get; set; }
+ ///
+ /// 修改时间
+ ///
+ [SugarColumn(ColumnName="ModifyTime" )]
+ public DateTime? ModifyTime { get; set; }
+ ///
+ /// 租户Id
+ ///
+ [SugarColumn(ColumnName="TenantId" )]
+ public long? TenantId { get; set; }
+ ///
+ /// 排序字段
+ ///
+ [SugarColumn(ColumnName="OrderNum" )]
+ public int? OrderNum { get; set; }
+ ///
+ /// 描述
+ ///
+ [SugarColumn(ColumnName="Remark" )]
+ public string Remark { get; set; }
+ ///
+ /// 是否删除
+ ///
+ [SugarColumn(ColumnName="IsDeleted" )]
+ public bool? IsDeleted { get; set; }
+ }
+}
diff --git a/Yi.Framework.Net6/Yi.Framework.Model/SeedData/DictionaryInfoSeed.cs b/Yi.Framework.Net6/Yi.Framework.Model/SeedData/DictionaryInfoSeed.cs
index 41257184..7b2f998e 100644
--- a/Yi.Framework.Net6/Yi.Framework.Model/SeedData/DictionaryInfoSeed.cs
+++ b/Yi.Framework.Net6/Yi.Framework.Model/SeedData/DictionaryInfoSeed.cs
@@ -335,7 +335,7 @@ namespace Yi.Framework.Model.SeedData
{
Id = SnowFlakeSingle.Instance.NextId(),
DictLabel = "成功",
- DictValue = "0",
+ DictValue = "false",
DictType = "sys_common_status",
OrderNum = 100,
Remark = "正常状态",
@@ -346,7 +346,7 @@ namespace Yi.Framework.Model.SeedData
{
Id = SnowFlakeSingle.Instance.NextId(),
DictLabel = "失败",
- DictValue = "1",
+ DictValue = "true",
DictType = "sys_common_status",
OrderNum = 99,
Remark = "失败状态",
diff --git a/Yi.Framework.Net6/Yi.Framework.Service/OperationLogService.cs b/Yi.Framework.Net6/Yi.Framework.Service/OperationLogService.cs
new file mode 100644
index 00000000..f2f13014
--- /dev/null
+++ b/Yi.Framework.Net6/Yi.Framework.Service/OperationLogService.cs
@@ -0,0 +1,29 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Yi.Framework.Common.Models;
+using Yi.Framework.Interface;
+using Yi.Framework.Model.Models;
+using Yi.Framework.Repository;
+
+namespace Yi.Framework.Service
+{
+ public partial class OperationLogService : BaseService, IOperationLogService
+ {
+ public async Task>> SelctPageList(OperationLogEntity operationLog, PageParModel page)
+ {
+ RefAsync total = 0;
+ var data = await _repository._DbQueryable
+ .WhereIF(!string.IsNullOrEmpty(operationLog.Title), u => u.Title.Contains(operationLog.Title))
+ .WhereIF(!string.IsNullOrEmpty(operationLog.OperUser), u => u.OperUser.Contains(operationLog.OperUser))
+ .WhereIF(operationLog.OperType is not null, u => u.OperType==operationLog.OperType.GetHashCode())
+ .WhereIF(operationLog.IsDeleted.IsNotNull(), u => u.IsDeleted == operationLog.IsDeleted)
+
+ .OrderBy(u => u.OrderNum, OrderByType.Desc)
+ .ToPageListAsync(page.PageNum, page.PageSize, total);
+
+ return new PageModel>(data, total);
+ }
+ }
+}
diff --git a/Yi.Framework.Net6/Yi.Framework.Service/ServiceTemplate/LoginLogService.cs b/Yi.Framework.Net6/Yi.Framework.Service/ServiceTemplate/LoginLogService.cs
new file mode 100644
index 00000000..1c0ed6c8
--- /dev/null
+++ b/Yi.Framework.Net6/Yi.Framework.Service/ServiceTemplate/LoginLogService.cs
@@ -0,0 +1,14 @@
+using SqlSugar;
+using Yi.Framework.Interface;
+using Yi.Framework.Model.Models;
+using Yi.Framework.Repository;
+
+namespace Yi.Framework.Service
+{
+ public partial class LoginLogService : BaseService, ILoginLogService
+ {
+ public LoginLogService(IRepository repository) : base(repository)
+ {
+ }
+ }
+}
diff --git a/Yi.Framework.Net6/Yi.Framework.Service/ServiceTemplate/OperationLogService.cs b/Yi.Framework.Net6/Yi.Framework.Service/ServiceTemplate/OperationLogService.cs
new file mode 100644
index 00000000..2acae0b0
--- /dev/null
+++ b/Yi.Framework.Net6/Yi.Framework.Service/ServiceTemplate/OperationLogService.cs
@@ -0,0 +1,14 @@
+using SqlSugar;
+using Yi.Framework.Interface;
+using Yi.Framework.Model.Models;
+using Yi.Framework.Repository;
+
+namespace Yi.Framework.Service
+{
+ public partial class OperationLogService : BaseService, IOperationLogService
+ {
+ public OperationLogService(IRepository repository) : base(repository)
+ {
+ }
+ }
+}
diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/AttributeExtend/GlobalLogAttribute.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/AttributeExtend/GlobalLogAttribute.cs
index 78687593..1db516e7 100644
--- a/Yi.Framework.Net6/Yi.Framework.WebCore/AttributeExtend/GlobalLogAttribute.cs
+++ b/Yi.Framework.Net6/Yi.Framework.WebCore/AttributeExtend/GlobalLogAttribute.cs
@@ -1,4 +1,6 @@
-using Microsoft.AspNetCore.Mvc.Controllers;
+using IPTools.Core;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System;
@@ -6,36 +8,92 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Yi.Framework.Common.Helper;
+using Yi.Framework.Common.Models;
+using Yi.Framework.Interface;
+using Yi.Framework.Model.Models;
namespace Yi.Framework.WebCore.AttributeExtend
{
public class GlobalLogAttribute : ActionFilterAttribute
{
private ILogger _logger;
+ private IOperationLogService _operationLogService;
//注入一个日志服务
- public GlobalLogAttribute(ILogger logger)
+ public GlobalLogAttribute(ILogger logger, IOperationLogService operationLogService)
{
_logger = logger;
+ _operationLogService = operationLogService;
}
+
public override void OnResultExecuted(ResultExecutedContext context)
{
try
{
- //查找标签,获取标签对象
+ //判断标签是在方法上
if (context.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor) return;
+
+ //查找标签,获取标签对象
LogAttribute logAttribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
.FirstOrDefault(a => a.GetType().Equals(typeof(LogAttribute))) as LogAttribute;
- if (logAttribute == null) return;
- string controller = context.RouteData.Values["Controller"].ToString();
- string action = context.RouteData.Values["Action"].ToString();
- string ip = "127.0.0.1";
- string ipData = "深圳";
+ //空对象直接返回
+ if (logAttribute is null) return;
+
+ ////获取控制器名
+ //string controller = context.RouteData.Values["Controller"].ToString();
+
+ ////获取方法名
+ //string action = context.RouteData.Values["Action"].ToString();
+
+ //获取Ip
+ string ip = context.HttpContext.GetClientIp();
+
+ //根据ip获取地址
+
+ //var ipTool = IpTool.Search(ip);
+ //string location = ipTool.Province + " " + ipTool.City;
+
//日志服务插入一条操作记录即可
+
+ var logEntity = new OperationLogEntity();
+
+ logEntity.OperIp = ip;
+ //logEntity.OperLocation = location;
+ logEntity.OperType = logAttribute.OperType.GetHashCode();
+ logEntity.Title = logAttribute.Title;
+ logEntity.RequestMethod = context.HttpContext.Request.Method;
+ logEntity.Method = context.HttpContext.Request.Path.Value;
+ logEntity.IsDeleted = false;
+ logEntity.OperUser= context.HttpContext.GetUserNameInfo();
+ if (logAttribute.IsSaveResponseData)
+ {
+ if (context.Result is ContentResult result && result.ContentType == "application/json")
+ {
+ logEntity.RequestResult = result.Content.Replace("\r\n", "").Trim();
+ }
+ if (context.Result is JsonResult result2)
+ {
+ logEntity.RequestResult = result2.Value?.ToString();
+ }
+
+ if (context.Result is ObjectResult result3)
+ {
+ logEntity.RequestResult = JsonHelper.ObjToStr(result3.Value);
+ }
+
+ }
+
+ if (logAttribute.IsSaveRequestData)
+ {
+ logEntity.RequestParam = context.HttpContext.GetRequestValue(logEntity.RequestMethod);
+ }
+
+ _operationLogService._repository.InsertReturnSnowflakeId(logEntity);
}
catch (Exception ex)
{
- _logger.LogError(ex, $"操作日志错误:{ex.Message}");
+ _logger.LogError(ex, $"操作日志记录错误:{ex.Message}");
}
}
diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/AttributeExtend/LogAttribute.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/AttributeExtend/LogAttribute.cs
index ea594683..2ead4163 100644
--- a/Yi.Framework.Net6/Yi.Framework.WebCore/AttributeExtend/LogAttribute.cs
+++ b/Yi.Framework.Net6/Yi.Framework.WebCore/AttributeExtend/LogAttribute.cs
@@ -13,11 +13,30 @@ namespace Yi.Framework.WebCore.AttributeExtend
[AttributeUsage(AttributeTargets.Method)]
public class LogAttribute : Attribute
{
- private OperationEnum OperationType { get; set; }
+ ///
+ /// 操作类型
+ ///
+ public OperEnum OperType { get; set; }
- public LogAttribute(OperationEnum operationType)
+ ///
+ /// 日志标题(模块)
+ ///
+ public string Title { get; set; }
+
+ ///
+ /// 是否保存请求数据
+ ///
+ public bool IsSaveRequestData { get; set; } = true;
+
+ ///
+ /// 是否保存返回数据
+ ///
+ public bool IsSaveResponseData { get; set; } = true;
+
+ public LogAttribute(string title, OperEnum operationType)
{
- this.OperationType = operationType;
+ this.Title = title;
+ this.OperType = operationType;
}
}
}
\ No newline at end of file
diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/BuilderExtend/OptionsWritable/Internal/JsonOptionsWritable.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/BuilderExtend/OptionsWritable/Internal/JsonOptionsWritable.cs
index 47ee93ff..662976d5 100644
--- a/Yi.Framework.Net6/Yi.Framework.WebCore/BuilderExtend/OptionsWritable/Internal/JsonOptionsWritable.cs
+++ b/Yi.Framework.Net6/Yi.Framework.WebCore/BuilderExtend/OptionsWritable/Internal/JsonOptionsWritable.cs
@@ -15,12 +15,12 @@ internal class JsonOptionsWritable : FileOptionsWritableBase
public override void Update(Action configuration)
{
- JObject? jObject = JsonConvert.DeserializeObject(File.ReadAllText(this.FileName));
+ JObject jObject = JsonConvert.DeserializeObject(File.ReadAllText(this.FileName));
if (jObject != null)
{
TOptions option = this.Monitor.CurrentValue ?? new TOptions();
- if (jObject.TryGetValue(this.Section, out JToken? jtoken))
+ if (jObject.TryGetValue(this.Section, out JToken jtoken))
{
option = JsonConvert.DeserializeObject(jtoken.ToString()) ?? new TOptions();
configuration?.Invoke(option);
diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/CommonExtend.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/CommonExtend/HttpContextExtend.cs
similarity index 75%
rename from Yi.Framework.Net6/Yi.Framework.WebCore/CommonExtend.cs
rename to Yi.Framework.Net6/Yi.Framework.WebCore/CommonExtend/HttpContextExtend.cs
index f6b28d9a..9192839c 100644
--- a/Yi.Framework.Net6/Yi.Framework.WebCore/CommonExtend.cs
+++ b/Yi.Framework.Net6/Yi.Framework.WebCore/CommonExtend/HttpContextExtend.cs
@@ -10,10 +10,11 @@ using System.Threading.Tasks;
using Yi.Framework.Model.Models;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
+using System.Text.RegularExpressions;
namespace Yi.Framework.WebCore
{
- public static class CommonExtend
+ public static class HttpContextExtend
{
///
/// 判断是否为异步请求
@@ -45,7 +46,7 @@ namespace Yi.Framework.WebCore
public static string GetUserNameInfo(this HttpContext httpContext)
{
var p = httpContext;
- return httpContext.User.Claims.FirstOrDefault(u => u.Type == JwtRegisteredClaimNames.Name).Value;
+ return httpContext.User.Claims.FirstOrDefault(u => u.Type == "userName")?.Value;
}
///
@@ -69,6 +70,8 @@ namespace Yi.Framework.WebCore
var p = httpContext;
return httpContext.User.Claims.FirstOrDefault(u => u.Type == "permission").Value;
}
+
+
///
/// 基于HttpContext,当前鉴权方式解析,获取用户信息
/// 现在使用redis作为缓存,不需要将菜单存放至jwt中了
@@ -96,18 +99,35 @@ namespace Yi.Framework.WebCore
};
}
+ ///
+ /// 设置文件下载名称
+ ///
+ ///
+ ///
public static void FileInlineHandle(this HttpContext httpContext, string fileName)
{
string encodeFilename = System.Web.HttpUtility.UrlEncode(fileName, System.Text.Encoding.GetEncoding("UTF-8"));
httpContext.Response.Headers.Add("Content-Disposition", "inline;filename=" + encodeFilename);
}
+
+ ///
+ /// 设置文件附件名称
+ ///
+ ///
+ ///
public static void FileAttachmentHandle(this HttpContext httpContext, string fileName)
{
string encodeFilename = System.Web.HttpUtility.UrlEncode(fileName, System.Text.Encoding.GetEncoding("UTF-8"));
httpContext.Response.Headers.Add("Content-Disposition", "attachment;filename=" + encodeFilename);
}
+
+ ///
+ /// 获取语言种类
+ ///
+ ///
+ ///
public static string GetLanguage(this HttpContext httpContext)
{
string res = "zh-CN";
@@ -120,20 +140,13 @@ namespace Yi.Framework.WebCore
}
- public static string GetBody(this HttpContext httpContext)
- {
- if (httpContext.Request.Body != null)
- {
- httpContext.Request.EnableBuffering();
- httpContext.Request.Body.Position = 0;
- StreamReader stream = new StreamReader(httpContext.Request.Body);
- return stream.ReadToEndAsync().GetAwaiter().GetResult();
- }
- return "";
-
- }
-
+ ///
+ /// 获取请求Body参数
+ ///
+ ///
+ ///
+ ///
public static string GetRequestValue(this HttpContext context, string reqMethod)
{
string param;
@@ -151,5 +164,32 @@ namespace Yi.Framework.WebCore
}
return param;
}
+
+
+ ///
+ /// 获取客户端IP
+ ///
+ ///
+ ///
+ public static string GetClientIp(this HttpContext context)
+ {
+ if (context == null) return "";
+ var result = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
+ if (string.IsNullOrEmpty(result))
+ {
+ result = context.Connection.RemoteIpAddress?.ToString();
+ }
+ if (string.IsNullOrEmpty(result) || result.Contains("::1"))
+ result = "127.0.0.1";
+
+ result = result.Replace("::ffff:", "127.0.0.1");
+
+ //Ip规则效验
+ var regResult = Regex.IsMatch(result, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
+
+ result = regResult ? result : "127.0.0.1";
+ return result;
+ }
+
}
}
diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/HttpBodyExtend.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/HttpBodyExtend.cs
new file mode 100644
index 00000000..6aa7f52e
--- /dev/null
+++ b/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/HttpBodyExtend.cs
@@ -0,0 +1,44 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.WebCore.MiddlewareExtend
+{
+ public class HttpBodyMiddleware
+ {
+
+ private readonly RequestDelegate _next;
+ private ILogger _logger;
+ public HttpBodyMiddleware(RequestDelegate next, ILogger logger)
+ {
+ _next = next;
+ _logger = logger;
+ }
+
+ public async Task Invoke(HttpContext context)
+ {
+
+ context.Request.EnableBuffering();
+ if (context.Request.Query.TryGetValue("access_token", out var token))
+ {
+ context.Request.Headers.Add("Authorization", $"Bearer {token}");
+ }
+ await _next(context);
+
+ }
+
+ }
+
+ public static class HttpBodyExtend
+ {
+ public static IApplicationBuilder UseHttpBodyService(this IApplicationBuilder builder)
+ {
+ return builder.UseMiddleware();
+ }
+ }
+}
diff --git a/Yi.Vue3.X.RuoYi/src/api/monitor/operlog.js b/Yi.Vue3.X.RuoYi/src/api/monitor/operlog.js
index a04bca84..17c3470a 100644
--- a/Yi.Vue3.X.RuoYi/src/api/monitor/operlog.js
+++ b/Yi.Vue3.X.RuoYi/src/api/monitor/operlog.js
@@ -3,7 +3,7 @@ import request from '@/utils/request'
// 查询操作日志列表
export function list(query) {
return request({
- url: '/monitor/operlog/list',
+ url: '/operationLog/pageList',
method: 'get',
params: query
})
@@ -12,15 +12,16 @@ export function list(query) {
// 删除操作日志
export function delOperlog(operId) {
return request({
- url: '/monitor/operlog/' + operId,
- method: 'delete'
+ url: '/operationLog/delList',
+ method: 'delete',
+ data:"string"==typeof(operId)?[operId]:operId
})
}
// 清空操作日志
export function cleanOperlog() {
return request({
- url: '/monitor/operlog/clean',
+ url: '/operationLog/clear',
method: 'delete'
})
}
diff --git a/Yi.Vue3.X.RuoYi/src/views/monitor/operlog/index.vue b/Yi.Vue3.X.RuoYi/src/views/monitor/operlog/index.vue
index 2e782bb7..4e2510c4 100644
--- a/Yi.Vue3.X.RuoYi/src/views/monitor/operlog/index.vue
+++ b/Yi.Vue3.X.RuoYi/src/views/monitor/operlog/index.vue
@@ -10,18 +10,18 @@
@keyup.enter="handleQuery"
/>
-
+
-
+
-
-
-
-
-
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
- {{ parseTime(scope.row.operTime) }}
+ {{ parseTime(scope.row.createTime) }}
@@ -147,32 +138,32 @@
{{ form.title }} / {{ typeFormat(form) }}
{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}
+ >{{ form.operUser }} / {{ form.operIp }} / {{ form.operLocation }}
- {{ form.operUrl }}
+ {{ form.method }}
{{ form.requestMethod }}
{{ form.method }}
- {{ form.operParam }}
+ {{ form.requestParam }}
- {{ form.jsonResult }}
+ {{ form.requestResult }}
- 正常
- 失败
+ 正常
+ 失败
- {{ parseTime(form.operTime) }}
+ {{ parseTime(form.createTime) }}
- {{ form.errorMsg }}
+ {{ form.errorMsg }}
@@ -209,9 +200,9 @@ const data = reactive({
pageNum: 1,
pageSize: 10,
title: undefined,
- operName: undefined,
- businessType: undefined,
- status: undefined
+ operUser: undefined,
+ operType: undefined,
+ isDeleted: undefined
}
});
@@ -221,8 +212,8 @@ const { queryParams, form } = toRefs(data);
function getList() {
loading.value = true;
list(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => {
- operlogList.value = response.rows;
- total.value = response.total;
+ operlogList.value = response.data.data;
+ total.value = response.data.total;
loading.value = false;
});
}
@@ -244,7 +235,7 @@ function resetQuery() {
}
/** 多选框选中数据 */
function handleSelectionChange(selection) {
- ids.value = selection.map(item => item.operId);
+ ids.value = selection.map(item => item.id);
multiple.value = !selection.length;
}
/** 排序触发事件 */
@@ -260,7 +251,7 @@ function handleView(row) {
}
/** 删除按钮操作 */
function handleDelete(row) {
- const operIds = row.operId || ids.value;
+ const operIds = row.id || ids.value;
proxy.$modal.confirm('是否确认删除日志编号为"' + operIds + '"的数据项?').then(function () {
return delOperlog(operIds);
}).then(() => {