hang - 用户登录日志修改-01

IRC_NewDev
hang 2023-07-13 10:49:09 +08:00
parent a52aac876a
commit 242bae10d1
6 changed files with 89 additions and 147 deletions

View File

@ -1148,11 +1148,6 @@
<member name="M:IRaCIS.Core.Application.Service.SystemNoticeService.GetUserSystemNoticeList(IRaCIS.Core.Application.ViewModel.SystemNoticeQuery)">
<summary>获取登陆用户的系统通知列表 只是过滤了用户类型 和已经发布的</summary>
</member>
<member name="T:IRaCIS.Core.Application.Service.UserLogService">
<summary>
UserLogService
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Service.QCCommon.VerifyIsCRCSubmmitAsync(IRaCIS.Core.Infra.EFCore.IRepository,IRaCIS.Core.Domain.Share.IUserInfo,System.Nullable{System.Guid})">
<summary>
验证CRC 是否已提交 已提交 就不允许进行任何操作如果是IQC 那么还验证是否是当前任务领取人

View File

@ -11,15 +11,22 @@ namespace IRaCIS.Core.Application.ViewModel
/// <summary> UserLogView 列表视图模型 </summary>
public class UserLogView: UserLogAddOrEdit
{
public Guid? Id { get; set; }
public string IP { get; set; }
public string LoginFaildName { get; set; }
public int OptType { get; set; }
public string UserRealName { get; set; }
public string UserName { get; set; }
public string LoginUserName { get; set; }
public UserType UserTypeEnum { get; set; }
public UserType LoginUserTypeEnum { get; set; }
public bool IsSuccess { get; set; }
public string OptUserName { get; set; }
public UserType OptUserTypeEnum { get; set; }
}
///<summary>UserLogQuery 列表查询参数模型</summary>
@ -31,7 +38,7 @@ namespace IRaCIS.Core.Application.ViewModel
public string? IP { get; set; }
public string? LoginName { get; set; }
public string? LoginFaildName { get; set; }
public DateTime? BeginDate { get; set; }
@ -43,12 +50,7 @@ namespace IRaCIS.Core.Application.ViewModel
///<summary> UserLogAddOrEdit 列表查询参数模型</summary>
public class UserLogAddOrEdit
{
public Guid? Id { get; set; }
public string IP { get; set; }
public string LoginName { get; set; }
public int OptType { get; set; }
public string LoginPassword { get; set; }
}

View File

@ -1,70 +0,0 @@
//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2023-07-04 16:10:37
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
namespace IRaCIS.Core.Application.Service
{
/// <summary>
/// UserLogService
/// </summary>
[ApiExplorerSettings(GroupName = "Test")]
public class UserLogService : BaseService, IUserLogService
{
private readonly IRepository<UserLog> _userLogRepository;
private readonly IRepository<TrialUser> _trialUserRepository;
public UserLogService(IRepository<UserLog> userLogRepository, IRepository<TrialUser> trialUserRepository)
{
_userLogRepository = userLogRepository;
_trialUserRepository = trialUserRepository;
}
public async Task<PageOutput<UserLogView>> GetUserLogList(UserLogQuery inQuery)
{
var userLogQueryable =
_userLogRepository
.WhereIf(inQuery.TrialId != null, t => t.LoginUser.UserTrials.Any(c => c.TrialId == inQuery.TrialId && c.UserId == t.CreateUserId))
.WhereIf(inQuery.OptType!=null ,t=>t.OptType==inQuery.OptType)
.WhereIf(inQuery.BeginDate != null, t => t.CreateTime >= inQuery.BeginDate)
.WhereIf(inQuery.EndDate != null, t => t.CreateTime <= inQuery.EndDate)
.WhereIf(!string.IsNullOrEmpty(inQuery.LoginName) , t => t.LoginName.Contains(inQuery.LoginName) )
.WhereIf(!string.IsNullOrEmpty(inQuery.IP), t => t.IP.Contains(inQuery.IP))
.ProjectTo<UserLogView>(_mapper.ConfigurationProvider);
var pageList = await userLogQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? "Id" : inQuery.SortField,inQuery.Asc);
return pageList;
}
//public async Task<IResponseOutput> AddOrUpdateUserLog(UserLogAddOrEdit addOrEditUserLog)
//{
// // 在此处拷贝automapper 映射
// var entity = await _userLogRepository.InsertOrUpdateAsync(addOrEditUserLog, true);
// return ResponseOutput.Ok(entity.Id.ToString());
//}
//[HttpDelete("{userLogId:guid}")]
//public async Task<IResponseOutput> DeleteUserLog(Guid userLogId)
//{
// var success = await _userLogRepository.DeleteFromQueryAsync(t => t.Id == userLogId, true);
// return ResponseOutput.Ok();
//}
}
}

View File

@ -11,6 +11,7 @@ using Microsoft.Extensions.Caching.Memory;
using IRaCIS.Core.Infra.Common.Cache;
using Microsoft.Identity.Client;
using static IRaCIS.Core.Domain.Share.StaticData;
using IRaCIS.Core.Application.ViewModel;
namespace IRaCIS.Application.Services
{
@ -22,12 +23,13 @@ namespace IRaCIS.Application.Services
private readonly IRepository<VerificationCode> _verificationCodeRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<TrialUser> _userTrialRepository;
private readonly IRepository<UserLog> _userLogRepository;
private readonly IMemoryCache _cache;
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
private readonly IRepository<UserLog> _userLogRepository;
public UserService(IRepository<User> userRepository,
@ -36,11 +38,12 @@ namespace IRaCIS.Application.Services
IRepository<Doctor> doctorRepository,
IMemoryCache cache,
IRepository<TrialUser> userTrialRepository,
IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig
,
IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig,
IRepository<UserLog> userLogRepository
)
{
_userLogRepository = userLogRepository;
_verifyConfig = verifyConfig;
_cache = cache;
_userRepository = userRepository;
@ -170,9 +173,7 @@ namespace IRaCIS.Application.Services
}
else //验证码正确 并且 没有超时
{
//更新密码
//var pwd = MD5Helper.Md5(newPwd);
//var count = _doctorRepository.Update<Doctor>().Where(t => t.Id == doctor.Id).Set(d => d.Password == pwd).ExecuteAffrows();
await VerifyUserEmailAsync(_userInfo.Id, _userInfo.UserTypeId, newEmail);
@ -185,6 +186,8 @@ namespace IRaCIS.Application.Services
//删除验证码历史记录
await _verificationCodeRepository.BatchDeleteNoTrackingAsync(t => t.UserId == _userInfo.Id && t.CodeType == 0);
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = _userInfo.Id, OptType = UserOptType.UpdateUser }, true);
return ResponseOutput.Ok();
}
@ -203,6 +206,8 @@ namespace IRaCIS.Application.Services
Phone = newPhone
});
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = _userInfo.Id, OptType = UserOptType.UpdateUser }, true);
return ResponseOutput.Ok();
}
@ -218,19 +223,11 @@ namespace IRaCIS.Application.Services
UserName = newUserName
});
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = _userInfo.Id, OptType = UserOptType.UpdateUser }, true);
return ResponseOutput.Ok();
}
///// <summary>
///// Result 为true 的时候 认为链接没有失效
///// </summary>
///// <param name="userId"></param>
///// <returns></returns>
//[HttpGet]
//public async Task<IResponseOutput> VerifyCanInitSetUserNameAndPwd(Guid userId)
//{
// return ResponseOutput.Ok(await _userRepository.AnyAsync(t => t.Id == userId && t.EmailToken == _userInfo.UserToken && t.IsFirstAdd));
//}
[HttpGet]
@ -238,8 +235,6 @@ namespace IRaCIS.Application.Services
{
await VerifyUserPwdAsync(userId, newPWd);
await VerifyUserNameAsync(userId, newUserName);
@ -256,6 +251,8 @@ namespace IRaCIS.Application.Services
}, true);
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = _userInfo.Id, OptType = UserOptType.UpdateUser }, true);
return ResponseOutput.Ok();
}
@ -295,7 +292,7 @@ namespace IRaCIS.Application.Services
IsFirstAdd = true
});
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, LoginName = _userInfo.UserName, IsSuccess = true, OptType = UserOptType.AdminResetPassword }, true);
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId=userId, OptType = UserOptType.ResetPassword }, true);
return ResponseOutput.Ok();
}
@ -407,7 +404,7 @@ namespace IRaCIS.Application.Services
IsFirstAdd = false
});
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, LoginName =string.Empty,LoginPassword=newPwd, IsSuccess = true, OptType = UserOptType.ModifyPassword }, true);
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId = userId,LoginPassword=newPwd, OptType = UserOptType.UnloginModifyPasswoed }, true);
return ResponseOutput.Result(success);
@ -443,24 +440,11 @@ namespace IRaCIS.Application.Services
IsFirstAdd = false
});
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, LoginName = _userInfo.UserName, IsSuccess = true, OptType = UserOptType.ModifyPassword }, true);
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId= _userInfo.Id, OptType = UserOptType.LoginModifyPassword }, true);
return ResponseOutput.Result(success);
////医生密码
//if (await _doctorRepository.AnyAsync(t => t.Id == _userInfo.Id && t.Password == editPwModel.OldPassWord))
//{
// var success = await _doctorRepository.BatchUpdateNoTrackingAsync(t => t.Id == _userInfo.Id, u => new Doctor()
// {
// Password = editPwModel.NewPassWord
// });
// return ResponseOutput.Result(success);
//}
//return ResponseOutput.NotOk("Old password is wrong.");
}
@ -571,6 +555,9 @@ namespace IRaCIS.Application.Services
{
user.OrganizationName = AppSettings.DefaultInternalOrganizationName;
}
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId= model.Id , OptType = UserOptType.UpdateUser }, true);
var success = await _userRepository.SaveChangesAsync();
return ResponseOutput.Ok(success);
@ -591,6 +578,8 @@ namespace IRaCIS.Application.Services
return ResponseOutput.NotOk(_localizer["User_InProject"]);
}
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId= userId, OptType = UserOptType.DeleteUser }, true);
var success = await _userRepository.BatchDeleteNoTrackingAsync(t => t.Id == userId);
return ResponseOutput.Result(success);
@ -606,6 +595,9 @@ namespace IRaCIS.Application.Services
[HttpPost("{userId:guid}/{state:int}")]
public async Task<IResponseOutput> UpdateUserState(Guid userId, UserStateEnum state)
{
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = userId, OptType = state==UserStateEnum.Enable? UserOptType.AccountEnable: UserOptType.AccountLocked }, true);
var success = await _userRepository.BatchUpdateNoTrackingAsync(u => u.Id == userId, t => new User
{
Status = state
@ -647,7 +639,7 @@ namespace IRaCIS.Application.Services
if (failCount >= maxFailures)
{
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, LoginName = userName,LoginPassword=password, IsSuccess = false, OptType = UserOptType.AccountLocked }, true);
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId = Guid.Empty, LoginFaildName = userName,LoginPassword=password, OptType = UserOptType.AccountLocked }, true);
throw new BusinessValidationFailedException($"密码连续错误{maxFailures}次,当前账号已被限制登录,请等待 {lockoutMinutes} 分钟后再试。");
}
@ -660,29 +652,11 @@ namespace IRaCIS.Application.Services
if (loginUser == null)
{
#region 屏蔽代码,现在没用到
////此处下面 代码 为了支持医生也能登录 而且前端不加选择到底是管理用户 还是医生用户 奇怪的需求 无法理解
//var loginDoctor = await _doctorRepository.Where(u => u.Phone == userName && u.Password == password).ProjectTo<UserBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
//if (loginDoctor == null)
//{
// return ResponseOutput.NotOk(_localizer["User_CheckNameOrPw"], new LoginReturnDTO());
//}
//userLoginReturnModel.BasicInfo = loginDoctor;
//登录 清除缓存
//_cache.Remove(userLoginReturnModel.BasicInfo.Id.ToString());
//return ResponseOutput.Ok(userLoginReturnModel);
#endregion
//错误次数累加
failCount++;
_cache.Set(cacheKey, failCount, TimeSpan.FromMinutes(lockoutMinutes));
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, LoginName = userName, LoginPassword = password, IsSuccess = false, OptType = UserOptType.AccountOrPasswordError }, true);
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId=Guid.Empty, LoginFaildName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError }, true);
return ResponseOutput.NotOk(_localizer["User_CheckNameOrPw"], new LoginReturnDTO());
@ -692,6 +666,8 @@ namespace IRaCIS.Application.Services
if (loginUser.Status == 0)
{
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = loginUser.Id, OptUserId = loginUser.Id, LoginFaildName = userName, OptType = UserOptType.LoginLockedAccount }, true);
//---该用户已经被禁用。
return ResponseOutput.NotOk(_localizer["User_Disabled"], new LoginReturnDTO());
}
@ -700,7 +676,7 @@ namespace IRaCIS.Application.Services
//登录成功 清除缓存
_cache.Set(cacheKey, 0, TimeSpan.FromMinutes(lockoutMinutes));
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = loginUser.Id, LoginName = userName, IsSuccess = true, OptType = UserOptType.Login }, true);
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = loginUser.Id, OptUserId = loginUser.Id, OptType = UserOptType.Login }, true);
userLoginReturnModel.BasicInfo = loginUser;
@ -711,11 +687,27 @@ namespace IRaCIS.Application.Services
}
public async Task<PageOutput<UserLogView>> GetUserLogList(UserLogQuery inQuery)
{
var userLogQueryable =
_userLogRepository
.WhereIf(inQuery.TrialId != null, t => t.LoginUser.UserTrials.Any(c => c.TrialId == inQuery.TrialId && c.UserId == t.CreateUserId))
.WhereIf(inQuery.OptType != null, t => t.OptType == inQuery.OptType)
.WhereIf(inQuery.BeginDate != null, t => t.CreateTime >= inQuery.BeginDate)
.WhereIf(inQuery.EndDate != null, t => t.CreateTime <= inQuery.EndDate)
.WhereIf(!string.IsNullOrEmpty(inQuery.LoginFaildName), t => t.LoginFaildName.Contains(inQuery.LoginFaildName))
.WhereIf(!string.IsNullOrEmpty(inQuery.IP), t => t.IP.Contains(inQuery.IP))
.ProjectTo<UserLogView>(_mapper.ConfigurationProvider);
var pageList = await userLogQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? "Id" : inQuery.SortField, inQuery.Asc);
return pageList;
}
public async Task<IResponseOutput> LoginOut(Guid userId,string loginName)
{
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = userId, LoginName = loginName, IsSuccess = true, OptType = UserOptType.LoginOut },true);
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = userId, OptUserId=userId, OptType = UserOptType.LoginOut },true);
return ResponseOutput.Ok();
}

View File

@ -119,7 +119,12 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.UserTypeId, c => c.MapFrom(t => t));
CreateMap<UserLog, UserLogView>();
CreateMap<UserLog, UserLogView>()
.ForMember(d => d.LoginUserName, c => c.MapFrom(t => t.LoginUser.UserName))
.ForMember(d => d.LoginUserTypeEnum, c => c.MapFrom(t => t.LoginUser.UserTypeEnum))
.ForMember(d => d.OptUserName, c => c.MapFrom(t => t.OptUser.UserName))
.ForMember(d => d.OptUserTypeEnum, c => c.MapFrom(t => t.OptUser.UserTypeEnum))
;
CreateMap<UserLog, UserLogAddOrEdit>().ReverseMap();
}
}

View File

@ -28,7 +28,7 @@ namespace IRaCIS.Core.Domain.Models
public Guid CreateUserId { get; set; }
public string LoginName { get; set; }
public string LoginFaildName { get; set; }=string.Empty;
public UserOptType OptType { get; set; }
@ -36,13 +36,17 @@ namespace IRaCIS.Core.Domain.Models
public string LoginPassword { get; set; } = string.Empty;
public bool IsSuccess { get; set; }
public Guid? LoginUserId { get;set; }
public Guid? OptUserId { get;set; }
[JsonIgnore]
public User LoginUser { get; set; }
[JsonIgnore]
public User OptUser { get; set; }
}
/// <summary>
@ -71,9 +75,23 @@ namespace IRaCIS.Core.Domain.Models
/// </summary>
AccountLocked = 4,
ModifyPassword=5,
//账号启用
AccountEnable = 5,
AdminResetPassword=6
//登录锁定账户
LoginLockedAccount=6,
//修改密码
LoginModifyPassword =7,
UnloginModifyPasswoed=8,
//admin 重置密码
ResetPassword=9,
DeleteUser=10,
UpdateUser=11
}
}