From dca0dfb003af4178da8cc0eb8262307434e4e453 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Thu, 16 Jan 2025 11:22:39 +0800
Subject: [PATCH 1/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=A3=81=E5=88=A4?=
=?UTF-8?q?=E9=98=85=E7=89=87=E6=98=8E=E7=BB=86=E8=A1=A8=E8=BF=87=E6=BB=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Service/Common/ExcelExportService.cs | 19 ++++---
.../ReadingImageTaskService.cs | 55 ++++++++++---------
.../Reading/ImageFilterState.cs | 4 +-
3 files changed, 43 insertions(+), 35 deletions(-)
diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs
index de447237f..b03622dab 100644
--- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs
+++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs
@@ -2224,12 +2224,6 @@ namespace IRaCIS.Core.Application.Service.Common
if (inQuery.ReadingExportType == ExportResult.DetailedTableOfAdjudicationResults)
{
- //R1 R2 两个人的访视都阅片完成了才可以,去除只有一个人阅片完成的访视
-
- //找到只有一个人阅片的受试者 和访视
- var exceptVisit = list.GroupBy(t => new { t.SubjectCode, t.TaskName }).Where(g => g.Count() == 1).Select(g => new { g.Key.SubjectCode, g.Key.TaskName }).ToList();
- list = list.Where(t => !exceptVisit.Any(ev => ev.SubjectCode == t.SubjectCode && ev.TaskName == t.TaskName)).ToList();
-
//裁判明表
export_Template = StaticData.Export.CommonJudgeReadingDetail_Export;
}
@@ -2704,12 +2698,23 @@ namespace IRaCIS.Core.Application.Service.Common
#region 最终导出参数处理
+ if (inQuery.ReadingExportType == ExportResult.DetailedTableOfAdjudicationResults)
+ {
+ //R1 R2 两个人的访视都阅片完成了才可以,去除只有一个人阅片完成的访视
+ //找到只有一个人阅片的受试者 和访视
+ var exceptVisit = list.Where(t => t.ReadingCategory == ReadingCategory.Visit)
+ .GroupBy(t => new { t.SubjectCode, t.TaskName}).Where(g => g.Count() == 1).Select(g => new { g.Key.SubjectCode, g.Key.TaskName }).ToList();
+
+ list = list.Where(t => !exceptVisit.Any(ev => ev.SubjectCode == t.SubjectCode && ev.TaskName == t.TaskName)).ToList();
+
+ }
+
list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.ArmEnum).ThenBy(t => t.VisitTaskNum).ToList();
//处理裁判标记
list = DealJudgeMark(criterion.ArbitrationRule, criterion.IsGlobalReading, list);
-
+ //裁判阅片明细表
if (export_Template == StaticData.Export.CommonJudgeReadingDetail_Export)
{
//裁判产生标记为空的数据过滤掉
diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs
index f35a4e975..e3634cc07 100644
--- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs
+++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs
@@ -4,6 +4,7 @@ using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.ImageAndDoc;
+using IRaCIS.Core.Application.Service.OAuth;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.Service.ReadingCalculate.Interface;
using IRaCIS.Core.Application.ViewModel;
@@ -101,7 +102,7 @@ namespace IRaCIS.Core.Application.Service
await _readingTableQuestionAnswerRepository.DeleteFromQueryAsync(x => x.RowId == mark.RowId && x.TableQuestionId == mark.TableQuestionId);
await _readingTaskQuestionMarkRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.Id, x => new ReadingTaskQuestionMark()
{
- InstanceId=null,
+ InstanceId = null,
SeriesId = null,
StudyId = null,
MarkTool = string.Empty,
@@ -117,7 +118,7 @@ namespace IRaCIS.Core.Application.Service
OtherNumberOfFrames = null,
OtherMeasureData = string.Empty,
});
- var result= await _readingTaskQuestionMarkRepository.SaveChangesAsync();
+ var result = await _readingTaskQuestionMarkRepository.SaveChangesAsync();
await _readingCalculateService.CalculateTask(new CalculateTaskInDto()
{
@@ -145,7 +146,7 @@ namespace IRaCIS.Core.Application.Service
SeriesId = null,
StudyId = null,
MarkTool = string.Empty,
- // PicturePath = string.Empty, 稽查需要显示截图
+ // PicturePath = string.Empty, 稽查需要显示截图
NumberOfFrames = null,
MeasureData = string.Empty,
OrderMarkName = string.Empty,
@@ -451,7 +452,7 @@ namespace IRaCIS.Core.Application.Service
///
///
[HttpPost]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task ChangeCalculationAnswer(ChangeCalculationAnswerInDto inDto)
{
var visitTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
@@ -527,7 +528,7 @@ namespace IRaCIS.Core.Application.Service
///
///
[HttpPost]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task ReadClinicalData(ReadClinicalDataInDto inDto)
{
await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask
@@ -904,7 +905,7 @@ namespace IRaCIS.Core.Application.Service
var criterionIdInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == trialReadingCriterionId).FirstNotNullAsync();
- var groupIds = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialReadingCriterionId &&( x.Type == ReadingQestionType.Table || x.Type == ReadingQestionType.BasicTable)).Select(x => x.GroupId).Distinct().ToListAsync();
+ var groupIds = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialReadingCriterionId && (x.Type == ReadingQestionType.Table || x.Type == ReadingQestionType.BasicTable)).Select(x => x.GroupId).Distinct().ToListAsync();
var questionIds = await _readingQuestionTrialRepository
.Where(x => x.IsShowInDicom)
@@ -1088,7 +1089,7 @@ namespace IRaCIS.Core.Application.Service
x.IsFirstChangeTask = x.VisitTaskId == inDto.VisitTaskId;
});
result.AddRange(questionMark);
- result= result.OrderBy(x=>x.ShowOrder).ThenBy(x=>x.RowIndex).ThenBy(x => x.OrderMarkName).ToList();
+ result = result.OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex).ThenBy(x => x.OrderMarkName).ToList();
return result;
}
@@ -1439,7 +1440,7 @@ namespace IRaCIS.Core.Application.Service
item.TableQuestions.Questions = tableQuestionLists.Where(x => x.ReadingQuestionId == item.Id).OrderBy(x => x.ShowOrder).ToList();
item.TableQuestions.Questions.ForEach(x =>
{
- x.RelationQuestions= _mapper.Map>(tableQuestionLists.Where(z => (z.DependParentId ?? default(Guid)) == x.Id));
+ x.RelationQuestions = _mapper.Map>(tableQuestionLists.Where(z => (z.DependParentId ?? default(Guid)) == x.Id));
x.RelationQuestions.ForEach(y =>
{
y.Childrens = new List();
@@ -1449,7 +1450,7 @@ namespace IRaCIS.Core.Application.Service
y.LesionType = item.LesionType;
y.RelationQuestions = new List();
});
-
+
});
var thisAnswer = tableAnswers.Where(x => x.QuestionId == item.Id).ToList();
@@ -1560,7 +1561,7 @@ namespace IRaCIS.Core.Application.Service
{
FloatParseHandling = FloatParseHandling.Double,
};
- answers.Add("TableQuestionMarkList", rowInfo == null ? "[]" : JsonConvert.SerializeObject(TableQuestionMarkList.Where(x=>x.RowId== rowInfo.Id).ToList(), settings));
+ answers.Add("TableQuestionMarkList", rowInfo == null ? "[]" : JsonConvert.SerializeObject(TableQuestionMarkList.Where(x => x.RowId == rowInfo.Id).ToList(), settings));
answers.Add("RowId", rowInfo == null ? string.Empty : rowInfo.Id.ToString());
answers.Add("MarkTool", rowInfo.MarkTool);
answers.Add("StudyId", rowInfo.StudyId.ToString());
@@ -1609,7 +1610,7 @@ namespace IRaCIS.Core.Application.Service
///
///
[HttpPost]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task SplitLesion(SplitLesionInDto inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
@@ -1847,7 +1848,7 @@ namespace IRaCIS.Core.Application.Service
///
[HttpPost]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task SaveImageQuality(ChangeDicomReadingQuestionAnswerInDto inDto)
{
inDto.UpdateMark = true;
@@ -1906,7 +1907,7 @@ namespace IRaCIS.Core.Application.Service
///
///
[HttpPost]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task ChangeDicomReadingQuestionAnswer(ChangeDicomReadingQuestionAnswerInDto inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
@@ -2023,7 +2024,7 @@ namespace IRaCIS.Core.Application.Service
///
///
[HttpPost]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task DeleteReadingRowAnswer(DeleteReadingRowAnswerInDto inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
@@ -2212,7 +2213,7 @@ namespace IRaCIS.Core.Application.Service
///
[HttpPost]
[Route("/SubmitTaskRowInfo/{param}")]
- public async Task SubmitTaskRowInfo(SubmitTableQuestionInDto inDto,string param)
+ public async Task SubmitTaskRowInfo(SubmitTableQuestionInDto inDto, string param)
{
inDto.ComputationTrigger = (ComputationTrigger)int.Parse(param);
@@ -2226,7 +2227,7 @@ namespace IRaCIS.Core.Application.Service
///
///
[HttpPost]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task SubmitTableQuestion(SubmitTableQuestionInDto inDto)
{
SubmitTableQuestionOutDto result = new SubmitTableQuestionOutDto();
@@ -2413,7 +2414,7 @@ namespace IRaCIS.Core.Application.Service
&& x.QuestionId == inDto.QuestionId
).CountAsync()) + 1))
{
- throw new BusinessValidationFailedException(_localizer["ReadingImage_MaxQuestion", _userInfo.IsEn_Us? questionInfo.QuestionEnName:questionInfo.QuestionName, questionInfo.MaxQuestionCount]);
+ throw new BusinessValidationFailedException(_localizer["ReadingImage_MaxQuestion", _userInfo.IsEn_Us ? questionInfo.QuestionEnName : questionInfo.QuestionName, questionInfo.MaxQuestionCount]);
}
}
@@ -2625,7 +2626,7 @@ namespace IRaCIS.Core.Application.Service
///
///
///
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task SubmitDicomVisitTask(SubmitDicomVisitTaskInDto inDto)
{
@@ -2710,7 +2711,7 @@ namespace IRaCIS.Core.Application.Service
var criterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskInfo.TrialReadingCriterionId).FirstNotNullAsync();
- var readingQuestionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId&&x.Type != "group")
+ var readingQuestionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId && x.Type != "group")
.WhereIf(taskInfo.SourceSubjectVisit.IsBaseLine, x => ((x.IsRequired == IsRequired.Required && x.ShowQuestion == ShowQuestion.Show) && (x.LimitEdit == LimitEdit.None || x.LimitEdit == LimitEdit.OnlyBaseLine)))
.WhereIf(!taskInfo.SourceSubjectVisit.IsBaseLine, x => ((x.IsRequired == IsRequired.Required && x.ShowQuestion == ShowQuestion.Show) && (x.LimitEdit == LimitEdit.None || x.LimitEdit == LimitEdit.OnlyVisit)))
.WhereIf(taskInfo.TrialReadingCriterion.CriterionType == CriterionType.PCWG3, x => x.QuestionType != QuestionType.SiteVisitForTumorEvaluation)
@@ -2988,7 +2989,7 @@ namespace IRaCIS.Core.Application.Service
List remainingItems = taskList.Select(x => x.Id).Except(cacheSkipIds).ToList();
//受试者随机固定排序
- taskList = taskList.Where(x => remainingItems.Contains(x.Id)).OrderBy(t=>t.TaskBlindName).ToList();
+ taskList = taskList.Where(x => remainingItems.Contains(x.Id)).OrderBy(t => t.TaskBlindName).ToList();
// 当前受试者没有就找其他受试者
if (taskList.Count() == 0)
@@ -3048,7 +3049,7 @@ namespace IRaCIS.Core.Application.Service
var query = _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterionId == trialReadingCriterionId && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.DoctorUserId == _userInfo.UserRoleId
&& x.TrialReadingCriterionId == trialReadingCriterionId
&& x.TaskState == TaskState.Effect)
- .Where(x=> !cacheSkipIds.Contains(x.Id));
+ .Where(x => !cacheSkipIds.Contains(x.Id));
var count = await query.CountAsync();
if (count == 0)
{
@@ -3273,12 +3274,9 @@ namespace IRaCIS.Core.Application.Service
///
///
[HttpPost]
- public async Task ResetReadingRestTime(Guid? userID)
+ public async Task ResetReadingRestTime([FromServices] IRepository _userLogRepository)
{
- if (userID == null)
- {
- userID = _userInfo.UserRoleId;
- }
+
//int readingMinute = 120; // 为60整数
int restMinute = 10; //
@@ -3298,6 +3296,9 @@ namespace IRaCIS.Core.Application.Service
{
await _fusionCache.SetAsync(CacheKeys.StartReadingTimeKey(_userInfo.UserRoleId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48));
}
+
+ await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = _userInfo.IdentityUserId, OptType = UserOptType.WebUnlock }, true);
+
return true;
}
@@ -3525,7 +3526,7 @@ namespace IRaCIS.Core.Application.Service
///
///
[HttpPost]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task AddReadingTask(Guid visitTaskId, Guid? trialId = null)
{
// ****** 先生成阅片期 阅片期任务阅片完成之后生成肿瘤学的 如果没有阅片期 直接生成肿瘤学 *********////
diff --git a/IRaCIS.Core.Domain.Share/Reading/ImageFilterState.cs b/IRaCIS.Core.Domain.Share/Reading/ImageFilterState.cs
index 8fdd57ae8..c905d7587 100644
--- a/IRaCIS.Core.Domain.Share/Reading/ImageFilterState.cs
+++ b/IRaCIS.Core.Domain.Share/Reading/ImageFilterState.cs
@@ -50,7 +50,9 @@ public enum UserOptType
TempLockLogin = 13,
- AddUser = 14
+ AddUser = 14,
+
+ WebUnlock=17
}
[Description("影像下载打包状态")]
From 5222cdb8f1faf14145196b9147c1a8ae23e279f7 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Thu, 16 Jan 2025 11:47:24 +0800
Subject: [PATCH 2/5] =?UTF-8?q?=E5=B1=8F=E5=B9=95=E8=A7=A3=E9=94=81+=20?=
=?UTF-8?q?=E5=AF=86=E7=A0=81=E9=94=99=E8=AF=AF=20=E4=B9=9F=E5=BC=82?=
=?UTF-8?q?=E5=9C=B0=E7=99=BB=E5=BD=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Service/Management/UserService.cs | 90 ++++++++++++-------
1 file changed, 58 insertions(+), 32 deletions(-)
diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs
index dba110cb8..da75b1e42 100644
--- a/IRaCIS.Core.Application/Service/Management/UserService.cs
+++ b/IRaCIS.Core.Application/Service/Management/UserService.cs
@@ -888,7 +888,7 @@ namespace IRaCIS.Core.Application.Service
if (_verifyConfig.CurrentValue.IsNeedChangePassWord && loginUser.LastChangePassWordTime != null && DateTime.Now.AddDays(-_verifyConfig.CurrentValue.ChangePassWordDays) > loginUser.LastChangePassWordTime.Value)
{
loginUser.NeedChangePassWord = true;
-
+
}
//await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = loginUser.IdentityUserId, OptUserId = loginUser.IdentityUserId, OptType = UserOptType.Login }, true);
@@ -1012,6 +1012,59 @@ namespace IRaCIS.Core.Application.Service
var loginUser = await _identityUserRepository.Where(u => u.UserName.Equals(userName) && u.Password == password).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
+ var existUserLoginInfo = await _identityUserRepository.Where(u => u.UserName == userName).Select(t => new { t.LastLoginIP, t.LastChangePassWordTime, t.Id }).FirstOrDefaultAsync();
+
+ var isExistAccount = existUserLoginInfo != null;
+
+ var isLoginUncommonly = false;
+
+ //登录用户是系统用户的时候,就要要记录异地登录
+
+ //账号在系统存在
+ if (isExistAccount || loginUser != null)
+ {
+ var ipinfo = _searcher.Search(_userInfo.IP);
+
+ var iPRegion = string.Join('|', ipinfo.Split('|').TakeLast(3));
+
+ string SplitAndConcatenate(string input)
+ {
+ string[] parts = input.Split('|');
+ return parts.Length >= 3 ? parts[0] + parts[1] : string.Join("", parts);
+ }
+
+ if (existUserLoginInfo.LastLoginIP != string.Empty)
+ {
+ // 与上一次区域不一致
+ if (SplitAndConcatenate(existUserLoginInfo.LastLoginIP) != SplitAndConcatenate(iPRegion))
+ {
+
+ isLoginUncommonly = true;
+
+ //设置上次登录的IP
+ await _identityUserRepository.BatchUpdateNoTrackingAsync(x => x.Id == existUserLoginInfo.Id, x => new IdentityUser()
+ {
+ LastLoginIP = iPRegion,
+ LastLoginTime = DateTime.Now
+
+ });
+
+ if (loginUser != null)
+ {
+ //异地登录
+ loginUser.LoginState = 2;
+
+ //超过90天没修改密码
+ if (_verifyConfig.CurrentValue.IsNeedChangePassWord && loginUser.LastChangePassWordTime != null && DateTime.Now.AddDays(-_verifyConfig.CurrentValue.ChangePassWordDays) > loginUser.LastChangePassWordTime.Value)
+ {
+ loginUser.NeedChangePassWord = true;
+ }
+ }
+ }
+ }
+
+ }
+
if (loginUser == null)
{
@@ -1019,48 +1072,26 @@ namespace IRaCIS.Core.Application.Service
failCount++;
await _fusionCache.SetAsync(cacheKey, failCount, TimeSpan.FromMinutes(lockoutMinutes));
- var errorPwdUserId = await _identityUserRepository.Where(u => u.UserName == userName).Select(t => t.Id).FirstOrDefaultAsync();
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionUserName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError }, true);
+
return ResponseOutput.NotOk(_localizer["User_CheckNameOrPw"], new IRCLoginReturnDTO());
}
- //登录用户是系统用户的时候,就要要记录异地登录
-
#region 处理用户状态
- var ipinfo = _searcher.Search(_userInfo.IP);
- var iPRegion = string.Join('|', ipinfo.Split('|').TakeLast(3));
- string SplitAndConcatenate(string input)
- {
- string[] parts = input.Split('|');
- return parts.Length >= 3 ? parts[0] + parts[1] : string.Join("", parts);
- }
- if (loginUser.LastLoginIP != string.Empty)
- {
- // 与上一次区域不一致
- if (SplitAndConcatenate(loginUser.LastLoginIP) != SplitAndConcatenate(iPRegion))
- {
- loginUser.LoginState = 2;
- }
- }
- //超过90天没修改密码
- if (_verifyConfig.CurrentValue.IsNeedChangePassWord && loginUser.LastChangePassWordTime != null && DateTime.Now.AddDays(-_verifyConfig.CurrentValue.ChangePassWordDays) > loginUser.LastChangePassWordTime.Value)
- {
- loginUser.NeedChangePassWord = true;
- }
#endregion
if (loginUser.Status == 0)
{
- await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = loginUser.IdentityUserId, ActionUserName = userName, OptType = UserOptType.LoginLockedAccount, IsLoginUncommonly = (loginUser.LoginState == 2) }, true);
+ await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = loginUser.IdentityUserId, ActionUserName = userName, OptType = UserOptType.LoginLockedAccount, IsLoginUncommonly = isLoginUncommonly }, true);
//---该用户已经被禁用。
return ResponseOutput.NotOk(_localizer["User_Disabled"], new IRCLoginReturnDTO());
@@ -1070,7 +1101,7 @@ namespace IRaCIS.Core.Application.Service
await _fusionCache.SetAsync(cacheKey, 0, TimeSpan.FromMinutes(lockoutMinutes));
- await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = loginUser.IdentityUserId, OptType = UserOptType.Login, IsLoginUncommonly = (loginUser.LoginState == 2) }, true);
+ await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = loginUser.IdentityUserId, OptType = UserOptType.Login, IsLoginUncommonly = isLoginUncommonly }, true);
userLoginReturnModel.BasicInfo = loginUser;
@@ -1084,12 +1115,7 @@ namespace IRaCIS.Core.Application.Service
}
- await _identityUserRepository.BatchUpdateNoTrackingAsync(x => x.Id == loginUser.IdentityUserId, x => new IdentityUser()
- {
- LastLoginIP = iPRegion,
- LastLoginTime = DateTime.Now
- });
//返回临时token
userLoginReturnModel.JWTStr = _tokenService.GetToken(new UserTokenInfo() { IdentityUserId = loginUser.IdentityUserId, UserName = userName });
@@ -1112,7 +1138,7 @@ namespace IRaCIS.Core.Application.Service
userLoginReturnModel.BasicInfo.EMail = hiddenEmail;
//修改密码 || 90天修改密码再mfa 之前
- if (userLoginReturnModel.BasicInfo.IsFirstAdd || userLoginReturnModel.BasicInfo.LoginState == 1)
+ if (userLoginReturnModel.BasicInfo.IsFirstAdd || userLoginReturnModel.BasicInfo.NeedChangePassWord)
{
//userLoginReturnModel.JWTStr = _tokenService.GetToken(userLoginReturnModel.BasicInfo);
}
From 2d792b4557ffbec53217e041ed11c8a80393c956 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Thu, 16 Jan 2025 12:26:26 +0800
Subject: [PATCH 3/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=94=A8=E6=88=B7?=
=?UTF-8?q?=E7=99=BB=E5=BD=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Controllers/ExtraController.cs | 189 ------------------
IRaCIS.Core.API/IRaCIS.Core.API.xml | 3 -
.../IRaCIS.Core.Application.xml | 2 +-
.../Service/Management/UserService.cs | 23 +--
.../ReadingImageTaskService.cs | 20 +-
5 files changed, 24 insertions(+), 213 deletions(-)
diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs
index 0aaba76b6..68d71badf 100644
--- a/IRaCIS.Core.API/Controllers/ExtraController.cs
+++ b/IRaCIS.Core.API/Controllers/ExtraController.cs
@@ -106,195 +106,6 @@ namespace IRaCIS.Api.Controllers
- /// 系统用户登录接口[New]
- [HttpPost, Route("user/login")]
- [AllowAnonymous]
- public async Task Login(UserLoginDTO loginUser,
- [FromServices] IFusionCache _fusionCache,
- [FromServices] IUserService _userService,
- [FromServices] ITokenService _tokenService,
- [FromServices] IReadingImageTaskService readingImageTaskService,
- [FromServices] IOptionsMonitor _verifyConfig,
- [FromServices] IOptionsMonitor _emailConfig,
- [FromServices] IMapper _mapper,
- [FromServices] IMailVerificationService _mailVerificationService)
- {
- var emailConfig = _emailConfig.CurrentValue;
- var companyInfo = new SystemEmailSendConfigView() { CompanyName = emailConfig.CompanyName, CompanyNameCN = emailConfig.CompanyNameCN, CompanyShortName = emailConfig.CompanyShortName, CompanyShortNameCN = emailConfig.CompanyShortNameCN };
-
- //MFA 邮箱验证 前端传递用户Id 和MFACode
- if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA)
- {
- Guid userId = (Guid)loginUser.UserId;
-
- //验证MFA 编码是否有问题 ,前端要拆开,自己调用验证的逻辑
- //await _userService.VerifyMFACodeAsync(userId, loginUser.MFACode);
-
- //var loginUser = await _userRoleRepository.Where(u => u.UserName.Equals(userName) && u.Password == password).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
-
- var basicInfo = await _userService.GetUserBasicInfo(userId, loginUser.Password);
-
- var loginReturn = new LoginReturnDTO() { BasicInfo = basicInfo };
-
- loginReturn.JWTStr = _tokenService.GetToken(new UserTokenInfo() { IdentityUserId = basicInfo.IdentityUserId });
-
-
- // 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
- var option = new CookieOptions
- {
- Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
- HttpOnly = false, // 确保 cookie 只能通过 HTTP 访问
- SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None, // 设置 SameSite 属性
- Secure = false // 确保 cookie 只能通过 HTTPS 访问
- };
-
- HttpContext.Response.Cookies.Append("access_token", loginReturn.JWTStr, option);
-
- // 验证阅片休息时间
- await readingImageTaskService.ResetReadingRestTime(userId);
-
-
- await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(userId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
-
- loginReturn.CompanyInfo = companyInfo;
- return ResponseOutput.Ok(loginReturn);
-
- }
- else
- {
- var returnModel = await _userService.Login(loginUser.UserName, loginUser.Password);
-
- if (returnModel.IsSuccess)
- {
- #region GRPC 调用鉴权中心,因为服务器IIS问题 http/2 故而没法使用
-
- ////重试策略
- //var defaultMethodConfig = new MethodConfig
- //{
- // Names = { MethodName.Default },
- // RetryPolicy = new RetryPolicy
- // {
- // MaxAttempts = 3,
- // InitialBackoff = TimeSpan.FromSeconds(1),
- // MaxBackoff = TimeSpan.FromSeconds(5),
- // BackoffMultiplier = 1.5,
- // RetryableStatusCodes = { Grpc.Core.StatusCode.Unavailable }
- // }
- //};
-
- //#region unable to trust the certificate then the gRPC client can be configured to ignore the invalid certificate
-
- //var httpHandler = new HttpClientHandler();
- //// Return `true` to allow certificates that are untrusted/invalid
- //httpHandler.ServerCertificateCustomValidationCallback =
- // HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
-
-
- //////这一句是让grpc支持本地 http 如果本地访问部署在服务器上,那么是访问不成功的
- //AppContext.SetSwitch(
- // "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
-
- //#endregion
-
-
-
- //var grpcAdress = configuration.GetValue("GrpcAddress");
- ////var grpcAdress = "http://localhost:7200";
-
- //var channel = GrpcChannel.ForAddress(grpcAdress, new GrpcChannelOptions
- //{
- // HttpHandler = httpHandler,
- // ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }
-
- //});
- ////var channel = GrpcChannel.ForAddress(grpcAdress);
- //var grpcClient = new TokenGrpcService.TokenGrpcServiceClient(channel);
-
- //var userInfo = returnModel.Data.BasicInfo;
-
- //var tokenResponse = grpcClient.GetUserToken(new GetTokenReuqest()
- //{
- // Id = userInfo.Id.ToString(),
- // ReviewerCode = userInfo.ReviewerCode,
- // IsAdmin = userInfo.IsAdmin,
- // RealName = userInfo.RealName,
- // UserTypeEnumInt = (int)userInfo.UserTypeEnum,
- // UserTypeShortName = userInfo.UserTypeShortName,
- // UserName = userInfo.UserName
- //});
-
- //returnModel.Data.JWTStr = tokenResponse.Token;
-
- #endregion
-
- var userId = returnModel.Data.BasicInfo.IdentityUserId;
-
- if (_verifyConfig.CurrentValue.OpenLoginMFA)
- {
-
-
-
-
- //MFA 发送邮件
-
- returnModel.Data.IsMFA = true;
-
- var email = returnModel.Data.BasicInfo.EMail;
-
- var hiddenEmail = IRCEmailPasswordHelper.MaskEmail(email);
-
- returnModel.Data.BasicInfo.EMail = hiddenEmail;
-
- //修改密码
- if (returnModel.Data.BasicInfo.IsFirstAdd || returnModel.Data.BasicInfo.LoginState == 1)
- {
- returnModel.Data.JWTStr = _tokenService.GetToken(_mapper.Map(returnModel.Data.BasicInfo));
- }
- else
- {
- //正常登录才发送邮件
- await _userService.SendMFAEmail(new Core.Application.ViewModel.SendMfaCommand() { IdentityUserId= userId });
-
- }
-
- }
- else
- {
- returnModel.Data.JWTStr = _tokenService.GetToken(_mapper.Map(returnModel.Data.BasicInfo));
-
- // 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
- var option = new CookieOptions
- {
- Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
- HttpOnly = false, // 确保 cookie 只能通过 HTTP 访问
- SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None, // 设置 SameSite 属性
- Secure = false // 确保 cookie 只能通过 HTTPS 访问
- };
-
- HttpContext.Response.Cookies.Append("access_token", returnModel.Data.JWTStr, option);
-
-
-
- // 验证阅片休息时间
- await readingImageTaskService.ResetReadingRestTime(returnModel.Data.BasicInfo.IdentityUserId);
-
-
-
- await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(userId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
- }
-
- }
-
- returnModel.Data.CompanyInfo = companyInfo;
- return returnModel;
-
- }
-
-
-
-
- }
-
[AllowAnonymous]
[HttpGet, Route("user/getPublicKey")]
public IResponseOutput GetPublicKey([FromServices] IOptionsMonitor _IRCEncreptOption)
diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.xml b/IRaCIS.Core.API/IRaCIS.Core.API.xml
index 556371672..df2392c13 100644
--- a/IRaCIS.Core.API/IRaCIS.Core.API.xml
+++ b/IRaCIS.Core.API/IRaCIS.Core.API.xml
@@ -34,9 +34,6 @@
-
- 系统用户登录接口[New]
-
回调到前端,前端调用后端的接口
diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
index d412a314d..81568c41e 100644
--- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
+++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
@@ -12047,7 +12047,7 @@
-
+
IR影像阅片
diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs
index da75b1e42..6758e4559 100644
--- a/IRaCIS.Core.Application/Service/Management/UserService.cs
+++ b/IRaCIS.Core.Application/Service/Management/UserService.cs
@@ -968,8 +968,8 @@ namespace IRaCIS.Core.Application.Service
[HttpPost]
public async Task> GetUserLoginRoleList(IRCLoginDto loginDto,
[FromServices] ITokenService _tokenService,
- [FromServices] IOptionsMonitor _emailConfig,
- [FromServices] IReadingImageTaskService readingImageTaskService)
+ [FromServices] IOptionsMonitor _emailConfig
+ )
{
var userName = loginDto.UserName;
@@ -1018,7 +1018,7 @@ namespace IRaCIS.Core.Application.Service
var isLoginUncommonly = false;
- //登录用户是系统用户的时候,就要要记录异地登录
+ #region //登录用户是系统用户的时候,就要要记录异地登录
//账号在系统存在
if (isExistAccount || loginUser != null)
@@ -1065,30 +1065,27 @@ namespace IRaCIS.Core.Application.Service
}
+ #endregion
+
+
if (loginUser == null)
{
//错误次数累加
failCount++;
+
await _fusionCache.SetAsync(cacheKey, failCount, TimeSpan.FromMinutes(lockoutMinutes));
-
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionUserName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError }, true);
-
return ResponseOutput.NotOk(_localizer["User_CheckNameOrPw"], new IRCLoginReturnDTO());
}
- #region 处理用户状态
-
-
- #endregion
-
if (loginUser.Status == 0)
{
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = loginUser.IdentityUserId, ActionUserName = userName, OptType = UserOptType.LoginLockedAccount, IsLoginUncommonly = isLoginUncommonly }, true);
@@ -1152,8 +1149,6 @@ namespace IRaCIS.Core.Application.Service
}
else
{
- // 验证阅片休息时间
- await readingImageTaskService.ResetReadingRestTime(userLoginReturnModel.BasicInfo.IdentityUserId);
await _fusionCache.SetAsync(CacheKeys.UserToken(identityUserId), userLoginReturnModel.JWTStr, TimeSpan.FromDays(7));
@@ -1175,7 +1170,7 @@ namespace IRaCIS.Core.Application.Service
///
///
[HttpGet]
- public async Task LoginSelectUserRole(Guid userRoleId, [FromServices] ITokenService _tokenService)
+ public async Task LoginSelectUserRole(Guid userRoleId, [FromServices] ITokenService _tokenService, [FromServices] IReadingImageTaskService readingImageTaskService)
{
var identityUserId = _userInfo.IdentityUserId;
@@ -1199,6 +1194,8 @@ namespace IRaCIS.Core.Application.Service
{
var jwt = _tokenService.GetToken(userTokenInfo);
+ // 验证阅片休息时间
+ await readingImageTaskService.ResetReadingRestTime(userTokenInfo.UserRoleId);
await _fusionCache.SetAsync(CacheKeys.UserToken(userTokenInfo.IdentityUserId), jwt, TimeSpan.FromDays(7));
diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs
index e3634cc07..e83bcef85 100644
--- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs
+++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs
@@ -32,6 +32,7 @@ namespace IRaCIS.Core.Application.Service
IRepository _noneDicomStudyRepository,
IRepository _visitTaskRepository,
IRepository _trialRepository,
+ IRepository _userLogRepository,
IRepository _readingTableQuestionAnswerRepository,
IRepository _readingOncologyTaskInfoRepository,
IVisitTaskHelpeService _visitTaskHelpeService,
@@ -3274,30 +3275,35 @@ namespace IRaCIS.Core.Application.Service
///
///
[HttpPost]
- public async Task ResetReadingRestTime([FromServices] IRepository _userLogRepository)
+ public async Task ResetReadingRestTime(Guid? userRoleId)
{
-
+ var roleId = (userRoleId != null && userRoleId != Guid.Empty) ? (Guid) userRoleId : _userInfo.UserRoleId;
//int readingMinute = 120; // 为60整数
int restMinute = 10; //
- var startReadingTime = await _fusionCache.GetOrDefaultAsync(CacheKeys.StartReadingTimeKey(_userInfo.UserRoleId));
- var startRestTime = await _fusionCache.GetOrDefaultAsync(CacheKeys.StartRestTime(_userInfo.UserRoleId));
+ var startReadingTime = await _fusionCache.GetOrDefaultAsync(CacheKeys.StartReadingTimeKey(roleId));
+ var startRestTime = await _fusionCache.GetOrDefaultAsync(CacheKeys.StartRestTime(roleId));
if (startRestTime != null)
{
var cacheStartRestTime = DateTime.Parse(startRestTime!.ToString());
int timespanMin = (DateTime.Now - cacheStartRestTime).Minutes;
if (timespanMin > restMinute)
{
- await _fusionCache.RemoveAsync(CacheKeys.StartRestTime(_userInfo.UserRoleId));
+ await _fusionCache.RemoveAsync(CacheKeys.StartRestTime(roleId));
}
}
else if (startReadingTime != null)
{
- await _fusionCache.SetAsync(CacheKeys.StartReadingTimeKey(_userInfo.UserRoleId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48));
+ await _fusionCache.SetAsync(CacheKeys.StartReadingTimeKey(roleId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48));
}
- await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = _userInfo.IdentityUserId, OptType = UserOptType.WebUnlock }, true);
+ //前端屏幕解锁才调用
+ if (userRoleId == null)
+ {
+ await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = _userInfo.IdentityUserId, OptType = UserOptType.WebUnlock }, true);
+
+ }
return true;
}
From 38fe5aea255704f938b58ae503e817b8c8f08148 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Thu, 16 Jan 2025 13:19:36 +0800
Subject: [PATCH 4/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9E=9A=E4=B8=BE?=
=?UTF-8?q?=E5=80=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
IRaCIS.Core.Application/IRaCIS.Core.Application.xml | 4 ++--
IRaCIS.Core.Domain.Share/Reading/ImageFilterState.cs | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
index 81568c41e..d72802c4c 100644
--- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
+++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
@@ -2288,14 +2288,14 @@
-
+
账号验证,获取账号角色信息 获取临时token
-
+
验证密码成功后,选定角色,然后获取当前角色的Token
diff --git a/IRaCIS.Core.Domain.Share/Reading/ImageFilterState.cs b/IRaCIS.Core.Domain.Share/Reading/ImageFilterState.cs
index c905d7587..60bef07e3 100644
--- a/IRaCIS.Core.Domain.Share/Reading/ImageFilterState.cs
+++ b/IRaCIS.Core.Domain.Share/Reading/ImageFilterState.cs
@@ -52,7 +52,7 @@ public enum UserOptType
AddUser = 14,
- WebUnlock=17
+ WebUnlock=16
}
[Description("影像下载打包状态")]
From e66df9bbc9fee4eca848bced42b74ac0295baa1e Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Thu, 16 Jan 2025 13:31:14 +0800
Subject: [PATCH 5/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=99=BB=E5=BD=95?=
=?UTF-8?q?=E8=AE=B0=E5=BD=95=E5=BC=82=E5=9C=B0=E7=99=BB=E5=BD=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
IRaCIS.Core.Application/Service/Management/UserService.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs
index 6758e4559..5e76c3dcb 100644
--- a/IRaCIS.Core.Application/Service/Management/UserService.cs
+++ b/IRaCIS.Core.Application/Service/Management/UserService.cs
@@ -1076,7 +1076,7 @@ namespace IRaCIS.Core.Application.Service
await _fusionCache.SetAsync(cacheKey, failCount, TimeSpan.FromMinutes(lockoutMinutes));
- await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionUserName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError }, true);
+ await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionUserName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError, IsLoginUncommonly = isLoginUncommonly }, true);
return ResponseOutput.NotOk(_localizer["User_CheckNameOrPw"], new IRCLoginReturnDTO());