diff --git a/src/2.services/ATS.NonCustodial.Application/Impl/Logs/AuditLogService.cs b/src/2.services/ATS.NonCustodial.Application/Impl/Logs/AuditLogService.cs
new file mode 100644
index 0000000..ef9d6b7
--- /dev/null
+++ b/src/2.services/ATS.NonCustodial.Application/Impl/Logs/AuditLogService.cs
@@ -0,0 +1,55 @@
+using ATS.NonCustodial.Application.Base;
+using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.AuditLog;
+using ATS.NonCustodial.AuditLogging.AuditLoggings.Services;
+using ATS.NonCustodial.AuditLogging.Dtos.Input;
+using ATS.NonCustodial.AuditLogging.Dtos.Output;
+using ATS.NonCustodial.AuditLogging.EntityFrameworkCore.Entities;
+using ATS.NonCustodial.AuditLogging.Mappers;
+using ATS.NonCustodial.DynamicApi;
+using ATS.NonCustodial.DynamicApi.Attributes;
+using Microsoft.AspNetCore.Mvc;
+
+namespace ATS.NonCustodial.Application.Impl.Logs
+{
+ ///
+ /// 审计日志服务
+ ///
+ /// Author:mxg
+ /// CreatedTimed:2022-04-25 16:31
+ [DynamicApi(Area = "admin")]
+ public class AuditLogService : AdminAppServiceBase, IAuditLogService, IDynamicApi
+ {
+ #region Identity
+
+ protected readonly IAuditLogRepository AuditLogRepository;
+
+ public AuditLogService(IAuditLogRepository auditLogRepository)
+ {
+ AuditLogRepository = auditLogRepository;
+ }
+
+ #endregion Identity
+
+ ///
+ /// 查询
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task GetAsync(AuditLogFilterDto filters)
+ {
+ var pagedList = await AuditLogRepository.GetAsync(filters.Event, filters.Source, filters.Category, filters.Created, filters.SubjectIdentifier, filters.SubjectName, filters.Page, filters.PageSize);
+ var auditLogsDto = pagedList.ToAuditLogModel();
+
+ return auditLogsDto;
+ }
+
+ ///
+ /// 删除
+ ///
+ ///
+ ///
+ [HttpDelete]
+ public virtual async Task DeleteLogsOlderThanAsync(DateTime deleteOlderThan) => await AuditLogRepository.DeleteLogsOlderThanAsync(deleteOlderThan);
+ }
+}
\ No newline at end of file
diff --git a/src/2.services/ATS.NonCustodial.Application/Impl/Logs/LoginLogService.cs b/src/2.services/ATS.NonCustodial.Application/Impl/Logs/LoginLogService.cs
new file mode 100644
index 0000000..75edc96
--- /dev/null
+++ b/src/2.services/ATS.NonCustodial.Application/Impl/Logs/LoginLogService.cs
@@ -0,0 +1,102 @@
+using ATS.NonCustodial.Application.Base;
+using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.LoginLog;
+using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.LoginLog.Input;
+using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.LoginLog.Output;
+using ATS.NonCustodial.Domain.Entities.Logs;
+using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore;
+using ATS.NonCustodial.DynamicApi;
+using ATS.NonCustodial.DynamicApi.Attributes;
+using ATS.NonCustodial.Shared.Common.UnifiedResults;
+using ATS.NonCustodial.Shared.Extensions;
+using ATS.NonCustodial.Shared.Helpers;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+
+namespace ATS.NonCustodial.Application.Impl.Logs
+{
+ ///
+ /// ¼־
+ ///
+ /// Author:mxg
+ /// CreatedTimed:2022-05-17 10:15 PM
+ [DynamicApi(Area = "admin")]
+ public class LoginLogService : AdminAppServiceBase, ILoginLogService, IDynamicApi
+ {
+ #region Identity
+
+ private readonly IHttpContextAccessor _context;
+ private readonly IEfRepository _loginLogRepository;
+
+ public LoginLogService(
+ IHttpContextAccessor context,
+ IEfRepository loginLogRepository
+ )
+ {
+ _context = context;
+ _loginLogRepository = loginLogRepository;
+ }
+
+ #endregion Identity
+
+ ///
+ /// ѯ¼־б
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task GetPageAsync(LogGetPageDto input)
+ {
+ var express = GetExpression(input, _loginLogRepository.AsQueryable(false, true));
+ var rtn = await base.GetPageAsync(input, express);
+ return ResultOutput.Ok(rtn);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task> AddAsync(LoginLogAddInput input)
+ {
+ var res = new ResultOutput();
+
+ input.IP = IPHelper.GetIP(_context?.HttpContext?.Request);
+
+ string ua = _context.HttpContext.Request.Headers["User-Agent"];
+ if (ua.NotNull())
+ {
+ 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(input);
+ var id = (await _loginLogRepository.InsertAsync(entity)).Id;
+
+ return id > 0 ? res.Ok(id) : res;
+ }
+
+ #region Private
+
+ ///
+ /// ѯ
+ ///
+ ///
+ ///
+ ///
+ private IQueryable GetExpression(LogGetPageDto pageInput, IQueryable query)
+ {
+ query = query
+ .WhereIf(pageInput.OperatorName.NotNull(), w => pageInput.OperatorName.Contains(w.CreatedUserName));
+
+ var express = base.GetEntityAddExpression(pageInput, query);
+
+ return express;
+ }
+
+ #endregion Private
+ }
+}
\ No newline at end of file
diff --git a/src/2.services/ATS.NonCustodial.Application/Impl/Logs/OperationLogService.cs b/src/2.services/ATS.NonCustodial.Application/Impl/Logs/OperationLogService.cs
new file mode 100644
index 0000000..17e8b14
--- /dev/null
+++ b/src/2.services/ATS.NonCustodial.Application/Impl/Logs/OperationLogService.cs
@@ -0,0 +1,153 @@
+using ATS.NonCustodial.Application.Base;
+using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement;
+using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.LoginLog.Input;
+using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.OprationLog;
+using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.OprationLog.Input;
+using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.OprationLog.Output;
+using ATS.NonCustodial.Domain.Entities.Logs;
+using ATS.NonCustodial.Domain.Shared.AggRootEntities.Dtos;
+using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore;
+using ATS.NonCustodial.DynamicApi;
+using ATS.NonCustodial.DynamicApi.Attributes;
+using ATS.NonCustodial.Shared.Common.UnifiedResults;
+using ATS.NonCustodial.Shared.Extensions;
+using AutoMapper.QueryableExtensions;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+
+namespace ATS.NonCustodial.Application.Impl.Logs
+{
+ ///
+ /// ־
+ ///
+ /// Author:mxg
+ /// CreatedTimed:2022-05-17 10:11 PM
+ [DynamicApi(Area = "admin")]
+ public class OperationLogService : AdminAppServiceBase, IOperationLogService, IDynamicApi
+ {
+ #region Identity
+
+ private readonly IHttpContextAccessor _context;
+ private readonly IEfRepository _oprationLogRepository;
+ private readonly IAppCaseManagementService _appCaseManagementService;
+
+ public OperationLogService(
+ IHttpContextAccessor context,
+ IEfRepository oprationLogRepository,
+ IAppCaseManagementService appCaseManagementService
+ )
+ {
+ _context = context;
+ _oprationLogRepository = oprationLogRepository;
+ _appCaseManagementService = appCaseManagementService;
+ }
+
+ #endregion Identity
+
+ ///
+ /// ѯ־б
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task GetPageAsync(LogGetPageDto input)
+ {
+ var express = await GetExpression(input, _oprationLogRepository.AsQueryable(false, true).Take(3000));
+ var rtn = await base.GetPageAsync(input, express);
+
+ return ResultOutput.Ok(rtn);
+ }
+
+ ///
+ /// ѯ־ϸ
+ ///
+ ///
+ ///
+ public async Task Get(long id)
+ {
+ var rtn = await base.GetAsync(_oprationLogRepository, id);
+ return ResultOutput.Ok(rtn);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task 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.NickName = User.NickName;
+ input.IpAddress = _context.HttpContext.Connection.RemoteIpAddress?.ToString().Replace("::ffff:", "")/*IPHelper.GetIP(_context?.HttpContext?.Request)*/;
+
+ var entity = Mapper.Map(input);
+ var id = ((await _oprationLogRepository.InsertAsync(entity))!).Id;
+
+ return ResultOutput.Result(id > 0);
+ }
+
+ ///
+ /// ҵ̨==>5־
+ ///
+ ///
+ public async Task OperationBusinessWorkbench()
+ {
+ var userIds = await _appCaseManagementService.GetUserIdListByCurrentUser();
+
+ var dataList = await _oprationLogRepository.AsQueryable(false, true)
+ .Where(w => w.CreatedUserId != null && userIds.Contains(w.CreatedUserId.Value))
+ .OrderByDescending(w => w.CreatedTime)
+ .Skip(0)
+ .Take(5)
+ .ProjectTo(Mapper.ConfigurationProvider)
+ .ToListAsync();
+ return ResultOutput.Ok(dataList);
+ }
+
+ ///
+ /// ɾ־
+ ///
+ ///
+ ///
+ public async Task BatchDeleteAsync(BatchIdsInput input)
+ {
+ var rtn = await _oprationLogRepository.DeleteAsync(w => input.Ids.Contains(w.Id));
+
+ return ResultOutput.Ok(rtn > 0);
+ }
+
+ #region Private
+
+ ///
+ /// ѯ
+ ///
+ ///
+ ///
+ ///
+ private async Task> GetExpression(LogGetPageDto pageInput, IQueryable query)
+ {
+ var userIds = await _appCaseManagementService.GetUserIdListByCurrentUser();
+
+ query = query
+ .Where(w => w.CreatedUserId != null && userIds.Contains(w.CreatedUserId.Value))
+ .WhereIf(pageInput.OperatorName.NotNull(), w => w.CreatedUserName.Contains(pageInput.OperatorName))
+ .WhereIf(pageInput.Device.NotNull(), w => w.Device==pageInput.Device)
+ .WhereIf(pageInput.NickName.NotNull(), w => w.NickName==pageInput.NickName);
+
+ var express = base.GetEntityAddExpression(pageInput, query);
+
+ return express;
+ }
+
+ #endregion Private
+ }
+}
\ No newline at end of file