Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running

This commit is contained in:
he
2026-05-25 16:38:42 +08:00
38 changed files with 67997 additions and 205 deletions
@@ -79,11 +79,12 @@ public class SystemEmailSendConfig
public bool IsEnv_US { get; set; }
public bool IsOpenErrorNoticeEmail { get; set; }
public string EmailRegexStr { get; set; }
public List<string> ErrorNoticeEmailList { get; set; } = new List<string>();
//public bool IsOpenErrorNoticeEmail { get; set; }
//public List<string> ErrorNoticeEmailList { get; set; } = new List<string>();
}
public class SystemEmailSendConfigView
@@ -566,6 +566,27 @@
<param name="options"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.Common.DeployConfigService.UpdateSystemBasicConfig(IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption)">
<summary>
更新系统基础配置
</summary>
<param name="basicSystemConfigOption"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.Common.DeployConfigService.GetEmailConfigInfo(Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig})">
<summary>
获取系统邮件配置信息
</summary>
<param name="options"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.Common.DeployConfigService.UpdateSystemEmailConfig(IRaCIS.Core.Domain.Share.SystemEmailSendConfig)">
<summary>
更新系统邮件配置
</summary>
<param name="emailConfig"></param>
<returns></returns>
</member>
<member name="P:IRaCIS.Core.Application.Service.Common.TU_TR_RSBaseModel.ResearchProgramNo">
<summary>
方案编号 STUDYID
@@ -15963,7 +15984,7 @@
<param name="inQuery"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.PatientService.SubmitVisitStudyBinding(IRaCIS.Application.Contracts.SubmitVisitStudyBindingCommand,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomSeries},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance})">
<member name="M:IRaCIS.Core.Application.Service.PatientService.SubmitVisitStudyBinding(IRaCIS.Application.Contracts.SubmitVisitStudyBindingCommand,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomSeries},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.FileUploadRecord})">
<summary>
提交 患者检查和访视的绑定
</summary>
@@ -16121,6 +16142,13 @@
<param name="outEnrollTime"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.TestService.SiteSuveryEquipment">
<summary>
维护中心调研设备默认配置
</summary>
<param name="modelVerify"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.TestService.MaskImage">
<summary>
遮挡影像
@@ -18905,6 +18933,11 @@
受试者ID
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Contracts.DTO.TrialVisitQADTO.IsSupportQCDownloadImage">
<summary>
QC质控下载
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Contracts.DTO.QAStudyInfoDTO.PatientSex">
<summary>
性别
@@ -19365,6 +19398,16 @@
检查名称列表
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Contracts.BasicTrialConfig.IsSupportQCDownloadImage">
<summary>
QC质控下载
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Contracts.BasicTrialConfig.IsOpenLostVistRead">
<summary>
打开失访可读
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Contracts.TrialProcessConfig.IsImageQualityControl">
<summary>
影像质控风险控制
@@ -54,8 +54,8 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(inQuery.DoctorUserIdeaEnum != null, t => t.DoctorUserIdeaEnum == inQuery.DoctorUserIdeaEnum)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid)
.WhereIf(inQuery.IsHaveQuestion != null, t => t.IsHaveQuestion == inQuery.IsHaveQuestion)
.WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid)
.WhereIf(inQuery.IsHaveQuestion != null, t => t.IsHaveQuestion == inQuery.IsHaveQuestion)
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime >= inQuery.BeginAllocateDate)
.WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime <= inQuery.EndAllocateDate)
@@ -211,23 +211,23 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId)
.WhereIf(inQuery.TrialSiteId != null, t => t.VisitTask.Subject.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.IsUrgent != null, t => t.VisitTask.IsUrgent == inQuery.IsUrgent)
.WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState)
.WhereIf(inQuery.DoctorUserIdeaEnum != null, t => t.DoctorUserIdeaEnum == inQuery.DoctorUserIdeaEnum)
.WhereIf(inQuery.TaskState != null, t => t.VisitTask.TaskState == inQuery.TaskState)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode) || t.VisitTask.Subject.MedicalNo.Contains(inQuery.SubjectCode))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName))
.WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState)
.WhereIf(inQuery.DoctorUserIdeaEnum != null, t => t.DoctorUserIdeaEnum == inQuery.DoctorUserIdeaEnum)
.WhereIf(inQuery.TaskState != null, t => t.VisitTask.TaskState == inQuery.TaskState)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode) || t.VisitTask.Subject.MedicalNo.Contains(inQuery.SubjectCode))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName))
.WhereIf(inQuery.DoctorUserId != null, t => t.VisitTask.DoctorUserId == inQuery.DoctorUserId)
.WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory)
.WhereIf(inQuery.ReadingTaskState != null, t => t.VisitTask.ReadingTaskState == inQuery.ReadingTaskState)
.WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid)
.WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid)
.WhereIf(inQuery.IsGetBeRead, x => !x.IsInvalid && x.AuditState != MedicalReviewAuditState.HaveSigned)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.BeginAuditSignTime != null, t => t.AuditSignTime >= inQuery.BeginAuditSignTime)
.WhereIf(inQuery.EndAuditSignTime != null, t => t.AuditSignTime <= inQuery.EndAuditSignTime)
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime >= inQuery.BeginAllocateDate)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.BeginAuditSignTime != null, t => t.AuditSignTime >= inQuery.BeginAuditSignTime)
.WhereIf(inQuery.EndAuditSignTime != null, t => t.AuditSignTime <= inQuery.EndAuditSignTime)
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime >= inQuery.BeginAllocateDate)
.WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime <= inQuery.EndAllocateDate)
.WhereIf(inQuery.ArmEnum != null, t => t.VisitTask.ArmEnum == inQuery.ArmEnum)
.WhereIf(inQuery.ArmEnum != null, t => t.VisitTask.ArmEnum == inQuery.ArmEnum)
.WhereIf(inQuery.MedicalManagerUserId != null, t => t.MedicalManagerUserId == inQuery.MedicalManagerUserId)
.WhereIf(inQuery.BeginSignTime != null, t => t.VisitTask.SignTime > inQuery.BeginSignTime)
.WhereIf(inQuery.EndSignTime != null, t => t.VisitTask.SignTime < inQuery.EndSignTime)
@@ -1016,9 +1016,9 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
if (critrion.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{
var extralObj = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.TrialExtraConfigJsonStr }).FirstOrDefault();
var extralObj = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.IsOpenLostVistRead }).FirstOrDefault();
var extralConfig = JsonConvert.DeserializeObject<TrialExtraConfig>(extralObj?.TrialExtraConfigJsonStr) ?? new TrialExtraConfig();
//var extralConfig = JsonConvert.DeserializeObject<TrialExtraConfig>(extralObj?.TrialExtraConfigJsonStr) ?? new TrialExtraConfig();
var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.UserRoleId && x.TaskState == TaskState.Effect && x.Subject.IsSubjectQuit == false)
@@ -1027,7 +1027,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
.WhereIf(critrion.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum))
// 前序 不存在 未一致性核查未通过的
.Where(t => !t.Subject.SubjectVisitList.Where(t => extralConfig.IsOpenLostVistRead ? t.IsLostVisit == false : true).Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum >= sv.VisitNum))
.Where(t => !t.Subject.SubjectVisitList.Where(t => extralObj.IsOpenLostVistRead ? t.IsLostVisit == false : true).Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum >= sv.VisitNum))
//.WhereIf(critrion.IsAutoCreate == false, t => t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(t => t.IsGeneratedTask == false) ?
//t.VisitTaskNum <= t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsGeneratedTask == false).Min(t => t.SubjectVisit.VisitNum) : true)
//.Where(t => t.Subject.SubjectVisitList.Any(t => t.CheckState != CheckStateEnum.CVPassed) ? t.VisitTaskNum <= t.Subject.SubjectVisitList.Where(t => t.CheckState != CheckStateEnum.CVPassed).Min(t => t.VisitNum) : true)
@@ -1050,14 +1050,14 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
UnReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(),
//未读 里可读任务量
UnReadCanReadTaskCount = x.Where(t => extralConfig.IsOpenLostVistRead ? true : t.IsFrontTaskNeedSignButNotSign == false).Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)
UnReadCanReadTaskCount = x.Where(t => extralObj.IsOpenLostVistRead ? true : t.IsFrontTaskNeedSignButNotSign == false).Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)
//不能对包含聚合或子查询的表达式执行聚合函数
//&& !x.Any(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.IsNeedClinicalDataSign == true && t.IsClinicalDataSign == false && t.VisitTaskNum<y.VisitTaskNum )
).Count(),
UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned)
.Where(t => extralConfig.IsOpenLostVistRead ? true : t.IsFrontTaskNeedSignButNotSign == false)
.Where(t => extralObj.IsOpenLostVistRead ? true : t.IsFrontTaskNeedSignButNotSign == false)
.Where(y => /*y.IsFrontTaskNeedSignButNotSign == false &&*/ (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
.OrderBy(x => x.VisitTaskNum)
.Select(u => new IRUnreadTaskView()
@@ -13,64 +13,118 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service.Common
namespace IRaCIS.Core.Application.Service.Common;
[ApiExplorerSettings(GroupName = "Common")]
public class DeployConfigService(IMapper _mapper, IUserInfo _userInfo, IWebHostEnvironment _hostEnvironment, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService
{
public class DeployConfigService(IMapper _mapper, IUserInfo _userInfo, IWebHostEnvironment _hostEnvironment, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService
/// <summary>
/// 获取系统基础配置信息
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
public async Task<ServiceVerifyConfigOption> GetSystemBasicConfigInfo([FromServices] IOptionsMonitor<ServiceVerifyConfigOption> options)
{
/// <summary>
/// 获取系统基础配置信息
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
public async Task<ServiceVerifyConfigOption> GetSystemBasicConfigInfo([FromServices] IOptionsMonitor<ServiceVerifyConfigOption> options)
{
return options.CurrentValue;
}
[HttpPost]
public async Task<IResponseOutput> UpdateSystemBasicConfig(ServiceVerifyConfigOption basicSystemConfigOption)
{
var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json";
string text = System.IO.File.ReadAllText(path);
// 修改
JObject obj = JObject.Parse(text);
// QCRiskControl 相关配置
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.QCRiskControl)] = basicSystemConfigOption.QCRiskControl;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenUserComplexPassword)] = basicSystemConfigOption.OpenUserComplexPassword;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenSignDocumentBeforeWork)] = basicSystemConfigOption.OpenSignDocumentBeforeWork;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenTrialRelationDelete)] = basicSystemConfigOption.OpenTrialRelationDelete;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenLoginLimit)] = basicSystemConfigOption.OpenLoginLimit;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.LoginMaxFailCount)] = basicSystemConfigOption.LoginMaxFailCount;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.LoginFailLockMinutes)] = basicSystemConfigOption.LoginFailLockMinutes;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.AutoLoginOutMinutes)] = basicSystemConfigOption.AutoLoginOutMinutes;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenLoginMFA)] = basicSystemConfigOption.OpenLoginMFA;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ContinuousReadingTimeMin)] = basicSystemConfigOption.ContinuousReadingTimeMin;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ReadingRestTimeMin)] = basicSystemConfigOption.ReadingRestTimeMin;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.IsNeedChangePassWord)] = basicSystemConfigOption.IsNeedChangePassWord;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ChangePassWordDays)] = basicSystemConfigOption.ChangePassWordDays;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.TemplateType)] = ((int)basicSystemConfigOption.TemplateType).ToString(); // 枚举需要转换为字符串
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ThirdPdfUrl)] = basicSystemConfigOption.ThirdPdfUrl;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.UserMFAVerifyMinutes)] = basicSystemConfigOption.UserMFAVerifyMinutes;
// 重新写入appsettings.json
string result = obj.ToString();
System.IO.File.WriteAllText(path, result);
return ResponseOutput.Ok();
}
public async Task<SystemEmailSendConfig> GetEmailConfigInfo([FromServices] IOptionsMonitor<SystemEmailSendConfig> options)
{
return options.CurrentValue;
}
return options.CurrentValue;
}
/// <summary>
/// 更新系统基础配置
/// </summary>
/// <param name="basicSystemConfigOption"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> UpdateSystemBasicConfig(ServiceVerifyConfigOption basicSystemConfigOption)
{
var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json";
string text = System.IO.File.ReadAllText(path);
// 修改
JObject obj = JObject.Parse(text);
// QCRiskControl 相关配置
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.QCRiskControl)] = basicSystemConfigOption.QCRiskControl;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenUserComplexPassword)] = basicSystemConfigOption.OpenUserComplexPassword;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenSignDocumentBeforeWork)] = basicSystemConfigOption.OpenSignDocumentBeforeWork;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenTrialRelationDelete)] = basicSystemConfigOption.OpenTrialRelationDelete;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenLoginLimit)] = basicSystemConfigOption.OpenLoginLimit;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.LoginMaxFailCount)] = basicSystemConfigOption.LoginMaxFailCount;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.LoginFailLockMinutes)] = basicSystemConfigOption.LoginFailLockMinutes;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.AutoLoginOutMinutes)] = basicSystemConfigOption.AutoLoginOutMinutes;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenLoginMFA)] = basicSystemConfigOption.OpenLoginMFA;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ContinuousReadingTimeMin)] = basicSystemConfigOption.ContinuousReadingTimeMin;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ReadingRestTimeMin)] = basicSystemConfigOption.ReadingRestTimeMin;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.IsNeedChangePassWord)] = basicSystemConfigOption.IsNeedChangePassWord;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ChangePassWordDays)] = basicSystemConfigOption.ChangePassWordDays;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.TemplateType)] = ((int)basicSystemConfigOption.TemplateType); // 枚举需要转换为字符串
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ThirdPdfUrl)] = basicSystemConfigOption.ThirdPdfUrl;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.UserMFAVerifyMinutes)] = basicSystemConfigOption.UserMFAVerifyMinutes;
// 重新写入appsettings.json
string result = obj.ToString();
System.IO.File.WriteAllText(path, result);
return ResponseOutput.Ok();
}
/// <summary>
/// 获取系统邮件配置信息
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
public async Task<SystemEmailSendConfig> GetEmailConfigInfo([FromServices] IOptionsMonitor<SystemEmailSendConfig> options)
{
return options.CurrentValue;
}
/// <summary>
/// 更新系统邮件配置
/// </summary>
/// <param name="emailConfig"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> UpdateSystemEmailConfig(SystemEmailSendConfig emailConfig)
{
var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json";
string text = System.IO.File.ReadAllText(path);
// 修改
JObject obj = JObject.Parse(text);
// SystemEmailSendConfig 相关配置
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.Port)] = emailConfig.Port;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.Host)] = emailConfig.Host;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.Imap)] = emailConfig.Imap;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.ImapPort)] = emailConfig.ImapPort;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.FromEmail)] = emailConfig.FromEmail;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.FromName)] = emailConfig.FromName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.AuthorizationCode)] = emailConfig.AuthorizationCode;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.SiteUrl)] = emailConfig.SiteUrl;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.PlatformName)] = emailConfig.PlatformName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.PlatformNameCN)] = emailConfig.PlatformNameCN;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.SystemShortName)] = emailConfig.SystemShortName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.OrganizationName)] = emailConfig.OrganizationName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.OrganizationNameCN)] = emailConfig.OrganizationNameCN;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyName)] = emailConfig.CompanyName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyNameCN)] = emailConfig.CompanyNameCN;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyShortName)] = emailConfig.CompanyShortName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyShortNameCN)] = emailConfig.CompanyShortNameCN;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.IsEnv_US)] = emailConfig.IsEnv_US;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.EmailRegexStr)] = emailConfig.EmailRegexStr;
// 重新写入appsettings.json
string result = obj.ToString();
System.IO.File.WriteAllText(path, result);
return ResponseOutput.Ok();
}
}
@@ -138,7 +138,7 @@ namespace IRaCIS.Core.Application.Service
var isNeedSend = true;
//手动发送的时候,也有可能答案是是 此时是 这里不发送,发送已经生成的文件
if (answer == "是" && isHandSend == null)
if ((answer == "是" || answer == "Yes") && isHandSend == null)
{
isNeedSend = true;
@@ -1183,7 +1183,7 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
/// <param name="userWorkLanguage"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
private async Task<string> TranslatePdStateAsync(Guid visitTaskId, ReadingCategory readingCategory, CriterionType criterionType, UserWorkLanguage userWorkLanguage, bool? IsGlobalGenerate = null )
private async Task<string> TranslatePdStateAsync(Guid visitTaskId, ReadingCategory readingCategory, CriterionType criterionType, UserWorkLanguage userWorkLanguage, bool? IsGlobalGenerate = null)
{
var answer = string.Empty;
@@ -263,6 +263,12 @@ namespace IRaCIS.Core.Application.Contracts.DTO
public class TrialVisitQADTO
{
/// <summary>
/// QC质控下载
/// </summary>
public bool IsSupportQCDownloadImage { get; set; } = false;
public bool ExistsManual { get; set; }
public bool IsHaveStudyClinicalData { get; set; }
public bool QCRiskControl { get; set; }
@@ -421,6 +421,7 @@ namespace IRaCIS.Core.Application.Image.QA
List<SecondReviewDto> secondReviewList = new List<SecondReviewDto>();
var isSupportQCImageDownload = _trialRepository.Where(t => t.Id == sv.TrialId).Select(t => t.IsSupportQCDownloadImage).FirstOrDefault();
if (sv.SecondReviewState != SecondReviewState.None)
{
@@ -459,6 +460,7 @@ namespace IRaCIS.Core.Application.Image.QA
return new TrialVisitQADTO
{
IsSupportQCDownloadImage = isSupportQCImageDownload,
QCQuestionAnswerList = qacheckList,
QCRiskControl = _verifyConfig.CurrentValue.QCRiskControl,
SecondReviewList = secondReviewList,
@@ -776,7 +778,7 @@ namespace IRaCIS.Core.Application.Image.QA
var query = _inspectionFileRepository.Where(t => t.TrialId == inQuery.TrialId && (t.CheckState == EDCCheckState.Success || t.CheckState == EDCCheckState.Failed))
.ProjectTo<GetUserUploadFileDto>(_mapper.ConfigurationProvider);
return await query.ToPagedListAsync(inQuery,nameof(GetUserUploadFileDto.CreateTime));
return await query.ToPagedListAsync(inQuery, nameof(GetUserUploadFileDto.CreateTime));
}
@@ -1111,12 +1111,12 @@ namespace IRaCIS.Core.Application.Image.QA
var visit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId);
var isExistStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(t => t.TrialId == visit.TrialId && t.ClinicalDataLevel == ClinicalLevel.Study&&t.IsConfirm&&t.IsApply);
if(isExistStudyClinicalData)
var isExistStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(t => t.TrialId == visit.TrialId && t.ClinicalDataLevel == ClinicalLevel.Study && t.IsConfirm && t.IsApply);
if (isExistStudyClinicalData)
{
List<string> modalitieTypes = new List<string>() { "PT、CT", "CT、PT", "PET-CT" };
var studyList=await _dicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId&& modalitieTypes.Contains(t.Modalities)).ProjectTo<QAStudyInfoDTO>(_mapper.ConfigurationProvider).ToListAsync();
var studyList = await _dicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId && modalitieTypes.Contains(t.Modalities)).ProjectTo<QAStudyInfoDTO>(_mapper.ConfigurationProvider).ToListAsync();
if (studyList.Any(x => x.IsHasEmptyPatientInfo))
{
return ResponseOutput.NotOk(_localizer["QCOperation_IsHasEmptyPatientInfo"]);
@@ -1189,7 +1189,7 @@ namespace IRaCIS.Core.Application.Image.QA
await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == id, u => new SCPStudy() { SubjectVisitId = null });
if (fisrtPath.IsNotNullOrEmpty())
if (fisrtPath.IsNotNullOrEmpty() && study.IsFromPACS == false)
{
var prefix = fisrtPath.Substring(1, fisrtPath.LastIndexOf('/') - 1);
@@ -1230,7 +1230,7 @@ namespace IRaCIS.Core.Application.Image.QA
string cacheKey = CacheKeys.UserQCSkipTask(_userInfo.UserRoleId);
await _fusionCache.SetAsync(cacheKey, new List<Guid>(), TimeSpan.FromMinutes(60));
return ResponseOutput.Ok();
@@ -1393,12 +1393,12 @@ namespace IRaCIS.Core.Application.Image.QA
// 获取当前缓存中的访视Id集合(如果没有则创建空集合)
var skippedVisits = await _fusionCache.GetOrDefaultAsync<List<Guid>>(CacheKeys.UserQCSkipTask(_userInfo.UserRoleId), new List<Guid>() { });
var skippedVisits = await _fusionCache.GetOrDefaultAsync<List<Guid>>(CacheKeys.UserQCSkipTask(_userInfo.UserRoleId), new List<Guid>() { });
//跳过当前访视
if (inDto.IsSkipCurrentVisit)
{
skippedVisits.Add(inDto.SubjectVisitId);
currentActionList = currentActionList.Where(t => !skippedVisits.Contains(t.SubjectVisitId)).ToList();
}
@@ -1449,7 +1449,7 @@ namespace IRaCIS.Core.Application.Image.QA
//跳过当前访视
if (inDto.IsSkipCurrentVisit)
{
{
visitList = visitList.Where(t => !skippedVisits.Contains(t.SubjectVisitId)).ToList();
}
@@ -6,17 +6,9 @@
namespace IRaCIS.Core.Application.Contracts
{
/// <summary> TrialSiteEquipmentSurveyView 列表视图模型 </summary>
public class TrialSiteEquipmentSurveyView
public class TrialSiteEquipmentSurveyView: TrialSiteEquipmentSurveyAddOrEdit
{
public Guid Id { get; set; }
public Guid TrialSiteSurveyId { get; set; }
public string EquipmentType { get; set; } = string.Empty;
public Guid? EquipmentTypeId { get; set; }
public string Parameters { get; set; } = string.Empty;
public string ManufacturerName { get; set; } = string.Empty;
public string ScannerType { get; set; } = string.Empty;
public string Note { get; set; } = string.Empty;
public DateTime CreateTime { get; set; }
public Guid CreateUserId { get; set; }
public DateTime UpdateTime { get; set; }
@@ -56,6 +48,36 @@ namespace IRaCIS.Core.Application.Contracts
public string ManufacturerName { get; set; } = string.Empty;
public string ScannerType { get; set; } = string.Empty;
public string Note { get; set; } = string.Empty;
[Comment("扫描设备-New")]
public int? EquipmentTypeEnum { get; set; }
public string OtherEquipmentType { get; set; }
[Comment("扫描设备厂商")]
public int? ManufacturerType { get; set; }
[Comment("磁场强度 (1.5T / 3.0T)")]
public int? MagneticFieldStrengthType { get; set; }
[Comment("体部线圈通道数 (≥16 或 16)")]
public int? BodyCoilChannelCount { get; set; }
[Comment("是否具备专用的PDFF脂肪定量序列(CSE-MRI序列)")]
public bool? HasDedicatedPdfFatQuantificationSequence { get; set; }
[Comment("专用的PDFF脂肪定量序列类型 (当 HasDedicatedPdfFatQuantificationSequence = true 时有效)")]
public int? PdfFatQuantificationSequenceType { get; set; }
[Comment("其他序列详细说明 (当 PdfFatQuantificationSequenceType = Other 时建议填写)")]
public string OtherSequenceSpecification { get; set; }
[Comment("是否包含 T2/R2 校正(用于铁沉积校正)")]
public bool? HasT2R2Correction { get; set; }
[Comment("是否可完整导出 PDFF 参数图及全部原始 DICOM 数据")]
public bool? CanFullyExportPdfParameterMapsAndRawDicom { get; set; }
}
@@ -678,7 +678,7 @@ namespace IRaCIS.Core.Application.Contracts
if (currentLatest.Email != userInfo.ReplaceUserEmailOrPhone)
{
//---该中心不存在该交接人的中心调研记录表,不允许选择更新。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_NoRecordToUpdate"]);
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_NoRecordToUpdate", currentLatest.Email]);
}
@@ -39,8 +39,7 @@ namespace IRaCIS.Core.Application.AutoMapper
//列表
CreateMap<TrialSiteEquipmentSurvey, TrialSiteEquipmentSurveyView>()
.ForMember(t => t.EquipmentType, u => u.MapFrom(d => isEn_Us ? d.EquipmentType.Value : d.EquipmentType.ValueCN));
CreateMap<TrialSiteEquipmentSurvey, TrialSiteEquipmentSurveyView>();
@@ -87,6 +87,17 @@ namespace IRaCIS.Core.Application.Contracts
public List<TrialObjectNameConfig> TrialObjectNameList { get; set; }
/// <summary>
/// QC质控下载
/// </summary>
public bool IsSupportQCDownloadImage { get; set; } = false;
/// <summary>
/// 打开失访可读
/// </summary>
public bool IsOpenLostVistRead { get; set; } = true;
}
public class ConfigTrialProcessInfoVerificationInDto
@@ -243,11 +243,16 @@ namespace IRaCIS.Application.Contracts
}
public class TrialExtraConfig
{
#region QC
#region QC --
//QC质控
//QC质控下载
public bool IsSupportQCDownloadImage { get; set; } = false;
/// <summary>
/// 打开失访可读
/// </summary>
public bool IsOpenLostVistRead { get; set; } = true;
#endregion
@@ -260,20 +265,19 @@ namespace IRaCIS.Application.Contracts
public List<SiteSurveyModifyFiled> ModifyFiledList { get; set; } = new List<SiteSurveyModifyFiled>();
public List<SiteSurveyEquipmentField> EquipmentControlFieldList { get; set; } = new List<SiteSurveyEquipmentField>();
#endregion
/// <summary>
/// 打开失访可读
/// </summary>
public bool IsOpenLostVistRead { get; set; } = true;
}
public class TrialConfigInfo: TrialExtraConfig
public class TrialConfigInfo : TrialExtraConfig
{
#region
public List<TrialObjectNameConfig> TrialObjectNameList { get; set; }
@@ -311,6 +315,14 @@ namespace IRaCIS.Application.Contracts
}
public class SiteSurveyEquipmentField
{
public string FiledName { get; set; }
public int ShowOrder { get; set; }
public bool IsView { get; set; }
}
}
@@ -255,6 +255,28 @@ namespace IRaCIS.Core.Application.Service
trial.IsConfigureEmail = true;
#endregion
#region
var trialExtalConfig = new TrialExtraConfig()
{
EquipmentControlFieldList = new List<SiteSurveyEquipmentField> {
new SiteSurveyEquipmentField() { FiledName = "EquipmentTypeEnum", ShowOrder = 0, IsView = true },
new SiteSurveyEquipmentField() { FiledName = "OtherEquipmentType", ShowOrder = 1, IsView = true },
new SiteSurveyEquipmentField() { FiledName = "Parameters", ShowOrder = 2, IsView = true },
new SiteSurveyEquipmentField() { FiledName = "ManufacturerType", ShowOrder = 3, IsView = true },
new SiteSurveyEquipmentField() { FiledName = "ManufacturerName", ShowOrder = 4, IsView = true },
new SiteSurveyEquipmentField() { FiledName = "ScannerType", ShowOrder = 5, IsView = true },
new SiteSurveyEquipmentField() { FiledName = "Note", ShowOrder = 6, IsView = true },
}
};
trial.TrialExtraConfigJsonStr = trialExtalConfig.ToJsonStr();
#endregion
//如果是PM, 则需要将该人员添加到 运维人员表
//添加运维人员PM
await _trialIdentityUserRepository.AddAsync(new TrialIdentityUser()
@@ -341,7 +363,7 @@ namespace IRaCIS.Core.Application.Service
trial.EmailFromName = $"{_systemEmailConfig.FromName}-{trial.TrialCode}";
trial.UpdateTime = DateTime.Now;
var success = await _trialRepository.SaveChangesAsync();
@@ -5,6 +5,7 @@ using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using Pipelines.Sockets.Unofficial.Arenas;
using System.Linq.Dynamic.Core;
@@ -42,7 +43,7 @@ namespace IRaCIS.Core.Application.Service
var instanceList = await _instanceRepository.Where(s => s.StudyId == scpStudyId).OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber)
.ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
.Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber,t.FileSize }).ToListAsync();//.GroupBy(u => u.SeriesId);
.Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber, t.FileSize }).ToListAsync();//.GroupBy(u => u.SeriesId);
foreach (var series in seriesList)
{
@@ -55,7 +56,7 @@ namespace IRaCIS.Core.Application.Service
//HtmlPath = string.Empty,
Path = k.Path,
InstanceNumber = k.InstanceNumber,
FileSize=k.FileSize,
FileSize = k.FileSize,
}).ToList();
}
@@ -378,11 +379,12 @@ namespace IRaCIS.Core.Application.Service
/// <returns></returns>
[HttpPost]
[UnitOfWork]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> SubmitVisitStudyBinding(SubmitVisitStudyBindingCommand inCommand,
[FromServices] IRepository<DicomStudy> _dicomstudyRepository,
[FromServices] IRepository<DicomSeries> _dicomSeriesRepository,
[FromServices] IRepository<DicomInstance> _dicomInstanceRepository)
[FromServices] IRepository<DicomInstance> _dicomInstanceRepository,
[FromServices] IRepository<FileUploadRecord> _fileUploadRecordRepository)
{
//这里要做校验 + 同时验证本地系统里面的影像是否存在pacs推过来的
@@ -403,11 +405,14 @@ namespace IRaCIS.Core.Application.Service
var subjectVisitId = inCommand.SubjectVisitId;
var trialId = inCommand.TrialId;
var studyCode = "";
var studyUid = "";
var @lock = _distributedLockProvider.CreateLock($"StudyCode");
using (await @lock.AcquireAsync())
{
var dbStudyCodeIntMax = _dicomStudyRepository.Where(s => s.TrialId == inCommand.TrialId).Select(t => t.Code).DefaultIfEmpty().Max();
var dbStudyCodeIntMax = _trialRepository.Where(s => s.Id == trialId, ignoreQueryFilters: true).Select(t => t.MaxDicomCode).DefaultIfEmpty().Max();
int currentNextCodeInt = dbStudyCodeIntMax + 1;
@@ -430,6 +435,8 @@ namespace IRaCIS.Core.Application.Service
newStuty.SubjectId = subjectId;
newStuty.SubjectVisitId = subjectVisitId;
studyCode = newStuty.StudyCode;
await _dicomStudyRepository.AddAsync(newStuty);
@@ -457,12 +464,22 @@ namespace IRaCIS.Core.Application.Service
}
await _dicomInstanceRepository.AddRangeAsync(newInstanceList);
//回更StudyCode
await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Path.Contains(newStuty.StudyInstanceUid), u => new FileUploadRecord() { StudyCode = studyCode, SubjectId = newStuty.SubjectId, SubjectVisitId = newStuty.SubjectVisitId });
await _trialRepository.BatchUpdateNoTrackingAsync(t => t.Id == trialId, u => new Trial() { MaxDicomCode = currentNextCodeInt });
await _scpPatientRepository.BatchUpdateNoTrackingAsync(t => t.Id == find.SCPStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
}
currentNextCodeInt++;
await _scpPatientRepository.BatchUpdateNoTrackingAsync(t => t.Id == find.SCPStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
}
@@ -549,6 +566,10 @@ namespace IRaCIS.Core.Application.Service
}
}
//回更StudyCode
await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Path.Contains(study.StudyInstanceUid), u => new FileUploadRecord() { StudyCode = studyCode, SubjectId = study.SubjectId, SubjectVisitId = study.SubjectVisitId });
await _scpPatientRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
}
+65
View File
@@ -33,6 +33,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MiniExcelLibs;
using Minio.DataModel;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using NPOI.XWPF.UserModel;
using SharpCompress.Common;
@@ -107,6 +108,70 @@ namespace IRaCIS.Core.Application.Service
public DateTime? DateTimeNUllValue { get; set; }
}
/// <summary>
/// 维护中心调研设备默认配置
/// </summary>
/// <param name="modelVerify"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpPost("{email}")]
public async Task<IResponseOutput> SiteSuveryEquipment()
{
//默认配置
var trialExtalConfig = new TrialExtraConfig()
{
EquipmentControlFieldList = new List<SiteSurveyEquipmentField> {
new SiteSurveyEquipmentField() { FiledName = "EquipmentTypeEnum", ShowOrder = 0, IsView = true },
new SiteSurveyEquipmentField() { FiledName = "OtherEquipmentType", ShowOrder = 1, IsView = true },
new SiteSurveyEquipmentField() { FiledName = "Parameters", ShowOrder = 2, IsView = true },
new SiteSurveyEquipmentField() { FiledName = "ManufacturerType", ShowOrder = 3, IsView = true },
new SiteSurveyEquipmentField() { FiledName = "ManufacturerName", ShowOrder = 4, IsView = true },
new SiteSurveyEquipmentField() { FiledName = "ScannerType", ShowOrder = 5, IsView = true },
new SiteSurveyEquipmentField() { FiledName = "Note", ShowOrder = 6, IsView = true },
}
};
var list = _trialRepository.Where(t => t.TrialExtraConfigJsonStr != "").Select(t => new { t.Id, t.TrialExtraConfigJsonStr }).ToList();
foreach (var item in list)
{
var extralConfig = JsonConvert.DeserializeObject<TrialExtraConfig>(item.TrialExtraConfigJsonStr);
if (extralConfig.ModifyFiledList.Count > 0)
{
extralConfig.EquipmentControlFieldList = trialExtalConfig.EquipmentControlFieldList.Where(t => t.ShowOrder != 2).ToList();
}
else
{
extralConfig.EquipmentControlFieldList = trialExtalConfig.EquipmentControlFieldList;
}
var jsonInfo = extralConfig.ToJsonStr();
await _trialRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new Trial() { TrialExtraConfigJsonStr = jsonInfo });
}
var info = trialExtalConfig.ToJsonStr();
var idQuery = _trialRepository.Where(t => t.TrialExtraConfigJsonStr == "").Select(t => t.Id);
await _trialRepository.BatchUpdateNoTrackingAsync(t => idQuery.Contains(t.Id), u => new Trial() { TrialExtraConfigJsonStr = info });
return ResponseOutput.Ok();
}
//创建一个模型验证的方法
[AllowAnonymous]