Browse Source

合并

dev_wp
zhaozhenjing 3 months ago
parent
commit
ec3758b0bf
  1. 6
      src/1.datas/ATS.NonCustodial.Domain/Entities/Admins/App_Unitcode.cs
  2. 2
      src/1.datas/ATS.NonCustodial.Domain/Entities/Business/CaseManagements/AppCaseSupervisor.cs
  3. 17
      src/1.datas/ATS.NonCustodial.Domain/Entities/Log/AppLoginLog.cs
  4. 42
      src/1.datas/ATS.NonCustodial.Domain/Entities/Log/AppOperationLog.cs
  5. 4
      src/2.services/ATS.NonCustodial.Application/Impl/Admins/AuthService.cs
  6. 46
      src/2.services/ATS.NonCustodial.Application/Impl/Admins/UnitcodeService.cs
  7. 1
      src/2.services/ATS.NonCustodial.Application/Impl/Admins/UserService.cs
  8. 2
      src/2.services/ATS.NonCustodial.Application/Impl/Business/AppEarlyWarningService.cs
  9. 37
      src/2.services/ATS.NonCustodial.Application/Impl/Business/CaseManagements/AppCaseManagementService.cs
  10. 55
      src/2.services/ATS.NonCustodial.Application/Impl/Logs/AuditLogService.cs
  11. 102
      src/2.services/ATS.NonCustodial.Application/Impl/Logs/LoginLogService.cs
  12. 153
      src/2.services/ATS.NonCustodial.Application/Impl/Logs/OperationLogService.cs
  13. 9
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/Auth/Output/AuthLoginOutput.cs
  14. 2
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppCaseManagements/AppCaseManagement/Input/AppCaseManagementGetPageInput.cs
  15. 2
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppCaseManagements/AppCaseManagement/Output/AppCaseManagementListDto.cs
  16. 17
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/AuditLog/IAuditLogService.cs
  17. 27
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/LoginLog/ILoginLogService.cs
  18. 25
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/LoginLog/Input/LogGetPageDto.cs
  19. 75
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/LoginLog/Input/LoginLogAddInput.cs
  20. 47
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/LoginLog/Output/LoginLogListOutput.cs
  21. 34
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/OprationLog/IOperationLogService.cs
  22. 85
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/OprationLog/Input/OprationLogAddInput.cs
  23. 77
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/OprationLog/Output/OprationLogListOutput.cs
  24. 3939
      src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_api.json
  25. 7
      src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_dictionary.json
  26. 3548
      src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_user.json
  27. 3052
      src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_user_role.json
  28. 2
      src/5.shared/ATS.NonCustodial.Admin.Jobs/Jobs/PunchRecordJob.cs
  29. 85
      src/5.shared/ATS.NonCustodial.AdminUi/Helpers/Logs/ApiHelper.cs
  30. 20
      src/5.shared/ATS.NonCustodial.AdminUi/Helpers/Logs/ILogHandler.cs
  31. 175
      src/5.shared/ATS.NonCustodial.AdminUi/Helpers/Logs/LogHandler.cs
  32. 10
      src/5.shared/ATS.NonCustodial.Shared/Common/Auth/ClaimAttributes.cs
  33. 7
      src/5.shared/ATS.NonCustodial.Shared/Common/Auth/IUser.cs
  34. 18
      src/5.shared/ATS.NonCustodial.Shared/Common/Auth/User.cs

6
src/1.datas/ATS.NonCustodial.Domain/Entities/Admins/App_Unitcode.cs

@ -57,5 +57,11 @@ namespace ATS.NonCustodial.Domain.Entities.Admins
/// </summary> /// </summary>
[MaxLength(StringLengthConstants.StringLength255)] [MaxLength(StringLengthConstants.StringLength255)]
public string? UnitIsReferToAs { get; set; } public string? UnitIsReferToAs { get; set; }
/// <summary>
/// 查询界限
/// </summary>
[MaxLength(StringLengthConstants.StringLength2048)]
public string? limits { get; set; }
} }
} }

2
src/1.datas/ATS.NonCustodial.Domain/Entities/Business/CaseManagements/AppCaseSupervisor.cs

@ -38,5 +38,7 @@ namespace ATS.NonCustodial.Domain.Entities.Business.CaseManagements
/// </summary> /// </summary>
[MaxLength(StringLengthConstants.StringLength20)] [MaxLength(StringLengthConstants.StringLength20)]
public string? SupervisorName { get; set; } public string? SupervisorName { get; set; }
public long UnitId { get; set; }
} }
} }

17
src/1.datas/ATS.NonCustodial.Domain/Entities/Log/AppLoginLog.cs

@ -0,0 +1,17 @@
using ATS.NonCustodial.Domain.Shared.AggRootEntities;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;
namespace ATS.NonCustodial.Domain.Entities.Logs
{
/// <summary>
/// 登录日志
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-12 18:30 PM
[Table("app_login_log")]
[Index(nameof(CreatedUserId), nameof(CreatedUserName))]
public class AppLoginLog : LogAbstract
{
}
}

42
src/1.datas/ATS.NonCustodial.Domain/Entities/Log/AppOperationLog.cs

@ -0,0 +1,42 @@
using ATS.NonCustodial.Domain.Shared.AggRootEntities;
using ATS.NonCustodial.Domain.Shared.Constants;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ATS.NonCustodial.Domain.Entities.Logs
{
/// <summary>
/// 操作日志
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-12 18:30 PM
[Table("app_operation_log")]
[Index(nameof(CreatedUserId), nameof(CreatedUserName))]
public class AppOperationLog : LogAbstract
{
/// <summary>
/// 接口名称
/// </summary>
[MaxLength(StringLengthConstants.StringLength255)]
public string? ApiLabel { get; set; }
/// <summary>
/// 接口地址
/// </summary>
[MaxLength(StringLengthConstants.StringLength128)]
public string? ApiPath { get; set; }
/// <summary>
/// 接口提交方法
/// </summary>
[MaxLength(StringLengthConstants.StringLength10)]
public string? ApiMethod { get; set; }
/// <summary>
/// 操作参数
/// </summary>
[MaxLength(StringLengthConstants.StringLength2048)]
public string? Params { get; set; }
}
}

4
src/2.services/ATS.NonCustodial.Application/Impl/Admins/AuthService.cs

@ -31,6 +31,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json; using Newtonsoft.Json;
using NPOI.SS.Formula.Functions; using NPOI.SS.Formula.Functions;
using NPOI.Util;
using StackExchange.Profiling; using StackExchange.Profiling;
using System.Diagnostics; using System.Diagnostics;
using System.Security.Claims; using System.Security.Claims;
@ -399,6 +400,7 @@ namespace ATS.NonCustodial.Application.Impl.Admins
if (user == null) return string.Empty; if (user == null) return string.Empty;
var roles = (await _userService.IsAdmin(user.Id)).Roles.Select(w => w.Id).ToList(); var roles = (await _userService.IsAdmin(user.Id)).Roles.Select(w => w.Id).ToList();
string limits = _appUnitRepository.AsQueryable(false, true).Where(a => a.Id == user.UnitId).Select(a => a.limits).FirstOrDefault();
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var timeLogin = Convert.ToInt64(ts.TotalMilliseconds).ToString(); var timeLogin = Convert.ToInt64(ts.TotalMilliseconds).ToString();
var token = LazyGetRequiredService<IUserToken>().Create(new[] var token = LazyGetRequiredService<IUserToken>().Create(new[]
@ -413,7 +415,7 @@ namespace ATS.NonCustodial.Application.Impl.Admins
new Claim(ClaimAttributes.orgs,JsonConvert.SerializeObject(Array.Empty<long>())) , new Claim(ClaimAttributes.orgs,JsonConvert.SerializeObject(Array.Empty<long>())) ,
new Claim(ClaimAttributes.phone,user?.Phone??""), new Claim(ClaimAttributes.phone,user?.Phone??""),
new Claim(ClaimAttributes.logtime,timeLogin), new Claim(ClaimAttributes.logtime,timeLogin),
new Claim(ClaimAttributes.limits,limits),
new Claim(ClaimAttributes.personType,user?.ChatPersonType.ToString()!) new Claim(ClaimAttributes.personType,user?.ChatPersonType.ToString()!)
}); });

46
src/2.services/ATS.NonCustodial.Application/Impl/Admins/UnitcodeService.cs

@ -18,6 +18,7 @@ using ATS.NonCustodial.Shared.Extensions.AdvancedQuery;
using AutoMapper.QueryableExtensions; using AutoMapper.QueryableExtensions;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Linq;
using Yitter.IdGenerator; using Yitter.IdGenerator;
namespace ATS.NonCustodial.Application.Impl.Admins namespace ATS.NonCustodial.Application.Impl.Admins
@ -34,12 +35,15 @@ namespace ATS.NonCustodial.Application.Impl.Admins
private readonly IEfRepository<App_Unitcode?, long> _appUnitcodeRepository; private readonly IEfRepository<App_Unitcode?, long> _appUnitcodeRepository;
private readonly IEfRepository<App_Deptcode?, long> _appDeptcodeRepository; private readonly IEfRepository<App_Deptcode?, long> _appDeptcodeRepository;
private readonly IEfRepository<AppUser?, long> _userRepository;
public UnitcodeService(IEfRepository<App_Unitcode?, long> appUnitcodeRepository, public UnitcodeService(IEfRepository<App_Unitcode?, long> appUnitcodeRepository,
IEfRepository<App_Deptcode?, long> appDeptcodeRepository) IEfRepository<App_Deptcode?, long> appDeptcodeRepository,
IEfRepository<AppUser?, long> userRepository)
{ {
_appUnitcodeRepository = appUnitcodeRepository; _appUnitcodeRepository = appUnitcodeRepository;
_appDeptcodeRepository = appDeptcodeRepository; _appDeptcodeRepository = appDeptcodeRepository;
_userRepository = userRepository;
} }
#endregion Identity #endregion Identity
@ -316,6 +320,11 @@ namespace ATS.NonCustodial.Application.Impl.Admins
{ {
if (!(input?.Id > 0)) return ResultOutput.NotOk(); if (!(input?.Id > 0)) return ResultOutput.NotOk();
var unitlist = _appUnitcodeRepository.AsQueryable(false, true).Where(q => q.Id == input.Id).ToList();
foreach (var item in unitlist)
{
if (item.ParentUnitCode != input.ParentUnitCode) { return ResultOutput.NotOk("单位父级无法修改"); }
}
var entity = await _appUnitcodeRepository.FindAsync((long)input.Id); var entity = await _appUnitcodeRepository.FindAsync((long)input.Id);
if (!(entity?.Id > 0)) return ResultOutput.NotOk("编辑失败"); if (!(entity?.Id > 0)) return ResultOutput.NotOk("编辑失败");
@ -334,14 +343,45 @@ namespace ATS.NonCustodial.Application.Impl.Admins
{ {
Uow.BeginTransaction(); Uow.BeginTransaction();
{ {
for (int i = 0; i < input.Ids.Count; i++)
{
var idlist= GetUnitIdList(input.Ids[i]);
//校验该单位下是否存在用户账户
if (_userRepository.AsQueryable(false, true).Where(q => idlist.Contains(q.UnitId??-1)).Any())
{
return ResultOutput.NotOk("该单位下存在用户账户,无法删除");
}
//删除 //删除
await _appUnitcodeRepository.DeleteAsync(w => input.Ids.Contains(w.Id)); await _appUnitcodeRepository.DeleteAsync(w => idlist.Contains(w.Id));
}
//删除 //删除
await _appUnitcodeRepository.DeleteAsync(w => input.Ids.Contains((long)w.ParentUnitCode)); // await _appUnitcodeRepository.DeleteAsync(w => input.Ids.Contains(w.Id));
//删除
// await _appUnitcodeRepository.DeleteAsync(w => input.Ids.Contains((long)w.ParentUnitCode));
} }
await Uow.CommitAsync(); await Uow.CommitAsync();
return ResultOutput.Ok(); return ResultOutput.Ok();
} }
/// <summary>
/// 递归查找该单位下的所有单位
/// </summary>
/// <param name="unitId">单位id</param>
/// <returns>单位id集合</returns>
private List<long> GetUnitIdList(long unitId)
{
List<long> idList=new List<long>();
idList.Add(unitId);
var unitlist=_appUnitcodeRepository.AsQueryable(false, true).Where(q => q.ParentUnitCode == unitId).ToList() ;
foreach (var item in unitlist)
{
idList.Add(item.Id);
var idlist = GetUnitIdList(item.Id);
idList.AddRange(idlist);
}
return idList;
}
#region Private #region Private
/// <summary> /// <summary>

1
src/2.services/ATS.NonCustodial.Application/Impl/Admins/UserService.cs

@ -12,6 +12,7 @@ using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore;
using ATS.NonCustodial.DynamicApi; using ATS.NonCustodial.DynamicApi;
using ATS.NonCustodial.DynamicApi.Attributes; using ATS.NonCustodial.DynamicApi.Attributes;
using ATS.NonCustodial.Shared.Common.Attributes; using ATS.NonCustodial.Shared.Common.Attributes;
using ATS.NonCustodial.Shared.Common.Auth;
using ATS.NonCustodial.Shared.Common.Constants; using ATS.NonCustodial.Shared.Common.Constants;
using ATS.NonCustodial.Shared.Common.Dtos; using ATS.NonCustodial.Shared.Common.Dtos;
using ATS.NonCustodial.Shared.Common.Dtos.Query; using ATS.NonCustodial.Shared.Common.Dtos.Query;

2
src/2.services/ATS.NonCustodial.Application/Impl/Business/AppEarlyWarningService.cs

@ -282,7 +282,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
.WhereIf(input.supname.NotNull(), w => w.SupervisedPersonName.Contains(input.supname)) .WhereIf(input.supname.NotNull(), w => w.SupervisedPersonName.Contains(input.supname))
.GroupBy(q => new { q.CaseId, q.CaseName, q.SupervisedPersonId, q.SupervisedPersonName }).Select(q => new { q.Key.CaseId, q.Key.CaseName, q.Key.SupervisedPersonName, q.Key.SupervisedPersonId, Count = q.ToList().Count() }).Skip((input.PageIndex - 1) * input.PageSize).Take(input.PageSize); .GroupBy(q => new { q.CaseId, q.CaseName, q.SupervisedPersonId, q.SupervisedPersonName }).Select(q => new { q.Key.CaseId, q.Key.CaseName, q.Key.SupervisedPersonName, q.Key.SupervisedPersonId, Count = q.ToList().Count() }).Skip((input.PageIndex - 1) * input.PageSize).Take(input.PageSize);
var SupervisedPersonIds = grudlist.Select(q => q.SupervisedPersonId); var SupervisedPersonIds = grudlist.Select(q => q.SupervisedPersonId);
var grudlistcunot = express.Where(q => SupervisedPersonIds.Contains(q.SupervisedPersonId)).ToList(); // var grudlistcunot = express.Where(q => SupervisedPersonIds.Contains(q.SupervisedPersonId)).ToList();
return ResultOutput.Ok(new { TotalCount = express.GroupBy(q => new { q.CaseId, q.CaseName, q.SupervisedPersonId, q.SupervisedPersonName }).Count(), grudlist }); return ResultOutput.Ok(new { TotalCount = express.GroupBy(q => new { q.CaseId, q.CaseName, q.SupervisedPersonId, q.SupervisedPersonName }).Count(), grudlist });
} }

37
src/2.services/ATS.NonCustodial.Application/Impl/Business/CaseManagements/AppCaseManagementService.cs

@ -16,6 +16,7 @@ using ATS.NonCustodial.Domain.Shared.Enums;
using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore; using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore;
using ATS.NonCustodial.DynamicApi; using ATS.NonCustodial.DynamicApi;
using ATS.NonCustodial.DynamicApi.Attributes; using ATS.NonCustodial.DynamicApi.Attributes;
using ATS.NonCustodial.Shared.Common.Auth;
using ATS.NonCustodial.Shared.Common.Dtos; using ATS.NonCustodial.Shared.Common.Dtos;
using ATS.NonCustodial.Shared.Common.Enums; using ATS.NonCustodial.Shared.Common.Enums;
using ATS.NonCustodial.Shared.Common.UnifiedResults; using ATS.NonCustodial.Shared.Common.UnifiedResults;
@ -140,24 +141,45 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
[HttpPost] [HttpPost]
public async Task<IResultOutput> GetPageAsync(AppCaseManagementGetPageInput input) public async Task<IResultOutput> GetPageAsync(AppCaseManagementGetPageInput input)
{ {
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
input.CaseIds= selectLimits.Select(w => w.CaseId).Distinct().ToList();
var express = await GetExpression(input, _appCaseManagementRepository.AsQueryable(false, true)); var express = await GetExpression(input, _appCaseManagementRepository.AsQueryable(false, true));
var rtn = await base.GetPageAsync<AppCaseManagement, AppCaseManagementGetPageInput, AppCaseManagementListDto>(input, express); var rtn = await base.GetPageAsync<AppCaseManagement, AppCaseManagementGetPageInput, AppCaseManagementListDto>(input, express);
var caseIds = rtn.Data.Select(w => w.Id).ToList();
var caseSupervisor = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => caseIds.Contains(w.CaseId))
.ToListAsync();
foreach (var listDto in rtn.Data) foreach (var listDto in rtn.Data)
{ {
listDto.Supervisor = caseSupervisor.Where(w => w.CaseId == listDto.Id).Select(w => w.SupervisorName).JoinAsString(","); listDto.Supervisor = selectLimits.Where(w => w.CaseId == listDto.Id).Select(w => w.SupervisorName).JoinAsString(",");
} }
return ResultOutput.Ok(rtn); return ResultOutput.Ok(rtn);
} }
//[HttpPost]
//public async Task<IResultOutput> GetPageAsync(AppCaseManagementGetPageInput input)
//{
// var express = await GetExpression(input, _appCaseManagementRepository.AsQueryable(false, true));
// var rtn = await base.GetPageAsync<AppCaseManagement, AppCaseManagementGetPageInput, AppCaseManagementListDto>(input, express);
// var caseIds = rtn.Data.Select(w => w.Id).ToList();
// var caseSupervisor = await _appCaseSupervisorRepository.AsQueryable(false, true)
// .Where(w => caseIds.Contains(w.CaseId))
// .ToListAsync();
// foreach (var listDto in rtn.Data)
// {
// listDto.Supervisor = caseSupervisor.Where(w => w.CaseId == listDto.Id).Select(w => w.SupervisorName).JoinAsString(",");
// }
// return ResultOutput.Ok(rtn);
//}
/// <summary> /// <summary>
/// 案件统计 /// 案件统计
/// </summary> /// </summary>
@ -1429,6 +1451,7 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync(); var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
query = query query = query
.WhereIf(pageInput.CaseIds.IsNotNullOrEmpty(), w => pageInput.CaseIds.Contains(w.Id))
.WhereIf(pageInput.CaseName.NotNull(), a => a.Name.Contains(pageInput.CaseName)) .WhereIf(pageInput.CaseName.NotNull(), a => a.Name.Contains(pageInput.CaseName))
.WhereIf(pageInput.CaseTypeId != null, a => a.CaseTypeId == pageInput.CaseTypeId) .WhereIf(pageInput.CaseTypeId != null, a => a.CaseTypeId == pageInput.CaseTypeId)
.WhereIf(pageInput.JudgmentStatusIds.IsNotNullOrEmpty(), w => pageInput.JudgmentStatusIds.Contains(w.JudgmentStatusId)) .WhereIf(pageInput.JudgmentStatusIds.IsNotNullOrEmpty(), w => pageInput.JudgmentStatusIds.Contains(w.JudgmentStatusId))

55
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
{
/// <summary>
/// 审计日志服务
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-04-25 16:31
[DynamicApi(Area = "admin")]
public class AuditLogService : AdminAppServiceBase, IAuditLogService, IDynamicApi
{
#region Identity
protected readonly IAuditLogRepository<AuditLog> AuditLogRepository;
public AuditLogService(IAuditLogRepository<AuditLog> auditLogRepository)
{
AuditLogRepository = auditLogRepository;
}
#endregion Identity
/// <summary>
/// 查询
/// </summary>
/// <param name="filters"></param>
/// <returns></returns>
[HttpPost]
public async Task<AuditLogsDto> 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;
}
/// <summary>
/// 删除
/// </summary>
/// <param name="deleteOlderThan"></param>
/// <returns></returns>
[HttpDelete]
public virtual async Task DeleteLogsOlderThanAsync(DateTime deleteOlderThan) => await AuditLogRepository.DeleteLogsOlderThanAsync(deleteOlderThan);
}
}

102
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
{
/// <summary>
/// 登录日志服务
/// </summary>
/// 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<AppLoginLog?, long> _loginLogRepository;
public LoginLogService(
IHttpContextAccessor context,
IEfRepository<AppLoginLog?, long> loginLogRepository
)
{
_context = context;
_loginLogRepository = loginLogRepository;
}
#endregion Identity
/// <summary>
/// 查询登录日志列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> GetPageAsync(LogGetPageDto input)
{
var express = GetExpression(input, _loginLogRepository.AsQueryable(false, true));
var rtn = await base.GetPageAsync<AppLoginLog, LogGetPageDto, LoginLogListOutput>(input, express);
return ResultOutput.Ok(rtn);
}
/// <summary>
/// 新增
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<IResultOutput<long>> AddAsync(LoginLogAddInput input)
{
var res = new ResultOutput<long>();
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<AppLoginLog>(input);
var id = (await _loginLogRepository.InsertAsync(entity)).Id;
return id > 0 ? res.Ok(id) : res;
}
#region Private
/// <summary>
/// 查询条件
/// </summary>
/// <param name="pageInput"></param>
/// <param name="query"></param>
/// <returns></returns>
private IQueryable<AppLoginLog> GetExpression(LogGetPageDto pageInput, IQueryable<AppLoginLog?> query)
{
query = query
.WhereIf(pageInput.OperatorName.NotNull(), w => pageInput.OperatorName.Contains(w.CreatedUserName));
var express = base.GetEntityAddExpression<AppLoginLog, LogGetPageDto, long>(pageInput, query);
return express;
}
#endregion Private
}
}

153
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
{
/// <summary>
/// 操作日志服务
/// </summary>
/// 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<AppOperationLog?, long> _oprationLogRepository;
private readonly IAppCaseManagementService _appCaseManagementService;
public OperationLogService(
IHttpContextAccessor context,
IEfRepository<AppOperationLog?, long> oprationLogRepository,
IAppCaseManagementService appCaseManagementService
)
{
_context = context;
_oprationLogRepository = oprationLogRepository;
_appCaseManagementService = appCaseManagementService;
}
#endregion Identity
/// <summary>
/// 查询操作日志列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> GetPageAsync(LogGetPageDto input)
{
var express = await GetExpression(input, _oprationLogRepository.AsQueryable(false, true).Take(3000));
var rtn = await base.GetPageAsync<AppOperationLog, LogGetPageDto, OprationLogListOutput>(input, express);
return ResultOutput.Ok(rtn);
}
/// <summary>
/// 查询操作日志明细
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<IResultOutput> Get(long id)
{
var rtn = await base.GetAsync<AppOperationLog, OprationLogListOutput, long>(_oprationLogRepository, id);
return ResultOutput.Ok(rtn);
}
/// <summary>
/// 新增
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<IResultOutput> 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<AppOperationLog>(input);
var id = ((await _oprationLogRepository.InsertAsync(entity))!).Id;
return ResultOutput.Result(id > 0);
}
/// <summary>
/// 业务工作台==>最新5条操作日志
/// </summary>
/// <returns></returns>
public async Task<IResultOutput> 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<OprationLogListOutput>(Mapper.ConfigurationProvider)
.ToListAsync();
return ResultOutput.Ok(dataList);
}
/// <summary>
/// 批量删除操作日志
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<IResultOutput> BatchDeleteAsync(BatchIdsInput input)
{
var rtn = await _oprationLogRepository.DeleteAsync(w => input.Ids.Contains(w.Id));
return ResultOutput.Ok(rtn > 0);
}
#region Private
/// <summary>
/// 查询条件
/// </summary>
/// <param name="pageInput"></param>
/// <param name="query"></param>
/// <returns></returns>
private async Task<IQueryable<AppOperationLog>> GetExpression(LogGetPageDto pageInput, IQueryable<AppOperationLog?> 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<AppOperationLog, LogGetPageDto, long>(pageInput, query);
return express;
}
#endregion Private
}
}

9
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/Auth/Output/AuthLoginOutput.cs

@ -1,4 +1,6 @@
using ATS.NonCustodial.Shared.Common.Enums; using ATS.NonCustodial.Domain.Shared.Constants;
using ATS.NonCustodial.Shared.Common.Enums;
using System.ComponentModel.DataAnnotations;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Auth.Output namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Auth.Output
{ {
@ -73,5 +75,10 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Auth.Output
/// 手机登录获取到得手机唯一标识,(用于个推) /// 手机登录获取到得手机唯一标识,(用于个推)
/// </summary> /// </summary>
public string? CId { get; set; } public string? CId { get; set; }
/// <summary>
/// 查询界限
/// </summary>
public string? limits { get; set; }
} }
} }

2
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppCaseManagements/AppCaseManagement/Input/AppCaseManagementGetPageInput.cs

@ -29,5 +29,7 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseMana
/// 案件类型(数据来自字典) /// 案件类型(数据来自字典)
/// </summary> /// </summary>
public long? CaseTypeId { get; set; } public long? CaseTypeId { get; set; }
public List<long>? CaseIds { get; set; }
} }
} }

2
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppCaseManagements/AppCaseManagement/Output/AppCaseManagementListDto.cs

@ -62,7 +62,7 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseMana
/// <summary> /// <summary>
/// 案子开始时间 /// 案子开始时间
/// </summary> /// </summary>
public DateTime CaseBeginTime { get; set; } public DateTime? CaseBeginTime { get; set; }
/// <summary> /// <summary>
/// 案子结束时间 /// 案子结束时间

17
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/AuditLog/IAuditLogService.cs

@ -0,0 +1,17 @@
using ATS.NonCustodial.AuditLogging.Dtos.Input;
using ATS.NonCustodial.AuditLogging.Dtos.Output;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Logs.AuditLog
{
/// <summary>
///
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-04-25 16:23
public interface IAuditLogService
{
Task<AuditLogsDto> GetAsync(AuditLogFilterDto filters);
Task DeleteLogsOlderThanAsync(DateTime deleteOlderThan);
}
}

27
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/LoginLog/ILoginLogService.cs

@ -0,0 +1,27 @@
using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.LoginLog.Input;
using ATS.NonCustodial.Shared.Common.UnifiedResults;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Logs.LoginLog
{
/// <summary>
/// µÇ¼ÈÕÖ¾½Ó¿Ú
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-14 09:32 PM
public interface ILoginLogService
{
/// <summary>
///
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<IResultOutput> GetPageAsync(LogGetPageDto input);
/// <summary>
///
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<IResultOutput<long>> AddAsync(LoginLogAddInput input);
}
}

25
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/LoginLog/Input/LogGetPageDto.cs

@ -0,0 +1,25 @@
using ATS.NonCustodial.Shared.Common.Dtos;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Logs.LoginLog.Input
{
/// <summary>
///
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-14 09:32 PM
public class LogGetPageDto : PageRequestBaseInput
{
/// <summary>
/// 操作者名称
/// </summary>
public string? OperatorName { get; set; }
/// <summary>
/// 手机型号
/// </summary>
public string? Device { get; set; }
/// <summary>
/// app
/// </summary>
public string? NickName { get; set; }
}
}

75
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/LoginLog/Input/LoginLogAddInput.cs

@ -0,0 +1,75 @@
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Logs.LoginLog.Input
{
/// <summary>
/// 添加
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-14 09:32 PM
public class LoginLogAddInput
{
/// <summary>
/// 租户Id
/// </summary>
public long? TenantId { get; set; }
/// <summary>
/// 昵称
/// </summary>
public string? NickName { 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; }
}
}

47
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/LoginLog/Output/LoginLogListOutput.cs

@ -0,0 +1,47 @@
using ATS.NonCustodial.Domain.Shared.AggRootEntities;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Logs.LoginLog.Output
{
/// <summary>
/// 登录日志输出Dto
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-14 09:32 PM
public class LoginLogListOutput : EntityFull
{
/// <summary>
/// 昵称
/// </summary>
public string? NickName { 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 string? Msg { get; set; }
}
}

34
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/OprationLog/IOperationLogService.cs

@ -0,0 +1,34 @@
using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.LoginLog.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.OprationLog.Input;
using ATS.NonCustodial.Shared.Common.UnifiedResults;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Logs.OprationLog
{
/// <summary>
/// 操作日志接口
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-14 09:32 PM
public interface IOperationLogService
{
/// <summary>
///
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<IResultOutput> GetPageAsync(LogGetPageDto input);
/// <summary>
///
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<IResultOutput> AddAsync(OprationLogAddInput input);
/// <summary>
/// 业务工作台==>最新5条操作日志
/// </summary>
/// <returns></returns>
Task<IResultOutput> OperationBusinessWorkbench();
}
}

85
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/OprationLog/Input/OprationLogAddInput.cs

@ -0,0 +1,85 @@
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Logs.OprationLog.Input
{
/// <summary>
/// 添加
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-14 09:32 PM
public class OprationLogAddInput
{
/// <summary>
/// 昵称
/// </summary>
public string? NickName { 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? IpAddress { 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; }
/// <summary>
/// 异常信息
/// </summary>
public string? Exception { get; set; }
}
}

77
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Logs/OprationLog/Output/OprationLogListOutput.cs

@ -0,0 +1,77 @@
using ATS.NonCustodial.Domain.Shared.AggRootEntities;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Logs.OprationLog.Output
{
/// <summary>
/// OprationLogListOutput
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-14 09:32 PM
public class OprationLogListOutput : EntityFull
{
/// <summary>
/// 昵称
/// </summary>
public string? NickName { get; set; }
/// <summary>
/// 接口名称
/// </summary>
public string? ApiLabel { get; set; }
/// <summary>
/// 接口地址
/// </summary>
public string? ApiPath { get; set; }
/// <summary>
/// 接口提交方法
/// </summary>
public string? ApiMethod { get; set; }
/// <summary>
/// IpAddress
/// </summary>
public string? IpAddress { 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 string? Msg { get; set; }
/// <summary>
/// 操作参数
/// </summary>
public string? Params { get; set; }
/// <summary>
/// 操作结果
/// </summary>
public string? Result { get; set; }
/// <summary>
/// 异常信息
/// </summary>
public string? Exception { get; set; }
}
}

3939
src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_api.json

File diff suppressed because it is too large Load Diff

7
src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_dictionary.json

@ -17940,12 +17940,5 @@
"value": "50,100", "value": "50,100",
"description": "预警 50 次变黄,预警 100 次变红", "description": "预警 50 次变黄,预警 100 次变红",
"id": 688380702408773 "id": 688380702408773
},
{
"dictionaryTypeId": 299412358086725,
"name": "脱离区域申请",
"code": "LeaveAreaApplication",
"description": "",
"id": 718135330779205
} }
] ]

3548
src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_user.json

File diff suppressed because it is too large Load Diff

3052
src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_user_role.json

File diff suppressed because it is too large Load Diff

2
src/5.shared/ATS.NonCustodial.Admin.Jobs/Jobs/PunchRecordJob.cs

@ -45,7 +45,7 @@ namespace ATS.NonCustodial.Admin.QuartzJobs.Jobs
{ {
ConsoleHelper.WriteWarningLine("job start……"); ConsoleHelper.WriteWarningLine("job start……");
await _appPunchRecordService.CheckPunchRecordForJob(); //await _appPunchRecordService.CheckPunchRecordForJob();
ConsoleHelper.WriteWarningLine("job end……"); ConsoleHelper.WriteWarningLine("job end……");
} }

85
src/5.shared/ATS.NonCustodial.AdminUi/Helpers/Logs/ApiHelper.cs

@ -0,0 +1,85 @@
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Api;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Api.Output;
using ATS.NonCustodial.Shared.Common.Attributes;
using ATS.NonCustodial.Shared.Common.UnifiedResults;
using ATS.NonCustodial.Shared.Extensions;
namespace ATS.NonCustodial.AdminUi.Helpers.Logs
{
/// <summary>
/// Api帮助类
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-18 09:46 AM
[SingleInstance]
public class ApiHelper
{
#region Identity
private List<ApiHelperDto> _apis;
private static readonly object LockObject = new();
private readonly IApiService _apiService;
public ApiHelper(IApiService apiService)
{
_apiService = apiService;
}
#endregion Identity
/// <summary>
/// 主要是在Action 操作的时候添加操作日志时候用
/// </summary>
/// <returns></returns>
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 apis = ((ResultOutput<List<ApiListOutput>>)_apiService.GetListAsync("").Result)
.Data
.Select(a => new
{
a.Id,
a.ParentId,
a.Label,
a.Path
});
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;
}
}
}
/// <summary>
///
/// </summary>
public class ApiHelperDto
{
/// <summary>
/// 接口名称
/// </summary>
public string Label { get; set; }
/// <summary>
/// 接口地址
/// </summary>
public string Path { get; set; }
}
}

20
src/5.shared/ATS.NonCustodial.AdminUi/Helpers/Logs/ILogHandler.cs

@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Mvc.Filters;
namespace ATS.NonCustodial.AdminUi.Helpers.Logs
{
/// <summary>
/// 操作日志处理接口
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-18 09:46 AM
public interface ILogHandler
{
/// <summary>
/// 写操作日志
/// </summary>
/// <param name="context"></param>
/// <param name="next"></param>
/// <returns></returns>
Task LogAsync(ActionExecutingContext context, ActionExecutionDelegate next);
}
}

175
src/5.shared/ATS.NonCustodial.AdminUi/Helpers/Logs/LogHandler.cs

@ -0,0 +1,175 @@
using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.OprationLog;
using ATS.NonCustodial.Application.Contracts.Interfaces.Logs.OprationLog.Input;
using ATS.NonCustodial.AuditLogging.AuditLoggings.Services;
using ATS.NonCustodial.Shared.Common.UnifiedResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Diagnostics;
using System.Reflection;
namespace ATS.NonCustodial.AdminUi.Helpers.Logs
{
/// <summary>
/// 控制器操作日志记录 ==> 操作日志处理
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-18 09:46 AM
public class LogHandler : ILogHandler
{
#region Identity
private readonly ILogger _logger;
private readonly ApiHelper _apiHelper;
private readonly IOperationLogService _operationLogService;
private readonly IAuditEventLogger _auditEventLogger;
public LogHandler(
ILogger<LogHandler> logger,
ApiHelper apiHelper,
IOperationLogService operationLogService,
IAuditEventLogger auditEventLogger
)
{
_logger = logger;
_apiHelper = apiHelper;
_operationLogService = operationLogService;
_auditEventLogger = auditEventLogger;
}
#endregion Identity
/// <summary>
///
/// </summary>
/// <param name="context"></param>
/// <param name="next"></param>
/// <returns></returns>
public async Task LogAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var sw = new Stopwatch();
sw.Start();
//调用接口
var actionExecutedContext = await next();
sw.Stop();
try
{
//接口Type
var controllerType = (context.ActionDescriptor as ControllerActionDescriptor)?.ControllerTypeInfo.AsType().GetSummary();
//方法信息
var controllerAction = (context.ActionDescriptor as ControllerActionDescriptor)?.MethodInfo.GetSummary();
var input = new OprationLogAddInput
{
ApiLabel = $"{controllerType}/{controllerAction}".Trim('/'),
ApiMethod = context.HttpContext.Request.Method.ToLower(),
ApiPath = context.ActionDescriptor.AttributeRouteInfo?.Template?.ToLower(),
ElapsedMilliseconds = sw.ElapsedMilliseconds,
Params = JsonConvert.SerializeObject(context.ActionArguments)
};
if (actionExecutedContext.Result is ObjectResult { Value: IResultOutput res })
{
input.Status = res.Success;
input.Msg = res.Msg;
}
#region 设置参数
//switch (context.HttpContext.Request.Method)
//{
// case "GET":
// case "DELETE":
// input.Params = context.HttpContext.Request.Path;
// break;
// case "PUT":
// case "POST":
// context.HttpContext.Request.EnableBuffering();
// context.HttpContext.Request.Body.Position = 0;
// StreamReader reader = new StreamReader(context.HttpContext.Request.Body, Encoding.UTF8);
// input.Params = reader.ReadToEndAsync().GetAwaiter().GetResult();
// context.HttpContext.Request.Body.Position = 0;
// break;
// default: break;
//}
//if (input.Params is { Length: > 1024 })
//{
// input.Params = input.Params.Substring(0, 1021) + "...";
//}
#endregion 设置参数
#region 设置返回值
try
{
if (actionExecutedContext.Exception != null && !actionExecutedContext.ExceptionHandled)
{
input.Exception = actionExecutedContext.Exception.StackTrace;
}
}
catch (Exception ex)
{
input.Exception = ex.StackTrace;
throw;
}
finally
{
if (input.Exception is { Length: > 2048 })
{
input.Exception = input.Exception.Substring(0, 2045) + "...";
}
if (actionExecutedContext != null)
{
input.Result = actionExecutedContext.Result switch
{
ObjectResult objectResult => JsonConvert.SerializeObject(objectResult.Value),
JsonResult jsonResult => JsonConvert.SerializeObject(jsonResult.Value),
ContentResult contentResult => contentResult.Content,
_ => input.Result
};
if (input.Result is { Length: > 2048 })
{
input.Result = input.Result.Substring(0, 2045) + "...";
}
}
}
#endregion 设置返回值
//接口名称
//input.ApiLabel = _apiHelper.GetApis().FirstOrDefault(a => a.Path == input.ApiPath)?.Label;
//添加操作日志
await _operationLogService.AddAsync(input);
#region 添加审计日志
//var apiAuditLog = new CustomizedLogEvent()
//{
// Category = nameof(CustomizedLogEvent),
// SubjectType = AuditSubjectTypes.machine,
// SubjectName = Environment.MachineName,
// SubjectIdentifier = Environment.MachineName,
// Action = new { Method = input.ApiPath, Class = context.Controller.ToString() }
//};
//await _auditEventLogger.LogEventAsync(apiAuditLog, options =>
//{
// options.UseDefaultSubject = false;
// options.UseDefaultAction = false;
//});
#endregion 添加审计日志
}
catch (Exception ex)
{
_logger.LogError("操作日志插入异常:{@ex}", ex);
}
}
}
}

10
src/5.shared/ATS.NonCustodial.Shared/Common/Auth/ClaimAttributes.cs

@ -1,4 +1,6 @@
namespace ATS.NonCustodial.Shared.Common.Auth using System.ComponentModel.DataAnnotations;
namespace ATS.NonCustodial.Shared.Common.Auth
{ {
/// <summary> /// <summary>
/// Claim属性 /// Claim属性
@ -83,5 +85,11 @@
/// 职位类型转换为枚举 /// 职位类型转换为枚举
/// </summary> /// </summary>
public const string personType = "persontype"; public const string personType = "persontype";
/// <summary>
/// 查询界限
/// </summary>
public const string limits = "limits";
} }
} }

7
src/5.shared/ATS.NonCustodial.Shared/Common/Auth/IUser.cs

@ -1,4 +1,5 @@
using ATS.NonCustodial.Shared.Common.Enums; using ATS.NonCustodial.Shared.Common.Enums;
using System.ComponentModel.DataAnnotations;
using System.Security.Claims; using System.Security.Claims;
namespace ATS.NonCustodial.Shared.Common.Auth namespace ATS.NonCustodial.Shared.Common.Auth
@ -50,6 +51,12 @@ namespace ATS.NonCustodial.Shared.Common.Auth
/// </summary> /// </summary>
string NickName { get; } string NickName { get; }
/// <summary>
/// 查询界限
/// </summary>
string limits { get; }
/// <summary> /// <summary>
/// 租户Id /// 租户Id
/// </summary> /// </summary>

18
src/5.shared/ATS.NonCustodial.Shared/Common/Auth/User.cs

@ -158,6 +158,24 @@ namespace ATS.NonCustodial.Shared.Common.Auth
} }
} }
/// <summary>
/// 昵称
/// </summary>
public string limits
{
get
{
var name = _accessor?.HttpContext?.User?.FindFirst(ClaimAttributes.limits);
if (name != null && name.Value.NotNull())
{
return name.Value;
}
return "";
}
}
/// <summary> /// <summary>
/// 租户Id /// 租户Id
/// </summary> /// </summary>

Loading…
Cancel
Save