Parcourir la source

新增登录日志和操作日志,优化代码

xiaoxue il y a 5 ans
Parent
commit
b014471742
55 fichiers modifiés avec 1609 ajouts et 119 suppressions
  1. 1 0
      Admin.Core.Common/Admin.Core.Common.csproj
  2. 19 7
      Admin.Core.Common/Auth/IUser.cs
  3. 21 23
      Admin.Core.Common/Auth/User.cs
  4. 22 0
      Admin.Core.Common/Configs/AppConfig.cs
  5. 69 0
      Admin.Core.Model/Admin/LogAbstract.cs
  6. 12 0
      Admin.Core.Model/Admin/LoginLogEntity.cs
  7. 36 0
      Admin.Core.Model/Admin/OprationLogEntity.cs
  8. 5 0
      Admin.Core.Model/Output/IResponseOutput.cs
  9. 11 0
      Admin.Core.Repository/Admin/LoginLog/ILoginLogRepository.cs
  10. 14 0
      Admin.Core.Repository/Admin/LoginLog/LoginLogRepository.cs
  11. 11 0
      Admin.Core.Repository/Admin/OprationLog/IOprationLogRepository.cs
  12. 13 0
      Admin.Core.Repository/Admin/OprationLog/OprationLogRepository.cs
  13. 17 1
      Admin.Core.Repository/Base/IRepositoryBase.cs
  14. 15 2
      Admin.Core.Repository/Base/RepositoryBase.cs
  15. 0 4
      Admin.Core.Services/Admin.Core.Service.csproj
  16. 1 1
      Admin.Core.Services/Admin/Api/Output/ApiListOutput.cs
  17. 9 14
      Admin.Core.Services/Admin/Auth/AuthService.cs
  18. 22 0
      Admin.Core.Services/Admin/Auth/Output/AuthLoginOutput.cs
  19. 2 2
      Admin.Core.Services/Admin/Auth/_MapConfig.cs
  20. 1 1
      Admin.Core.Services/Admin/Dictionary/Output/DictionaryListOutput.cs
  21. 15 0
      Admin.Core.Services/Admin/LoginLog/ILoginLogService.cs
  22. 68 0
      Admin.Core.Services/Admin/LoginLog/Input/LoginLogAddInput.cs
  23. 74 0
      Admin.Core.Services/Admin/LoginLog/LoginLogService.cs
  24. 62 0
      Admin.Core.Services/Admin/LoginLog/Output/LoginLogListOutput.cs
  25. 17 0
      Admin.Core.Services/Admin/LoginLog/_MapConfig.cs
  26. 15 0
      Admin.Core.Services/Admin/OprationLog/IOprationLogService.cs
  27. 78 0
      Admin.Core.Services/Admin/OprationLog/Input/OprationLogAddInput.cs
  28. 73 0
      Admin.Core.Services/Admin/OprationLog/OprationLogService.cs
  29. 77 0
      Admin.Core.Services/Admin/OprationLog/Output/OprationLogListOutput.cs
  30. 17 0
      Admin.Core.Services/Admin/OprationLog/_MapConfig.cs
  31. 1 1
      Admin.Core.Services/Admin/Permission/Output/PermissionListOutput.cs
  32. 1 1
      Admin.Core.Services/Admin/Role/Output/RoleListOutput.cs
  33. 1 1
      Admin.Core.Services/Admin/User/Output/UserListOutput.cs
  34. 1 1
      Admin.Core.Services/Admin/View/Output/ViewListOutput.cs
  35. 90 0
      Admin.Core/Admin.Core.Model.xml
  36. 290 0
      Admin.Core/Admin.Core.Service.xml
  37. 0 4
      Admin.Core/Admin.Core.csproj
  38. 54 2
      Admin.Core/Admin.Core.xml
  39. 12 0
      Admin.Core/Attributes/NoOprationLogAttribute.cs
  40. 8 1
      Admin.Core/Attributes/PermissionAttribute.cs
  41. 64 9
      Admin.Core/Controllers/Admin/AuthController.cs
  42. 2 0
      Admin.Core/Controllers/Admin/ImgController.cs
  43. 33 0
      Admin.Core/Controllers/Admin/LoginLogController.cs
  44. 33 0
      Admin.Core/Controllers/Admin/OprationLogController.cs
  45. 0 0
      Admin.Core/Db/Data/data.json
  46. 3 1
      Admin.Core/Db/DbHelper.cs
  47. 8 4
      Admin.Core/Db/ServiceCollectionExtensions.cs
  48. 13 9
      Admin.Core/Filters/AdminExceptionFilter.cs
  49. 28 0
      Admin.Core/Filters/LogActionFilter.cs
  50. 53 0
      Admin.Core/Logs/ApiHelper.cs
  51. 20 0
      Admin.Core/Logs/ILogHandler.cs
  52. 59 0
      Admin.Core/Logs/LogHandler.cs
  53. 32 30
      Admin.Core/Startup.cs
  54. 5 0
      Admin.Core/configs/appconfig.json
  55. 1 0
      Admin.Core/configs/dbconfig.Development.json

+ 1 - 0
Admin.Core.Common/Admin.Core.Common.csproj

@@ -17,6 +17,7 @@
     <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.5.0" />
     <PackageReference Include="System.Drawing.Common" Version="4.7.0" />
     <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.5.0" />
+    <PackageReference Include="UAParser" Version="3.1.44" />
   </ItemGroup>
 
 </Project>

+ 19 - 7
Admin.Core.Common/Auth/IUser.cs

@@ -1,14 +1,26 @@
-using System.Collections.Generic;
-using System.Security.Claims;
-
-namespace Admin.Core.Common.Auth
+namespace Admin.Core.Common.Auth
 {
     public interface IUser
     {
+        /// <summary>
+        /// 主键
+        /// </summary>
         long Id { get; }
+        /// <summary>
+        /// 登录日志Id
+        /// </summary>
+        long LoginLogId { get; }
+        /// <summary>
+        /// 用户名
+        /// </summary>
         string Name { get; }
-        bool IsAuthenticated();
-        IEnumerable<Claim> GetClaimsIdentity();
-        List<string> GetClaimValueByType(string ClaimType);
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        string RealName { get; }
+        /// <summary>
+        /// IP
+        /// </summary>
+        string IP { get; }
     }
 }

+ 21 - 23
Admin.Core.Common/Auth/User.cs

@@ -1,7 +1,4 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Claims;
-using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http;
 
 namespace Admin.Core.Common.Auth
 {
@@ -69,6 +66,21 @@ namespace Admin.Core.Common.Auth
             }
         }
 
+        /// <summary>
+        /// 登录日志Id
+        /// </summary>
+        public long LoginLogId
+        {
+            get
+            {
+                var id = _accessor?.HttpContext?.User?.FindFirst(ClaimAttributes.UserLoginLogId);
+                if (id != null && id.Value.NotNull())
+                {
+                    return id.Value.ToLong();
+                }
+                return 0;
+            }
+        }
 
         /// <summary>
         /// 用户IP
@@ -111,25 +123,6 @@ namespace Admin.Core.Common.Auth
                 return _accessor.HttpContext.Connection.RemoteIpAddress.MapToIPv6().ToString();
             }
         }
-
-        public bool IsAuthenticated()
-        {
-            return _accessor.HttpContext.User.Identity.IsAuthenticated;
-        }
-
-        public IEnumerable<Claim> GetClaimsIdentity()
-        {
-            return _accessor.HttpContext.User.Claims;
-        }
-
-        public List<string> GetClaimValueByType(string ClaimType)
-        {
-
-            return (from item in GetClaimsIdentity()
-                    where item.Type == ClaimType
-                    select item.Value).ToList();
-
-        }
     }
 
     /// <summary>
@@ -151,5 +144,10 @@ namespace Admin.Core.Common.Auth
         /// 姓名
         /// </summary>
         public const string UserRealName = "rna";
+
+        /// <summary>
+        /// 登录日志Id
+        /// </summary>
+        public const string UserLoginLogId = "llid";
     }
 }

+ 22 - 0
Admin.Core.Common/Configs/AppConfig.cs

@@ -15,9 +15,20 @@
         /// </summary>
         public string Urls { get; set; } = "http://*:8081";
 
+        /// <summary>
+        /// Aop配置
+        /// </summary>
         public AopConfig Aop { get; set; }
+
+        /// <summary>
+        /// 日志配置
+        /// </summary>
+        public LogConfig Log { get; set; }
     }
 
+    /// <summary>
+    /// Aop配置
+    /// </summary>
     public class AopConfig
     {
         /// <summary>
@@ -25,4 +36,15 @@
         /// </summary>
         public bool Transaction { get; set; }
     }
+
+    /// <summary>
+    /// 日志配置
+    /// </summary>
+    public class LogConfig
+    {
+        /// <summary>
+        /// 操作日志
+        /// </summary>
+        public bool Operation { get; set; }
+    }
 }

+ 69 - 0
Admin.Core.Model/Admin/LogAbstract.cs

@@ -0,0 +1,69 @@
+using FreeSql.DataAnnotations;
+using System.ComponentModel.DataAnnotations;
+
+namespace Admin.Core.Model.Admin
+{
+    /// <summary>
+    /// 日志
+    /// </summary>
+    public abstract class LogAbstract : EntityAdd
+    {
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        [MaxLength(60)]
+        public string RealName { get; set; }
+
+        /// <summary>
+        /// IP
+        /// </summary>
+        [MaxLength(100)]
+        public string IP { get; set; }
+
+        /// <summary>
+        /// 浏览器
+        /// </summary>
+        [MaxLength(100)]
+        public string Browser { get; set; }
+
+        /// <summary>
+        /// 操作系统
+        /// </summary>
+        [MaxLength(100)]
+        public string Os { get; set; }
+
+        /// <summary>
+        /// 设备
+        /// </summary>
+        [MaxLength(50)]
+        public string Device { get; set; }
+
+        /// <summary>
+        /// 浏览器信息
+        /// </summary>
+        [Column(StringLength = -1)]
+        public string BrowserInfo { get; set; }
+
+        /// <summary>
+        /// 耗时(毫秒)
+        /// </summary>
+        public long ElapsedMilliseconds { get; set; }
+
+        /// <summary>
+        /// 操作状态
+        /// </summary>
+        public bool Status { get; set; }
+
+        /// <summary>
+        /// 操作消息
+        /// </summary>
+        [Column(StringLength = 500)]
+        public string Msg { get; set; }
+
+        /// <summary>
+        /// 操作结果
+        /// </summary>
+        [Column(StringLength = -1)]
+        public string Result { get; set; }
+    }
+}

+ 12 - 0
Admin.Core.Model/Admin/LoginLogEntity.cs

@@ -0,0 +1,12 @@
+using FreeSql.DataAnnotations;
+
+namespace Admin.Core.Model.Admin
+{
+    /// <summary>
+    /// 操作日志
+    /// </summary>
+	[Table(Name = "ad_login_log")]
+    public class LoginLogEntity : LogAbstract
+    {
+    }
+}

+ 36 - 0
Admin.Core.Model/Admin/OprationLogEntity.cs

@@ -0,0 +1,36 @@
+using System.ComponentModel.DataAnnotations;
+using FreeSql.DataAnnotations;
+
+namespace Admin.Core.Model.Admin
+{
+    /// <summary>
+    /// 操作日志
+    /// </summary>
+	[Table(Name = "ad_opration_log")]
+    public class OprationLogEntity: LogAbstract
+    {
+        /// <summary>
+        /// 接口名称
+        /// </summary>
+        [Column(Position = 2, StringLength = 50)]
+        public string ApiLabel { get; set; }
+
+        /// <summary>
+        /// 接口地址
+        /// </summary>
+        [Column(Position = 3, StringLength = 500)]
+        public string ApiPath { get; set; }
+
+        /// <summary>
+        /// 接口提交方法
+        /// </summary>
+        [Column(Position = 4, StringLength = 50)]
+        public string ApiMethod { get; set; }
+
+        /// <summary>
+        /// 操作参数
+        /// </summary>
+        [Column(StringLength = -1)]
+        public string Params { get; set; }
+    }
+}

+ 5 - 0
Admin.Core.Model/Output/IResponseOutput.cs

@@ -12,6 +12,11 @@ namespace Admin.Core.Model.Output
         /// </summary>
         [JsonIgnore]
         bool Success { get; }
+
+        /// <summary>
+        /// 消息
+        /// </summary>
+        public string Msg { get;}
     }
 
     /// <summary>

+ 11 - 0
Admin.Core.Repository/Admin/LoginLog/ILoginLogRepository.cs

@@ -0,0 +1,11 @@
+using Admin.Core.Model.Admin;
+
+namespace Admin.Core.Repository.Admin
+{
+	public interface ILoginLogRepository : IRepositoryBase<LoginLogEntity>
+    {
+    }
+}
+
+
+	

+ 14 - 0
Admin.Core.Repository/Admin/LoginLog/LoginLogRepository.cs

@@ -0,0 +1,14 @@
+using FreeSql;
+using Admin.Core.Model.Admin;
+using Admin.Core.Common.Auth;
+using System.Threading.Tasks;
+
+namespace Admin.Core.Repository.Admin
+{
+    public class LoginLogRepository : RepositoryBase<LoginLogEntity>, ILoginLogRepository
+    {
+        public LoginLogRepository(IFreeSql orm, IUnitOfWork uow, IUser user) : base(orm, uow, user)
+        {
+        }
+    }
+}

+ 11 - 0
Admin.Core.Repository/Admin/OprationLog/IOprationLogRepository.cs

@@ -0,0 +1,11 @@
+using Admin.Core.Model.Admin;
+
+namespace Admin.Core.Repository.Admin
+{
+	public interface IOprationLogRepository : IRepositoryBase<OprationLogEntity>
+    {
+    }
+}
+
+
+	

+ 13 - 0
Admin.Core.Repository/Admin/OprationLog/OprationLogRepository.cs

@@ -0,0 +1,13 @@
+using FreeSql;
+using Admin.Core.Model.Admin;
+using Admin.Core.Common.Auth;
+
+namespace Admin.Core.Repository.Admin
+{
+    public class OprationLogRepository : RepositoryBase<OprationLogEntity>, IOprationLogRepository
+    {
+        public OprationLogRepository(IFreeSql orm, IUnitOfWork uow, IUser user) : base(orm, uow, user)
+        {
+        }
+    }
+}

+ 17 - 1
Admin.Core.Repository/Base/IRepositoryBase.cs

@@ -1,6 +1,8 @@
 
-using FreeSql;
+using System;
+using System.Linq.Expressions;
 using System.Threading.Tasks;
+using FreeSql;
 
 namespace Admin.Core.Repository
 {
@@ -14,6 +16,20 @@ namespace Admin.Core.Repository
         /// <returns></returns>
         Task<TDto> GetAsync<TDto>(TKey id);
 
+        /// <summary>
+        /// 根据条件获取实体
+        /// </summary>
+        /// <param name="exp"></param>
+        /// <returns></returns>
+        Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> exp);
+
+        /// <summary>
+        /// 根据条件获取Dto
+        /// </summary>
+        /// <param name="exp"></param>
+        /// <returns></returns>
+        Task<TDto> GetAsync<TDto>(Expression<Func<TEntity, bool>> exp);
+
         /// <summary>
         /// 软删除
         /// </summary>

+ 15 - 2
Admin.Core.Repository/Base/RepositoryBase.cs

@@ -1,6 +1,9 @@
 
-using FreeSql;
+
+using System;
 using System.Threading.Tasks;
+using System.Linq.Expressions;
+using FreeSql;
 using Admin.Core.Common.Auth;
 
 namespace Admin.Core.Repository
@@ -14,12 +17,22 @@ namespace Admin.Core.Repository
             UnitOfWork = uow;
             _user = user;
         }
-
+        
         public virtual Task<TDto> GetAsync<TDto>(TKey id)
         {
             return Select.WhereDynamic(id).ToOneAsync<TDto>();
         }
 
+        public virtual Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> exp)
+        {
+            return Select.Where(exp).ToOneAsync();
+        }
+
+        public virtual Task<TDto> GetAsync<TDto>(Expression<Func<TEntity, bool>> exp)
+        {
+            return Select.Where(exp).ToOneAsync<TDto>();
+        }
+
         public async Task<bool> SoftDeleteAsync(TKey id)
         {
             await UpdateDiy

+ 0 - 4
Admin.Core.Services/Admin.Core.Service.csproj

@@ -29,8 +29,4 @@
     <ProjectReference Include="..\Admin.Core.Repository\Admin.Core.Repository.csproj" />
   </ItemGroup>
 
-  <ItemGroup>
-    <Folder Include="Admin\Auth\Output\" />
-  </ItemGroup>
-
 </Project>

+ 1 - 1
Admin.Core.Services/Admin/Api/Output/ApiListOutput.cs

@@ -5,7 +5,7 @@
         /// <summary>
         /// 接口Id
         /// </summary>
-        public int Id { get; set; }
+        public long Id { get; set; }
 
         /// <summary>
         /// 接口父级

+ 9 - 14
Admin.Core.Services/Admin/Auth/AuthService.cs

@@ -9,6 +9,8 @@ using Admin.Core.Common.Helpers;
 using Admin.Core.Common.Auth;
 using Admin.Core.Common.Cache;
 using Admin.Core.Service.Admin.Auth.Input;
+using AutoMapper;
+using Admin.Core.Service.Admin.Auth.Output;
 
 namespace Admin.Core.Service.Admin.Auth
 {
@@ -16,6 +18,7 @@ namespace Admin.Core.Service.Admin.Auth
     {
         private readonly IUser _user;
         private readonly ICache _cache;
+        private readonly IMapper _mapper;
         private readonly IUserToken _userToken;
         private readonly IUserRepository _userRepository;
         private readonly IRolePermissionRepository _rolePermissionRepository;
@@ -23,6 +26,7 @@ namespace Admin.Core.Service.Admin.Auth
         public AuthService(
             IUser user,
             ICache cache,
+            IMapper mapper,
             IUserToken userToken,
             IUserRepository userRepository,
             IRolePermissionRepository rolePermissionRepository
@@ -30,6 +34,7 @@ namespace Admin.Core.Service.Admin.Auth
         {
             _user = user;
             _cache = cache;
+            _mapper = mapper;
             _userToken = userToken;
             _userRepository = userRepository;
             _rolePermissionRepository = rolePermissionRepository;
@@ -59,7 +64,7 @@ namespace Admin.Core.Service.Admin.Auth
             }
             #endregion
 
-            var user = (await _userRepository.Select.Where(a => a.UserName == input.UserName).ToOneAsync());
+            var user = (await _userRepository.GetAsync(a => a.UserName == input.UserName));
             if (!(user?.Id > 0))
             {
                 return ResponseOutput.NotOk("账号输入有误!", 3);
@@ -93,19 +98,9 @@ namespace Admin.Core.Service.Admin.Auth
                 return ResponseOutput.NotOk("密码输入有误!",4);
             }
 
-            //生成token信息
-            var claims = new[]
-            {
-                new Claim(ClaimAttributes.UserId, user.Id.ToString()),
-                new Claim(ClaimAttributes.UserName, user.UserName),
-                new Claim(ClaimAttributes.UserRealName, user.Name)
-            };
-            var token = _userToken.Build(claims);
-
-            return ResponseOutput.Ok(new 
-            { 
-                token
-            });
+            var authLoginOutput = _mapper.Map<AuthLoginOutput>(user);
+
+            return ResponseOutput.Ok(authLoginOutput);
         }
 
         public async Task<IResponseOutput> GetUserInfoAsync()

+ 22 - 0
Admin.Core.Services/Admin/Auth/Output/AuthLoginOutput.cs

@@ -0,0 +1,22 @@
+using System;
+
+namespace Admin.Core.Service.Admin.Auth.Output
+{
+    public class AuthLoginOutput
+    {
+        /// <summary>
+        /// 主键Id
+        /// </summary>
+        public long Id { get; set; }
+
+        /// <summary>
+        /// 账号
+        /// </summary>
+        public string UserName { get; set; }
+
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        public string Name { get; set; }
+    }
+}

+ 2 - 2
Admin.Core.Services/Admin/Auth/_MapConfig.cs

@@ -1,6 +1,6 @@
 using AutoMapper;
 using Admin.Core.Model.Admin;
-using Admin.Core.Service.Admin.Permission.Input;
+using Admin.Core.Service.Admin.Auth.Output;
 
 namespace Admin.Core.Service.Admin.Auth
 {
@@ -11,7 +11,7 @@ namespace Admin.Core.Service.Admin.Auth
     {
         public MapConfig()
         {
-            
+            CreateMap<UserEntity, AuthLoginOutput>();
         }
     }
 }

+ 1 - 1
Admin.Core.Services/Admin/Dictionary/Output/DictionaryListOutput.cs

@@ -7,7 +7,7 @@ namespace Admin.Core.Service.Admin.Dictionary.Output
         /// <summary>
         /// 主键Id
         /// </summary>
-        public int Id { get; set; }
+        public long Id { get; set; }
 
         /// <summary>
         /// 字典父级

+ 15 - 0
Admin.Core.Services/Admin/LoginLog/ILoginLogService.cs

@@ -0,0 +1,15 @@
+using System.Threading.Tasks;
+using Admin.Core.Model.Input;
+using Admin.Core.Model.Output;
+using Admin.Core.Model.Admin;
+using Admin.Core.Service.Admin.LoginLog.Input;
+
+namespace Admin.Core.Service.Admin.LoginLog
+{	
+    public interface ILoginLogService
+    {
+        Task<IResponseOutput> PageAsync(PageInput<LoginLogEntity> input);
+
+        Task<IResponseOutput<long>> AddAsync(LoginLogAddInput input);
+    }
+}

+ 68 - 0
Admin.Core.Services/Admin/LoginLog/Input/LoginLogAddInput.cs

@@ -0,0 +1,68 @@
+namespace Admin.Core.Service.Admin.LoginLog.Input
+{
+    /// <summary>
+    /// 添加
+    /// </summary>
+    public class LoginLogAddInput
+    {
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        public string RealName { get; set; }
+
+        /// <summary>
+        /// IP
+        /// </summary>
+        public string IP { get; set; }
+
+        /// <summary>
+        /// 浏览器
+        /// </summary>
+        public string Browser { get; set; }
+
+        /// <summary>
+        /// 操作系统
+        /// </summary>
+        public string Os { get; set; }
+
+        /// <summary>
+        /// 设备
+        /// </summary>
+        public string Device { get; set; }
+
+        /// <summary>
+        /// 浏览器信息
+        /// </summary>
+        public string BrowserInfo { get; set; }
+
+        /// <summary>
+        /// 耗时(毫秒)
+        /// </summary>
+        public long ElapsedMilliseconds { get; set; }
+
+        /// <summary>
+        /// 操作状态
+        /// </summary>
+        public bool? Status { get; set; }
+
+        /// <summary>
+        /// 操作消息
+        /// </summary>
+        public string Msg { get; set; }
+
+        /// <summary>
+        /// 操作结果
+        /// </summary>
+        public string Result { get; set; }
+
+        /// <summary>
+        /// 创建者Id
+        /// </summary>
+        public long? CreatedUserId { get; set; }
+
+        /// <summary>
+        /// 创建者
+        /// </summary>
+        public string CreatedUserName { get; set; }
+    }
+}

+ 74 - 0
Admin.Core.Services/Admin/LoginLog/LoginLogService.cs

@@ -0,0 +1,74 @@
+using System.Threading.Tasks;
+using AutoMapper;
+using Admin.Core.Common.Auth;
+using Admin.Core.Model.Input;
+using Admin.Core.Model.Output;
+using Admin.Core.Model.Admin;
+using Admin.Core.Repository.Admin;
+using Admin.Core.Service.Admin.LoginLog.Input;
+using Admin.Core.Service.Admin.LoginLog.Output;
+using Microsoft.AspNetCore.Http;
+
+namespace Admin.Core.Service.Admin.LoginLog
+{	
+	public class LoginLogService : ILoginLogService
+    {
+        private readonly IUser _user;
+        private readonly IMapper _mapper;
+        private readonly IHttpContextAccessor _context;
+        private readonly ILoginLogRepository _loginLogRepository;
+        public LoginLogService(
+            IUser user,
+            IMapper mapper,
+            IHttpContextAccessor context,
+            ILoginLogRepository loginLogRepository
+        )
+        {
+            _user = user;
+            _mapper = mapper;
+            _context = context;
+            _loginLogRepository = loginLogRepository;
+        }
+
+        public async Task<IResponseOutput> PageAsync(PageInput<LoginLogEntity> input)
+        {
+            var userName = input.Filter?.CreatedUserName;
+
+            var list = await _loginLogRepository.Select
+            .WhereIf(userName.NotNull(), a => a.CreatedUserName.Contains(userName))
+            .Count(out var total)
+            .OrderByDescending(true, c => c.Id)
+            .Page(input.CurrentPage, input.PageSize)
+            .ToListAsync<LoginLogListOutput>();
+
+            var data = new PageOutput<LoginLogListOutput>()
+            {
+                List = list,
+                Total = total
+            };
+            
+            return ResponseOutput.Ok(data);
+        }
+
+        public async Task<IResponseOutput<long>> AddAsync(LoginLogAddInput input)
+        {
+            var res = new ResponseOutput<long>();
+
+            input.IP = _user.IP;
+
+            string ua = _context.HttpContext.Request.Headers["User-Agent"];
+            var client = UAParser.Parser.GetDefault().Parse(ua);
+            var device = client.Device.Family;
+            device = device.ToLower() == "other" ? "" : device;
+            input.Browser = client.UA.Family;
+            input.Os = client.OS.Family;
+            input.Device = device;
+            input.BrowserInfo = ua;
+
+            var entity = _mapper.Map<LoginLogEntity>(input);
+            var id = (await _loginLogRepository.InsertAsync(entity)).Id;
+
+            return id > 0 ? res.Ok(id) : res;
+        }
+    }
+}

+ 62 - 0
Admin.Core.Services/Admin/LoginLog/Output/LoginLogListOutput.cs

@@ -0,0 +1,62 @@
+using System;
+
+namespace Admin.Core.Service.Admin.LoginLog.Output
+{
+    public class LoginLogListOutput
+    {
+        /// <summary>
+        /// 编号
+        /// </summary>
+        public long Id { get; set; }
+
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        public string RealName { get; set; }
+
+        /// <summary>
+        /// 创建者
+        /// </summary>
+        public string CreatedUserName { get; set; }
+
+        /// <summary>
+        /// IP
+        /// </summary>
+        public string IP { get; set; }
+
+        /// <summary>
+        /// 浏览器
+        /// </summary>
+        public string Browser { get; set; }
+
+        /// <summary>
+        /// 操作系统
+        /// </summary>
+        public string Os { get; set; }
+
+        /// <summary>
+        /// 设备
+        /// </summary>
+        public string Device { get; set; }
+
+        /// <summary>
+        /// 耗时(毫秒)
+        /// </summary>
+        public long ElapsedMilliseconds { get; set; }
+
+        /// <summary>
+        /// 操作状态
+        /// </summary>
+        public bool Status { get; set; }
+
+        /// <summary>
+        /// 操作消息
+        /// </summary>
+        public string Msg { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public DateTime? CreatedTime { get; set; }
+    }
+}

+ 17 - 0
Admin.Core.Services/Admin/LoginLog/_MapConfig.cs

@@ -0,0 +1,17 @@
+using AutoMapper;
+using Admin.Core.Model.Admin;
+using Admin.Core.Service.Admin.LoginLog.Input;
+
+namespace Admin.Core.Service.Admin.LoginLog
+{
+    /// <summary>
+    /// 映射配置
+    /// </summary>
+    public class MapConfig : Profile
+    {
+        public MapConfig()
+        {
+            CreateMap<LoginLogAddInput, LoginLogEntity>();
+        }
+    }
+}

+ 15 - 0
Admin.Core.Services/Admin/OprationLog/IOprationLogService.cs

@@ -0,0 +1,15 @@
+using System.Threading.Tasks;
+using Admin.Core.Model.Input;
+using Admin.Core.Model.Output;
+using Admin.Core.Model.Admin;
+using Admin.Core.Service.Admin.OprationLog.Input;
+
+namespace Admin.Core.Service.Admin.OprationLog
+{	
+    public interface IOprationLogService
+    {
+        Task<IResponseOutput> PageAsync(PageInput<OprationLogEntity> input);
+
+        Task<IResponseOutput> AddAsync(OprationLogAddInput input);
+    }
+}

+ 78 - 0
Admin.Core.Services/Admin/OprationLog/Input/OprationLogAddInput.cs

@@ -0,0 +1,78 @@
+namespace Admin.Core.Service.Admin.OprationLog.Input
+{
+    /// <summary>
+    /// 添加
+    /// </summary>
+    public class OprationLogAddInput
+    {
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        public string RealName { get; set; }
+
+        /// <summary>
+        /// 接口名称
+        /// </summary>
+        public string ApiLabel { get; set; }
+
+        /// <summary>
+        /// 接口地址
+        /// </summary>
+        public string ApiPath { get; set; }
+
+        /// <summary>
+        /// 接口提交方法
+        /// </summary>
+        public string ApiMethod { get; set; }
+
+        /// <summary>
+        /// IP
+        /// </summary>
+        public string IP { get; set; }
+
+        /// <summary>
+        /// 浏览器
+        /// </summary>
+        public string Browser { get; set; }
+
+        /// <summary>
+        /// 操作系统
+        /// </summary>
+        public string Os { get; set; }
+
+        /// <summary>
+        /// 设备
+        /// </summary>
+        public string Device { get; set; }
+
+        /// <summary>
+        /// 浏览器信息
+        /// </summary>
+        public string BrowserInfo { get; set; }
+
+        /// <summary>
+        /// 耗时(毫秒)
+        /// </summary>
+        public long ElapsedMilliseconds { get; set; }
+
+        /// <summary>
+        /// 操作状态
+        /// </summary>
+        public bool? Status { get; set; }
+
+        /// <summary>
+        /// 操作消息
+        /// </summary>
+        public string Msg { get; set; }
+
+        /// <summary>
+        /// 操作参数
+        /// </summary>
+        public string Params { get; set; }
+
+        /// <summary>
+        /// 操作结果
+        /// </summary>
+        public string Result { get; set; }
+    }
+}

+ 73 - 0
Admin.Core.Services/Admin/OprationLog/OprationLogService.cs

@@ -0,0 +1,73 @@
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using AutoMapper;
+using Admin.Core.Common.Auth;
+using Admin.Core.Model.Input;
+using Admin.Core.Model.Output;
+using Admin.Core.Model.Admin;
+using Admin.Core.Repository.Admin;
+using Admin.Core.Service.Admin.OprationLog.Input;
+using Admin.Core.Service.Admin.OprationLog.Output;
+
+namespace Admin.Core.Service.Admin.OprationLog
+{	
+	public class OprationLogService : IOprationLogService
+    {
+        private readonly IUser _user;
+        private readonly IMapper _mapper;
+        private readonly IHttpContextAccessor _context;
+        private readonly IOprationLogRepository _oprationLogRepository;
+        public OprationLogService(
+            IUser user,
+            IMapper mapper,
+            IHttpContextAccessor context,
+            IOprationLogRepository oprationLogRepository
+        )
+        {
+            _user = user;
+            _mapper = mapper;
+            _context = context;
+            _oprationLogRepository = oprationLogRepository;
+        }
+
+        public async Task<IResponseOutput> PageAsync(PageInput<OprationLogEntity> input)
+        {
+            var userName = input.Filter?.CreatedUserName;
+
+            var list = await _oprationLogRepository.Select
+            .WhereIf(userName.NotNull(), a => a.CreatedUserName.Contains(userName))
+            .Count(out var total)
+            .OrderByDescending(true, c => c.Id)
+            .Page(input.CurrentPage, input.PageSize)
+            .ToListAsync<OprationLogListOutput>();
+
+            var data = new PageOutput<OprationLogListOutput>()
+            {
+                List = list,
+                Total = total
+            };
+            
+            return ResponseOutput.Ok(data);
+        }
+
+        public async Task<IResponseOutput> AddAsync(OprationLogAddInput input)
+        {
+            string ua = _context.HttpContext.Request.Headers["User-Agent"];
+            var client = UAParser.Parser.GetDefault().Parse(ua);
+            var device = client.Device.Family;
+            device = device.ToLower() == "other" ? "" : device;
+            input.Browser = client.UA.Family;
+            input.Os = client.OS.Family;
+            input.Device = device;
+            input.BrowserInfo = ua;
+
+            input.RealName = _user.RealName;
+            input.IP = _user.IP;
+
+            var entity = _mapper.Map<OprationLogEntity>(input);
+            var id = (await _oprationLogRepository.InsertAsync(entity)).Id;
+
+            return ResponseOutput.Result(id > 0);
+        }
+    }
+}

+ 77 - 0
Admin.Core.Services/Admin/OprationLog/Output/OprationLogListOutput.cs

@@ -0,0 +1,77 @@
+using System;
+
+namespace Admin.Core.Service.Admin.OprationLog.Output
+{
+    public class OprationLogListOutput
+    {
+        /// <summary>
+        /// 编号
+        /// </summary>
+        public long Id { get; set; }
+
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        public string RealName { get; set; }
+
+        /// <summary>
+        /// 创建者
+        /// </summary>
+        public string CreatedUserName { get; set; }
+
+        /// <summary>
+        /// 接口名称
+        /// </summary>
+        public string ApiLabel { get; set; }
+
+        /// <summary>
+        /// 接口地址
+        /// </summary>
+        public string ApiPath { get; set; }
+
+        /// <summary>
+        /// 接口提交方法
+        /// </summary>
+        public string ApiMethod { get; set; }
+
+        /// <summary>
+        /// IP
+        /// </summary>
+        public string IP { get; set; }
+
+        /// <summary>
+        /// 浏览器
+        /// </summary>
+        public string Browser { get; set; }
+
+        /// <summary>
+        /// 操作系统
+        /// </summary>
+        public string Os { get; set; }
+
+        /// <summary>
+        /// 设备
+        /// </summary>
+        public string Device { get; set; }
+
+        /// <summary>
+        /// 耗时(毫秒)
+        /// </summary>
+        public long ElapsedMilliseconds { get; set; }
+
+        /// <summary>
+        /// 操作状态
+        /// </summary>
+        public bool Status { get; set; }
+
+        /// <summary>
+        /// 操作消息
+        /// </summary>
+        public string Msg { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public DateTime? CreatedTime { get; set; }
+    }
+}

+ 17 - 0
Admin.Core.Services/Admin/OprationLog/_MapConfig.cs

@@ -0,0 +1,17 @@
+using AutoMapper;
+using Admin.Core.Model.Admin;
+using Admin.Core.Service.Admin.OprationLog.Input;
+
+namespace Admin.Core.Service.Admin.OprationLog
+{
+    /// <summary>
+    /// 映射配置
+    /// </summary>
+    public class MapConfig : Profile
+    {
+        public MapConfig()
+        {
+            CreateMap<OprationLogAddInput, OprationLogEntity>();
+        }
+    }
+}

+ 1 - 1
Admin.Core.Services/Admin/Permission/Output/PermissionListOutput.cs

@@ -8,7 +8,7 @@ namespace Admin.Core.Service.Admin.Permission.Output
         /// <summary>
         /// 权限Id
         /// </summary>
-        public int Id { get; set; }
+        public long Id { get; set; }
 
         /// <summary>
         /// 父级节点

+ 1 - 1
Admin.Core.Services/Admin/Role/Output/RoleListOutput.cs

@@ -7,7 +7,7 @@ namespace Admin.Core.Service.Admin.Role.Output
         /// <summary>
         /// 主键
         /// </summary>
-        public int Id { get; set; }
+        public long Id { get; set; }
 
         /// <summary>
         /// 名称

+ 1 - 1
Admin.Core.Services/Admin/User/Output/UserListOutput.cs

@@ -7,7 +7,7 @@ namespace Admin.Core.Service.Admin.User.Output
         /// <summary>
         /// 主键Id
         /// </summary>
-        public int Id { get; set; }
+        public long Id { get; set; }
 
         /// <summary>
         /// 账号

+ 1 - 1
Admin.Core.Services/Admin/View/Output/ViewListOutput.cs

@@ -5,7 +5,7 @@
         /// <summary>
         /// 视图Id
         /// </summary>
-        public int Id { get; set; }
+        public long Id { get; set; }
 
         /// <summary>
         /// 视图父级

+ 90 - 0
Admin.Core/Admin.Core.Model.xml

@@ -89,6 +89,91 @@
             排序
             </summary>
         </member>
+        <member name="T:Admin.Core.Model.Admin.LogAbstract">
+            <summary>
+            日志
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.LogAbstract.RealName">
+            <summary>
+            姓名
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.LogAbstract.IP">
+            <summary>
+            IP
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.LogAbstract.Browser">
+            <summary>
+            浏览器
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.LogAbstract.Os">
+            <summary>
+            操作系统
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.LogAbstract.Device">
+            <summary>
+            设备
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.LogAbstract.BrowserInfo">
+            <summary>
+            浏览器信息
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.LogAbstract.ElapsedMilliseconds">
+            <summary>
+            耗时(毫秒)
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.LogAbstract.Status">
+            <summary>
+            操作状态
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.LogAbstract.Msg">
+            <summary>
+            操作消息
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.LogAbstract.Result">
+            <summary>
+            操作结果
+            </summary>
+        </member>
+        <member name="T:Admin.Core.Model.Admin.LoginLogEntity">
+            <summary>
+            操作日志
+            </summary>
+        </member>
+        <member name="T:Admin.Core.Model.Admin.OprationLogEntity">
+            <summary>
+            操作日志
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.OprationLogEntity.ApiLabel">
+            <summary>
+            接口名称
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.OprationLogEntity.ApiPath">
+            <summary>
+            接口地址
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.OprationLogEntity.ApiMethod">
+            <summary>
+            接口提交方法
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Model.Admin.OprationLogEntity.Params">
+            <summary>
+            操作参数
+            </summary>
+        </member>
         <member name="T:Admin.Core.Model.Admin.PermissionEntity">
             <summary>
             权限
@@ -494,6 +579,11 @@
             是否成功
             </summary>
         </member>
+        <member name="P:Admin.Core.Model.Output.IResponseOutput.Msg">
+            <summary>
+            消息
+            </summary>
+        </member>
         <member name="T:Admin.Core.Model.Output.IResponseOutput`1">
             <summary>
             响应数据泛型接口

+ 290 - 0
Admin.Core/Admin.Core.Service.xml

@@ -232,6 +232,21 @@
             验证码键
             </summary>
         </member>
+        <member name="P:Admin.Core.Service.Admin.Auth.Output.AuthLoginOutput.Id">
+            <summary>
+            主键Id
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.Auth.Output.AuthLoginOutput.UserName">
+            <summary>
+            账号
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.Auth.Output.AuthLoginOutput.Name">
+            <summary>
+            姓名
+            </summary>
+        </member>
         <member name="T:Admin.Core.Service.Admin.Auth.MapConfig">
             <summary>
             映射配置
@@ -350,6 +365,281 @@
             映射配置
             </summary>
         </member>
+        <member name="T:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput">
+            <summary>
+            添加
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput.RealName">
+            <summary>
+            姓名
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput.IP">
+            <summary>
+            IP
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput.Browser">
+            <summary>
+            浏览器
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput.Os">
+            <summary>
+            操作系统
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput.Device">
+            <summary>
+            设备
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput.BrowserInfo">
+            <summary>
+            浏览器信息
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput.ElapsedMilliseconds">
+            <summary>
+            耗时(毫秒)
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput.Status">
+            <summary>
+            操作状态
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput.Msg">
+            <summary>
+            操作消息
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput.Result">
+            <summary>
+            操作结果
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput.CreatedUserId">
+            <summary>
+            创建者Id
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Input.LoginLogAddInput.CreatedUserName">
+            <summary>
+            创建者
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Output.LoginLogListOutput.Id">
+            <summary>
+            编号
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Output.LoginLogListOutput.RealName">
+            <summary>
+            姓名
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Output.LoginLogListOutput.CreatedUserName">
+            <summary>
+            创建者
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Output.LoginLogListOutput.IP">
+            <summary>
+            IP
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Output.LoginLogListOutput.Browser">
+            <summary>
+            浏览器
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Output.LoginLogListOutput.Os">
+            <summary>
+            操作系统
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Output.LoginLogListOutput.Device">
+            <summary>
+            设备
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Output.LoginLogListOutput.ElapsedMilliseconds">
+            <summary>
+            耗时(毫秒)
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Output.LoginLogListOutput.Status">
+            <summary>
+            操作状态
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Output.LoginLogListOutput.Msg">
+            <summary>
+            操作消息
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.LoginLog.Output.LoginLogListOutput.CreatedTime">
+            <summary>
+            创建时间
+            </summary>
+        </member>
+        <member name="T:Admin.Core.Service.Admin.LoginLog.MapConfig">
+            <summary>
+            映射配置
+            </summary>
+        </member>
+        <member name="T:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput">
+            <summary>
+            添加
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.RealName">
+            <summary>
+            姓名
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.ApiLabel">
+            <summary>
+            接口名称
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.ApiPath">
+            <summary>
+            接口地址
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.ApiMethod">
+            <summary>
+            接口提交方法
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.IP">
+            <summary>
+            IP
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.Browser">
+            <summary>
+            浏览器
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.Os">
+            <summary>
+            操作系统
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.Device">
+            <summary>
+            设备
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.BrowserInfo">
+            <summary>
+            浏览器信息
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.ElapsedMilliseconds">
+            <summary>
+            耗时(毫秒)
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.Status">
+            <summary>
+            操作状态
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.Msg">
+            <summary>
+            操作消息
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.Params">
+            <summary>
+            操作参数
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Input.OprationLogAddInput.Result">
+            <summary>
+            操作结果
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.Id">
+            <summary>
+            编号
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.RealName">
+            <summary>
+            姓名
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.CreatedUserName">
+            <summary>
+            创建者
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.ApiLabel">
+            <summary>
+            接口名称
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.ApiPath">
+            <summary>
+            接口地址
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.ApiMethod">
+            <summary>
+            接口提交方法
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.IP">
+            <summary>
+            IP
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.Browser">
+            <summary>
+            浏览器
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.Os">
+            <summary>
+            操作系统
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.Device">
+            <summary>
+            设备
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.ElapsedMilliseconds">
+            <summary>
+            耗时(毫秒)
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.Status">
+            <summary>
+            操作状态
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.Msg">
+            <summary>
+            操作消息
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Service.Admin.OprationLog.Output.OprationLogListOutput.CreatedTime">
+            <summary>
+            创建时间
+            </summary>
+        </member>
+        <member name="T:Admin.Core.Service.Admin.OprationLog.MapConfig">
+            <summary>
+            映射配置
+            </summary>
+        </member>
         <member name="P:Admin.Core.Service.Admin.Permission.Input.PermissionAddApiInput.Type">
             <summary>
             权限类型

+ 0 - 4
Admin.Core/Admin.Core.csproj

@@ -14,16 +14,12 @@
   <ItemGroup>
     <Compile Remove="AutoMapper\**" />
     <Compile Remove="Hubs\**" />
-    <Compile Remove="Log\**" />
     <Content Remove="AutoMapper\**" />
     <Content Remove="Hubs\**" />
-    <Content Remove="Log\**" />
     <EmbeddedResource Remove="AutoMapper\**" />
     <EmbeddedResource Remove="Hubs\**" />
-    <EmbeddedResource Remove="Log\**" />
     <None Remove="AutoMapper\**" />
     <None Remove="Hubs\**" />
-    <None Remove="Log\**" />
   </ItemGroup>
 
   <ItemGroup>

+ 54 - 2
Admin.Core/Admin.Core.xml

@@ -9,6 +9,11 @@
             启用登录
             </summary>
         </member>
+        <member name="T:Admin.Core.Attributes.NoOprationLogAttribute">
+            <summary>
+            禁用操作日志
+            </summary>
+        </member>
         <member name="T:Admin.Core.Attributes.PermissionAttribute">
             <summary>
             启用权限
@@ -242,6 +247,30 @@
             <param name="environment"></param>
             <returns></returns>
         </member>
+        <member name="T:Admin.Core.Controllers.Admin.LoginLogController">
+            <summary>
+            登录日志管理
+            </summary>
+        </member>
+        <member name="M:Admin.Core.Controllers.Admin.LoginLogController.GetPage(Admin.Core.Model.Input.PageInput{Admin.Core.Model.Admin.LoginLogEntity})">
+            <summary>
+            查询分页登录日志
+            </summary>
+            <param name="model"></param>
+            <returns></returns>
+        </member>
+        <member name="T:Admin.Core.Controllers.Admin.OprationLogController">
+            <summary>
+            操作日志管理
+            </summary>
+        </member>
+        <member name="M:Admin.Core.Controllers.Admin.OprationLogController.GetPage(Admin.Core.Model.Input.PageInput{Admin.Core.Model.Admin.OprationLogEntity})">
+            <summary>
+            查询分页操作日志
+            </summary>
+            <param name="model"></param>
+            <returns></returns>
+        </member>
         <member name="T:Admin.Core.Controllers.Admin.PermissionController">
             <summary>
             权限管理
@@ -631,9 +660,32 @@
             系统内部错误(非业务代码里显式抛出的异常,例如由于数据不正确导致空指针异常、数据库异常等等)
             </summary>
         </member>
-        <member name="T:Admin.Core.Filters.GlobalExceptionFilter">
+        <member name="T:Admin.Core.Filters.AdminExceptionFilter">
+            <summary>
+            Admin异常错误过滤
+            </summary>
+        </member>
+        <member name="T:Admin.Core.Logs.ApiHelper">
+            <summary>
+            Api帮助类
+            </summary>
+        </member>
+        <member name="T:Admin.Core.Logs.ILogHandler">
+            <summary>
+            操作日志处理接口
+            </summary>
+        </member>
+        <member name="M:Admin.Core.Logs.ILogHandler.LogAsync(Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext,Microsoft.AspNetCore.Mvc.Filters.ActionExecutionDelegate)">
+            <summary>
+            写操作日志
+            </summary>
+            <param name="context"></param>
+            <param name="next"></param>
+            <returns></returns>
+        </member>
+        <member name="T:Admin.Core.Logs.LogHandler">
             <summary>
-            全局异常错误过滤
+            操作日志处理
             </summary>
         </member>
     </members>

+ 12 - 0
Admin.Core/Attributes/NoOprationLogAttribute.cs

@@ -0,0 +1,12 @@
+using System;
+
+namespace Admin.Core.Attributes
+{
+    /// <summary>
+    /// 禁用操作日志
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
+    public class NoOprationLogAttribute : Attribute
+    {
+    }
+}

+ 8 - 1
Admin.Core/Attributes/PermissionAttribute.cs

@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authorization;
 using Microsoft.Extensions.DependencyInjection;
 using Admin.Core.Auth;
 using Admin.Core.Common.Auth;
+using System.Threading.Tasks;
 
 namespace Admin.Core.Attributes
 {
@@ -13,7 +14,7 @@ namespace Admin.Core.Attributes
     /// 启用权限
     /// </summary>
     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
-    public class PermissionAttribute : AuthorizeAttribute, IAuthorizationFilter
+    public class PermissionAttribute : AuthorizeAttribute, IAuthorizationFilter, IAsyncAuthorizationFilter
     {
         public async void OnAuthorization(AuthorizationFilterContext context)
         {
@@ -43,5 +44,11 @@ namespace Admin.Core.Attributes
                 context.Result = new ForbidResult();
             }
         }
+
+        public Task OnAuthorizationAsync(AuthorizationFilterContext context)
+        {
+            OnAuthorization(context);
+            return Task.CompletedTask;
+        }
     }
 }

+ 64 - 9
Admin.Core/Controllers/Admin/AuthController.cs

@@ -1,10 +1,16 @@
 using System.Threading.Tasks;
+using System.Security.Claims;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Authorization;
 using Admin.Core.Attributes;
 using Admin.Core.Model.Output;
 using Admin.Core.Service.Admin.Auth;
 using Admin.Core.Service.Admin.Auth.Input;
+using Admin.Core.Service.Admin.Auth.Output;
+using Admin.Core.Common.Auth;
+using System.Diagnostics;
+using Admin.Core.Service.Admin.LoginLog.Input;
+using Admin.Core.Service.Admin.LoginLog;
 
 namespace Admin.Core.Controllers.Admin
 {
@@ -13,12 +19,19 @@ namespace Admin.Core.Controllers.Admin
     /// </summary>
     public class AuthController : AreaController
     {
-        
-        private readonly IAuthService _authServices;
-        
-        public AuthController(IAuthService authServices)
+        private readonly IUserToken _userToken;
+        private readonly IAuthService _authService;
+        private readonly ILoginLogService _loginLogService;
+
+        public AuthController(
+            IUserToken userToken,
+            IAuthService authServices,
+            ILoginLogService loginLogService
+        )
         {
-            _authServices = authServices;
+            _userToken = userToken;
+            _authService = authServices;
+            _loginLogService = loginLogService;
         }
 
         /// <summary>
@@ -28,9 +41,10 @@ namespace Admin.Core.Controllers.Admin
         /// <returns></returns>
         [HttpGet]
         [AllowAnonymous]
+        [NoOprationLog]
         public async Task<IResponseOutput> GetVerifyCode(string lastKey)
         {
-            return await _authServices.GetVerifyCodeAsync(lastKey);
+            return await _authService.GetVerifyCodeAsync(lastKey);
         }
 
         /// <summary>
@@ -39,9 +53,10 @@ namespace Admin.Core.Controllers.Admin
         /// <returns></returns>
         [HttpGet]
         [AllowAnonymous]
+        [NoOprationLog]
         public async Task<IResponseOutput> GetPassWordEncryptKey()
         {
-            return await _authServices.GetPassWordEncryptKeyAsync();
+            return await _authService.GetPassWordEncryptKeyAsync();
         }
 
         /// <summary>
@@ -52,7 +67,7 @@ namespace Admin.Core.Controllers.Admin
         [Login]
         public async Task<IResponseOutput> GetUserInfo()
         {
-            return await _authServices.GetUserInfoAsync();
+            return await _authService.GetUserInfoAsync();
         }
 
         /// <summary>
@@ -63,9 +78,49 @@ namespace Admin.Core.Controllers.Admin
         /// <returns></returns>
         [HttpPost]
         [AllowAnonymous]
+        [NoOprationLog]
         public async Task<IResponseOutput> Login(AuthLoginInput input)
         {
-            return await _authServices.LoginAsync(input);
+            var sw = new Stopwatch();
+            sw.Start();
+            var res = (await _authService.LoginAsync(input)) as IResponseOutput;
+            sw.Stop();
+
+            #region 添加登录日志
+            var loginLogAddInput = new LoginLogAddInput()
+            {
+                CreatedUserName = input.UserName,
+                ElapsedMilliseconds = sw.ElapsedMilliseconds,
+                Status = res.Success,
+                Msg = res.Msg
+            };
+
+            AuthLoginOutput user = null;
+            if (res.Success)
+            {
+                user = (res as IResponseOutput<AuthLoginOutput>).Data;
+                loginLogAddInput.CreatedUserId = user.Id;
+                loginLogAddInput.RealName = user.Name;
+            }
+
+            await _loginLogService.AddAsync(loginLogAddInput);
+            #endregion
+
+            if (!res.Success)
+            {
+                return res;
+            }
+
+            #region 生成token信息
+            var token = _userToken.Build(new[]
+            {
+                new Claim(ClaimAttributes.UserId, user.Id.ToString()),
+                new Claim(ClaimAttributes.UserName, user.UserName),
+                new Claim(ClaimAttributes.UserRealName, user.Name)
+            }); 
+            #endregion
+
+            return ResponseOutput.Ok(new { token });
         }
     }
 }

+ 2 - 0
Admin.Core/Controllers/Admin/ImgController.cs

@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Admin.Core.Model.Output;
+using Admin.Core.Attributes;
 
 namespace Admin.Core.Controllers.Admin
 {
@@ -15,6 +16,7 @@ namespace Admin.Core.Controllers.Admin
     [Area("Admin")]
     [Route("api/[area]/[controller]/[action]")]
     [ApiController]
+    [NoOprationLog]
     public class ImgController : ControllerBase
     {
         /// <summary>

+ 33 - 0
Admin.Core/Controllers/Admin/LoginLogController.cs

@@ -0,0 +1,33 @@
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Admin.Core.Model.Input;
+using Admin.Core.Model.Output;
+using Admin.Core.Model.Admin;
+using Admin.Core.Service.Admin.LoginLog;
+
+namespace Admin.Core.Controllers.Admin
+{
+    /// <summary>
+    /// 登录日志管理
+    /// </summary>
+    public class LoginLogController : AreaController
+    {
+        private readonly ILoginLogService _loginLogService;
+
+        public LoginLogController(ILoginLogService loginLogService)
+        {
+            _loginLogService = loginLogService;
+        }
+
+        /// <summary>
+        /// 查询分页登录日志
+        /// </summary>
+        /// <param name="model"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<IResponseOutput> GetPage(PageInput<LoginLogEntity> model)
+        {
+            return await _loginLogService.PageAsync(model);
+        }
+    }
+}

+ 33 - 0
Admin.Core/Controllers/Admin/OprationLogController.cs

@@ -0,0 +1,33 @@
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Admin.Core.Model.Input;
+using Admin.Core.Model.Output;
+using Admin.Core.Model.Admin;
+using Admin.Core.Service.Admin.OprationLog;
+
+namespace Admin.Core.Controllers.Admin
+{
+    /// <summary>
+    /// 操作日志管理
+    /// </summary>
+    public class OprationLogController : AreaController
+    {
+        private readonly IOprationLogService _oprationLogService;
+
+        public OprationLogController(IOprationLogService loginLogService)
+        {
+            _oprationLogService = loginLogService;
+        }
+
+        /// <summary>
+        /// 查询分页操作日志
+        /// </summary>
+        /// <param name="model"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<IResponseOutput> GetPage(PageInput<OprationLogEntity> model)
+        {
+            return await _oprationLogService.PageAsync(model);
+        }
+    }
+}

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
Admin.Core/Db/Data/data.json


+ 3 - 1
Admin.Core/Db/DbHelper.cs

@@ -70,7 +70,9 @@ namespace Admin.Core.Db
                 typeof(UserEntity),
                 typeof(RoleEntity),
                 typeof(UserRoleEntity),
-                typeof(RolePermissionEntity)
+                typeof(RolePermissionEntity),
+                typeof(OprationLogEntity),
+                typeof(LoginLogEntity)
             };
 
             foreach (var type in types)

+ 8 - 4
Admin.Core/Db/ServiceCollectionExtensions.cs

@@ -83,16 +83,20 @@ namespace Admin.Core.Db
             fsql.Aop.AuditValue += (s, e) =>
             {
                 var user = services.BuildServiceProvider().GetService<IUser>();
+                if(user == null || !(user.Id > 0))
+                {
+                    return;
+                }
 
                 if (e.AuditValueType == FreeSql.Aop.AuditValueType.Insert)
                 {
                     switch (e.Property.Name)
                     {
                         case "CreatedUserId":
-                            e.Value = user?.Id;
+                            e.Value = user.Id;
                             break;
                         case "CreatedUserName":
-                            e.Value = user?.Name;
+                            e.Value = user.Name;
                             break;
                             //case "CreatedTime":
                             //    e.Value = DateTime.Now.Subtract(timeOffset);
@@ -104,10 +108,10 @@ namespace Admin.Core.Db
                     switch (e.Property.Name)
                     {
                         case "ModifiedUserId":
-                            e.Value = user?.Id;
+                            e.Value = user.Id;
                             break;
                         case "ModifiedUserName":
-                            e.Value = user?.Name;
+                            e.Value = user.Name;
                             break;
                             //case "ModifiedTime":
                             //    e.Value = DateTime.Now.Subtract(timeOffset);

+ 13 - 9
Admin.Core/Filters/GlobalExceptionFilter.cs → Admin.Core/Filters/AdminExceptionFilter.cs

@@ -1,22 +1,22 @@
-using System;
-using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.Filters;
 using Microsoft.Extensions.Hosting;
-using Admin.Core.Model.Output;
 using Microsoft.Extensions.Logging;
+using Admin.Core.Model.Output;
+using System.Threading.Tasks;
 
 namespace Admin.Core.Filters
 {
     /// <summary>
-    /// 全局异常错误过滤
+    /// Admin异常错误过滤
     /// </summary>
-    public class GlobalExceptionFilter : IExceptionFilter
+    public class AdminExceptionFilter : IExceptionFilter, IAsyncExceptionFilter
     {
         private readonly IWebHostEnvironment _env;
-        private readonly ILogger<GlobalExceptionFilter> _logger;
+        private readonly ILogger<AdminExceptionFilter> _logger;
 
-        public GlobalExceptionFilter(IWebHostEnvironment env, ILogger<GlobalExceptionFilter> logger)
+        public AdminExceptionFilter(IWebHostEnvironment env, ILogger<AdminExceptionFilter> logger)
         {
             _env = env;
             _logger = logger;
@@ -35,11 +35,15 @@ namespace Admin.Core.Filters
             }
 
             _logger.LogError(context.Exception,"");
-
             var data = ResponseOutput.NotOk(message);
-
             context.Result = new InternalServerErrorResult(data);
         }
+
+        public Task OnExceptionAsync(ExceptionContext context)
+        {
+            OnException(context);
+            return Task.CompletedTask;
+        }
     }
     public class InternalServerErrorResult : ObjectResult
     {

+ 28 - 0
Admin.Core/Filters/LogActionFilter.cs

@@ -0,0 +1,28 @@
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc.Filters;
+using Admin.Core.Logs;
+using Admin.Core.Attributes;
+
+namespace Admin.Core.Filters
+{
+    public class LogActionFilter : IAsyncActionFilter
+    {
+        private readonly ILogHandler _logHandler;
+
+        public LogActionFilter(ILogHandler opratoinLogHandler)
+        {
+            _logHandler = opratoinLogHandler;
+        }
+
+        public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
+        {
+            if (context.ActionDescriptor.EndpointMetadata.Any(m => m.GetType() == typeof(NoOprationLogAttribute)))
+            {
+                return next();
+            }
+
+            return _logHandler.LogAsync(context, next);
+        }
+    }
+}

+ 53 - 0
Admin.Core/Logs/ApiHelper.cs

@@ -0,0 +1,53 @@
+using System.IO;
+using System.Linq;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Admin.Core.Common.Helpers;
+using Admin.Core.Db;
+
+namespace Admin.Core.Logs
+{
+    /// <summary>
+    /// Api帮助类
+    /// </summary>
+    public class ApiHelper
+    {
+        private List<ApiHelperDto> _apis;
+        private static readonly object _lockObject = new object();
+
+        public List<ApiHelperDto> GetApis()
+        {
+            if (_apis != null && _apis.Any())
+                    return _apis;
+
+            lock (_lockObject)
+            {
+                if (_apis != null && _apis.Any())
+                    return _apis;
+
+                _apis = new List<ApiHelperDto>();
+                var filePath = Path.Combine(Directory.GetCurrentDirectory(), @"Db\Data\data.json");
+                var jsonData = FileHelper.ReadFile(filePath);
+                var apis = JsonConvert.DeserializeObject<Data>(jsonData).Apis;
+                foreach (var api in apis)
+                {
+                    var parentLabel = apis.FirstOrDefault(a => a.Id == api.ParentId)?.Label;
+
+                    _apis.Add(new ApiHelperDto
+                    {
+                        Label = parentLabel.NotNull() ? $"{parentLabel} / {api.Label}" : api.Label,
+                        Path = api.Path?.ToLower().Trim('/')
+                    });
+                }
+
+                return _apis;
+            }
+        }
+    }
+
+    public class ApiHelperDto
+    {
+        public string Label { get; set; }
+        public string Path { get; set; }
+    }
+}

+ 20 - 0
Admin.Core/Logs/ILogHandler.cs

@@ -0,0 +1,20 @@
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc.Filters;
+
+
+namespace Admin.Core.Logs
+{
+    /// <summary>
+    /// 操作日志处理接口
+    /// </summary>
+    public interface ILogHandler
+    {
+        /// <summary>
+        /// 写操作日志
+        /// </summary>
+        /// <param name="context"></param>
+        /// <param name="next"></param>
+        /// <returns></returns>
+        Task LogAsync(ActionExecutingContext context, ActionExecutionDelegate next);
+    }
+}

+ 59 - 0
Admin.Core/Logs/LogHandler.cs

@@ -0,0 +1,59 @@
+using System.Linq;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using Admin.Core.Model.Output;
+using Admin.Core.Service.Admin.OprationLog;
+using Admin.Core.Service.Admin.OprationLog.Input;
+using Microsoft.AspNetCore.Mvc.Filters;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Admin.Core.Logs
+{
+    /// <summary>
+    /// 操作日志处理
+    /// </summary>
+    public class LogHandler : ILogHandler
+    {
+        private readonly ApiHelper _apiHelper;
+        private readonly IOprationLogService _oprationLogService;
+
+        public LogHandler(
+            ApiHelper apiHelper, 
+            IOprationLogService oprationLogService
+        )
+        {
+            _apiHelper = apiHelper;
+            _oprationLogService = oprationLogService;
+        }
+
+        public async Task LogAsync(ActionExecutingContext context, ActionExecutionDelegate next)
+        {
+            var sw = new Stopwatch();
+            sw.Start();
+
+            dynamic actionResult = (await next()).Result;
+
+            sw.Stop();
+
+            //操作参数
+            //var args = JsonConvert.SerializeObject(context.ActionArguments);
+            //操作结果
+            //var result = JsonConvert.SerializeObject(actionResult?.Value);
+
+            var res = actionResult?.Value as IResponseOutput;
+
+            var input = new OprationLogAddInput
+            {
+                ApiMethod = context.HttpContext.Request.Method.ToLower(),
+                ApiPath = context.ActionDescriptor.AttributeRouteInfo.Template.ToLower(),
+                ElapsedMilliseconds = sw.ElapsedMilliseconds,
+                Status = res?.Success,
+                Msg = res?.Msg
+            };
+            input.ApiLabel = _apiHelper.GetApis().FirstOrDefault(a => a.Path == input.ApiPath)?.Label;
+
+            await _oprationLogService.AddAsync(input);
+        }
+    }
+}

+ 32 - 30
Admin.Core/Startup.cs

@@ -32,6 +32,7 @@ using Admin.Core.Db;
 using Admin.Core.Common.Cache;
 using PermissionHandler = Admin.Core.Auth.PermissionHandler;
 using Admin.Core.Aop;
+using Admin.Core.Logs;
 
 namespace Admin.Core
 {
@@ -44,14 +45,16 @@ namespace Admin.Core
         public Startup(IWebHostEnvironment env)
         {
             _env = env;
-            _appConfig = new ConfigHelper().Get<AppConfig>("appconfig",env.EnvironmentName) ?? new AppConfig();
+            _appConfig = new ConfigHelper().Get<AppConfig>("appconfig", env.EnvironmentName) ?? new AppConfig();
         }
 
         public void ConfigureServices(IServiceCollection services)
         {
+            services.AddSingleton(_appConfig);
+            services.AddSingleton(typeof(ApiHelper));
+
             #region AutoMapper 自动映射
-            var ServiceDll = Path.Combine(basePath, "Admin.Core.Service.dll");
-            var serviceAssembly = Assembly.LoadFrom(ServiceDll);
+            var serviceAssembly = Assembly.Load("Admin.Core.Service");
             services.AddAutoMapper(serviceAssembly);
             #endregion
 
@@ -83,12 +86,12 @@ namespace Admin.Core
                         //c.OrderActionsBy(o => o.RelativePath);
                     });
 
-                    var xmlModelPath = Path.Combine(basePath, "Admin.Core.Model.xml");
-                    c.IncludeXmlComments(xmlModelPath);
-
                     var xmlPath = Path.Combine(basePath, "Admin.Core.xml");
                     c.IncludeXmlComments(xmlPath, true);
 
+                    var xmlModelPath = Path.Combine(basePath, "Admin.Core.Model.xml");
+                    c.IncludeXmlComments(xmlModelPath);
+
                     var xmlServicesPath = Path.Combine(basePath, "Admin.Core.Service.xml");
                     c.IncludeXmlComments(xmlServicesPath);
 
@@ -132,7 +135,7 @@ namespace Admin.Core
             services.TryAddSingleton<IUserToken, UserToken>();
             services.AddScoped<IPermissionHandler, PermissionHandler>();
 
-            services.AddAuthentication(options => 
+            services.AddAuthentication(options =>
             {
                 options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                 options.DefaultChallengeScheme = nameof(ResponseAuthenticationHandler); //401
@@ -156,9 +159,17 @@ namespace Admin.Core
             #endregion
 
             #region 控制器
-            services.AddControllers(options => 
-            { 
-                options.Filters.Add(typeof(GlobalExceptionFilter));
+            if (_appConfig.Log.Operation)
+            {
+                services.AddSingleton<ILogHandler, LogHandler>();
+            }
+            services.AddControllers(options =>
+            {
+                options.Filters.Add<AdminExceptionFilter>();
+                if (_appConfig.Log.Operation)
+                {
+                    options.Filters.Add<LogActionFilter>();
+                }
             })
             //.AddFluentValidation(config =>
             //{
@@ -175,13 +186,13 @@ namespace Admin.Core
                 options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
             });
             #endregion
-            
+
             //数据库
             services.AddDb(_env);
 
             #region 缓存
             var cacheConfig = new ConfigHelper().Get<CacheConfig>("cacheconfig", _env.EnvironmentName);
-            if(cacheConfig.Type == CacheType.Redis)
+            if (cacheConfig.Type == CacheType.Redis)
             {
                 var csredis = new CSRedis.CSRedisClient(cacheConfig.Redis.ConnectionString);
                 RedisHelper.Initialization(csredis);
@@ -201,7 +212,7 @@ namespace Admin.Core
         public void ConfigureContainer(ContainerBuilder builder)
         {
             #region AutoFac IOC容器
-            
+
             try
             {
                 #region Aop
@@ -210,25 +221,23 @@ namespace Admin.Core
                 {
                     builder.RegisterType<TransactionInterceptor>();
                     interceptorServiceTypes.Add(typeof(TransactionInterceptor));
-                } 
+                }
                 #endregion
 
                 #region Service
-                var servicesDllFile = Path.Combine(basePath, "Admin.Core.Service.dll");
-                var assemblysServices = Assembly.LoadFrom(servicesDllFile);
-
+                var assemblysServices = Assembly.Load("Admin.Core.Service");
                 builder.RegisterAssemblyTypes(assemblysServices)
                 .AsImplementedInterfaces()
-                .InstancePerLifetimeScope()
+                .InstancePerDependency()
                 .EnableInterfaceInterceptors()
                 .InterceptedBy(interceptorServiceTypes.ToArray());
                 #endregion
 
                 #region Repository
-                var repositoryDllFile = Path.Combine(basePath, "Admin.Core.Repository.dll");
-                var assemblysRepository = Assembly.LoadFrom(repositoryDllFile);
+                var assemblysRepository = Assembly.Load("Admin.Core.Repository");
                 builder.RegisterAssemblyTypes(assemblysRepository)
-                .AsImplementedInterfaces();
+                .AsImplementedInterfaces()
+                .InstancePerDependency();
                 #endregion
             }
             catch (Exception ex)
@@ -242,14 +251,7 @@ namespace Admin.Core
         {
             #region app配置
             //异常
-            if (env.IsDevelopment())
-            {
-                app.UseDeveloperExceptionPage();
-            }
-            else
-            {
-                app.UseExceptionHandler("/Error");
-            }
+            app.UseExceptionHandler("/Error");
 
             //静态文件
             app.UseStaticFiles();
@@ -289,4 +291,4 @@ namespace Admin.Core
             #endregion
         }
     }
-}
+}

+ 5 - 0
Admin.Core/configs/appconfig.json

@@ -7,5 +7,10 @@
   "aop": {
     //事物
     "transaction": false
+  },
+  //日志
+  "log": {
+    //操作日志
+    "operation": true
   }
 }

+ 1 - 0
Admin.Core/configs/dbconfig.Development.json

@@ -23,5 +23,6 @@
   //数据库类型 MySql = 0, SqlServer = 1, PostgreSQL = 2, Oracle = 3, Sqlite = 4, OdbcOracle = 5, OdbcSqlServer = 6, OdbcMySql = 7, OdbcPostgreSQL = 8, Odbc = 9, OdbcDameng = 10, MsAccess = 11
   "type": 4,
   //连接字符串
+  //MySql "Server=localhost; Port=3306; Database=admindb; Uid=root; Pwd=pwd; Charset=utf8mb4;"
   "connectionString": "Data Source=|DataDirectory|\\admindb.db; Pooling=true;Min Pool Size=1"
 }

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff