Compare commits
107 Commits
Test_IRC_N
...
EICS-V1.6.
| Author | SHA1 | Date |
|---|---|---|
|
|
6f43535cf7 | |
|
|
0697003b78 | |
|
|
e4b9a570d5 | |
|
|
9f775df00c | |
|
|
62757d7506 | |
|
|
1822e201b7 | |
|
|
b25c72c153 | |
|
|
c64b826266 | |
|
|
fb2d2f7b2f | |
|
|
92fe7bbaa9 | |
|
|
75f4d5696a | |
|
|
509f5ff2fc | |
|
|
4f6a42aff5 | |
|
|
be42f52867 | |
|
|
2519ad0f7a | |
|
|
ad4dcd294c | |
|
|
c251486267 | |
|
|
ee4fede7af | |
|
|
92430c93b3 | |
|
|
d093c172a4 | |
|
|
2740ed109a | |
|
|
92facb02e8 | |
|
|
718234f631 | |
|
|
7be63f08b5 | |
|
|
127e124993 | |
|
|
fbd9280b22 | |
|
|
b8481207fc | |
|
|
b1b82a016e | |
|
|
768345616a | |
|
|
1feb985eb7 | |
|
|
496f47a4e8 | |
|
|
bd3d6ffe12 | |
|
|
08daea6a92 | |
|
|
e9d720e1a5 | |
|
|
5cd1454949 | |
|
|
d9a85b6825 | |
|
|
424026866f | |
|
|
e5081ff568 | |
|
|
3ca7d6f21b | |
|
|
4faa15a219 | |
|
|
d61f4e89a3 | |
|
|
712a1312f4 | |
|
|
e38739381e | |
|
|
ae05b73ffd | |
|
|
87c9f423c9 | |
|
|
2d44da15f1 | |
|
|
d7d7a0af55 | |
|
|
b3e187b53c | |
|
|
b0ef2dc8ab | |
|
|
ccf4bbdff9 | |
|
|
c3e36991b8 | |
|
|
81f6c10f23 | |
|
|
719ca071e1 | |
|
|
dad420a7e8 | |
|
|
d84aedf135 | |
|
|
34f3b1607e | |
|
|
7fa73e0054 | |
|
|
c146c2bfd2 | |
|
|
2a1220899e | |
|
|
874d36de28 | |
|
|
0283052555 | |
|
|
effef5ad65 | |
|
|
43d260e036 | |
|
|
19708240b2 | |
|
|
0999bae749 | |
|
|
e6bd35ae04 | |
|
|
102e193ae8 | |
|
|
20d557e795 | |
|
|
593ab42882 | |
|
|
b56d256e10 | |
|
|
614a3bd70e | |
|
|
2eb3b04365 | |
|
|
1fa3a5a181 | |
|
|
cd2007c4fd | |
|
|
67e710eac0 | |
|
|
ef451d82ec | |
|
|
899ebf2a30 | |
|
|
f233d27f96 | |
|
|
9e8ab8acca | |
|
|
2265387f47 | |
|
|
baf8f39bc6 | |
|
|
3fa14d92ae | |
|
|
e6c577e68b | |
|
|
bb111dbbeb | |
|
|
0df0b10a72 | |
|
|
0a7ba9f0f5 | |
|
|
cd88990c32 | |
|
|
d53a1300fc | |
|
|
07332ff3e1 | |
|
|
8195a1cf3e | |
|
|
f5e5a47624 | |
|
|
28608f3ecb | |
|
|
bb2da7ca81 | |
|
|
713518a68c | |
|
|
bc448da297 | |
|
|
8447878cb2 | |
|
|
1b5a9673f6 | |
|
|
27711f4184 | |
|
|
bb9bac1edf | |
|
|
41ae2febc7 | |
|
|
c072c526e2 | |
|
|
d6bb98b84f | |
|
|
42587ee59f | |
|
|
62a964a3ea | |
|
|
72447eb82f | |
|
|
2f83c27fde | |
|
|
b219593f61 |
|
|
@ -31,10 +31,8 @@
|
|||
},
|
||||
|
||||
"ConnectionStrings": {
|
||||
//"RemoteNew": "Server=47.117.165.18,1434;Database=Prod_Study;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
//"Hangfire": "Server=47.117.165.18,1434;Database=Prod_Study_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_Study;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_Study_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||
"RemoteNew": "Server=us-prod-mssql-service,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=us-prod-mssql-service,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
},
|
||||
|
||||
"BasicSystemConfig": {
|
||||
|
|
|
|||
|
|
@ -6,8 +6,19 @@
|
|||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
<<<<<<<< HEAD:IRaCIS.Core.API/appsettings.US_Test_IRC.json
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
},
|
||||
|
||||
"ObjectStoreService": {
|
||||
|
||||
"ObjectStoreUse": "MinIO",
|
||||
========
|
||||
"ObjectStoreService": {
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
>>>>>>>> Test_IRC_Net8:IRC.Core.SCP/appsettings.Test_IRC_SCP.json
|
||||
"AliyunOSS": {
|
||||
"regionId": "cn-shanghai",
|
||||
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
|
|
@ -21,6 +32,22 @@
|
|||
},
|
||||
|
||||
"MinIO": {
|
||||
<<<<<<<< HEAD:IRaCIS.Core.API/appsettings.US_Test_IRC.json
|
||||
//"endPoint": "hir-oss.uat.extimaging.com",
|
||||
//"port": "443",
|
||||
//"useSSL": true,
|
||||
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/hir-uat",
|
||||
|
||||
"endPoint": "47.117.164.182",
|
||||
"port": "9001",
|
||||
"useSSL": false,
|
||||
"viewEndpoint": "http://47.117.164.182:9001/test-irc-us",
|
||||
|
||||
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
|
||||
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
|
||||
"bucketName": "test-irc-us"
|
||||
|
||||
========
|
||||
"endPoint": "106.14.89.110",
|
||||
"port": "9001",
|
||||
"useSSL": false,
|
||||
|
|
@ -28,6 +55,7 @@
|
|||
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
|
||||
"bucketName": "hir-test",
|
||||
"viewEndpoint": "http://106.14.89.110:9001/hir-test/"
|
||||
>>>>>>>> Test_IRC_Net8:IRC.Core.SCP/appsettings.Test_IRC_SCP.json
|
||||
},
|
||||
|
||||
"AWS": {
|
||||
|
|
@ -55,6 +83,31 @@
|
|||
"OpenLoginLimit": false,
|
||||
"LoginMaxFailCount": 5,
|
||||
|
||||
<<<<<<<< HEAD:IRaCIS.Core.API/appsettings.US_Test_IRC.json
|
||||
"LoginFailLockMinutes": 30,
|
||||
"AutoLoginOutMinutes": 60,
|
||||
|
||||
"ContinuousReadingTimeMin": 120,
|
||||
|
||||
"ReadingRestTimeMin": 10
|
||||
},
|
||||
|
||||
"SystemEmailSendConfig": {
|
||||
"Port": 587,
|
||||
"Host": "smtp-mail.outlook.com",
|
||||
"FromEmail": "donotreply@elevateimaging.ai",
|
||||
"FromName": "LiLi",
|
||||
"AuthorizationCode": "Q#669869497420ul",
|
||||
|
||||
"OrganizationName": "Elevate Imaging",
|
||||
"OrganizationNameCN": "Elevate Imaging",
|
||||
"CompanyName": "Elevate Imaging Inc.",
|
||||
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||
"CompanyShortName": "Elevate Imaging",
|
||||
"CompanyShortNameCN": "展影医疗",
|
||||
"SiteUrl": "https://lili.test.elevateimaging.ai/login"
|
||||
}
|
||||
========
|
||||
"LoginFailLockMinutes": 30
|
||||
|
||||
},
|
||||
|
|
@ -65,6 +118,7 @@
|
|||
"FromEmail": "test-study@extimaging.com",
|
||||
"FromName": "Test_Study",
|
||||
"AuthorizationCode": "zhanying123",
|
||||
>>>>>>>> Test_IRC_Net8:IRC.Core.SCP/appsettings.Test_IRC_SCP.json
|
||||
|
||||
"SiteUrl": "http://study.test.extimaging.com/login"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -20,16 +20,6 @@
|
|||
"region": "oss-cn-shanghai"
|
||||
},
|
||||
|
||||
"MinIO": {
|
||||
"endPoint": "47.117.164.182",
|
||||
"port": "9001",
|
||||
"useSSL": false,
|
||||
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
|
||||
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
|
||||
"bucketName": "hir-uat",
|
||||
"viewEndpoint": "http://hir.uat.extimaging.com/oss/hir-uat"
|
||||
},
|
||||
|
||||
"AWS": {
|
||||
"endPoint": "s3.us-east-1.amazonaws.com",
|
||||
"useSSL": false,
|
||||
|
|
@ -40,8 +30,8 @@
|
|||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=47.117.164.182,1434;Database=Uat_HIR;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=47.117.164.182,1434;Database=Uat_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
"RemoteNew": "Server=47.117.164.182,1434;Database=Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=47.117.164.182,1434;Database=Uat_IRC.Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
},
|
||||
"BasicSystemConfig": {
|
||||
|
||||
|
|
|
|||
|
|
@ -68,5 +68,10 @@
|
|||
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||
"CompanyShortName": "Extensive Imaging",
|
||||
"CompanyShortNameCN": "展影医疗"
|
||||
},
|
||||
"SystemPacsConfig": {
|
||||
"Port": "11113",
|
||||
"IP": "101.132.193.237"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
},
|
||||
"ObjectStoreService": {
|
||||
|
||||
"ObjectStoreUse": "MinIO",
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
|
||||
"AliyunOSS": {
|
||||
"regionId": "cn-shanghai",
|
||||
|
|
|
|||
|
|
@ -35,18 +35,6 @@ namespace IRaCIS.Core.Application.Filter
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//public TrialResourceFilter(IEasyCachingProvider provider, IUserInfo userInfo)
|
||||
//{
|
||||
// _provider = provider;
|
||||
// _userInfo = userInfo;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//优先选择异步的方法
|
||||
public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -69,8 +69,12 @@ namespace IRaCIS.Application.Services.BusinessFilter
|
|||
{
|
||||
var result = objectResult.Value as IResponseOutput;
|
||||
|
||||
//统一在这里记录国际化的日志信息
|
||||
_logger.LogWarning($"{result.LocalizedInfo}");
|
||||
if (!string.IsNullOrWhiteSpace(result.LocalizedInfo))
|
||||
{
|
||||
//统一在这里记录国际化的日志信息
|
||||
_logger.LogWarning($"{result.LocalizedInfo}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if (statusCode != 200 && !(objectResult.Value is IResponseOutput))
|
||||
|
|
|
|||
|
|
@ -13362,7 +13362,7 @@
|
|||
</member>
|
||||
<member name="M:IRaCIS.Application.Services.BackGroundJob.IRaCISCHangfireJob.MemoryCacheTrialStatusAsync">
|
||||
<summary>
|
||||
缓存项目状态
|
||||
缓存项目状态--之前是启动的时候就获取所有的项目进行缓存,加上定时任务刷新,现在的话,改为是按照需要进行缓存请求数据库
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
|
|
@ -15239,11 +15239,14 @@
|
|||
<param name="inQuery"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Application.Services.PatientService.SubmitVisitStudyBinding(IRaCIS.Application.Contracts.SubmitVisitStudyBindingCommand)">
|
||||
<member name="M:IRaCIS.Application.Services.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})">
|
||||
<summary>
|
||||
提交 患者检查和访视的绑定
|
||||
</summary>
|
||||
<param name="inCommand"></param>
|
||||
<param name="_dicomstudyRepository"></param>
|
||||
<param name="_dicomSeriesRepository"></param>
|
||||
<param name="_dicomInstanceRepository"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Application.Services.SubjectService.AddOrUpdateSubject(IRaCIS.Application.Contracts.SubjectCommand)">
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||
|
||||
public class TaskConsistentRuleBasic : TaskConsistentRuleAddOrEdit
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class SubjectGeneratedTask
|
||||
|
|
@ -288,7 +287,14 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||
}
|
||||
|
||||
|
||||
|
||||
public class GetConsistentRuleOut
|
||||
{
|
||||
public TaskConsistentRuleBasic? ConsistentRuleBasic { get; set; }
|
||||
/// <summary>
|
||||
/// 任务展示访视 读片任务显示是否顺序
|
||||
/// </summary>
|
||||
public ReadingOrder IsReadingTaskViewInOrder { get; set; } = ReadingOrder.InOrder;
|
||||
}
|
||||
|
||||
///<summary>TaskConsistentRuleQuery 列表查询参数模型</summary>
|
||||
public class TaskConsistentRuleQuery
|
||||
|
|
|
|||
|
|
@ -211,7 +211,9 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||
{
|
||||
public bool? IsSelfAnalysis { get; set; }
|
||||
|
||||
public bool IsReReadingOrBackInfluenceAnalysis { get; set; }
|
||||
public int ConsistentClinicalDataCount { get; set; } = 0;
|
||||
|
||||
public bool IsReReadingOrBackInfluenceAnalysis { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ using IRaCIS.Core.Infrastructure.Extention;
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
|
|
@ -32,6 +33,9 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
private readonly IRepository<TaskConsistentRule> _taskConsistentRuleRepository;
|
||||
private readonly IRepository<VisitTask> _visitTaskRepository;
|
||||
private readonly IRepository<ReadingConsistentClinicalData> _readingConsistentClinicalDataRepository;
|
||||
private readonly IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository;
|
||||
private readonly IReadingClinicalDataService _readingClinicalDataService;
|
||||
private readonly IRepository<SubjectUser> _subjectUserRepository;
|
||||
private readonly IRepository<Subject> _subjectRepository;
|
||||
private readonly IRepository<Enroll> _enrollRepository;
|
||||
|
|
@ -44,11 +48,18 @@ namespace IRaCIS.Core.Application.Service
|
|||
private readonly IVisitTaskHelpeService _visitTaskCommonService;
|
||||
|
||||
|
||||
public TaskConsistentRuleService(IRepository<VisitTask> visitTaskRepository, IRepository<Enroll> enrollRepository, IRepository<TaskConsistentRule> taskConsistentRuleRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<Subject> subjectRepository, IDistributedLockProvider distributedLockProvider,
|
||||
public TaskConsistentRuleService(IRepository<VisitTask> visitTaskRepository,
|
||||
IRepository<ReadingConsistentClinicalData> readingConsistentClinicalDataRepository,
|
||||
IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository,
|
||||
IReadingClinicalDataService readingClinicalDataService,
|
||||
IRepository<Enroll> enrollRepository, IRepository<TaskConsistentRule> taskConsistentRuleRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<Subject> subjectRepository, IDistributedLockProvider distributedLockProvider,
|
||||
IRepository<Trial> trialRepository, IRepository<TrialSite> trialSiteRepository, IRepository<TrialVirtualSiteCodeUpdate> trialVirtualSiteCodeUpdateRepository, IVisitTaskHelpeService visitTaskCommonService)
|
||||
{
|
||||
_taskConsistentRuleRepository = taskConsistentRuleRepository;
|
||||
_visitTaskRepository = visitTaskRepository;
|
||||
this._readingConsistentClinicalDataRepository = readingConsistentClinicalDataRepository;
|
||||
this._trialReadingCriterionRepository = trialReadingCriterionRepository;
|
||||
this._readingClinicalDataService = readingClinicalDataService;
|
||||
_subjectUserRepository = subjectUserRepository;
|
||||
_subjectRepository = subjectRepository;
|
||||
_enrollRepository = enrollRepository;
|
||||
|
|
@ -117,6 +128,20 @@ namespace IRaCIS.Core.Application.Service
|
|||
var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) };
|
||||
|
||||
var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);
|
||||
#region 统计一致性分析临床数据数量
|
||||
|
||||
foreach (var item in pageList.CurrentPageData)
|
||||
{
|
||||
item.ConsistentClinicalDataCount = (await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
|
||||
{
|
||||
SubjectId = item.SubjectId,
|
||||
TrialId = item.TrialId,
|
||||
SelectIsSign = false,
|
||||
IsGetAllConsistencyAnalysis = false,
|
||||
VisitTaskId = item.Id,
|
||||
})).Count();
|
||||
}
|
||||
#endregion
|
||||
|
||||
var trialTaskConfig = _repository.Where<Trial>(t => t.Id == queryVisitTask.TrialId).Select(t => new { IsHaveDoubleReadCriterion = t.TrialReadingCriterionList.Any(t => t.IsSigned && t.IsConfirm && t.ReadingType == ReadingMethod.Double), t.VitrualSiteCode }).FirstOrDefault();
|
||||
|
||||
|
|
@ -253,6 +278,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
TaskName = lastTask.TaskName + "_Global",
|
||||
TaskBlindName = lastTask.TaskBlindName + "_Global",
|
||||
TrialReadingCriterionId = trialReadingCriterionId,
|
||||
VisitTaskNum= lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]
|
||||
};
|
||||
|
||||
var afterGlobal = _visitTaskRepository.Where(t => t.SubjectId == lastTask.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum > lastTask.VisitTaskNum).ProjectTo<VisitTaskSimpleDTO>(_mapper.ConfigurationProvider).FirstOrDefault();
|
||||
|
|
@ -496,7 +522,9 @@ namespace IRaCIS.Core.Application.Service
|
|||
TrialReadingCriterionId = trialReadingCriterionId,
|
||||
|
||||
BlindSubjectCode = blindSubjectCode,
|
||||
BlindTrialSiteCode = filterObj.BlindTrialSiteCode
|
||||
BlindTrialSiteCode = filterObj.BlindTrialSiteCode,
|
||||
|
||||
VisitTaskNum = lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]
|
||||
|
||||
};
|
||||
}
|
||||
|
|
@ -757,9 +785,16 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
|
||||
[HttpPost]
|
||||
public async Task<TaskConsistentRuleBasic?> GetConsistentRule(TaskConsistentRuleQuery inQuery)
|
||||
public async Task<GetConsistentRuleOut> GetConsistentRule(TaskConsistentRuleQuery inQuery)
|
||||
{
|
||||
return await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == inQuery.IsSelfAnalysis && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo<TaskConsistentRuleBasic>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
|
||||
|
||||
var IsReadingTaskViewInOrder = await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).Select(x => x.IsReadingTaskViewInOrder).FirstNotNullAsync();
|
||||
var result = await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == inQuery.IsSelfAnalysis && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo<TaskConsistentRuleBasic>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
|
||||
return new GetConsistentRuleOut()
|
||||
{
|
||||
ConsistentRuleBasic = result,
|
||||
IsReadingTaskViewInOrder = IsReadingTaskViewInOrder
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ using IRaCIS.Core.Infra.EFCore.Common;
|
|||
using System.Linq.Expressions;
|
||||
using IRaCIS.Core.Domain.Share.Reading;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
|
|
@ -26,7 +27,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
/// 访视读片任务
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "Trial")]
|
||||
public class VisitTaskHelpeService : IVisitTaskHelpeService
|
||||
public class VisitTaskHelpeService : BaseService, IVisitTaskHelpeService
|
||||
{
|
||||
|
||||
private readonly IRepository<VisitTask> _visitTaskRepository;
|
||||
|
|
@ -450,6 +451,19 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取GetIsClinicalDataSignTest
|
||||
/// </summary>
|
||||
/// <param name="visitTask"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> GetIsClinicalDataSignTest(Guid visitTask)
|
||||
{
|
||||
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTask).FirstNotNullAsync();
|
||||
var clinicalDataConfirmList = _trialClinicalDataSetRepository.Where(t => t.TrialId == taskinfo.TrialId && t.IsConfirm).Include(t => t.TrialClinicalDataSetCriteriaList).ToList();
|
||||
|
||||
Guid readingid = taskinfo.SourceSubjectVisitId == null ? taskinfo.SouceReadModuleId!.Value : taskinfo.SourceSubjectVisitId.Value;
|
||||
return IsClinicalDataSign(taskinfo.ReadingCategory, taskinfo.VisitTaskNum == 0m, taskinfo.TrialReadingCriterionId, clinicalDataConfirmList, readingid, taskinfo.TrialId); ;
|
||||
}
|
||||
|
||||
// 有可能在任务生成之前 就签名完了临床数据
|
||||
private bool IsClinicalDataSign(ReadingCategory readingCategory, bool isbaseLine, Guid trialReadingCriterionId, List<ClinicalDataTrialSet> trialClinicalDataSetList, Guid readingId, Guid trialId)
|
||||
|
|
@ -468,7 +482,9 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
//CRC 的自动签名 不用管 只用处理PM的就好
|
||||
var haveSignedCount = _readingClinicalDataRepository
|
||||
.Where(t => t.TrialId == trialId && t.IsSign && t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count();
|
||||
.Where(t => t.TrialId == trialId && t.IsSign
|
||||
&& t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(x=>x.TrialReadingCriterionId== trialReadingCriterionId)
|
||||
&& t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count();
|
||||
|
||||
|
||||
var readModule = _readModuleRepository.Where(t => t.Id == readingId).FirstOrDefault();
|
||||
|
|
@ -1415,6 +1431,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
case GenerateTaskCategory.SelfConsistent:
|
||||
|
||||
var readingCriterionId = generateTaskCommand.GenerataConsistentTaskList.First().TrialReadingCriterionId;
|
||||
var isReadingTaskViewInOrder = await _trialReadingCriterionRepository.Where(t => t.Id == readingCriterionId).Select(x => x.IsReadingTaskViewInOrder).FirstNotNullAsync();
|
||||
var subjectId = generateTaskCommand.GenerataConsistentTaskList.First().SubjectId;
|
||||
//var trialReadingCriterion=_trialReadingCriterionRepository.Where(t=>t.Id== trialReadingCriterionId).FirstOrDefault();
|
||||
|
||||
|
|
@ -1457,7 +1474,11 @@ namespace IRaCIS.Core.Application.Service
|
|||
foreach (var task in generateTaskCommand.GenerataConsistentTaskList)
|
||||
{
|
||||
|
||||
var exsitPDF = await _readingClinicalDataRepository.AnyAsync(t => t.TrialId == trialId &&
|
||||
|
||||
|
||||
var exsitPDF = await _readingClinicalDataRepository
|
||||
.WhereIf(isReadingTaskViewInOrder== ReadingOrder.Random,t=>t.ReadingId== task.SouceReadModuleId|| t.ReadingId == task.SourceSubjectVisitId)
|
||||
.AnyAsync(t => t.TrialId == trialId &&
|
||||
t.SubjectId== task.SubjectId&&
|
||||
|
||||
t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == readingCriterionId)
|
||||
|
|
|
|||
|
|
@ -206,7 +206,8 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||
var isIR = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer;
|
||||
|
||||
|
||||
var query = _trialRepository.AsQueryable().IgnoreQueryFilters()
|
||||
var query = _trialRepository.AsQueryable()
|
||||
.WhereIf(inQuery.TrialIdList.Count()>0, o => inQuery.TrialIdList.Contains(o.Id))
|
||||
|
||||
.WhereIf(inQuery.SponsorId != null, o => o.SponsorId == inQuery.SponsorId)
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.Code), o => o.TrialCode.Contains(inQuery.Code))
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ namespace IRaCIS.Application.Services
|
|||
|
||||
public async Task<EmailNoticeConfig> GetEmailConfigInfoAsync(EmailBusinessScenario scenario)
|
||||
{
|
||||
var configInfo = await _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario).Include(t=>t.EmailNoticeUserTypeList).FirstOrDefaultAsync();
|
||||
var configInfo = await _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario).Include(t => t.EmailNoticeUserTypeList).FirstOrDefaultAsync();
|
||||
|
||||
if (configInfo == null)
|
||||
{
|
||||
|
|
@ -758,11 +758,13 @@ namespace IRaCIS.Application.Services
|
|||
|
||||
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
var emailConfigInfo = await GetEmailConfigInfoAsync(feedBack.VisitTaskId != null? EmailBusinessScenario.IRImageError:(feedBack.TrialId != null? EmailBusinessScenario.TrialFeedBack: EmailBusinessScenario.SysFeedBack));
|
||||
var emialScenario = feedBack.VisitTaskId != null ? EmailBusinessScenario.IRImageError : (feedBack.SubjectVisitId != null ? EmailBusinessScenario.TrialSubjectVisitFeedBack : (feedBack.TrialId != null ? EmailBusinessScenario.TrialFeedBack : EmailBusinessScenario.SysFeedBack));
|
||||
|
||||
var emailConfigInfo = await GetEmailConfigInfoAsync(emialScenario);
|
||||
|
||||
var userTypeEnumList = emailConfigInfo.EmailNoticeUserTypeList.Where(t => t.EmailUserType == EmailUserType.To).Select(t => t.UserType).ToList();
|
||||
|
||||
var emailList = await _repository.Where<User>(t => userTypeEnumList.Contains(t.UserTypeEnum) &&
|
||||
var emailList = await _repository.Where<User>(t => userTypeEnumList.Contains(t.UserTypeEnum) &&
|
||||
(isHaveTrialId ? t.UserTrials.Any(t => t.TrialId == feedBack.TrialId) : true)).Select(t => new { t.EMail, t.UserTypeEnum, t.FullName }).ToListAsync();
|
||||
|
||||
|
||||
|
|
@ -771,10 +773,11 @@ namespace IRaCIS.Application.Services
|
|||
messageToSend.To.Add(new MailboxAddress(email.FullName, email.EMail));
|
||||
}
|
||||
|
||||
var userNames = string.Join(',', emailList.Select(t => t.FullName));
|
||||
|
||||
//影像阅片反馈 pm
|
||||
if (feedBack.VisitTaskId != null)
|
||||
{
|
||||
var userNames = string.Join(',', emailList.Where(email => email.UserTypeEnum == UserTypeEnum.ProjectManager).Select(t => t.FullName));
|
||||
|
||||
var emailType = await _repository.Where<Dictionary>(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.IRImageError).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync();
|
||||
|
||||
|
|
@ -783,7 +786,7 @@ namespace IRaCIS.Application.Services
|
|||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, info.SubejctCode, info.VisitName, info.ResearchProgramNo);
|
||||
var topicStr = string.Format(input.topicStr, info.ResearchProgramNo, info.SubejctCode, info.VisitName);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
userNames,
|
||||
|
|
@ -804,10 +807,38 @@ namespace IRaCIS.Application.Services
|
|||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.IRImageError, messageToSend, emailConfigFunc);
|
||||
|
||||
}
|
||||
else if (feedBack.SubjectVisitId != null)
|
||||
{
|
||||
var emailType = await _repository.Where<Dictionary>(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.TrialSubjectVisitFeedBack).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
var info = await _repository.Where<SubjectVisit>(t => t.Id == feedBack.SubjectVisitId).Select(t => new { t.Trial.ResearchProgramNo, t.Trial.TrialCode, SubejctCode = t.Subject.Code, t.VisitName }).FirstNotNullAsync();
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, info.ResearchProgramNo, info.SubejctCode, info.VisitName);
|
||||
|
||||
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
|
||||
userNames,
|
||||
info.TrialCode,
|
||||
info.SubejctCode,
|
||||
info.VisitName,
|
||||
feedBack.CreateUser.UserTypeRole.UserTypeShortName,
|
||||
feedBack.CreateUser.FullName,
|
||||
emailType,
|
||||
feedBack.QuestionDescription,
|
||||
_systemEmailConfig.SiteUrl
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
};
|
||||
|
||||
|
||||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.TrialSubjectVisitFeedBack, messageToSend, emailConfigFunc);
|
||||
}
|
||||
//项目相关的反馈 pm admin
|
||||
else if (feedBack.TrialId != null)
|
||||
{
|
||||
var userNames = string.Join(',', emailList.Where(email => email.UserTypeEnum == UserTypeEnum.ProjectManager || email.UserTypeEnum == UserTypeEnum.Admin).Select(t => t.FullName));
|
||||
|
||||
var emailType = await _repository.Where<Dictionary>(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.TrialFeedBack).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync();
|
||||
|
||||
|
|
@ -835,11 +866,10 @@ namespace IRaCIS.Application.Services
|
|||
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.TrialFeedBack, messageToSend, emailConfigFunc);
|
||||
|
||||
}
|
||||
//项目无关的反馈 admin zyss
|
||||
//项目无关的反馈 admin
|
||||
else
|
||||
{
|
||||
|
||||
var userNames = string.Join(',', emailList.Where(email => email.UserTypeEnum == UserTypeEnum.ZYSS || email.UserTypeEnum == UserTypeEnum.Admin).Select(t => t.FullName));
|
||||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
{
|
||||
GroupId=gropId,
|
||||
LimitEdit=LimitEdit.OnlyBaseLine,
|
||||
DictionaryCode="YesOrNoOrNa",
|
||||
DictionaryCode="YesOrNoOrNE",
|
||||
IsJudgeQuestion=false,
|
||||
IsShowInDicom=false,
|
||||
GlobalReadingShowType=GlobalReadingShowType.NotShow,
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
study.TrialId = incommand.TrialId;
|
||||
study.SubjectId = incommand.SubjectId;
|
||||
study.SubjectVisitId = incommand.SubjectVisitId;
|
||||
study.IsFromPACS = false;
|
||||
|
||||
//如果因为意外情况,连续点击两次,导致第一次插入了,第二次进来也会插入,在此判断一下
|
||||
var findStudy = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == study.Id);
|
||||
|
|
@ -280,6 +281,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
studyMonitor.StudyCode = study.StudyCode;
|
||||
|
||||
//特殊处理逻辑
|
||||
study.IsFromPACS = false;
|
||||
study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Union(study.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct());
|
||||
SpecialArchiveStudyDeal(study);
|
||||
modalitys = study.Modalities;
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
.ForMember(o => o.IsReading, t => t.MapFrom(u => u.DicomSerie.IsReading));
|
||||
CreateMap<DicomStudy, DicomStudyDTO>();
|
||||
CreateMap<DicomSeries, DicomSeriesDTO>();
|
||||
CreateMap<SCPSeries, DicomSeriesDTO>();
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using IRaCIS.Core.Application.Contracts;
|
|||
using IRaCIS.Core.Application.Service.Inspection.DTO;
|
||||
using IRaCIS.Core.Application.Service.Inspection.Interface;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore.Common;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
|
|
@ -58,8 +59,11 @@ namespace IRaCIS.Core.Application.Service.Inspection
|
|||
join usertype in _repository.GetQueryable<UserType>().IgnoreQueryFilters() on leftuser.UserTypeId equals usertype.Id into usertypetemp
|
||||
from leftusertype in usertypetemp.DefaultIfEmpty()
|
||||
|
||||
//join trialCriterion in _repository.GetQueryable<ReadingQuestionCriterionTrial>().IgnoreQueryFilters() on data.TrialReadingCriterionId equals trialCriterion.Id into criterion
|
||||
//from leftCriterion in criterion.DefaultIfEmpty()
|
||||
join visttask in _repository.GetQueryable<VisitTask>().IgnoreQueryFilters() on data.VisitTaskId equals visttask.Id into visttasktemp
|
||||
from leftvisttask in visttasktemp.DefaultIfEmpty()
|
||||
|
||||
//join trialCriterion in _repository.GetQueryable<ReadingQuestionCriterionTrial>().IgnoreQueryFilters() on data.TrialReadingCriterionId equals trialCriterion.Id into criterion
|
||||
//from leftCriterion in criterion.DefaultIfEmpty()
|
||||
|
||||
//join moduleTyped in _repository.GetQueryable<Dictionary>().Where(x => x.Code == "ModuleType") on 1 equals 1
|
||||
//join moduleTypec in _repository.GetQueryable<Dictionary>() on new { ParentId = moduleTyped.Id, ModuleType = data.ModuleType } equals new { ParentId = moduleTypec.ParentId.Value, ModuleType = moduleTypec.Value } into moduleTypectemp
|
||||
|
|
@ -131,7 +135,7 @@ namespace IRaCIS.Core.Application.Service.Inspection
|
|||
ExperimentName = leftrial.ExperimentName,
|
||||
|
||||
|
||||
SubjectCode = leftsubject.Code,
|
||||
SubjectCode = leftvisttask.BlindSubjectCode.IsNullOrEmpty()? leftsubject.Code: leftvisttask.BlindSubjectCode,
|
||||
SiteCode = lefttrialSite.TrialSiteCode,
|
||||
|
||||
ResearchProgramNo = leftrial.ResearchProgramNo,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ namespace IRaCIS.Application.Contracts
|
|||
public string RealName { get; set; } = string.Empty;
|
||||
public int? Sex { get; set; } // 1-男 2-女
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// LastLoginIP
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
var entity = await _userFeedBackRepository.InsertOrUpdateAsync(addOrEditUserFeedBack, true);
|
||||
|
||||
//任务反馈的添加更新都需要发送邮件,其他的是添加的时候发送
|
||||
if (addOrEditUserFeedBack.VisitTaskId != null || addOrEditUserFeedBack.Id == null)
|
||||
{
|
||||
await mailService.UserFeedBackMail(entity.Id);
|
||||
|
|
|
|||
|
|
@ -157,6 +157,8 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
|
||||
public bool IsHaveVisitClinicalData { get; set; } = false;
|
||||
|
||||
public bool IsPacsConnectConfiged { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -185,7 +187,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
public DateTime CreateTime { get; set; }
|
||||
|
||||
[DictionaryTranslateAttribute("YesOrNo")]
|
||||
public bool IsConfirmed { get; set; }
|
||||
public bool IsConfirmed => ConfirmTime != null;
|
||||
|
||||
public string RealName { get; set; }
|
||||
|
||||
|
|
@ -292,7 +294,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
|
||||
public string Content { get; set; } = string.Empty;
|
||||
|
||||
[DictionaryTranslateAttribute("YesOrNo")]
|
||||
[DictionaryTranslateAttribute("ChallengeIsClosed")]
|
||||
public bool IsClosed { get; set; }
|
||||
|
||||
public DateTime? ClosedTime { get; set; }
|
||||
|
|
|
|||
|
|
@ -547,6 +547,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
|
||||
config.IsHaveStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.IsConfirm && x.TrialId == visit.TrialId && x.ClinicalDataLevel == ClinicalLevel.Study);
|
||||
|
||||
config.IsPacsConnectConfiged= await _subjectVisitRepository.Where(t=>t.Id==subjectVisitId).AnyAsync(t=>t.Trial.IsPACSConnect && t.Subject.TrialSite.TrialSiteDicomAEList.Any());
|
||||
|
||||
return (list, config);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ namespace IRaCIS.Application.Services
|
|||
var query = _readingClinicalDataRepository.AsQueryable();
|
||||
if (inDto.StudyId != null)
|
||||
{
|
||||
query = query.Where(x => x.StudyId == inDto.StudyId.Value);
|
||||
query = query.Where(x => x.StudyId == inDto.StudyId.Value && x.TrialId==inDto.TrialId&&x.SubjectId==inDto.SubjectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1227,6 +1227,7 @@ namespace IRaCIS.Application.Services
|
|||
entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded;
|
||||
entity.IsSign = false;
|
||||
entity.FileCount = fileCount;
|
||||
entity.CreateTime=DateTime.Now;
|
||||
var success = await _readingConsistentClinicalDataRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Ok(entity.Id);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,5 +31,6 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
Task DealVisiTaskClinicalDataSignedAsync(Guid trialId, Guid subjectId, Guid readingId, bool isVisit, Guid trialReadingCritrialId);
|
||||
|
||||
Task<IResponseOutput> SignConsistencyAnalysisReadingClinicalData(SignConsistencyAnalysisReadingClinicalDataInDto inDto);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -398,7 +398,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
var result = await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId && t.TrialId == trialId).IgnoreQueryFilters()
|
||||
.ProjectTo<LoginReturnDTO>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync().IfNullThrowException();
|
||||
|
||||
var siteSurveryConfig = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).Select(t => t.Trial.TrialExtraConfigJsonStr).FirstOrDefault()??string.Empty;
|
||||
var siteSurveryConfig = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).IgnoreQueryFilters().Select(t => t.Trial.TrialExtraConfigJsonStr).FirstOrDefault()??string.Empty;
|
||||
|
||||
result.SiteSurveyFiledConfig = JsonConvert.DeserializeObject<TrialExtraConfig>(siteSurveryConfig) ?? new TrialExtraConfig();
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -279,6 +279,8 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
public CriterionType? CriterionType { get; set; }
|
||||
|
||||
public string? PM_EMail { get; set; }
|
||||
|
||||
public List<Guid> TrialIdList { get; set; }=new List<Guid>();
|
||||
}
|
||||
|
||||
public class TrialToBeDoneDto : TrialBaseInfoDto
|
||||
|
|
|
|||
|
|
@ -256,9 +256,9 @@ namespace IRaCIS.Application.Contracts
|
|||
|
||||
public string? TrialSiteCode { get; set; }
|
||||
|
||||
public string? TrialSiteName { get; set; }
|
||||
public string? TrialSiteName { get; set; }
|
||||
|
||||
public string? TrialSiteAliasName { get; set; }
|
||||
public string? TrialSiteAliasName { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -382,7 +382,7 @@ namespace IRaCIS.Application.Contracts
|
|||
|
||||
}
|
||||
|
||||
public class SubmitVisitStudyBindingCommand
|
||||
public class VerifyPacsImageCommand
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid TrialId { get; set; }
|
||||
|
|
@ -396,6 +396,13 @@ namespace IRaCIS.Application.Contracts
|
|||
public List<Guid> SCPStudyIdList { get; set; }
|
||||
}
|
||||
|
||||
public class SubmitVisitStudyBindingCommand: VerifyPacsImageCommand
|
||||
{
|
||||
|
||||
|
||||
public List<Guid> ReUploadSCPStudyIdList { get; set; }
|
||||
}
|
||||
|
||||
public class SubjectVisitSelectQuery
|
||||
{
|
||||
[NotDefault]
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
|
||||
public bool IsCriticalSequence { get; set; } = false;
|
||||
|
||||
public int SeriesCount =>SeriesList.Count;
|
||||
public int SeriesCount => SeriesList.Count;
|
||||
public int InstanceCount { get; set; }
|
||||
|
||||
public bool IsDicom { get; set; } = true;
|
||||
|
|
@ -369,6 +369,16 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
public List<string> SOPInstanceUIDList { get; set; }
|
||||
}
|
||||
|
||||
public class VerifySCPStudyUploadResult
|
||||
{
|
||||
public Guid SCPStudyId { get; set; }
|
||||
|
||||
public string ErrorMesseage { get; set; } = String.Empty;
|
||||
|
||||
public bool AllowUpload { get; set; } = false;
|
||||
|
||||
public bool AllowReUpload { get; set; } = false;
|
||||
}
|
||||
|
||||
public class VerifyStudyUploadResult
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,10 +54,12 @@ namespace IRaCIS.Application.Services
|
|||
private readonly IRepository<SCPStudy> _scpStudyRepository;
|
||||
private readonly IRepository<Subject> _subjectRepository;
|
||||
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
|
||||
private readonly IRepository<Dictionary> _dictionaryRepository;
|
||||
private readonly IDistributedLockProvider _distributedLockProvider;
|
||||
|
||||
public PatientService(IRepository<SCPStudy> studyRepository, IRepository<Trial> trialRepository, IRepository<SCPPatient> patientRepository, IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository, IDistributedLockProvider distributedLockProvider)
|
||||
public PatientService(IRepository<SCPStudy> studyRepository, IRepository<Dictionary> dictionaryRepository, IRepository<Trial> trialRepository, IRepository<SCPPatient> patientRepository, IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository, IDistributedLockProvider distributedLockProvider)
|
||||
{
|
||||
_dictionaryRepository = dictionaryRepository;
|
||||
_scpStudyRepository = studyRepository;
|
||||
_trialRepository = trialRepository;
|
||||
_patientRepository = patientRepository;
|
||||
|
|
@ -67,6 +69,43 @@ namespace IRaCIS.Application.Services
|
|||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IResponseOutput<List<DicomSeriesDTO>>> GetPatientSeriesList(Guid scpStudyId,
|
||||
[FromServices] IRepository<SCPSeries> _seriesRepository,
|
||||
[FromServices] IRepository<SCPInstance> _instanceRepository
|
||||
)
|
||||
{
|
||||
|
||||
var seriesList = await _seriesRepository.Where(s => s.StudyId == scpStudyId).OrderBy(s => s.SeriesNumber).
|
||||
ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime)
|
||||
.ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
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 }).ToListAsync();//.GroupBy(u => u.SeriesId);
|
||||
|
||||
foreach (var series in seriesList)
|
||||
{
|
||||
|
||||
series.InstanceInfoList = instanceList.Where(t => t.SeriesId == series.Id).OrderBy(t => t.InstanceNumber).Select(k =>
|
||||
new InstanceBasicInfo()
|
||||
{
|
||||
Id = k.Id,
|
||||
NumberOfFrames = k.NumberOfFrames,
|
||||
//HtmlPath = string.Empty,
|
||||
Path = k.Path,
|
||||
InstanceNumber = k.InstanceNumber,
|
||||
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
var study = await _scpStudyRepository.FindAsync(scpStudyId);
|
||||
|
||||
return ResponseOutput.Ok(seriesList, study);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// scp 影像推送记录表
|
||||
/// </summary>
|
||||
|
|
@ -75,7 +114,7 @@ namespace IRaCIS.Application.Services
|
|||
[HttpPost]
|
||||
public async Task<IResponseOutput<PageOutput<SCPImageUploadView>>> GetSCPImageUploadList(SCPImageUploadQuery inQuery)
|
||||
{
|
||||
var query = _repository.Where<SCPImageUpload>(t=>t.TrialId==inQuery.TrialId)
|
||||
var query = _repository.Where<SCPImageUpload>(t => t.TrialId == inQuery.TrialId)
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.CalledAE.Contains(inQuery.CalledAE))
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAEIP), t => t.CallingAEIP.Contains(inQuery.CallingAEIP))
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.CallingAE.Contains(inQuery.CallingAE))
|
||||
|
|
@ -283,23 +322,126 @@ namespace IRaCIS.Application.Services
|
|||
|
||||
|
||||
|
||||
public async Task<List<VerifySCPStudyUploadResult>> VerifyPacsImage(VerifyPacsImageCommand inCommand)
|
||||
{
|
||||
var trialId = inCommand.TrialId;
|
||||
|
||||
var subjectId = inCommand.SubjectId;
|
||||
|
||||
var isVerifyVisitImageDate = await _repository.Where<Trial>(t => t.Id == inCommand.TrialId).Select(t => t.IsVerifyVisitImageDate).FirstNotNullAsync();
|
||||
|
||||
var result = new List<VerifySCPStudyUploadResult>();
|
||||
|
||||
var visitList = _repository.Where<SubjectVisit>(t => t.SubjectId == inCommand.SubjectId).Select(t => new { t.VisitNum, t.EarliestScanDate, t.LatestScanDate, t.Id }).ToList();
|
||||
|
||||
var currentVisitNum = visitList.First(t => t.Id == inCommand.SubjectVisitId).VisitNum;
|
||||
|
||||
var scpStudyList = _scpStudyRepository.Where(t => inCommand.SCPStudyIdList.Contains(t.Id)).Select(t => new { StudyDate = t.StudyTime, t.Id }).ToList();
|
||||
|
||||
foreach (var waitUploadItem in scpStudyList)
|
||||
{
|
||||
|
||||
if (isVerifyVisitImageDate)
|
||||
{
|
||||
//小于当前访视 最近的最晚拍片
|
||||
var before = visitList.Where(u => u.VisitNum < currentVisitNum).Max(k => k.LatestScanDate);
|
||||
|
||||
if (before != null && waitUploadItem.StudyDate != null && before > waitUploadItem.StudyDate)
|
||||
{
|
||||
|
||||
// $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能早于前序访视检查时间{before?.ToString("yyyy-MM-dd")},请核对检查数据是否有误",
|
||||
result.Add(new VerifySCPStudyUploadResult() { SCPStudyId = waitUploadItem.Id, ErrorMesseage = _localizer["Study_VisitBeforePrevError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, before?.ToString("yyyy-MM-dd")!] });
|
||||
continue; // 跳过当前迭代
|
||||
}
|
||||
|
||||
//大于当前访视 最近的最早拍片日期
|
||||
var after = visitList.Where(u => u.VisitNum > currentVisitNum).Min(k => k.EarliestScanDate);
|
||||
|
||||
if (after != null && waitUploadItem.StudyDate != null && after < waitUploadItem.StudyDate)
|
||||
{
|
||||
// $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能晚于该访视之后的检查时间{after?.ToString("yyyy-MM-dd")},请核对检查数据是否有误"
|
||||
result.Add(new VerifySCPStudyUploadResult() { SCPStudyId = waitUploadItem.Id, ErrorMesseage = _localizer["Study_VisitAfterSubseqError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, after?.ToString("yyyy-MM-dd")!] });
|
||||
continue; // 跳过当前迭代
|
||||
}
|
||||
}
|
||||
|
||||
var verifyStudyInfo = _repository.Where<DicomStudy>(t => t.TrialId == trialId && t.Id == waitUploadItem.Id).ProjectTo<VerifyStudyDto>(_mapper.ConfigurationProvider).FirstOrDefault();
|
||||
|
||||
var currentStudyResult = new VerifySCPStudyUploadResult() { SCPStudyId = waitUploadItem.Id };
|
||||
|
||||
|
||||
//数据库不存在该检查 允许上传
|
||||
if (verifyStudyInfo == null)
|
||||
{
|
||||
currentStudyResult.AllowUpload = true;
|
||||
}
|
||||
//数据库该项目有该检查 看是否支持重传
|
||||
else
|
||||
{
|
||||
//是同一个受试者 支持重传
|
||||
if (verifyStudyInfo.SubjectId == subjectId && verifyStudyInfo.SubjectVisitId == inCommand.SubjectVisitId)
|
||||
{
|
||||
currentStudyResult.AllowReUpload = true;
|
||||
}
|
||||
//不是同一个受试者
|
||||
else
|
||||
{
|
||||
//有默认值,其实不用写,这里为了好理解
|
||||
currentStudyResult.AllowUpload = false;
|
||||
|
||||
currentStudyResult.AllowReUpload = false;
|
||||
|
||||
//$"此处不可以上传。当前影像检查已经上传给受试者{verifyStudyInfo.SubjectCode}的{verifyStudyInfo.VisitName}"
|
||||
currentStudyResult.ErrorMesseage = _localizer["Study_ImgAlreadyUploaded", verifyStudyInfo.SubjectCode, verifyStudyInfo.VisitName];
|
||||
}
|
||||
}
|
||||
|
||||
result.Add(currentStudyResult);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 提交 患者检查和访视的绑定
|
||||
/// </summary>
|
||||
/// <param name="inCommand"></param>
|
||||
/// <param name="_dicomstudyRepository"></param>
|
||||
/// <param name="_dicomSeriesRepository"></param>
|
||||
/// <param name="_dicomInstanceRepository"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[UnitOfWork]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
public async Task<IResponseOutput> SubmitVisitStudyBinding(SubmitVisitStudyBindingCommand inCommand)
|
||||
public async Task<IResponseOutput> SubmitVisitStudyBinding(SubmitVisitStudyBindingCommand inCommand,
|
||||
[FromServices] IRepository<DicomStudy> _dicomstudyRepository,
|
||||
[FromServices] IRepository<DicomSeries> _dicomSeriesRepository,
|
||||
[FromServices] IRepository<DicomInstance> _dicomInstanceRepository)
|
||||
{
|
||||
|
||||
//这里要做校验 + 同时验证本地系统里面的影像是否存在pacs推过来的
|
||||
|
||||
var copyCommand = inCommand.Clone();
|
||||
copyCommand.SCPStudyIdList = inCommand.SCPStudyIdList.Union(inCommand.ReUploadSCPStudyIdList).ToList();
|
||||
var verifyResult = await VerifyPacsImage(copyCommand);
|
||||
|
||||
var allowUploadList = verifyResult.Where(u => u.AllowUpload == true).Select(t => t.SCPStudyId).ToList();
|
||||
var allowReUploadList = verifyResult.Where(u => u.AllowReUpload == true).Select(t => t.SCPStudyId).ToList();
|
||||
|
||||
if (!(inCommand.SCPStudyIdList.All(t => allowUploadList.Contains(t)) && inCommand.ReUploadSCPStudyIdList.All(t => allowReUploadList.Contains(t))))
|
||||
{
|
||||
throw new BusinessValidationFailedException("对接提示: 前端提交的检查有不能上传的,请刷新页面调用验证接口重试!");
|
||||
}
|
||||
|
||||
var subjectId = inCommand.SubjectId;
|
||||
var subjectVisitId = inCommand.SubjectVisitId;
|
||||
var trialId = inCommand.TrialId;
|
||||
|
||||
|
||||
|
||||
var @lock = _distributedLockProvider.CreateLock($"StudyCode");
|
||||
|
||||
using (await @lock.AcquireAsync())
|
||||
|
|
@ -308,6 +450,7 @@ namespace IRaCIS.Application.Services
|
|||
|
||||
int currentNextCodeInt = dbStudyCodeIntMax + 1;
|
||||
|
||||
//新增的,上传的
|
||||
foreach (var scpStudyId in inCommand.SCPStudyIdList)
|
||||
{
|
||||
|
||||
|
|
@ -315,7 +458,6 @@ namespace IRaCIS.Application.Services
|
|||
|
||||
if (find != null)
|
||||
{
|
||||
|
||||
var newStuty = _mapper.Map<DicomStudy>(find.SCPStudy);
|
||||
|
||||
await _repository.AddAsync(newStuty);
|
||||
|
|
@ -362,6 +504,93 @@ namespace IRaCIS.Application.Services
|
|||
|
||||
}
|
||||
|
||||
foreach (var scpStudyId in inCommand.ReUploadSCPStudyIdList)
|
||||
{
|
||||
|
||||
var study = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == scpStudyId);
|
||||
|
||||
var instanceIdList = _dicomInstanceRepository.Where(t => t.Id == scpStudyId).Select(t => t.Id).ToList();
|
||||
|
||||
var scpStudy = _scpStudyRepository.Where(t => t.Id == scpStudyId).Include(t => t.SeriesList).ThenInclude(t => t.SCPInstanceList).FirstOrDefault();
|
||||
|
||||
//以最后一次为准
|
||||
study.IsFromPACS = true;
|
||||
//特殊处理逻辑
|
||||
study.Modalities = string.Join("、", scpStudy.SeriesList.Select(t => t.Modality).Union(study.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct());
|
||||
|
||||
SpecialArchiveStudyDeal(study);
|
||||
|
||||
|
||||
// 少了整个序列
|
||||
|
||||
//某个序列下少了instance
|
||||
foreach (var seriesItem in scpStudy.SeriesList)
|
||||
{
|
||||
var seriesId = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, trialId.ToString());
|
||||
|
||||
DicomSeries dicomSeries = await _dicomSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
|
||||
|
||||
//判断重复
|
||||
if (dicomSeries == null)
|
||||
{
|
||||
var series = _mapper.Map<DicomSeries>(seriesItem);
|
||||
|
||||
series.SeqId = Guid.Empty;
|
||||
series.TrialId = trialId;
|
||||
series.SubjectId = subjectId;
|
||||
series.SubjectVisitId = subjectVisitId;
|
||||
|
||||
|
||||
dicomSeries = await _dicomSeriesRepository.AddAsync(series);
|
||||
|
||||
|
||||
|
||||
foreach (var instanceItem in seriesItem.SCPInstanceList)
|
||||
{
|
||||
var instance = _mapper.Map<DicomInstance>(instanceItem);
|
||||
|
||||
instance.SeqId = Guid.Empty;
|
||||
instance.TrialId = trialId;
|
||||
instance.SubjectId = subjectId;
|
||||
instance.SubjectVisitId = subjectVisitId;
|
||||
|
||||
await _dicomInstanceRepository.AddAsync(instance);
|
||||
}
|
||||
|
||||
//新的序列 那么 检查的序列数量+1
|
||||
study.SeriesCount += 1;
|
||||
|
||||
study.InstanceCount += seriesItem.SCPInstanceList.Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
//该序列掉了instance
|
||||
dicomSeries.InstanceCount += seriesItem.SCPInstanceList.Count;
|
||||
|
||||
var newInstanceList = seriesItem.SCPInstanceList.Where(t => !instanceIdList.Contains(t.Id));
|
||||
|
||||
foreach (var instanceItem in newInstanceList)
|
||||
{
|
||||
var instance = _mapper.Map<DicomInstance>(instanceItem);
|
||||
|
||||
instance.SeqId = Guid.Empty;
|
||||
instance.TrialId = trialId;
|
||||
instance.SubjectId = subjectId;
|
||||
instance.SubjectVisitId = subjectVisitId;
|
||||
|
||||
await _dicomInstanceRepository.AddAsync(instance);
|
||||
}
|
||||
|
||||
study.InstanceCount += newInstanceList.Count();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
await _repository.SaveChangesAsync();
|
||||
await _repository.BatchUpdateAsync<SCPPatient>(t => t.Id == scpStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
|
||||
await _repository.BatchUpdateAsync<SCPStudy>(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -373,6 +602,43 @@ namespace IRaCIS.Application.Services
|
|||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
|
||||
private void SpecialArchiveStudyDeal(DicomStudy study)
|
||||
{
|
||||
#region 特殊逻辑
|
||||
|
||||
|
||||
if (study.PatientBirthDate.Length == 8)
|
||||
{
|
||||
study.PatientBirthDate = $"{study.PatientBirthDate[0]}{study.PatientBirthDate[1]}{study.PatientBirthDate[2]}{study.PatientBirthDate[3]}-{study.PatientBirthDate[4]}{study.PatientBirthDate[5]}-{study.PatientBirthDate[6]}{study.PatientBirthDate[7]}";
|
||||
}
|
||||
|
||||
var dicModalityList = _dictionaryRepository.Where(t => t.Code == "Modality").SelectMany(t => t.ChildList.Select(c => c.Value)).ToList();
|
||||
|
||||
|
||||
var modality = study.Modalities;
|
||||
|
||||
var modalityForEdit = dicModalityList.Contains(modality) ? modality : String.Empty;
|
||||
|
||||
if (modality == "MR")
|
||||
{
|
||||
modalityForEdit = "MRI";
|
||||
}
|
||||
|
||||
if (modality == "PT")
|
||||
{
|
||||
modalityForEdit = "PET";
|
||||
}
|
||||
if (modality == "PT、CT")
|
||||
{
|
||||
modalityForEdit = "PET-CT";
|
||||
}
|
||||
|
||||
study.ModalityForEdit = modalityForEdit;
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,11 @@ namespace IRaCIS.Core.Domain.Share
|
|||
|
||||
SysFeedBack=26,
|
||||
|
||||
TrialFeedBack=27
|
||||
TrialFeedBack=27,
|
||||
|
||||
TrialSubjectVisitFeedBack = 28,
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,8 @@ namespace IRaCIS.Core.Infra.EFCore.Common
|
|||
t.IsTrialBasicLogicConfirmed,
|
||||
t.IsTrialProcessConfirmed,
|
||||
t.IsTrialUrgentConfirmed,
|
||||
t.IsConfigureEmail
|
||||
t.IsConfigureEmail,
|
||||
t.IsTrialPACSConfirmed,
|
||||
}).FirstOrDefaultAsync();
|
||||
switch (_userInfo.RequestUrl)
|
||||
{
|
||||
|
|
@ -172,6 +173,9 @@ namespace IRaCIS.Core.Infra.EFCore.Common
|
|||
case "configTrialBasicInfo/ConfigTrialUrgentInfoConfirm":
|
||||
extraIdentification = $"/{oldentity.IsTrialUrgentConfirmed.ToString()}";
|
||||
break;
|
||||
case "configTrialBasicInfo/ConfigTrialPACSInfoConfirm":
|
||||
extraIdentification = $"/{oldentity.IsTrialPACSConfirmed.ToString()}";
|
||||
break;
|
||||
|
||||
case "TrialEmailNoticeConfig/setTrialEmail":
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ steps:
|
|||
- name: build-uat-irc
|
||||
commands:
|
||||
- cd /opt/1panel/xc-deploy/Uat_IRC/devops-build-publish/Uat-To-Uat
|
||||
- sh pull-build-uat-irc-image.sh v${DRONE_BUILD_NUMBER}
|
||||
- sh uat-branch-latest-build-image-publish.sh v${DRONE_BUILD_NUMBER}
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
|
|
|
|||
Loading…
Reference in New Issue