diff --git a/IRaCIS.Core.API/appsettings.CenterImageDev.json b/IRaCIS.Core.API/appsettings.CenterImageDev.json index 1262501aa..67e7a16fc 100644 --- a/IRaCIS.Core.API/appsettings.CenterImageDev.json +++ b/IRaCIS.Core.API/appsettings.CenterImageDev.json @@ -17,7 +17,10 @@ "OpenTrialRelationDelete": true, - "OpenLoginLimit": false + "OpenLoginLimit": false, + "LoginMaxFailCount": 5, + + "LoginFailLockMinutes": 30 }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.API/appsettings.Development.json b/IRaCIS.Core.API/appsettings.Development.json index 42058565c..db4a1fba2 100644 --- a/IRaCIS.Core.API/appsettings.Development.json +++ b/IRaCIS.Core.API/appsettings.Development.json @@ -21,7 +21,7 @@ "OpenLoginLimit": false, - "LoginMaxFailCount": 3, + "LoginMaxFailCount": 5, "LoginFailLockMinutes":1 }, diff --git a/IRaCIS.Core.API/appsettings.Production.json b/IRaCIS.Core.API/appsettings.Production.json index f1e4a54f6..91ca65025 100644 --- a/IRaCIS.Core.API/appsettings.Production.json +++ b/IRaCIS.Core.API/appsettings.Production.json @@ -18,9 +18,9 @@ "OpenSignDocumentBeforeWork": true, "OpenLoginLimit": true, - "LoginMaxFailCount": 3, + "LoginMaxFailCount": 5, - "LoginFailLockMinutes": 1 + "LoginFailLockMinutes": 30 }, //"SystemEmailSendConfig": { // "Port": 465, diff --git a/IRaCIS.Core.API/appsettings.Staging.json b/IRaCIS.Core.API/appsettings.Staging.json index db61eee61..c40e2367e 100644 --- a/IRaCIS.Core.API/appsettings.Staging.json +++ b/IRaCIS.Core.API/appsettings.Staging.json @@ -17,9 +17,9 @@ "OpenSignDocumentBeforeWork": true, "OpenLoginLimit": true, - "LoginMaxFailCount": 3, + "LoginMaxFailCount": 5, - "LoginFailLockMinutes": 1 + "LoginFailLockMinutes": 30 }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.API/appsettings.USDemo.json b/IRaCIS.Core.API/appsettings.USDemo.json index e6194ddc6..973c6c597 100644 --- a/IRaCIS.Core.API/appsettings.USDemo.json +++ b/IRaCIS.Core.API/appsettings.USDemo.json @@ -21,9 +21,9 @@ "OpenLoginLimit": false, - "LoginMaxFailCount": 3, + "LoginMaxFailCount": 5, - "LoginFailLockMinutes": 1 + "LoginFailLockMinutes": 30 }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.Application/Service/Management/DTO/UserTypeRoleModel.cs b/IRaCIS.Core.Application/Service/Management/DTO/UserTypeRoleModel.cs index f29a43272..3a059e4bd 100644 --- a/IRaCIS.Core.Application/Service/Management/DTO/UserTypeRoleModel.cs +++ b/IRaCIS.Core.Application/Service/Management/DTO/UserTypeRoleModel.cs @@ -38,6 +38,8 @@ namespace IRaCIS.Core.Application.Contracts public class UserTypeMenuAddOrEdit: UserTypeRoleAddOrEdit { + public UserTypeEnum UserTypeEnum { get; set; } + public List MenuIds { get; set; } = new List(); } @@ -53,6 +55,7 @@ namespace IRaCIS.Core.Application.Contracts public int Order { get; set; } + public List UserTypeGroupIdList { get; set; } = new List(); diff --git a/IRaCIS.Core.Application/Service/Management/UserTypeService.cs b/IRaCIS.Core.Application/Service/Management/UserTypeService.cs index 009323dfc..1e55c1dd3 100644 --- a/IRaCIS.Core.Application/Service/Management/UserTypeService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserTypeService.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infra.EFCore; +using IRaCIS.Application.Contracts; namespace IRaCIS.Core.Application.Contracts { @@ -15,18 +16,18 @@ namespace IRaCIS.Core.Application.Contracts [ApiExplorerSettings(GroupName = "Management")] public class UserTypeRoleService : BaseService, IUserTypeService { - private readonly IRepository userTypeServiceRepository; + private readonly IRepository _userTypeRepository; - public UserTypeRoleService(IRepository userTypeServiceRepository) + public UserTypeRoleService(IRepository userTypeRepository) { - this.userTypeServiceRepository = userTypeServiceRepository; + _userTypeRepository = userTypeRepository; } [HttpPost] public async Task> GetUserTypeRoleList(UserTypeQuery userTypeQuery) { - var userTypeRoleQueryable = userTypeServiceRepository + var userTypeRoleQueryable = _userTypeRepository .WhereIf(!string.IsNullOrWhiteSpace(userTypeQuery.SearchFilter), t => t.Description.Contains(userTypeQuery.SearchFilter!) || t.UserTypeName.Contains(userTypeQuery.SearchFilter!) || t.UserTypeShortName.Contains(userTypeQuery.SearchFilter!)) .WhereIf(userTypeQuery.GroupId!=null,t=>t.UserTypeGroupList.Any(t=>t.DictionaryId== userTypeQuery.GroupId)) @@ -40,16 +41,22 @@ namespace IRaCIS.Core.Application.Contracts public async Task AddOrUpdateUserTypeRole(UserTypeMenuAddOrEdit addOrEditUserTypeRole) { + var verifyExp1 = new EntityVerifyExp() + { + VerifyExp = u => u.UserTypeEnum == addOrEditUserTypeRole.UserTypeEnum , + + VerifyMsg = "已存在该用户类型的角色。" + }; + var entity = new UserType(); if (addOrEditUserTypeRole.Id == null) { entity = _mapper.Map(addOrEditUserTypeRole); - entity.UserTypeEnum = userTypeServiceRepository.Select(t => t.UserTypeEnum).DefaultIfEmpty().Max() + 1; - - await _repository.AddAsync(entity); + //entity.UserTypeEnum = userTypeServiceRepository.Select(t => t.UserTypeEnum).DefaultIfEmpty().Max() + 1; + await _userTypeRepository.InsertFromDTOAsync(addOrEditUserTypeRole,false, verifyExp1); } else @@ -57,14 +64,17 @@ namespace IRaCIS.Core.Application.Contracts if (addOrEditUserTypeRole.MenuIds.Count > 0) { - entity = userTypeServiceRepository.Where(t => t.Id == addOrEditUserTypeRole.Id, true).Include(t => t.UserTypeMenuList).Include(t=>t.UserTypeGroupList).FirstOrDefault().IfNullThrowException(); + entity = _userTypeRepository.Where(t => t.Id == addOrEditUserTypeRole.Id, true).Include(t => t.UserTypeMenuList).Include(t=>t.UserTypeGroupList).FirstOrDefault().IfNullThrowException(); } else { - entity = userTypeServiceRepository.Where(t => t.Id == addOrEditUserTypeRole.Id, true).FirstOrDefault().IfNullThrowException(); + entity = _userTypeRepository.Where(t => t.Id == addOrEditUserTypeRole.Id, true).FirstOrDefault().IfNullThrowException(); } _mapper.Map(addOrEditUserTypeRole, entity); + + + await _userTypeRepository.EntityVerifyAsync(entity.Id, verifyExp1); } var success = await _repository.SaveChangesAsync(); @@ -83,7 +93,7 @@ namespace IRaCIS.Core.Application.Contracts return ResponseOutput.NotOk(_localizer["UserType_InUse"]); } - var success = await userTypeServiceRepository.BatchDeleteNoTrackingAsync(t => t.Id == userTypeId); + var success = await _userTypeRepository.BatchDeleteNoTrackingAsync(t => t.Id == userTypeId); return ResponseOutput.Result(success); } @@ -139,7 +149,7 @@ namespace IRaCIS.Core.Application.Contracts - var query = userTypeServiceRepository.Where(x => x.UserTypeEnum != UserTypeEnum.SuperAdmin) + var query = _userTypeRepository.Where(x => x.UserTypeEnum != UserTypeEnum.SuperAdmin) .WhereIf(userTypeSelectEnum != UserTypeSelectEnum.None, t => userTypeEnums.Contains(t.UserTypeEnum)) .OrderBy(t => t.Order).ProjectTo(_mapper.ConfigurationProvider); @@ -156,7 +166,7 @@ namespace IRaCIS.Core.Application.Contracts /// public async Task> GetTrialUserTypeList() { - var query = userTypeServiceRepository.Where(x => x.UserTypeEnum != UserTypeEnum.SuperAdmin) + var query = _userTypeRepository.Where(x => x.UserTypeEnum != UserTypeEnum.SuperAdmin) .Where(t => !t.UserTypeGroupList.Any(t=> t.Group.Code=="3")) .OrderBy(t => t.Order).ProjectTo(_mapper.ConfigurationProvider); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs index 59bc45268..a5e088ad0 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs @@ -8,6 +8,7 @@ using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure.Extention; using MathNet.Numerics; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore.Metadata.Internal; using System.Linq; using System.Linq.Dynamic.Core; @@ -872,6 +873,9 @@ namespace IRaCIS.Core.Application CriterionName = g.Key.CriterionName, TrialReadingCriterionId = g.Key.TrialReadingCriterionId, + #region 不能对包含聚合或子查询的表达式执行聚合函数 + + #endregion //UrgentCount = g.Where(u => u.VisitTask.IsUrgent //&& u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First().UserTypeEnumInt == (int)UserTypeEnum.MIM).Count(), @@ -913,65 +917,37 @@ namespace IRaCIS.Core.Application #region 废弃不能对包含聚合或子查询的表达式执行聚合函数 - var query = _taskMedicalReviewRepository - .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) - .Where(t => t.IsClosedDialog == false) - .GroupBy(t => new - { - t.TrialId, - t.Trial.ResearchProgramNo, - t.Trial.ExperimentName, - t.Trial.TrialCode, - t.VisitTask.TrialReadingCriterionId, - t.VisitTask.TrialReadingCriterion.CriterionName - }) - .Select(g => new MedicalCommentsToBeDoneDto() - { - TrialId = g.Key.TrialId, - ResearchProgramNo = g.Key.ResearchProgramNo, - ExperimentName = g.Key.ExperimentName, - TrialCode = g.Key.TrialCode, - CriterionName = g.Key.CriterionName, + .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) + .Where(t => t.IsClosedDialog == false) + .GroupBy(t => new + { + t.TrialId, + t.Trial.ResearchProgramNo, + t.Trial.ExperimentName, + t.Trial.TrialCode, + t.VisitTask.TrialReadingCriterionId, + t.VisitTask.TrialReadingCriterion.CriterionName + }) + .Select(g => new MedicalCommentsToBeDoneDto() + { + TrialId = g.Key.TrialId, + ResearchProgramNo = g.Key.ResearchProgramNo, + ExperimentName = g.Key.ExperimentName, + TrialCode = g.Key.TrialCode, + CriterionName = g.Key.CriterionName, - //UrgentCount = g.Where(u => u.VisitTask.IsUrgent).Select(u => u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First()) - //.Count(t => t.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer), + //UrgentCount = g.Where(u => u.VisitTask.IsUrgent).Select(u => u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First()).Count(t => t.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer), - //ToBeReplyedCount = g.Select(t => t.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First()).Count(t => t.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer), + //ToBeReplyedCount = g.Select(t => t.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First()).Count(t => t.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer), - ToBeReviewedCount = g.Where(u => !u.IsInvalid && u.AuditState != MedicalReviewAuditState.HaveSigned).Count() + ToBeReviewedCount = g.Where(u => !u.IsInvalid && u.AuditState != MedicalReviewAuditState.HaveSigned).Count() - }); + }); #endregion - //var query = _trialReadingCriterionRepository - // .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) - // //.Where(t => t.IsClosedDialog == false) - // .GroupBy(t => new - // { - // t.TrialId, - // t.Trial.ResearchProgramNo, - // t.Trial.ExperimentName, - // t.Trial.TrialCode, - // t.VisitTask.TrialReadingCriterionId, - // t.VisitTask.TrialReadingCriterion.CriterionName - // }) - // .Select(g => new MedicalCommentsToBeDoneDto() - // { - // TrialId = g.Key.TrialId, - // ResearchProgramNo = g.Key.ResearchProgramNo, - // ExperimentName = g.Key.ExperimentName, - // TrialCode = g.Key.TrialCode, - // CriterionName = g.Key.CriterionName, - // UrgentCount = g.Where(u => u.VisitTask.IsUrgent).Select(u=>u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First()) - // .Count(t=>t.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer), - // ToBeReplyedCount = g.Select(t=>t.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First()).Count(t=>t.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer), - - // ToBeReviewedCount=g.Where(u => !u.IsInvalid && u.AuditState != MedicalReviewAuditState.HaveSigned).Count() - - // }); var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(MedicalCommentsToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc); @@ -1206,11 +1182,11 @@ namespace IRaCIS.Core.Application .Where(t => t.IsClosedDialog == false) .Where(u => u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First().UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer).Count() : 0, - Medical_MIM_ToBeReviewedCount= + Medical_MIM_ToBeReviewedCount = (t.User.UserTypeEnum == UserTypeEnum.MIM) ? t.Trial.TaskMedicalReviewList .Where(t => t.IsClosedDialog == false) - .Where(u => !u.IsInvalid && u.AuditState != MedicalReviewAuditState.HaveSigned).Count():0 + .Where(u => !u.IsInvalid && u.AuditState != MedicalReviewAuditState.HaveSigned).Count() : 0 }); diff --git a/IRaCIS.Core.Infra.EFCore/Repository/IRaCISContextExtension.cs b/IRaCIS.Core.Infra.EFCore/Repository/IRaCISContextExtension.cs index 80bb27dae..5428578f6 100644 --- a/IRaCIS.Core.Infra.EFCore/Repository/IRaCISContextExtension.cs +++ b/IRaCIS.Core.Infra.EFCore/Repository/IRaCISContextExtension.cs @@ -83,6 +83,43 @@ namespace IRaCIS.Core.Infra.EFCore } } + public static async Task EntityVerifyAsync(this IRepository _entityRepository, Guid? entitydId = null,params EntityVerifyExp[] verify) where T : Entity + { + + if (entitydId==null) + { + foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyUpdate && t.IsVerify)) + { + if (await _entityRepository.AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) + { + throw new BusinessValidationFailedException(verifyItem.VerifyMsg); + } + } + } + else + { + foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyAdd && t.IsVerify)) + { + if (verifyItem.verifyType == VerifyEnum.OnlyUpdate) + { + if (await _entityRepository.AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) + { + throw new BusinessValidationFailedException(verifyItem.VerifyMsg); + } + } + else if (verifyItem.verifyType == VerifyEnum.Both) + { + if (await _entityRepository.AnyAsync(verifyItem.VerifyExp.And(t => t.Id != entitydId)).ConfigureAwait(false)) + { + throw new BusinessValidationFailedException(verifyItem.VerifyMsg); + } + } + } + } + } + + + ///注意 模型标注了 ConcurrencyCheck的属性,这样的实体,不适合用部分字段更新,ef生成的更新sql会自动带上ConcurrencyCheck的属性条件 /// EntityState.Detached的实体 修改 部分字段 public static void EntityModifyPartialFiled(this IRaCISDBContext _dbContext,T waitModifyEntity, Expression> updateFactory) where T : Entity