Compare commits
332 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9d876b44cf | |||
| 32af01c8f4 | |||
| 803f7f43b4 | |||
| 2260303876 | |||
| 943058b84a | |||
| 4f8f4fe9b8 | |||
| 92aa223f3f | |||
| 4dafe15386 | |||
| 5e70d2ec36 | |||
| f7f84ef28a | |||
| 1f7ce33643 | |||
| 22a03ff3df | |||
| a256aec1cc | |||
| 8da1ab2413 | |||
| 6b6ab9e406 | |||
| a2c35ba83d | |||
| dfb8757719 | |||
| 65d68a3116 | |||
| 13d709c88d | |||
| 31bbd5295e | |||
| 270bccc432 | |||
| 4915b3c62c | |||
| 8d8f9c166e | |||
| 6be7f3e81b | |||
| a635360c95 | |||
| 2d32a5e0de | |||
| 3cd37c2be6 | |||
| dc63f1c735 | |||
| 94462015f2 | |||
| 689cce246a | |||
| 5d3ed34a31 | |||
| 8099ff0fa9 | |||
| c0fd38b03b | |||
| ab1fd89026 | |||
| b1d357956c | |||
| 045269d88f | |||
| c456045381 | |||
| 54a44991fd | |||
| 975adba203 | |||
| 0d8091b41a | |||
| 41db19ec01 | |||
| 00be8908ef | |||
| 7c5263415f | |||
| d93da5abd9 | |||
| 08a7dd9e85 | |||
| 7476f8a8e9 | |||
| 0c04c845b4 | |||
| b4448df047 | |||
| 74502510db | |||
| c5d94eff03 | |||
| 01501b36b5 | |||
| 5e5913255c | |||
| b1cf4dc592 | |||
| ec53815bb0 | |||
| 01c91a6398 | |||
| 6d1c72718b | |||
| 768d936ba9 | |||
| ef8220c236 | |||
| 47a4403cbe | |||
| 09e0187a7d | |||
| 9d4fea4407 | |||
| df508335a0 | |||
| 6900433496 | |||
| fc5f68bd7c | |||
| e9ee41e1a1 | |||
| e1a63b6da5 | |||
| 45a84a65ec | |||
| 8550612a8b | |||
| cc02e89e1b | |||
| ec808c68f5 | |||
| 644d94ed22 | |||
| b7d50de7d1 | |||
| 6a53aaf010 | |||
| edaab02d0b | |||
| 7a03474d07 | |||
| c810f6165f | |||
| 23673ba60c | |||
| 065be00d43 | |||
| da29b194a7 | |||
| 010a69f7ad | |||
| 242bae10d1 | |||
| b44f79ab60 | |||
| 4f5d817789 | |||
| fd13769010 | |||
| fb94e1cf6c | |||
| b03d539578 | |||
| 9f4582bf27 | |||
| 3a79251b91 | |||
| b4bc39f0d9 | |||
| 2526ac32fa | |||
| fc71dea8e9 | |||
| 27b51e7ede | |||
| 5511d6339e | |||
| 79a4ad8cfd | |||
| a23325584b | |||
| 61cdb2fada | |||
| 8b96163e37 | |||
| d84e246b23 | |||
| 3dd7da5a39 | |||
| 260e29989c | |||
| a08cc44cd0 | |||
| 98cc35e614 | |||
| b5e4b7db86 | |||
| a10a9a2255 | |||
| 18f5bcd62f | |||
| c2cbbba637 | |||
| 8e9b9c54fd | |||
| f0a7af4af1 | |||
| 2c262f27ad | |||
| a4819c4016 | |||
| 52e7166177 | |||
| 581f7fcbf3 | |||
| 65da0b877b | |||
| 06e8dc21fa | |||
| 03c07cf969 | |||
| a52aac876a | |||
| 32d8f8b648 | |||
| bfeb41fea9 | |||
| fb118d88f1 | |||
| aacce0b453 | |||
| cee382651b | |||
| 64633a1d63 | |||
| 63e5880154 | |||
| 5e383cb7b5 | |||
| 163af3b269 | |||
| c1bfa55ea6 | |||
| 5ffcc21917 | |||
| 790b69d0a6 | |||
| 313e07de43 | |||
| 7b27009d31 | |||
| 6b318f94fd | |||
| 7da1b40a5c | |||
| d90a98c1ef | |||
| 8a174711f4 | |||
| 48f386546e | |||
| 24d7912f1f | |||
| 090868b299 | |||
| 6dbfda36ee | |||
| 4c6315f2a5 | |||
| e2cdbb7580 | |||
| 13abd86be0 | |||
| 8364b00d3f | |||
| 274e4fdcce | |||
| 5354d3b9dc | |||
| 560f58a7b3 | |||
| b3697c1e21 | |||
| 051b61b2e8 | |||
| fc229fb645 | |||
| 93517d90ec | |||
| 0611e373b8 | |||
| cadaf368ef | |||
| ddcd9cb0c1 | |||
| d00158fa38 | |||
| 4a6dfc9a2a | |||
| e0829ffecf | |||
| 02ce0c993d | |||
| ac3eaea3f6 | |||
| 891af745bb | |||
| 3e49e78dfe | |||
| c67dcb1d5c | |||
| 0208edb9ed | |||
| 7f966b0a24 | |||
| b6f398bd2b | |||
| cb096a1d9b | |||
| 9913ff67ca | |||
| 9f4b274985 | |||
| 6903ccb3a6 | |||
| 020fbf33e5 | |||
| a7b8cc6307 | |||
| 1e5edd1c4c | |||
| faafc8fdfc | |||
| 75543f9bcf | |||
| 5f158137dd | |||
| e7f281a03d | |||
| 6813b42ae1 | |||
| b20d78c102 | |||
| ec3087efc4 | |||
| bf04562180 | |||
| 2faec8513f | |||
| a8b732abb9 | |||
| fbf90b4efc | |||
| 34aa515344 | |||
| 35f8379d65 | |||
| 9d752286f4 | |||
| 6b854cc9ad | |||
| 58e11f12e1 | |||
| 850c44b12a | |||
| d6a37cbd6b | |||
| f2dee26cdb | |||
| 2ee115a47d | |||
| 849c0be13d | |||
| 9a51c7a3b6 | |||
| e9e083d9ee | |||
| bb871a32fd | |||
| 04811681a3 | |||
| ec3f4cf121 | |||
| e2060a1460 | |||
| 4a70ba0134 | |||
| 630fda3c45 | |||
| 04762b3f7e | |||
| 00b48695f6 | |||
| e996557b51 | |||
| e5faf00df9 | |||
| 4beca9497b | |||
| 049c3918a4 | |||
| d71286b265 | |||
| 80eb9aa036 | |||
| 70813984be | |||
| f904ca8f11 | |||
| 068c347178 | |||
| c9f5b2a330 | |||
| 529dc52823 | |||
| b4b4c82e59 | |||
| 276e7ee729 | |||
| 808dfe7d31 | |||
| 88b800415c | |||
| 1679b6b406 | |||
| 748cc495be | |||
| c3ad6ae8cb | |||
| da44e67d65 | |||
| 70be5ae184 | |||
| fe260a6a06 | |||
| 631afde7b6 | |||
| 7a6e4d5f2c | |||
| 8683273022 | |||
| 2c9f691d8e | |||
| 398a804b41 | |||
| 79ffa3e29a | |||
| db0319bfba | |||
| 747ad313e6 | |||
| 4f5b7be7b8 | |||
| e3b9576a2d | |||
| 0dcd74388f | |||
| 302f99172f | |||
| 05adb5ee84 | |||
| 013f63b52f | |||
| 640c28a260 | |||
| 2c06dfb553 | |||
| 63ae52d99c | |||
| 03026a84c7 | |||
| fd33e4c3d4 | |||
| 4606b3980c | |||
| be6affb2c6 | |||
| b75fc89011 | |||
| 5849309dad | |||
| 02dd9aca32 | |||
| 4c4905e60b | |||
| c63251b832 | |||
| 808ade6e8d | |||
| 73fb523b3d | |||
| 0c56b55c2a | |||
| e66b56af58 | |||
| a718aa9c69 | |||
| 49749b3f59 | |||
| 045c6bfc9f | |||
| 91a6f20dba | |||
| 4eb5c97725 | |||
| 978b230f00 | |||
| 9d2632106c | |||
| dd73415c00 | |||
| f0635ba323 | |||
| 38205b3b97 | |||
| ae7306a3ef | |||
| 5448216e7a | |||
| 4f111a710d | |||
| f5df39a971 | |||
| 1866257ff5 | |||
| 8d9fbbf7e9 | |||
| bcd87dfa6d | |||
| 653aca500f | |||
| ca36fd35a6 | |||
| 260b2ad5c9 | |||
| 230413a5cc | |||
| d9618472cb | |||
| 9d96789302 | |||
| 0a69979417 | |||
| ce21c72f37 | |||
| b4ade5e956 | |||
| c79f387af2 | |||
| 9171a62979 | |||
| 793704c111 | |||
| 0cb5c8ca94 | |||
| ca5f50586b | |||
| 6f09c10bd7 | |||
| 8205f33ec6 | |||
| 5360c577af | |||
| ea48fcac64 | |||
| fbc639030a | |||
| eef042b469 | |||
| d34bf1ee7d | |||
| 6987f4be83 | |||
| 1b443af123 | |||
| aa100c2383 | |||
| e3541d78ce | |||
| c0b973370c | |||
| 129419df9d | |||
| ac635c4b38 | |||
| f05f7168ac | |||
| 21a5c25760 | |||
| 756b44db5e | |||
| 38538ca358 | |||
| e22b019147 | |||
| 39fab36541 | |||
| b96a1dcefc | |||
| 4ab56202f0 | |||
| 9baa6e3c85 | |||
| 300b4582ec | |||
| 3cdd9b6af2 | |||
| 355d71769a | |||
| 851f785f50 | |||
| c462dbb745 | |||
| 5706fea2eb | |||
| c403951050 | |||
| 214e425796 | |||
| 2ea2c037e8 | |||
| a20ed9c876 | |||
| d995cc01bc | |||
| 3643693bde | |||
| 928c3ea3c2 | |||
| 779b07b1b5 | |||
| 2aea40d26f | |||
| 7a2a05063b | |||
| fa58ac7419 | |||
| 44ad83790d | |||
| 48ede05926 | |||
| 50ef2e83ce | |||
| 1be72c87f2 | |||
| 961b76fd1e | |||
| bc6a82a7fe | |||
| 1ac81b8f17 | |||
| 79e556ac80 | |||
| 50fdea4095 |
@@ -93,6 +93,7 @@ namespace IRaCIS.Api.Controllers
|
||||
[FromServices] ITokenService _tokenService, [FromServices] IConfiguration configuration)
|
||||
{
|
||||
|
||||
|
||||
var returnModel = await _userService.Login(loginUser.UserName, loginUser.Password);
|
||||
|
||||
if (returnModel.IsSuccess)
|
||||
@@ -160,6 +161,17 @@ namespace IRaCIS.Api.Controllers
|
||||
|
||||
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(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);
|
||||
|
||||
}
|
||||
|
||||
var userId = returnModel.Data.BasicInfo.Id.ToString();
|
||||
@@ -205,6 +217,8 @@ namespace IRaCIS.Api.Controllers
|
||||
|
||||
var token = decodeUrl.Substring(decodeUrl.IndexOf("access_token=") + "access_token=".Length);
|
||||
|
||||
var lang = decodeUrl.Substring(decodeUrl.IndexOf("lang=") + "lang=".Length, 2);
|
||||
|
||||
var domainStrList = decodeUrl.Split("/").ToList().Take(3).ToList();
|
||||
|
||||
var errorUrl = domainStrList[0]+"//"+ domainStrList[2]+ "/error";
|
||||
@@ -212,7 +226,7 @@ namespace IRaCIS.Api.Controllers
|
||||
|
||||
if (!await _userRepository.AnyAsync(t => t.Id == Guid.Parse(userId) && t.EmailToken == token && t.IsFirstAdd))
|
||||
{
|
||||
decodeUrl = errorUrl+ $"?ErrorMessage={System.Web.HttpUtility.UrlEncode("您的初始化链接已过期")} ";
|
||||
decodeUrl = errorUrl+ $"?lang={lang}&ErrorMessage={System.Web.HttpUtility.UrlEncode(lang=="zh"? "您的初始化链接已过期": "Error!The initialization link has expired. Return")} ";
|
||||
}
|
||||
|
||||
return Redirect(decodeUrl);
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace IRaCIS.Core.API.Controllers.Special
|
||||
/// <param name="param"></param>
|
||||
/// <returns>新记录Id</returns>
|
||||
[HttpPost, Route("trial/addOrUpdateTrial")]
|
||||
[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AddOrUpdateTrial", "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })]
|
||||
public async Task<IResponseOutput<Trial>> AddOrUpdateTrial(TrialCommand param)
|
||||
|
||||
@@ -11,6 +11,7 @@ using IRaCIS.Core.Application.Service;
|
||||
using IRaCIS.Core.Application.Service.Inspection.DTO;
|
||||
using IRaCIS.Core.Application.Service.Inspection.Interface;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Application.Service.Reading.Interface;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
@@ -36,6 +37,7 @@ namespace IRaCIS.Core.API.Controllers
|
||||
private readonly IHttpContextAccessor _httpContext;
|
||||
private readonly ITrialConfigService _trialConfigService;
|
||||
private readonly INoneDicomStudyService _noneDicomStudyService;
|
||||
private readonly IClinicalAnswerService _clinicalAnswerService;
|
||||
private readonly ISubjectService _subjectService;
|
||||
private readonly IReadingClinicalDataService _readingClinicalDataService;
|
||||
private readonly ISubjectVisitService _subjectVisitService;
|
||||
@@ -62,6 +64,7 @@ namespace IRaCIS.Core.API.Controllers
|
||||
IReadingMedicineQuestionService readingMedicineQuestionService,
|
||||
ITrialConfigService _trialConfigService,
|
||||
INoneDicomStudyService noneDicomStudyService,
|
||||
IClinicalAnswerService clinicalAnswerService,
|
||||
ISubjectService _subjectService,
|
||||
IReadingClinicalDataService _readingClinicalDataService,
|
||||
ISubjectVisitService subjectVisitService,
|
||||
@@ -82,6 +85,7 @@ namespace IRaCIS.Core.API.Controllers
|
||||
this._httpContext = httpContext;
|
||||
this._trialConfigService = _trialConfigService;
|
||||
this._noneDicomStudyService = noneDicomStudyService;
|
||||
this._clinicalAnswerService = clinicalAnswerService;
|
||||
this._subjectService = _subjectService;
|
||||
this._readingClinicalDataService = _readingClinicalDataService;
|
||||
this._subjectVisitService = subjectVisitService;
|
||||
@@ -233,6 +237,94 @@ namespace IRaCIS.Core.API.Controllers
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// CRC签名临床数据
|
||||
/// </summary>
|
||||
/// <param name="opt"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost, Route("Inspection/ClinicalAnswer/CRCSignClinicalData")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
|
||||
[UnitOfWork]
|
||||
public async Task<IResponseOutput> CRCSignClinicalData(DataInspectionDto<CRCSignClinicalDataInDto> opt)
|
||||
{
|
||||
var singid = await _inspectionService.RecordSing(opt.SignInfo);
|
||||
var result = await _clinicalAnswerService.CRCSignClinicalData(opt.Data);
|
||||
await _inspectionService.CompletedSign(singid, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// CRC确认临床数据
|
||||
/// </summary>
|
||||
/// <param name="opt"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost, Route("Inspection/ClinicalAnswer/CRCConfirmClinical")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
|
||||
[UnitOfWork]
|
||||
public async Task<IResponseOutput> CRCConfirmClinical(DataInspectionDto<CRCConfirmClinicalInDto> opt)
|
||||
{
|
||||
var singid = await _inspectionService.RecordSing(opt.SignInfo);
|
||||
var result = await _clinicalAnswerService.CRCConfirmClinical(opt.Data);
|
||||
await _inspectionService.CompletedSign(singid, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CRC撤销临床数据
|
||||
/// </summary>
|
||||
/// <param name="opt"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost, Route("Inspection/ClinicalAnswer/CRCCancelConfirmClinical")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
|
||||
[UnitOfWork]
|
||||
public async Task<IResponseOutput> CRCCancelConfirmClinical(DataInspectionDto<CRCCancelConfirmClinicalInDto> opt)
|
||||
{
|
||||
var singid = await _inspectionService.RecordSing(opt.SignInfo);
|
||||
var result = await _clinicalAnswerService.CRCCancelConfirmClinical(opt.Data);
|
||||
await _inspectionService.CompletedSign(singid, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// PM确认临床数据
|
||||
/// </summary>
|
||||
/// <param name="opt"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost, Route("Inspection/ClinicalAnswer/PMConfirmClinical")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
|
||||
[UnitOfWork]
|
||||
public async Task<IResponseOutput> PMConfirmClinical(DataInspectionDto<CRCConfirmClinicalInDto> opt)
|
||||
{
|
||||
var singid = await _inspectionService.RecordSing(opt.SignInfo);
|
||||
var result = await _clinicalAnswerService.PMConfirmClinical(opt.Data);
|
||||
await _inspectionService.CompletedSign(singid, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 提交结构化录入并签名
|
||||
/// </summary>
|
||||
/// <param name="opt"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost, Route("Inspection/ClinicalAnswer/SubmitClinicalFormAndSign")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
|
||||
[UnitOfWork]
|
||||
public async Task<IResponseOutput> SubmitClinicalFormAndSign(DataInspectionDto<SubmitClinicalFormInDto> opt)
|
||||
{
|
||||
var singid = await _inspectionService.RecordSing(opt.SignInfo);
|
||||
var result = await _clinicalAnswerService.SubmitClinicalForm(opt.Data);
|
||||
await _inspectionService.CompletedSign(singid, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交阅片裁判问题
|
||||
/// </summary>
|
||||
|
||||
@@ -227,6 +227,8 @@ namespace IRaCIS.Core.API.Controllers
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpPost, Route("Study/PreArchiveStudy")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
public async Task<IResponseOutput> PreArchiveStudy(PreArchiveStudyCommand preArchiveStudyCommand,
|
||||
@@ -262,6 +264,12 @@ namespace IRaCIS.Core.API.Controllers
|
||||
}
|
||||
|
||||
|
||||
//public string UploadOOSTest(string filePath, string route)
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>Dicom 归档</summary>
|
||||
[HttpPost, Route("Study/ArchiveStudy")]
|
||||
[DisableFormValueModelBinding]
|
||||
@@ -446,7 +454,7 @@ namespace IRaCIS.Core.API.Controllers
|
||||
/// <returns></returns>
|
||||
[HttpPost("ClinicalData/UploadVisitClinicalData/{trialId:guid}/{subjectVisitId:guid}")]
|
||||
[DisableRequestSizeLimit]
|
||||
[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
|
||||
public async Task<IResponseOutput> UploadVisitClinicalData(Guid subjectVisitId)
|
||||
@@ -684,7 +692,7 @@ namespace IRaCIS.Core.API.Controllers
|
||||
[RequestSizeLimit(1_073_741_824)]
|
||||
[HttpPost("NoneDicomStudy/UploadNoneDicomFile/{trialId:guid}/{subjectVisitId:guid}/{noneDicomStudyId:guid}/{studyMonitorId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
public async Task<IResponseOutput> UploadNoneDicomFile(IFormCollection formCollection, Guid subjectVisitId, Guid noneDicomStudyId, Guid studyMonitorId,
|
||||
[FromServices] IRepository<NoneDicomStudy> _noneDicomStudyRepository, [FromServices] IRepository<StudyMonitor> _studyMonitorRepository)
|
||||
{
|
||||
@@ -741,7 +749,7 @@ namespace IRaCIS.Core.API.Controllers
|
||||
/// <returns></returns>
|
||||
[HttpPost("QCOperation/UploadVisitCheckExcel/{trialId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
public async Task<IResponseOutput> UploadVisitCheckExcel(Guid trialId)
|
||||
{
|
||||
|
||||
|
||||
@@ -86,6 +86,8 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.10" />
|
||||
<PackageReference Include="Quartz.Extensions.DependencyInjection" Version="3.6.2" />
|
||||
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.6.2" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="6.0.1" />
|
||||
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="1.2.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Email" Version="2.4.0" />
|
||||
@@ -115,12 +117,6 @@
|
||||
<Content Update="wwwroot\EmailTemplate\AdminResetUser.html">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\EmailTemplate\EmailConfigTest_US.html">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\EmailTemplate\EmailConfigTest.html">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\EmailTemplate\SubjectEnrollConfirmOrPDProgress_US.html">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
||||
@@ -139,6 +139,41 @@
|
||||
<param name="opt"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.CRCSignClinicalData(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.CRCSignClinicalDataInDto})">
|
||||
<summary>
|
||||
CRC签名临床数据
|
||||
</summary>
|
||||
<param name="opt"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.CRCConfirmClinical(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.CRCConfirmClinicalInDto})">
|
||||
<summary>
|
||||
CRC确认临床数据
|
||||
</summary>
|
||||
<param name="opt"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.CRCCancelConfirmClinical(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.CRCCancelConfirmClinicalInDto})">
|
||||
<summary>
|
||||
CRC撤销临床数据
|
||||
</summary>
|
||||
<param name="opt"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.PMConfirmClinical(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.CRCConfirmClinicalInDto})">
|
||||
<summary>
|
||||
PM确认临床数据
|
||||
</summary>
|
||||
<param name="opt"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.SubmitClinicalFormAndSign(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.SubmitClinicalFormInDto})">
|
||||
<summary>
|
||||
提交结构化录入并签名
|
||||
</summary>
|
||||
<param name="opt"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.SubmitJudgeVisitTaskResult(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.SaveJudgeVisitTaskResult})">
|
||||
<summary>
|
||||
提交阅片裁判问题
|
||||
|
||||
+15
-45
@@ -11,6 +11,8 @@ using MassTransit;
|
||||
using MassTransit.NewIdProviders;
|
||||
using System.IO;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
|
||||
namespace IRaCIS.Core.API
|
||||
{
|
||||
@@ -64,13 +66,11 @@ namespace IRaCIS.Core.API
|
||||
//缓存项目的状态 匿名化数据
|
||||
await InitCache(host);
|
||||
|
||||
WatchJsonFile(Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, StaticData.En_US_Json) );
|
||||
|
||||
WatchJsonFile(Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, StaticData.Zh_CN_Json));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
host.Run();
|
||||
|
||||
|
||||
@@ -100,58 +100,28 @@ namespace IRaCIS.Core.API
|
||||
webBuilder.UseStartup<Startup>();
|
||||
}).UseSerilog()
|
||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
|
||||
|
||||
|
||||
|
||||
private static async Task InitCache(IHost host)
|
||||
{
|
||||
var _repository = host.Services.GetService(typeof(IRepository)) as IRepository;
|
||||
|
||||
//初始化 国际化数据,并且监测国际化文件变更
|
||||
await InternationalizationHelper.InitInternationlizationDataAndWatchJsonFileAsync(_repository);
|
||||
|
||||
var _mediator = host.Services.GetService(typeof(IMediator)) as IMediator;
|
||||
|
||||
await _mediator.Send(new AnonymizeCacheRequest());
|
||||
|
||||
await _mediator.Send(new TrialStateCacheRequest());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void LoadJsonFile(string filePath)
|
||||
{
|
||||
|
||||
IConfigurationBuilder builder = new ConfigurationBuilder()
|
||||
.AddJsonFile(filePath);
|
||||
|
||||
IConfigurationRoot enConfiguration = builder.Build();
|
||||
|
||||
|
||||
|
||||
foreach (IConfigurationSection section in enConfiguration.GetChildren())
|
||||
{
|
||||
if (filePath.Contains(StaticData.En_US_Json) )
|
||||
{
|
||||
StaticData.En_US_Dic[section.Key] = section.Value;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
StaticData.Zh_CN_Dic[section.Key] = section.Value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
public static void WatchJsonFile(string filePath)
|
||||
{
|
||||
LoadJsonFile(filePath);
|
||||
|
||||
|
||||
FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(filePath), Path.GetFileName(filePath));
|
||||
watcher.Changed += (sender, e) => LoadJsonFile(filePath);
|
||||
watcher.EnableRaisingEvents = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,14 @@
|
||||
"ASPNETCORE_ENVIRONMENT": "CertificateApply"
|
||||
},
|
||||
"applicationUrl": "http://localhost:6400"
|
||||
},
|
||||
"IRaCIS.CenterImageDev": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "CenterImageDev"
|
||||
},
|
||||
"applicationUrl": "http://localhost:6500"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,7 +114,7 @@ namespace IRaCIS.Core.API
|
||||
//services.AddDistributedMemoryCache();
|
||||
|
||||
// hangfire 定时任务框架 有界面,更友好~
|
||||
services.AddhangfireSetup(_configuration);
|
||||
//services.AddhangfireSetup(_configuration);
|
||||
// QuartZ 定时任务框架 使用了hangfire 暂时不用,后续需要可以打开,已经配好
|
||||
services.AddQuartZSetup(_configuration);
|
||||
|
||||
@@ -136,7 +136,7 @@ namespace IRaCIS.Core.API
|
||||
//IP 限流 可设置白名单 或者黑名单
|
||||
//services.AddIpPolicyRateLimitSetup(_configuration);
|
||||
// 用户类型 策略授权
|
||||
services.AddAuthorizationPolicySetup(_configuration);
|
||||
//services.AddAuthorizationPolicySetup(_configuration);
|
||||
|
||||
services.AddJsonConfigSetup(_configuration);
|
||||
//转发头设置 获取真实IP
|
||||
@@ -181,7 +181,7 @@ namespace IRaCIS.Core.API
|
||||
app.UseLogDashboard("/LogDashboard");
|
||||
|
||||
//hangfire
|
||||
app.UseHangfireConfig(env);
|
||||
//app.UseHangfireConfig(env);
|
||||
|
||||
////暂时废弃
|
||||
//app.UseHttpReports();
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace IRaCIS.Core.API
|
||||
triggerOptions.AddTrigger<AddSubjectTrigger>();
|
||||
triggerOptions.AddTrigger<ChallengeStateTrigger>();
|
||||
triggerOptions.AddTrigger<SubjectStateTrigger>();
|
||||
triggerOptions.AddTrigger<AddCRCCliniaclDataTrigger>();
|
||||
triggerOptions.AddTrigger<SubjectVisitCheckPassedTrigger>();
|
||||
triggerOptions.AddTrigger<SubjectVisitFinalVisitTrigger>();
|
||||
triggerOptions.AddTrigger<SubjectVisitTrigger>();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
|
||||
using IRaCIS.Application.Services.BackGroundJob;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Quartz;
|
||||
|
||||
namespace IRaCIS.Core.API
|
||||
{
|
||||
@@ -8,37 +10,35 @@ namespace IRaCIS.Core.API
|
||||
{
|
||||
public static void AddQuartZSetup(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
//services.AddTransient<CacheTrialStatusQuartZJob>();
|
||||
services.AddTransient<CacheTrialStatusQuartZJob>();
|
||||
|
||||
//services.AddQuartz(q =>
|
||||
//{
|
||||
// // base quartz scheduler, job and trigger configuration
|
||||
services.AddQuartz(q =>
|
||||
{
|
||||
// base quartz scheduler, job and trigger configuration
|
||||
|
||||
// // as of 3.3.2 this also injects scoped services (like EF DbContext) without problems
|
||||
// q.UseMicrosoftDependencyInjectionJobFactory();
|
||||
// as of 3.3.2 this also injects scoped services (like EF DbContext) without problems
|
||||
q.UseMicrosoftDependencyInjectionJobFactory();
|
||||
|
||||
// // 基本Quartz调度器、作业和触发器配置
|
||||
// var jobKey = new JobKey("RegularTrialWork", "regularWorkGroup");
|
||||
// q.AddJob<CacheTrialStatusQuartZJob>(jobKey, j => j
|
||||
// .WithDescription("Trial regular work")
|
||||
// );
|
||||
// q.AddTrigger(t => t
|
||||
// .WithIdentity("TrialStatusTrigger")
|
||||
// .ForJob(jobKey)
|
||||
// //.StartNow()
|
||||
// //.WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromSeconds(15))//开始秒数 15s
|
||||
// // .RepeatForever())//持续工作
|
||||
// .WithCronSchedule("0 0 0/2 * * ?")//每小时执行一次
|
||||
// .WithDescription("My regular trial work trigger")
|
||||
// );
|
||||
//});
|
||||
// 基本Quartz调度器、作业和触发器配置
|
||||
var jobKey = new JobKey("RegularTrialWork", "regularWorkGroup");
|
||||
q.AddJob<CacheTrialStatusQuartZJob>(jobKey, j => j
|
||||
.WithDescription("Trial regular work")
|
||||
);
|
||||
q.AddTrigger(t => t
|
||||
.WithIdentity("TrialStatusTrigger")
|
||||
.ForJob(jobKey)
|
||||
|
||||
.WithCronSchedule("0 0 * * * ?")
|
||||
.WithDescription("My regular trial work trigger")
|
||||
);
|
||||
});
|
||||
|
||||
//// ASP.NET Core hosting
|
||||
//services.AddQuartzServer(options =>
|
||||
//{
|
||||
// // when shutting down we want jobs to complete gracefully
|
||||
// options.WaitForJobsToComplete = true;
|
||||
//});
|
||||
// ASP.NET Core hosting
|
||||
services.AddQuartzHostedService(options =>
|
||||
{
|
||||
// when shutting down we want jobs to complete gracefully
|
||||
options.WaitForJobsToComplete = true;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=CenterImage_Test;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true"
|
||||
},
|
||||
"BasicSystemConfig": {
|
||||
|
||||
"OpenUserComplexPassword": false,
|
||||
|
||||
"OpenSignDocumentBeforeWork": false,
|
||||
|
||||
"OpenTrialRelationDelete": true,
|
||||
|
||||
"OpenLoginLimit": false,
|
||||
|
||||
"LoginMaxFailCount": 5,
|
||||
|
||||
"LoginFailLockMinutes": 30
|
||||
},
|
||||
|
||||
"SystemEmailSendConfig": {
|
||||
"Port": 465,
|
||||
"Host": "smtp.qiye.aliyun.com",
|
||||
"FromEmail": "test@extimaging.com",
|
||||
"FromName": "Test_IRC",
|
||||
"AuthorizationCode": "SHzyyl2021"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,10 +7,17 @@
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=IRaCIS_New_Tet;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true",
|
||||
"RemoteNew": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=Test.IRC;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=Hangfire_IRaCIS;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true"
|
||||
|
||||
},
|
||||
|
||||
"AliyunOSS": {
|
||||
"endpoint": "https://zyypacs-code.oss-cn-shanghai.aliyuncs.com",
|
||||
"accessKeyId": "mpXG7Nu6zTpsDrI1",
|
||||
"accessKeySecret": "yNINcEb099SkNfF6vYKaoP8TZNI3xZ",
|
||||
"bucketName": "zyypacs-code"
|
||||
},
|
||||
"BasicSystemConfig": {
|
||||
|
||||
"OpenUserComplexPassword": false,
|
||||
@@ -19,7 +26,11 @@
|
||||
|
||||
"OpenTrialRelationDelete": true,
|
||||
|
||||
"OpenLoginLimit": false
|
||||
"OpenLoginLimit": false,
|
||||
|
||||
"LoginMaxFailCount": 5,
|
||||
|
||||
"LoginFailLockMinutes":1
|
||||
},
|
||||
|
||||
"SystemEmailSendConfig": {
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
|
||||
"OpenSignDocumentBeforeWork": true,
|
||||
|
||||
"OpenLoginLimit": true
|
||||
"OpenLoginLimit": true,
|
||||
"LoginMaxFailCount": 5,
|
||||
|
||||
"LoginFailLockMinutes": 30
|
||||
},
|
||||
//"SystemEmailSendConfig": {
|
||||
// "Port": 465,
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
|
||||
"OpenSignDocumentBeforeWork": true,
|
||||
|
||||
"OpenLoginLimit": true
|
||||
"OpenLoginLimit": true,
|
||||
"LoginMaxFailCount": 5,
|
||||
|
||||
"LoginFailLockMinutes": 30
|
||||
|
||||
},
|
||||
"SystemEmailSendConfig": {
|
||||
|
||||
@@ -19,7 +19,11 @@
|
||||
|
||||
"OpenTrialRelationDelete": true,
|
||||
|
||||
"OpenLoginLimit": false
|
||||
"OpenLoginLimit": false,
|
||||
|
||||
"LoginMaxFailCount": 5,
|
||||
|
||||
"LoginFailLockMinutes": 30
|
||||
},
|
||||
|
||||
"SystemEmailSendConfig": {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -32,7 +32,7 @@
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>祝您顺利!/Best Regards</div>
|
||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
||||
<div style="font-size: 14px;">展影医疗</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,35 +4,35 @@
|
||||
<meta charset='UTF-8'>
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||
<body style='font-family: Times New Roman;padding: 0;margin: 0;'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6;font-size: 16px'>
|
||||
<div style='padding-top: 20px;'>
|
||||
<div style='line-height: 40px;font-size: 18px'>
|
||||
<div style='line-height: 40px;font-size: 16px'>
|
||||
Dear {0} ,
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
Extimaging has added an account for you. The account information is as follows:
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
Extensive Imaging has generated a user account for you. <br>The account information is as follows:
|
||||
</div>
|
||||
<span style="color: #00D1B2"></span>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
|
||||
<div>
|
||||
User name: {1}
|
||||
User ID: {1}
|
||||
</div>
|
||||
<div>
|
||||
Role: {2}
|
||||
</div>
|
||||
<div>
|
||||
Before logging in for the first time, please modify your account information by this link:
|
||||
<a href='{3}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||
Initialize the account information
|
||||
Before logging in for the first time, please initialize your account information through this link:
|
||||
<a href='{3}' style='margin-left:30px;font-size:12px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;font-size: 16px'>
|
||||
Initialize Account Information
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best Regards</div>
|
||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
||||
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best regards,</div>
|
||||
<div style="font-size: 16px;">Extensive Imaging</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>祝您顺利!/Best Regards</div>
|
||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
||||
<div style="font-size: 14px;">展影医疗</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
<meta charset='UTF-8'>
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||
<body style='font-family: Times New Roman;padding: 0;margin: 0;'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6;font-size: 16px'>
|
||||
<div style='padding-top: 20px;'>
|
||||
<div style='line-height: 40px;font-size: 18px'>
|
||||
<div style='line-height: 40px;font-size: 16px'>
|
||||
Dear {0} ,
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
Extimaging has reset your account password, and the account information is as follows:
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
Extensive Imaging has reset your password.<br>The account information is as follows:
|
||||
</div>
|
||||
<span style="color: #00D1B2"></span>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 12px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
|
||||
<div>
|
||||
User name: {1}
|
||||
User ID: {1}
|
||||
</div>
|
||||
<div>
|
||||
Role: {2}
|
||||
@@ -27,9 +27,9 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best Regards</div>
|
||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
||||
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best regards,</div>
|
||||
<div style="font-size: 16px;">Extensive Imaging</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||
<div style='padding-top: 20px;'>
|
||||
<div style='line-height: 40px;font-size: 18px'>
|
||||
您好:
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
感谢您使用展影云平台。
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
{0}。
|
||||
</div>
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>祝您顺利!/Best Regards</div>
|
||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,27 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||
<div style='padding-top: 20px;'>
|
||||
<div style='line-height: 40px;font-size: 18px'>
|
||||
Dear:
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
Thank you for using Extensive Imaging Cloud System.
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
{0}。
|
||||
</div>
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best Regards</div>
|
||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>祝您顺利!/Best Regards</div>
|
||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
||||
<div style="font-size: 14px;">展影医疗</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
<meta charset='UTF-8'>
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||
<body style='font-family: Times New Roman;padding: 0;margin: 0;font-size: 16px'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6;font-size: 16px'>
|
||||
<div style='padding-top: 20px;'>
|
||||
<div style='line-height: 40px;font-size: 18px'>
|
||||
Dear:
|
||||
<div style='line-height: 40px;font-size: 16px'>
|
||||
Dear Sir or Madam:
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
Thank you for using Extensive Imaging Cloud System.
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
Thank you for using our IRC imaging system.
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
{0}。
|
||||
</div>
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best Regards</div>
|
||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
||||
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best regards,</div>
|
||||
<div style="font-size: 16px;">Extensive Imaging</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
尊敬的 {0} ,您好:
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
展影医疗作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC阅片相关工作,欢迎您提供指导和建议,非常感谢!
|
||||
展影医疗作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC阅片相关工作。
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
该项目采用电子化工作流,系统及您的账号信息如下:
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>祝您顺利!/Best Regards</div>
|
||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
||||
<div style="font-size: 14px;">展影医疗</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,20 +4,20 @@
|
||||
<meta charset='UTF-8'>
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
||||
<body style='font-family: Times New Roman;padding: 0;margin: 0;'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||
<div style='padding-top: 20px;'>
|
||||
<div style='line-height: 40px;font-size: 18px'>
|
||||
<div style='line-height: 40px;font-size: 16px'>
|
||||
Dear {0},
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
Hello, as the IRC supplier of [ {1} (Protocol ID is {2}) ] project,Extiming sincerely invites you to participate in the IRC related work of this project. Your guidance and suggestions are welcome.
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
As the IRC service provider of {1} trial(Protocol ID is {2}), Extensive Imaging invites you to participate in the independent assessment work of this trial.
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
This project adopts electronic workflow. The system and your account information are as follows:
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
Digital workflow is implemented for this trial, and your account information is as follows:
|
||||
</div>
|
||||
<span style="color: #00D1B2"></span>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
|
||||
<div>
|
||||
Trial ID: {3}
|
||||
</div>
|
||||
@@ -25,23 +25,22 @@
|
||||
Protocol ID: {2}
|
||||
</div>
|
||||
<div>
|
||||
Study name: {1}
|
||||
Study Name: {1}
|
||||
</div>
|
||||
<div>
|
||||
User name: {4}
|
||||
User Name: {4}
|
||||
</div>
|
||||
<div>
|
||||
Role: {5}
|
||||
</div>
|
||||
<div>
|
||||
System login address:{6}
|
||||
Login URL: {6}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best Regards</div>
|
||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
||||
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best regards,</div>
|
||||
<div style="font-size: 16px;">Extensive Imaging</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>祝您顺利!/Best Regards</div>
|
||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
||||
<div style="font-size: 14px;">展影医疗</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,20 +4,21 @@
|
||||
<meta charset='UTF-8'>
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
||||
<body style='font-family: Times New Roman;padding: 0;margin: 0;'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||
<div style='padding-top: 20px;'>
|
||||
<div style='line-height: 40px;font-size: 18px'>
|
||||
<div style='line-height: 40px;font-size: 16px'>
|
||||
Dear {0},
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
Hello, as the IRC supplier of [ {1} (Protocol ID is {2}) ] project,Extiming sincerely invites you to participate in the IRC related work of this project. Your guidance and suggestions are welcome.
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
As the IRC service provider of {1}trial (Protocol ID is {2}), Extensive Imaging invites you to participate in the independent assessment work of this trial.
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
This project adopts electronic workflow. The system and your account information are as follows:
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
Digital workflow is implemented for this trial, and your account information is as follows:
|
||||
</div>
|
||||
<span style="color: #00D1B2"></span>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
|
||||
<div>
|
||||
Trial ID: {3}
|
||||
</div>
|
||||
@@ -25,26 +26,26 @@
|
||||
Protocol ID: {2}
|
||||
</div>
|
||||
<div>
|
||||
Study name: {1}
|
||||
Study Name: {1}
|
||||
</div>
|
||||
<div>
|
||||
User name: {4}
|
||||
User ID: {4}
|
||||
</div>
|
||||
<div>
|
||||
Role: {5}
|
||||
</div>
|
||||
<div>
|
||||
Before logging in for the first time, please modify your account information by this link:
|
||||
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||
Initialize the account information
|
||||
Before logging in for the first time, please modify your account information through this link:
|
||||
<a href='{6}' style='margin-left:30px;font-size:16px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||
Initialize Account Information
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best Regards</div>
|
||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;font-size: 16px'>
|
||||
<div>Best regards,</div>
|
||||
<div style="font-size: 16px;">Extensive Imaging</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>祝您顺利!/Best Regards</div>
|
||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
||||
<div style="font-size: 14px;">展影医疗</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
<meta charset='UTF-8'>
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||
<div style='padding-top: 20px;'>
|
||||
<div style='line-height: 40px;font-size: 18px'>
|
||||
<body style='font-family: Times New Roman;padding: 0;margin: 0;font-size: 16px'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6;font-size: 16px'>
|
||||
<div style='padding-top: 20px;font-size: 16px'>
|
||||
<div style='line-height: 40px;font-size: 16px'>
|
||||
Dear {0} ,
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
Hello, the center survey form you filled in has been rejected. The details are as follows:
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
The site survey questionnaire you filled in has been rejected. Details are as follows:
|
||||
</div>
|
||||
<span style="color: #00D1B2"></span>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
|
||||
<div>
|
||||
Trial ID: {1}
|
||||
</div>
|
||||
@@ -22,26 +22,26 @@
|
||||
Protocol ID: {2}
|
||||
</div>
|
||||
<div>
|
||||
Study name: {3}
|
||||
Study Name: {3}
|
||||
</div>
|
||||
<div>
|
||||
Site ID: {4}
|
||||
</div>
|
||||
<div>
|
||||
Site name: {5}
|
||||
Site Name: {5}
|
||||
</div>
|
||||
<div>
|
||||
Reason for rejection: {6}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<a href='{7}' style='margin-left:60px;font-size:14px;padding: 10px;text-decoration: none;display:{8} ;height: 40px;width: 140px;background: #00D1B2;color:#fff;border-radius: 5px;line-height: 40px;text-align: center;margin-bottom: 100px;'>
|
||||
Login and view
|
||||
<a href='{7}' style='margin-left:60px;font-size:16px;padding: 10px;text-decoration: none;display:{8} ;height: 40px;width: 140px;background: #00D1B2;color:#fff;border-radius: 5px;line-height: 40px;text-align: center;margin-bottom: 100px;font-size: 16px'>
|
||||
Login & View
|
||||
</a>
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best Regards</div>
|
||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
||||
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best regards,</div>
|
||||
<div style="font-size: 16px;">Extensive Imaging</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>祝您顺利!/Best Regards</div>
|
||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
||||
<div style="font-size: 14px;">展影医疗</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,20 +4,20 @@
|
||||
<meta charset='UTF-8'>
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||
<div style='padding-top: 20px;'>
|
||||
<div style='line-height: 40px;font-size: 18px'>
|
||||
<body style='font-family: Times New Roman;padding: 0;margin: 0;font-size: 16px'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6;font-size: 16px'>
|
||||
<div style='padding-top: 20px;font-size: 16px'>
|
||||
<div style='line-height: 40px;font-size: 16px'>
|
||||
Dear {0},
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
Hello, as the IRC supplier of [ {1} (Protocol ID is {2}) ] project,Extiming sincerely invites you to participate in the IRC related work of this project. Your guidance and suggestions are welcome.
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
As the IRC service provider of {1} trial (Protocol ID is {2}), Extensive Imaging invites you to participate in IRC-related work of this trial.
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
This project adopts electronic workflow. The system and your account information are as follows:
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
Digital workflow is implemented for this trial, and your account information is as follows:
|
||||
</div>
|
||||
<span style="color: #00D1B2"></span>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
|
||||
<div>
|
||||
Trial ID: {3}
|
||||
</div>
|
||||
@@ -25,23 +25,23 @@
|
||||
Protocol ID: {2}
|
||||
</div>
|
||||
<div>
|
||||
Study name: {1}
|
||||
Study Name: {1}
|
||||
</div>
|
||||
<div>
|
||||
User name: {4}
|
||||
User Name: {4}
|
||||
</div>
|
||||
<div>
|
||||
Role: {5}
|
||||
</div>
|
||||
<div>
|
||||
System login address:{6}
|
||||
Login URL: {6}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best Regards</div>
|
||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
||||
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best regards,</div>
|
||||
<div style="font-size: 16px;">Extensive Imaging</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
尊敬的 {0} ,您好:
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
展影医疗作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢!
|
||||
展影医疗作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC相关工作。
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
该项目采用电子化工作流,系统及您的账号信息如下:
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>祝您顺利!/Best Regards</div>
|
||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
||||
<div style="font-size: 14px;">展影医疗</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,20 +4,20 @@
|
||||
<meta charset='UTF-8'>
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
||||
<body style='font-family: Times New Roman;padding: 0;margin: 0;font-size: 16px'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||
<div style='padding-top: 20px;'>
|
||||
<div style='line-height: 40px;font-size: 18px'>
|
||||
<div style='line-height: 40px;font-size: 16px'>
|
||||
Dear {0},
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
Hello, as the IRC supplier of [ {1} (Protocol ID is {2}) ] project,Extiming sincerely invites you to participate in the IRC related work of this project. Your guidance and suggestions are welcome.
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
As the IRC service provider of {1} trial (Protocol ID is {2}), Extensive Imaging invites you to participate in IRC-related work of this trial.
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
This project adopts electronic workflow. The system and your account information are as follows:
|
||||
Digital workflow is implemented for this trial, and your account information is as follows:
|
||||
</div>
|
||||
<span style="color: #00D1B2"></span>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
|
||||
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
|
||||
<div>
|
||||
Trial ID: {3}
|
||||
</div>
|
||||
@@ -25,26 +25,26 @@
|
||||
Protocol ID: {2}
|
||||
</div>
|
||||
<div>
|
||||
Study name: {1}
|
||||
Study Name: {1}
|
||||
</div>
|
||||
<div>
|
||||
User name: {4}
|
||||
User Name: {4}
|
||||
</div>
|
||||
<div>
|
||||
Role: {5}
|
||||
</div>
|
||||
<div>
|
||||
Before logging in for the first time, please modify your account information by this link:
|
||||
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||
Initialize the account information
|
||||
Before logging in for the first time, please modify your account information through this link:
|
||||
<a href='{6}' style='margin-left:30px;font-size:16px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
|
||||
Initialize Account Information
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best Regards</div>
|
||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
||||
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best regards,</div>
|
||||
<div style="font-size: 16px;">Extensive Imaging</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,18 +8,18 @@
|
||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||
<div style='padding-top: 20px;'>
|
||||
<div style='line-height: 40px;font-size: 18px'>
|
||||
Dear {0},
|
||||
亲爱的用户 ,
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
感谢您使用展影云平台。
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
{1},验证码是: {2},请在3分钟内输入该验证码,进行后续操作。如非本人操作,请忽略该邮件。
|
||||
{0},验证码是: {1},请在3分钟内输入该验证码,进行后续操作。如非本人操作,请忽略该邮件。
|
||||
</div>
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>祝您顺利!/Best Regards</div>
|
||||
<div style="font-size: 14px;">上海展影医疗科技有限公司</div>
|
||||
<div style="font-size: 14px;">展影医疗</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,23 +4,25 @@
|
||||
<meta charset='UTF-8'>
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
|
||||
<body style='font-family: Times New Roman;padding: 0;margin: 0;'>
|
||||
<div style='padding-left: 40px;background: #f6f6f6'>
|
||||
<div style='padding-top: 20px;'>
|
||||
<div style='line-height: 40px;font-size: 18px'>
|
||||
Dear {0},
|
||||
<div style='line-height: 40px;font-size: 16px'>
|
||||
Dear Sir or Madam:
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
Thank you for using Extensive Imaging Cloud System.
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
Thank you for using our IRC imaging system.
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
|
||||
{1}, the verification code is {2}. Enter the verification code within 3 minutes for subsequent operations. Please ignore this email if not by yourself.
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
{0}, the verification code is {1}. Please enter this code within 3 minutes for follow-up operations.
|
||||
</div>
|
||||
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
|
||||
If you are not the intended person, please ignore this email.
|
||||
</div>
|
||||
|
||||
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
|
||||
<div>Best Regards</div>
|
||||
<div style="font-size: 14px;">Shanghai Extensive Imaging Medical Technology Co., LTD</div>
|
||||
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;font-size: 16px'>
|
||||
<div>Best regards,</div>
|
||||
<div style="font-size: 16px;">Extensive Imaging</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -276,8 +276,10 @@ var abp = abp || {};
|
||||
}
|
||||
|
||||
var password = document.getElementById('password').value;
|
||||
if (!password) {
|
||||
alert('PassWord Can Not Be Null');
|
||||
var pwdMd5 = document.getElementById('pwdMd5').value;
|
||||
console.log(pwdMd5);
|
||||
if (!password && !pwdMd5) {
|
||||
alert('PassWord And Md5 Can Not Be Null');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -321,6 +323,9 @@ var abp = abp || {};
|
||||
UserName: usernameOrEmailAddress,
|
||||
Password: hex_md5(password),
|
||||
}
|
||||
if (pwdMd5 != '') {
|
||||
parm.Password = pwdMd5;
|
||||
}
|
||||
xhr.send(JSON.stringify(parm));
|
||||
//xhr.send("{" + "userName:'" + usernameOrEmailAddress + "'," + "passWord:'" + password + "'}");
|
||||
|
||||
@@ -414,8 +419,9 @@ var abp = abp || {};
|
||||
|
||||
//Inputs
|
||||
createInput(modalUxContent, 'tenancyName', 'Tenancy Name (Leave empty for Host)');
|
||||
createInput(modalUxContent, 'userName', 'Username or email address','text','admin');
|
||||
createInput(modalUxContent, 'password', 'Password','password');
|
||||
createInput(modalUxContent, 'userName', 'Username or email address','text','cyldev');
|
||||
createInput(modalUxContent, 'password', 'Password', 'password', '123456');
|
||||
createInput(modalUxContent, 'pwdMd5', 'PwdMd5', 'text', '');
|
||||
|
||||
//Buttons
|
||||
var authBtnWrapper = document.createElement('div');
|
||||
|
||||
@@ -7,6 +7,7 @@ using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Quartz;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
|
||||
namespace IRaCIS.Application.Services.BackGroundJob
|
||||
{
|
||||
@@ -17,36 +18,55 @@ namespace IRaCIS.Application.Services.BackGroundJob
|
||||
private readonly IRepository<Trial> _trialRepository;
|
||||
private readonly IEasyCachingProvider _provider;
|
||||
private readonly ILogger<CacheTrialStatusQuartZJob> _logger;
|
||||
private readonly IRepository<SystemAnonymization> _systemAnonymizationRepository;
|
||||
|
||||
public CacheTrialStatusQuartZJob(IRepository<Trial> trialRepository, IEasyCachingProvider provider,ILogger<CacheTrialStatusQuartZJob> logger)
|
||||
public CacheTrialStatusQuartZJob(IRepository<Trial> trialRepository, IEasyCachingProvider provider,ILogger<CacheTrialStatusQuartZJob> logger, IRepository<SystemAnonymization> systemAnonymizationRepository)
|
||||
{
|
||||
_trialRepository = trialRepository;
|
||||
_provider = provider;
|
||||
_logger = logger;
|
||||
_systemAnonymizationRepository = systemAnonymizationRepository;
|
||||
}
|
||||
|
||||
public Task Execute(IJobExecutionContext context)
|
||||
public async Task Execute(IJobExecutionContext context)
|
||||
|
||||
{
|
||||
_logger.LogInformation($"开始执行QuartZ定时任务作业");
|
||||
try
|
||||
{
|
||||
var list = _trialRepository.Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr })
|
||||
.ToList();
|
||||
await MemoryCacheTrialStatus();
|
||||
|
||||
await MemoryCacheAnonymizeData();
|
||||
|
||||
list.ForEach(t => _provider.Set(t.TrialId.ToString(), t.TrialStatusStr, TimeSpan.FromDays(1)));
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError($" 查询和缓存过程出现异常"+e.Message);
|
||||
}
|
||||
_logger.LogInformation("QuartZ定时任务作业结束");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public async Task MemoryCacheTrialStatus()
|
||||
{
|
||||
var list = await _trialRepository.Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr })
|
||||
.ToListAsync();
|
||||
|
||||
list.ForEach(t => _provider.Set(t.TrialId.ToString(), t.TrialStatusStr, TimeSpan.FromDays(7)));
|
||||
|
||||
}
|
||||
|
||||
public async Task MemoryCacheAnonymizeData()
|
||||
{
|
||||
var systemAnonymizationList = await _systemAnonymizationRepository.Where(t => t.IsEnable).ToListAsync();
|
||||
|
||||
_provider.Set(StaticData.Anonymize.Anonymize_AddFixedFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed).ToList(), TimeSpan.FromDays(7));
|
||||
_provider.Set(StaticData.Anonymize.Anonymize_AddIRCInfoFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
|
||||
_provider.Set(StaticData.Anonymize.Anonymize_FixedField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed).ToList(), TimeSpan.FromDays(7));
|
||||
_provider.Set(StaticData.Anonymize.Anonymize_IRCInfoField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
using EasyCaching.Core;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@@ -11,9 +14,9 @@ namespace IRaCIS.Core.Application.Filter;
|
||||
|
||||
|
||||
|
||||
public class LimitUserRequestAuthorization :BaseService, IAsyncAuthorizationFilter
|
||||
public class LimitUserRequestAuthorization : IAsyncAuthorizationFilter
|
||||
{
|
||||
|
||||
public IStringLocalizer _localizer { get; set; }
|
||||
|
||||
private readonly IEasyCachingProvider _provider;
|
||||
|
||||
@@ -21,11 +24,12 @@ public class LimitUserRequestAuthorization :BaseService, IAsyncAuthorizationFilt
|
||||
|
||||
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
|
||||
|
||||
public LimitUserRequestAuthorization(IEasyCachingProvider provider, IUserInfo userInfo, IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig)
|
||||
public LimitUserRequestAuthorization(IEasyCachingProvider provider, IUserInfo userInfo, IStringLocalizer localizer ,IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig)
|
||||
{
|
||||
_provider = provider;
|
||||
_userInfo = userInfo;
|
||||
_verifyConfig = verifyConfig;
|
||||
_localizer = localizer;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +53,9 @@ public class LimitUserRequestAuthorization :BaseService, IAsyncAuthorizationFilt
|
||||
context.HttpContext.Response.ContentType = "application/json";
|
||||
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
||||
//---当前请求未从Header/Url取到用户Token,请联系开发者
|
||||
await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["LimitUser_AuthTokenMissing"])));
|
||||
//await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["LimitUser_AuthTokenMissing"])));
|
||||
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["LimitUser_AuthTokenMissing"]));
|
||||
}
|
||||
|
||||
//2、在这里取缓存 进行比较 看是否有其他人进行了登陆,如果其他人登陆了,就把之前用户挤掉
|
||||
@@ -75,8 +81,13 @@ public class LimitUserRequestAuthorization :BaseService, IAsyncAuthorizationFilt
|
||||
|
||||
context.HttpContext.Response.ContentType = "application/json";
|
||||
context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
|
||||
//---您的账户在其他地方已登陆,您被迫下线。
|
||||
await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["LimitUser_AccountLoggedInElsewhere"], ApiResponseCodeEnum.LoginInOtherPlace)));
|
||||
//---您的账户在其他地方已登陆,您被迫下线。
|
||||
|
||||
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["LimitUser_AccountLoggedInElsewhere"], ApiResponseCodeEnum.LoginInOtherPlace));
|
||||
|
||||
|
||||
//await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["LimitUser_AccountLoggedInElsewhere"], ApiResponseCodeEnum.LoginInOtherPlace)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
|
||||
|
||||
using Aliyun.OSS;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Configuration;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace IRaCIS.Core.Application.Helper;
|
||||
@@ -12,6 +14,39 @@ namespace IRaCIS.Core.Application.Helper;
|
||||
public static class FileStoreHelper
|
||||
{
|
||||
|
||||
public static string UploadOOS(string filePath,string route)
|
||||
{
|
||||
var endpoint = ConfigurationManager.AppSettings["AliyunOSS:endpoint"];
|
||||
// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
|
||||
|
||||
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
|
||||
var accessKeyId = ConfigurationManager.AppSettings["AliyunOSS:accessKeyId"];
|
||||
var accessKeySecret = ConfigurationManager.AppSettings["AliyunOSS:accessKeySecret"];
|
||||
// 填写Bucket名称,例如examplebucket。
|
||||
var bucketName = ConfigurationManager.AppSettings["AliyunOSS:bucketName"];
|
||||
// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
|
||||
|
||||
var fileNameList = filePath.Split(',').ToList();
|
||||
var fileName = fileNameList[fileNameList.Count() - 1];
|
||||
|
||||
var objectName = route+ fileName;
|
||||
// 填写本地文件完整路径,例如D:\\localpath\\examplefile.txt。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
|
||||
var localFilename = filePath;
|
||||
// 创建OSSClient实例。
|
||||
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
|
||||
try
|
||||
{
|
||||
// 上传文件。
|
||||
var result = client.PutObject(bucketName, objectName, localFilename);
|
||||
|
||||
return result.ETag;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new BusinessValidationFailedException("上传异常!");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//处理文件名 压缩包,或者目录类的 会带上相对路径
|
||||
public static (string TrustedFileNameForFileStorage, string RealName) GetStoreFileName(string fileName,bool isChangeToPdfFormat=false)
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static BeetleX.Redis.Commands.HSCAN;
|
||||
using static IRaCIS.Core.Application.Service.Common.SystemMonitor;
|
||||
|
||||
namespace IRaCIS.Core.Application.Helper
|
||||
{
|
||||
public static class InternationalizationHelper
|
||||
{
|
||||
public static string JsonFileFolder = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources);
|
||||
|
||||
private static void VerifyFolder()
|
||||
{
|
||||
if (!Directory.Exists(JsonFileFolder) ||
|
||||
!Directory.GetFiles(JsonFileFolder).Any(filePath => Path.GetExtension(filePath).Equals(".json", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
throw new BusinessValidationFailedException("国际化Json文件目录有误");
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task BatchAddJsonKeyValueAsync(List<BatchAddInternationalizationDto> batchAddDtos)
|
||||
{
|
||||
VerifyFolder();
|
||||
|
||||
var usJsonPath = Path.Combine(JsonFileFolder, StaticData.En_US_Json);
|
||||
var cnJsonPath = Path.Combine(JsonFileFolder, StaticData.Zh_CN_Json);
|
||||
|
||||
|
||||
//更新json 文件 同时更新内存缓存的数据
|
||||
foreach (var filePath in new string[] { usJsonPath, cnJsonPath })
|
||||
{
|
||||
var json = await File.ReadAllTextAsync(filePath);
|
||||
|
||||
JObject jsonObject = JObject.Parse(json, new JsonLoadSettings() { CommentHandling = CommentHandling.Load });
|
||||
|
||||
// 添加或更新指定的键值对
|
||||
|
||||
if (filePath.Contains(StaticData.En_US_Json))
|
||||
{
|
||||
foreach (var item in batchAddDtos)
|
||||
{
|
||||
jsonObject[item.Code] = item.Value;
|
||||
|
||||
StaticData.En_US_Dic[item.Code] = item.Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var item in batchAddDtos)
|
||||
{
|
||||
jsonObject[item.Code] = item.Value;
|
||||
|
||||
StaticData.Zh_CN_Dic[item.Code] = item.Value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
await File.WriteAllTextAsync(filePath, jsonObject.ToString());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task AddOrUpdateJsonKeyValueAsync(string key, string value, string valueCN)
|
||||
{
|
||||
|
||||
VerifyFolder();
|
||||
|
||||
var usJsonPath = Path.Combine(JsonFileFolder, StaticData.En_US_Json);
|
||||
var cnJsonPath = Path.Combine(JsonFileFolder, StaticData.Zh_CN_Json);
|
||||
|
||||
|
||||
//更新json 文件 同时更新内存缓存的数据
|
||||
foreach (var filePath in new string[] { usJsonPath, cnJsonPath })
|
||||
{
|
||||
var json = await File.ReadAllTextAsync(filePath);
|
||||
|
||||
JObject jsonObject = JObject.Parse(json, new JsonLoadSettings() { CommentHandling = CommentHandling.Load });
|
||||
|
||||
// 添加或更新指定的键值对
|
||||
|
||||
if (filePath.Contains(StaticData.En_US_Json))
|
||||
{
|
||||
jsonObject[key] = value;
|
||||
|
||||
StaticData.En_US_Dic[key] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonObject[key] = valueCN;
|
||||
|
||||
StaticData.Zh_CN_Dic[key] = valueCN;
|
||||
}
|
||||
|
||||
|
||||
await File.WriteAllTextAsync(filePath, jsonObject.ToString());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static async Task InitInternationlizationDataAndWatchJsonFileAsync(IRepository _repository)
|
||||
{
|
||||
//查询数据库的数据
|
||||
var toJsonList = await _repository.Where<Internationalization>(t => t.InternationalizationType == 1).Select(t => new
|
||||
{
|
||||
t.Code,
|
||||
t.Value,
|
||||
t.ValueCN
|
||||
}).ToListAsync();
|
||||
|
||||
//组织成json 文件
|
||||
|
||||
var usJsonPath = Path.Combine(JsonFileFolder, StaticData.En_US_Json);
|
||||
var cnJsonPath = Path.Combine(JsonFileFolder, StaticData.Zh_CN_Json);
|
||||
|
||||
|
||||
//本地静态文件国际化需要
|
||||
foreach (var tojsonItem in toJsonList)
|
||||
{
|
||||
StaticData.En_US_Dic[tojsonItem.Code] = tojsonItem.Value;
|
||||
StaticData.Zh_CN_Dic[tojsonItem.Code] = tojsonItem.ValueCN;
|
||||
}
|
||||
|
||||
File.WriteAllText(usJsonPath, JsonConvert.SerializeObject(StaticData.En_US_Dic));
|
||||
File.WriteAllText(cnJsonPath, JsonConvert.SerializeObject(StaticData.Zh_CN_Dic));
|
||||
|
||||
|
||||
//监测Json文件变更 实时刷新数据
|
||||
|
||||
WatchJsonFile(usJsonPath);
|
||||
WatchJsonFile(cnJsonPath);
|
||||
|
||||
}
|
||||
|
||||
public static void WatchJsonFile(string filePath)
|
||||
{
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
throw new BusinessValidationFailedException("国际化Json文件不存在");
|
||||
}
|
||||
|
||||
FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(filePath), Path.GetFileName(filePath));
|
||||
watcher.Changed += (sender, e) => LoadJsonFile(filePath);
|
||||
watcher.EnableRaisingEvents = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void LoadJsonFile(string filePath)
|
||||
{
|
||||
|
||||
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath);
|
||||
|
||||
IConfigurationRoot enConfiguration = builder.Build();
|
||||
|
||||
foreach (IConfigurationSection section in enConfiguration.GetChildren())
|
||||
{
|
||||
if (filePath.Contains(StaticData.En_US_Json))
|
||||
{
|
||||
StaticData.En_US_Dic[section.Key] = section.Value;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
StaticData.Zh_CN_Dic[section.Key] = section.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
|
||||
<PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="9.0.0" />
|
||||
<PackageReference Include="BeetleX.BNR" Version="1.0.1" />
|
||||
<PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,7 +39,10 @@
|
||||
|
||||
//-------------------------------------------------------------------------------------Reading-----------------------------------------------------------------
|
||||
//ClinicalDataSetService
|
||||
"ClinicalDataSet_Apply": "",
|
||||
"ClinicalDataSet_DupTypeFail": "The same type of clinical data exists. The operation failed.",
|
||||
//ClinicalQuestionService
|
||||
"ClinicalQuestion_Repeat": "",
|
||||
//ReadingClinicalDataService
|
||||
"ReadingClinicalData_DupTypeFail": "The same type of clinical data exists. The operation failed.",
|
||||
"ReadingClinicalData_Unchecked": "The current clinical data status is not verified and signing is not allowed!",
|
||||
@@ -371,7 +374,7 @@
|
||||
"QCOperation_NoRecipient": "You are not the current recipient of the quality control task, no operation authority!",
|
||||
"QCOperation_QCImageTaskAlreadyReleased": "The image QC of the current visit has been released by the original recipient. You can get it by 'claime'.",
|
||||
"QCOperation_QCTaskNoAccess": "The image quality control task of the current visit has been claimed by other QC, so it is not allowed to claim.",
|
||||
"QCOperation_QCConfigFirst": "Please configure the image QC question before claiming the image QC task.",
|
||||
"QCOperation_QCConfigFirst": "Please configure the image QC questions before claiming any image QC work.",
|
||||
"QCOperation_NoQC": "The trial configuration of image QC was not check, and the QC Task was not be claimed.",
|
||||
"QCOperation_InitialAuditPassed": "The first review has passed, continue to receive can not be allowed.",
|
||||
"QCOperation_NoSingleAudit": "The trial is configured with single image QC , does not meet Submmit State: Submitted or Audit State: pending QC/ in QC, not allowed to collect.Please refresh the page.",
|
||||
@@ -381,8 +384,8 @@
|
||||
"QCOperation_NoQCFunction": "The project configuration of image QC process was not check, so there is no need to cancel the task function.",
|
||||
"QCOperation_NoTaskOwner": "The current visiting image QC has not been claimed by anyone, and cannot been released.",
|
||||
"QCOperation_DiseaseProgressConfirmation": "Current visit required PD Confirmation. Please process the unsubmitted prior visit before submitting the current visit: {0}.",
|
||||
"QCOperation_UnsubmittedVisits": " After submitting the current visit, please as soon as possible process any prior visits that have not been submitted: {0}.",
|
||||
"QCOperation_NoBaselineData": "No clinical data at baseline, confirm to submit?",
|
||||
"QCOperation_UnsubmittedVisits": "After submitting the current visit, please submit any prior visits which have not been submitted as soon as possible. ({0})",
|
||||
"QCOperation_NoBaselineData": "No clinical data at baseline. Confirm to submit?",
|
||||
"QCOperation_NoImageData": "Dicom/ Non-dicom image data has not been uploaded. Submission is not allowed.",
|
||||
"QCOperation_ImagesSubmitted": "The image data of the current visit has been submitted by another CRC.",
|
||||
"QCOperation_BatchImagesSubmitted": "The visit image data is currently submitted in batches, part of which has been submitted by other CRCs.",
|
||||
|
||||
@@ -39,7 +39,10 @@
|
||||
|
||||
// ------------------------------------------------------------Reading--------------------------------------------------------------------
|
||||
//ClinicalDataSetService
|
||||
"ClinicalDataSet_Apply": "当前临床数据需要配置一个检查日期才能应用",
|
||||
"ClinicalDataSet_DupTypeFail": "存在同类型的临床数据,操作失败",
|
||||
//ClinicalQuestionService
|
||||
"ClinicalQuestion_Repeat": "存在相同的问题名称!",
|
||||
//ReadingClinicalDataService
|
||||
"ReadingClinicalData_DupTypeFail": "存在同类型的临床数据,操作失败",
|
||||
"ReadingClinicalData_Unchecked": "当前临床数据状态不是已核查状态,不允许签名!",
|
||||
|
||||
@@ -257,7 +257,7 @@ namespace IRaCIS.Core.Application.ViewModel
|
||||
public Guid SubjectId { get; set; }
|
||||
public string SubjectCode { get; set; } = String.Empty;
|
||||
|
||||
public bool IsUrgent => UnReadTaskList.Any(t => t.IsUrgent);
|
||||
public bool IsUrgent => UnReadCanReadTaskList.Any(t => t.IsUrgent);
|
||||
|
||||
public int UnReadTaskCount { get; set; }
|
||||
|
||||
@@ -271,6 +271,38 @@ namespace IRaCIS.Core.Application.ViewModel
|
||||
|
||||
public DateTime? SuggesteFinishedTime { get; set; }
|
||||
|
||||
public int? UrgentColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.SuggesteFinishedTime != null)
|
||||
{
|
||||
var date = DateTime.Now;
|
||||
var timeSpan = SuggesteFinishedTime.Value- date;
|
||||
if (timeSpan.TotalDays <= 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (timeSpan.TotalDays <= 5)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int UrgentCount => UnReadCanReadTaskList.Count(t => t.IsUrgent);
|
||||
|
||||
public List<IRUnreadTaskView> UnReadCanReadTaskList => UnReadTaskList.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)).ToList();
|
||||
|
||||
public List<IRUnreadTaskView> UnReadTaskList { get; set; } = new List<IRUnreadTaskView>();
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace IRaCIS.Core.Application.Interfaces
|
||||
|
||||
//Task<PageOutput<TaskMedicalReviewView>> GetTaskMedicalReviewList(TaskMedicalReviewQuery queryTaskMedicalReview);
|
||||
|
||||
|
||||
|
||||
Task<TaskMedicalReviewView> GetNextMedicalReviewTask(GetNextMedicalReviewTaskInDto inDto);
|
||||
Task<IResponseOutput<PageOutput<TaskMedicalReviewView>>> GetMIMMedicalReviewTaskList(TaskMedicalReviewQuery inQuery);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.MedicalReviewId).Include(x=>x.VisitTask).FirstNotNullAsync();
|
||||
|
||||
var subjectReview = await GetMIMMedicalReviewTaskList(new TaskMedicalReviewQuery()
|
||||
var subjectReview = (await GetMIMMedicalReviewTaskList(new TaskMedicalReviewQuery()
|
||||
{
|
||||
|
||||
TrialId = medicalReview.TrialId,
|
||||
@@ -148,14 +148,14 @@ namespace IRaCIS.Core.Application.Service
|
||||
TrialReadingCriterionId = medicalReview.VisitTask.TrialReadingCriterionId,
|
||||
PageIndex=1,
|
||||
PageSize=1,
|
||||
});
|
||||
})).Data;
|
||||
|
||||
if (subjectReview.Item1.CurrentPageData.Count == 1)
|
||||
if (subjectReview.CurrentPageData.Count == 1)
|
||||
{
|
||||
return subjectReview.Item1.CurrentPageData[0];
|
||||
return subjectReview.CurrentPageData[0];
|
||||
}
|
||||
|
||||
var data = await GetMIMMedicalReviewTaskList(new TaskMedicalReviewQuery()
|
||||
var data = (await GetMIMMedicalReviewTaskList(new TaskMedicalReviewQuery()
|
||||
{
|
||||
|
||||
TrialId = medicalReview.TrialId,
|
||||
@@ -164,11 +164,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
TrialReadingCriterionId = medicalReview.VisitTask.TrialReadingCriterionId,
|
||||
PageIndex = 1,
|
||||
PageSize = 1,
|
||||
});
|
||||
})).Data;
|
||||
|
||||
if (data.Item1.CurrentPageData.Count == 1)
|
||||
if (data.CurrentPageData.Count == 1)
|
||||
{
|
||||
return data.Item1.CurrentPageData[0];
|
||||
return data.CurrentPageData[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -186,7 +186,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
/// <param name="inQuery"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<(PageOutput<TaskMedicalReviewView>, object)> GetMIMMedicalReviewTaskList(TaskMedicalReviewQuery inQuery)
|
||||
public async Task<IResponseOutput< PageOutput<TaskMedicalReviewView>>> GetMIMMedicalReviewTaskList(TaskMedicalReviewQuery inQuery)
|
||||
{
|
||||
|
||||
var taskMedicalReviewQueryable = _taskMedicalReviewRepository.Where(t => t.VisitTask.TrialId == inQuery.TrialId && t.MedicalManagerUserId == _userInfo.Id&&t.VisitTask.TrialReadingCriterionId==inQuery.TrialReadingCriterionId)
|
||||
@@ -206,7 +206,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(TaskMedicalReviewView.Id) : inQuery.SortField, inQuery.Asc);
|
||||
|
||||
return (pageList, new
|
||||
return ResponseOutput.Ok(pageList, new
|
||||
{
|
||||
|
||||
IsConfirmMedicineQuestion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).Select(x => x.IsConfirmMedicineQuestion).FirstOrDefaultAsync()
|
||||
|
||||
@@ -459,6 +459,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
var haveSignedCount = _readingClinicalDataRepository
|
||||
.Where(t => t.TrialId == trialId && t.IsSign && t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count();
|
||||
|
||||
|
||||
var readModule = _readModuleRepository.Where(t => t.Id == readingId).FirstOrDefault();
|
||||
//CRC 阅片期自定义结构化录入是否签名
|
||||
bool crcReadModuleSign = true;
|
||||
|
||||
|
||||
|
||||
//访视
|
||||
if (readingCategory == ReadingCategory.Visit)
|
||||
{
|
||||
@@ -478,16 +485,37 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//阅片期
|
||||
else if (readingCategory == ReadingCategory.Global)
|
||||
{
|
||||
needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCriterionId) && t.ClinicalDataLevel == ClinicalLevel.ImageRead && t.UploadRole == UploadRole.PM).Count();
|
||||
|
||||
if (readModule != null)
|
||||
{
|
||||
// 不存在需要CRC上传的临床数据 或者 PM已确认
|
||||
crcReadModuleSign =
|
||||
!trialClinicalDataSetList.Any(x =>
|
||||
x.UploadRole == UploadRole.CRC
|
||||
&& x.ClinicalDataLevel == ClinicalLevel.ImageRead
|
||||
&& x.ClinicalUploadType == ClinicalUploadType.Structuring
|
||||
&& x.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCriterionId)) || readModule.IsPMConfirm;
|
||||
}
|
||||
}
|
||||
// 肿瘤学
|
||||
else if (readingCategory == ReadingCategory.Oncology)
|
||||
{
|
||||
return trialClinicalDataSetList.Any(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCriterionId) && t.ClinicalDataLevel == ClinicalLevel.OncologyRead);
|
||||
needSignCount= trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCriterionId) && t.ClinicalDataLevel == ClinicalLevel.OncologyRead && t.UploadRole == UploadRole.PM).Count();
|
||||
if (readModule != null)
|
||||
{
|
||||
// 不存在需要CRC上传的临床数据 或者 PM已确认
|
||||
crcReadModuleSign =
|
||||
!trialClinicalDataSetList.Any(x =>
|
||||
x.UploadRole == UploadRole.CRC
|
||||
&& x.ClinicalDataLevel == ClinicalLevel.OncologyRead
|
||||
&& x.ClinicalUploadType == ClinicalUploadType.Structuring
|
||||
&& x.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCriterionId)) || readModule.IsPMConfirm;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -495,7 +523,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
}
|
||||
|
||||
//可能仅仅CRC 基线 没有PM
|
||||
if (needSignCount == haveSignedCount /*&& needSignCount != 0*/)
|
||||
if (needSignCount == haveSignedCount && crcReadModuleSign )
|
||||
{
|
||||
isClinicalDataSign = true;
|
||||
|
||||
@@ -620,7 +648,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
foreach (var trialReadingCriterionConfig in trialReadingCriterionConfigList)
|
||||
{
|
||||
|
||||
var trialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId;
|
||||
//var subjectCriteriaEvaluation = _subjectCriteriaEvaluationRepository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.IsJoinEvaluation && t.SubjectId == subjectVisit.SubjectId).FirstOrDefault();
|
||||
|
||||
if (trialReadingCriterionConfig.IsAutoCreate == true /*|| (trialReadingCriterionConfig.IsAutoCreate == false && subjectCriteriaEvaluation != null && subjectCriteriaEvaluation?.IsJoinEvaluation == true)*/)
|
||||
@@ -660,7 +688,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
|
||||
var existCurrentVisitTaskList = _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId
|
||||
&& t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.TaskState == TaskState.Effect
|
||||
&& t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect
|
||||
&& t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.SourceSubjectVisitId == subjectVisit.Id).ToList();
|
||||
|
||||
VisitTask? task1 = null;
|
||||
@@ -1061,7 +1089,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
|
||||
//该Subject 之前是否有已分配的 如果改变配置 可能会出现 一个Subject 分配的同一个医生 有的在Arm1 有的在Arm2
|
||||
var allocateSubjectArmList = _visitTaskRepository.Where(t => t.SubjectId == subjectVisit.SubjectId && t.TrialId == trialId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm)
|
||||
var allocateSubjectArmList = _visitTaskRepository.Where(t => t.SubjectId == subjectVisit.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.TrialId == trialId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm)
|
||||
.Select(t => new { t.DoctorUserId, t.ArmEnum }).Distinct().ToList();
|
||||
|
||||
//不是初次分配
|
||||
@@ -1082,7 +1110,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder)
|
||||
{
|
||||
//之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的)
|
||||
var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
|
||||
var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
if (beforeBackVisitTask == null)
|
||||
@@ -1107,11 +1135,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
#endregion
|
||||
|
||||
|
||||
var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
|
||||
var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
|
||||
|
||||
//存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过,但是访视1还未通过时 生成任务
|
||||
var followVisitTaskList = await _visitTaskRepository
|
||||
.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true)
|
||||
.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true)
|
||||
.WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask.VisitTaskNum)
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
@@ -1081,11 +1081,15 @@ namespace IRaCIS.Core.Application.Service.Allocation
|
||||
|
||||
var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.DoctorUserId == _userInfo.Id
|
||||
&& x.TaskState == TaskState.Effect /*&& x.TrialReadingCriterionId== inDto.TrialReadingCriterionId*/)
|
||||
.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)
|
||||
|
||||
//前序 不存在 未生成任务的访视
|
||||
.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.Any(t => t.CheckState != CheckStateEnum.CVPassed) ? t.VisitTaskNum <= t.Subject.SubjectVisitList.Where(t => t.CheckState != CheckStateEnum.CVPassed).Min(t => t.VisitNum) : true)
|
||||
// 前序 不存在 未一致性核查未通过的
|
||||
.Where( t=>! t.Subject.SubjectVisitList.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)
|
||||
//满足前序访视不存在 需要签署但是未签署 sql 相当复杂 同时想查询所有未读的统计数字 就无法统计 byzhouhang
|
||||
//但是加字段 IsFrontTaskNeedSignButNotSign 那么签名临床数据的时候,要对该subject 该标准的有效的任务 这个字段需要在签名的时候维护 采取这种方式 统计数字灵活
|
||||
//.Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum))
|
||||
@@ -1412,7 +1416,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
|
||||
//添加申请记录
|
||||
var visitTaskReReading = await _visitTaskReReadingRepository.AddAsync(new VisitTaskReReading()
|
||||
{
|
||||
|
||||
TrialId=applyReReadingCommand.TrialId,
|
||||
RootReReadingTaskId = rootReReadingTaskId == Guid.Empty ? task.Id : rootReReadingTaskId,
|
||||
OriginalReReadingTaskId = task.Id,
|
||||
RequestReReadingTime = DateTime.Now,
|
||||
|
||||
@@ -165,7 +165,40 @@ namespace IRaCIS.Application.Contracts
|
||||
|
||||
|
||||
|
||||
public class AddBasicDicAndChild
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid ConfigTypeId { get; set; }
|
||||
|
||||
public bool IsEnable { get; set; }
|
||||
|
||||
public string Code { get; set; } = String.Empty;
|
||||
|
||||
public int ShowOrder { get; set; }
|
||||
public string Description { get; set; } = String.Empty;
|
||||
|
||||
public DicDataTypeEnum DataTypeEnum { get; set; }
|
||||
|
||||
|
||||
public List<AddBasicDicChild> ChildList { get; set; } = new List<AddBasicDicChild>();
|
||||
}
|
||||
|
||||
|
||||
public class AddBasicDicChild
|
||||
{
|
||||
public string Code { get; set; } = String.Empty;
|
||||
public string Value { get; set; } = String.Empty;
|
||||
|
||||
public string ValueCN { get; set; } = String.Empty;
|
||||
|
||||
public string ChildGroup { get; set; } = String.Empty;
|
||||
|
||||
public int ShowOrder { get; set; }
|
||||
|
||||
public string Description { get; set; } = String.Empty;
|
||||
|
||||
public bool IsEnable { get; set; } = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,27 +9,23 @@ using System.Collections.Generic;
|
||||
namespace IRaCIS.Core.Application.ViewModel
|
||||
{
|
||||
/// <summary> InternationalizationView 列表视图模型 </summary>
|
||||
public class InternationalizationView
|
||||
public class InternationalizationView : InternationalizationAddOrEdit
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public int ShowOrder { get; set; }
|
||||
public Guid CreateUserId { get; set; }
|
||||
public DateTime CreateTime { get; set; }
|
||||
public DateTime UpdateTime { get; set; }
|
||||
public Guid UpdateUserId { get; set; }
|
||||
public int State { get; set; }
|
||||
public string FolderPath { get; set; }
|
||||
public string Code { get; set; }
|
||||
public string Value { get; set; }
|
||||
public string ValueCN { get; set; }
|
||||
|
||||
}
|
||||
|
||||
///<summary>InternationalizationQuery 列表查询参数模型</summary>
|
||||
public class InternationalizationQuery:PageInput
|
||||
public class InternationalizationQuery : PageInput
|
||||
{
|
||||
|
||||
public string? FolderPath { get; set; }
|
||||
public string? Code { get; set; }
|
||||
public int? InternationalizationType { get; set; }
|
||||
public int? State { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public string? Code { get; set; }
|
||||
public string? Value { get; set; }
|
||||
|
||||
public string? ValueCN { get; set; }
|
||||
@@ -41,14 +37,38 @@ namespace IRaCIS.Core.Application.ViewModel
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public int State { get; set; }
|
||||
public string FolderPath { get; set; }
|
||||
public string Code { get; set; }
|
||||
public string Value { get; set; }
|
||||
public string ValueCN { get; set; }
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string Value { get; set; } = string.Empty;
|
||||
public string ValueCN { get; set; } = string.Empty;
|
||||
|
||||
public int InternationalizationType { get; set; }
|
||||
}
|
||||
|
||||
public class BatchAddInternationalization
|
||||
{
|
||||
public int InternationalizationType { get; set; }
|
||||
|
||||
public int State { get; set; }
|
||||
|
||||
public List<BatchAddInternationalizationDto> AddList { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class BatchAddInternationalizationDto
|
||||
{
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string Value { get; set; } = string.Empty;
|
||||
public string ValueCN { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class InternationalizationSimpleDto
|
||||
{
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string Value { get; set; } = string.Empty;
|
||||
public string ValueCN { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2023-06-27 15:47:02
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using System;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using System.Collections.Generic;
|
||||
namespace IRaCIS.Core.Application.ViewModel
|
||||
{
|
||||
/// <summary> PublishLogView 列表视图模型 </summary>
|
||||
public class PublishLogView : PublishLogAddOrEdit
|
||||
{
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
public Guid CreateUserId { get; set; }
|
||||
public Guid UpdateUserId { get; set; }
|
||||
public DateTime UpdateTime { get; set; }
|
||||
}
|
||||
|
||||
///<summary>PublishLogQuery 列表查询参数模型</summary>
|
||||
public class PublishLogQuery:PageInput
|
||||
{
|
||||
|
||||
public string? Version { get; set; }
|
||||
|
||||
public string? UpdateContent { get; set; }
|
||||
|
||||
}
|
||||
|
||||
///<summary> PublishLogAddOrEdit 列表查询参数模型</summary>
|
||||
public class PublishLogAddOrEdit
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string Version { get; set; }
|
||||
public DateTime PublishTime { get; set; }
|
||||
public string UpdateContent { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,39 @@ namespace IRaCIS.Application.Services
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加字典 的同时 一起添加子项 --New
|
||||
/// </summary>
|
||||
/// <param name="addBasicDicAndChild"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddBasicDicAndChild(AddBasicDicAndChild addBasicDicAndChild)
|
||||
{
|
||||
var verifyExp1 = new EntityVerifyExp<Dictionary>()
|
||||
{
|
||||
VerifyExp = t => t.Code == addBasicDicAndChild.Code && t.ParentId == null,
|
||||
VerifyMsg = $"已有{addBasicDicAndChild.Code}名称的字典",
|
||||
IsVerify = true
|
||||
};
|
||||
|
||||
|
||||
var entity = await _dicRepository.InsertFromDTOAsync(addBasicDicAndChild, false, verifyExp1);
|
||||
|
||||
var childList = _mapper.Map<List<Dictionary>>(addBasicDicAndChild.ChildList);
|
||||
|
||||
foreach (var item in childList)
|
||||
{
|
||||
item.DataTypeEnum = addBasicDicAndChild.DataTypeEnum;
|
||||
item.ParentId = entity.Id;
|
||||
}
|
||||
|
||||
await _dicRepository.AddRangeAsync(childList);
|
||||
|
||||
await _dicRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// New 查询条件
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2023-06-27 15:47:10
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
namespace IRaCIS.Core.Application.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// IPublishLogService
|
||||
/// </summary>
|
||||
public interface IPublishLogService
|
||||
{
|
||||
|
||||
Task<PageOutput<PublishLogView>> GetPublishLogList(PublishLogQuery inQuery);
|
||||
|
||||
Task<IResponseOutput> AddOrUpdatePublishLog(PublishLogAddOrEdit addOrEditPublishLog);
|
||||
|
||||
Task<IResponseOutput> DeletePublishLog(Guid publishLogId);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,9 @@ using IRaCIS.Core.Domain.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
/// <summary>
|
||||
@@ -24,23 +27,70 @@ namespace IRaCIS.Core.Application.Service
|
||||
_internationalizationRepository = internationalizationRepository;
|
||||
}
|
||||
|
||||
|
||||
[AllowAnonymous]
|
||||
|
||||
public async Task<List<InternationalizationSimpleDto>> GetFrontInternationalizationList()
|
||||
{
|
||||
|
||||
var list = await _internationalizationRepository.Where(t => t.InternationalizationType == 0).Select(t => new InternationalizationSimpleDto()
|
||||
{
|
||||
Code = t.Code,
|
||||
Value = t.Value,
|
||||
ValueCN = t.ValueCN
|
||||
}).ToListAsync();
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<InternationalizationView>> GetInternationalizationList(InternationalizationQuery inQuery)
|
||||
{
|
||||
|
||||
var internationalizationQueryable =_internationalizationRepository
|
||||
.WhereIf(inQuery.FolderPath!=null,t=>t.FolderPath.Contains(inQuery.FolderPath))
|
||||
.WhereIf(inQuery.Code != null, t => t.FolderPath.Contains(inQuery.Code))
|
||||
.WhereIf(inQuery.Value != null, t => t.FolderPath.Contains(inQuery.Value))
|
||||
.WhereIf(inQuery.ValueCN != null, t => t.FolderPath.Contains(inQuery.ValueCN))
|
||||
.ProjectTo<InternationalizationView>(_mapper.ConfigurationProvider);
|
||||
var internationalizationQueryable = _internationalizationRepository
|
||||
.WhereIf(inQuery.Description != null, t => t.Description.Contains(inQuery.Description))
|
||||
.WhereIf(inQuery.Code != null, t => t.Code.Contains(inQuery.Code))
|
||||
.WhereIf(inQuery.State != null, t => t.State == inQuery.State)
|
||||
.WhereIf(inQuery.InternationalizationType != null, t => t.InternationalizationType == inQuery.InternationalizationType)
|
||||
.WhereIf(inQuery.Value != null, t => t.Value.Contains(inQuery.Value))
|
||||
.WhereIf(inQuery.ValueCN != null, t => t.ValueCN.Contains(inQuery.ValueCN))
|
||||
.ProjectTo<InternationalizationView>(_mapper.ConfigurationProvider);
|
||||
|
||||
var pageList = await internationalizationQueryable
|
||||
.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? "Id" : inQuery.SortField,
|
||||
.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(InternationalizationView.State) : inQuery.SortField,
|
||||
inQuery.Asc);
|
||||
|
||||
return pageList;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> BatchAddInternationalization(BatchAddInternationalization batchAdd)
|
||||
{
|
||||
foreach (var item in batchAdd.AddList)
|
||||
{
|
||||
|
||||
var mapItem = _mapper.Map<InternationalizationAddOrEdit>(item);
|
||||
|
||||
mapItem.InternationalizationType = batchAdd.InternationalizationType;
|
||||
mapItem.State = batchAdd.State;
|
||||
|
||||
var verifyExp1 = new EntityVerifyExp<Internationalization>()
|
||||
{
|
||||
VerifyExp = t => t.Code == mapItem.Code && t.InternationalizationType == mapItem.InternationalizationType,
|
||||
|
||||
VerifyMsg = $"该类型已有{item.Code}名称的国际化标识",
|
||||
IsVerify = true
|
||||
};
|
||||
|
||||
var entity = await _internationalizationRepository.InsertOrUpdateAsync(mapItem, false, verifyExp1);
|
||||
}
|
||||
|
||||
await _internationalizationRepository.SaveChangesAsync();
|
||||
|
||||
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
public async Task<IResponseOutput> AddOrUpdateInternationalization(InternationalizationAddOrEdit addOrEditInternationalization)
|
||||
{
|
||||
@@ -52,7 +102,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
IsVerify = true
|
||||
};
|
||||
|
||||
var entity = await _internationalizationRepository.InsertOrUpdateAsync(addOrEditInternationalization, true,verifyExp1);
|
||||
var entity = await _internationalizationRepository.InsertOrUpdateAsync(addOrEditInternationalization, true, verifyExp1);
|
||||
|
||||
if (addOrEditInternationalization.InternationalizationType == 1)
|
||||
{
|
||||
await InternationalizationHelper.AddOrUpdateJsonKeyValueAsync(entity.Code, addOrEditInternationalization.Value, addOrEditInternationalization.ValueCN);
|
||||
|
||||
}
|
||||
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
|
||||
|
||||
@@ -186,7 +186,6 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
|
||||
builder.HtmlBody = string.Format(templateInfo,
|
||||
"",
|
||||
//---您正在进行邮箱重置密码操作
|
||||
_localizer["Mail_ResettingPassword "],
|
||||
verificationCode
|
||||
@@ -254,7 +253,6 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
|
||||
builder.HtmlBody = string.Format(templateInfo,
|
||||
"",
|
||||
//---您正在参与展影医疗IRC项目
|
||||
_localizer["Mail_IRCProject"],
|
||||
verificationCode
|
||||
@@ -321,7 +319,6 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
|
||||
builder.HtmlBody = string.Format(templateInfo,
|
||||
"",
|
||||
//---您正在参与展影医疗IRC项目中心调研工作
|
||||
_localizer["Mail_CenterResearchReminder"],
|
||||
verificationCode
|
||||
@@ -398,7 +395,7 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token });
|
||||
|
||||
routeUrl = routeUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&access_token=" + token;
|
||||
routeUrl = routeUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us?"en":"zh") + "&access_token=" + token;
|
||||
|
||||
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
|
||||
|
||||
@@ -512,7 +509,7 @@ namespace IRaCIS.Application.Services
|
||||
{
|
||||
var templateInfo = SourceReader.ReadToEnd();
|
||||
|
||||
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&access_token=" + token;
|
||||
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
|
||||
|
||||
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
|
||||
|
||||
@@ -576,7 +573,7 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
|
||||
|
||||
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&access_token=" + token;
|
||||
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
|
||||
|
||||
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
|
||||
|
||||
@@ -694,7 +691,7 @@ namespace IRaCIS.Application.Services
|
||||
{
|
||||
var templateInfo = SourceReader.ReadToEnd();
|
||||
|
||||
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + userType.UserTypeShortName + "&access_token=" + token;
|
||||
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + userType.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
|
||||
|
||||
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2023-06-27 15:47:06
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Application.Contracts;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// PublishLogService
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "Common")]
|
||||
public class PublishLogService : BaseService, IPublishLogService
|
||||
{
|
||||
|
||||
private readonly IRepository<PublishLog> _publishLogRepository;
|
||||
|
||||
public PublishLogService(IRepository<PublishLog> publishLogRepository)
|
||||
{
|
||||
_publishLogRepository = publishLogRepository;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<PublishLogView>> GetPublishLogList(PublishLogQuery inQuery)
|
||||
{
|
||||
|
||||
var publishLogQueryable = _publishLogRepository
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.Version) , t => t.Version.Contains(inQuery.Version))
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.UpdateContent), t => t.UpdateContent.Contains(inQuery.UpdateContent))
|
||||
.ProjectTo<PublishLogView>(_mapper.ConfigurationProvider);
|
||||
|
||||
var pageList = await publishLogQueryable
|
||||
.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc);
|
||||
|
||||
return pageList;
|
||||
}
|
||||
|
||||
|
||||
public async Task<IResponseOutput> AddOrUpdatePublishLog(PublishLogAddOrEdit addOrEditPublishLog)
|
||||
{
|
||||
Version version;
|
||||
|
||||
if (!Version.TryParse(addOrEditPublishLog.Version, out version))
|
||||
{
|
||||
return ResponseOutput.NotOk("版本号不符合要求");
|
||||
}
|
||||
|
||||
var verifyExp1 = new EntityVerifyExp<PublishLog>()
|
||||
{
|
||||
VerifyExp = u => u.Version == addOrEditPublishLog.Version ,
|
||||
|
||||
VerifyMsg = "发布编号不能重复"
|
||||
};
|
||||
|
||||
|
||||
|
||||
var entity = await _publishLogRepository.InsertOrUpdateAsync(addOrEditPublishLog, true, verifyExp1);
|
||||
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete("{publishLogId:guid}")]
|
||||
public async Task<IResponseOutput> DeletePublishLog(Guid publishLogId)
|
||||
{
|
||||
var success = await _publishLogRepository.DeleteFromQueryAsync(t => t.Id == publishLogId, true);
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
CreateMap<AddOrEditBasicDic, Dictionary>().ReverseMap();
|
||||
|
||||
|
||||
CreateMap<AddBasicDicAndChild, Dictionary>().ForMember(o => o.ChildList, t => t.Ignore());
|
||||
CreateMap<AddBasicDicChild, Dictionary>();
|
||||
|
||||
CreateMap<Dictionary, BasicDicSelectCopy>()
|
||||
.ForMember(o => o.ParentChildCodeEnum, t => t.MapFrom(u => u.Parent.ChildCodeEnum))
|
||||
.ForMember(o => o.Value, t => t.MapFrom(u => u.MappedValue))
|
||||
@@ -57,6 +61,12 @@ namespace IRaCIS.Core.Application.Service
|
||||
CreateMap<Internationalization, InternationalizationView>();
|
||||
CreateMap<Internationalization, InternationalizationAddOrEdit>().ReverseMap();
|
||||
|
||||
CreateMap<BatchAddInternationalizationDto, InternationalizationAddOrEdit>();
|
||||
|
||||
|
||||
CreateMap<PublishLog, PublishLogView>();
|
||||
CreateMap<PublishLog, PublishLogAddOrEdit>().ReverseMap();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,5 @@ namespace IRaCIS.Application.Contracts
|
||||
public string AwardsHonorsCN { get; set; } = String.Empty;
|
||||
|
||||
|
||||
public string BlindPublications { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -155,8 +155,6 @@ namespace IRaCIS.Application.Services
|
||||
await _repository.BatchDeleteAsync<Attachment>(a => a.Id == updateGCPExperienceParam.GCPId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return ResponseOutput.Result(successs, updateGCPExperienceParam.GCPId.ToString());
|
||||
|
||||
}
|
||||
|
||||
@@ -104,6 +104,15 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
}
|
||||
|
||||
public class GetNextUnSignDocumentInDto
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public bool Asc { get; set; } = true;
|
||||
public string SortField { get; set; } = "";
|
||||
}
|
||||
|
||||
public class TrialUserDocUnionQuery: PageInput
|
||||
{
|
||||
[NotDefault]
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using User = IRaCIS.Core.Domain.Models.User;
|
||||
using DocumentFormat.OpenXml.Office2010.Word;
|
||||
|
||||
namespace IRaCIS.Core.Application.Services
|
||||
{
|
||||
@@ -19,14 +20,16 @@ namespace IRaCIS.Core.Application.Services
|
||||
|
||||
private readonly IRepository<SystemDocument> _systemDocumentRepository;
|
||||
private readonly IRepository<SystemDocNeedConfirmedUserType> _systemDocNeedConfirmedUserTypeRepository;
|
||||
private readonly IRepository<SystemDocConfirmedUser> _systemDocConfirmedUserRepository;
|
||||
|
||||
public SystemDocumentService( IRepository<SystemDocument> systemDocumentRepository,
|
||||
IRepository<SystemDocNeedConfirmedUserType> systemDocNeedConfirmedUserTypeRepository
|
||||
)
|
||||
IRepository<SystemDocNeedConfirmedUserType> systemDocNeedConfirmedUserTypeRepository,
|
||||
IRepository<SystemDocConfirmedUser> systemDocConfirmedUserRepository)
|
||||
{
|
||||
_systemDocumentRepository = systemDocumentRepository;
|
||||
this._systemDocNeedConfirmedUserTypeRepository = systemDocNeedConfirmedUserTypeRepository;
|
||||
}
|
||||
_systemDocConfirmedUserRepository = systemDocConfirmedUserRepository;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -109,6 +112,22 @@ namespace IRaCIS.Core.Application.Services
|
||||
|
||||
}
|
||||
|
||||
[HttpDelete("{systemDocumentId:guid}")]
|
||||
public async Task<IResponseOutput> AbandonSystemDocumentAsync(Guid systemDocumentId)
|
||||
{
|
||||
|
||||
await _systemDocumentRepository.UpdatePartialFromQueryAsync(systemDocumentId, u => new SystemDocument() { IsDeleted = true });
|
||||
|
||||
await _systemDocConfirmedUserRepository.UpdatePartialFromQueryAsync(x => x.SystemDocumentId == systemDocumentId, x => new SystemDocConfirmedUser()
|
||||
{
|
||||
IsDeleted = true
|
||||
});
|
||||
|
||||
await _systemDocConfirmedUserRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpDelete("{systemDocumentId:guid}")]
|
||||
public async Task<IResponseOutput> DeleteSystemDocumentAsync(Guid systemDocumentId)
|
||||
|
||||
@@ -66,6 +66,33 @@ namespace IRaCIS.Core.Application.Services
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取下一个未签名的文件
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<UnionDocumentWithConfirmInfoView?> GetNextUnSignDocument(GetNextUnSignDocumentInDto inDto)
|
||||
{
|
||||
var result =await this.GetUserDocumentList(new TrialUserDocUnionQuery()
|
||||
{
|
||||
Asc = inDto.Asc,
|
||||
IsSign = false,
|
||||
SortField = inDto.SortField,
|
||||
TrialId= inDto.TrialId,
|
||||
PageIndex = 1,
|
||||
PageSize = 1,
|
||||
});
|
||||
|
||||
if (result.Data.CurrentPageData.Count() > 0)
|
||||
{
|
||||
return result.Data.CurrentPageData.First();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 具体用户看到的 系统文件列表 + 项目类型文档
|
||||
@@ -407,7 +434,7 @@ namespace IRaCIS.Core.Application.Services
|
||||
}
|
||||
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.PM)]
|
||||
//[Authorize(Policy = IRaCISPolicy.PM)]
|
||||
public async Task<IResponseOutput> AddOrUpdateTrialDocument(AddOrEditTrialDocument addOrEditTrialDocument)
|
||||
{
|
||||
if (addOrEditTrialDocument.Id == null)
|
||||
@@ -477,7 +504,7 @@ namespace IRaCIS.Core.Application.Services
|
||||
/// <param name="trialId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{trialId:guid}/{trialDocumentId:guid}")]
|
||||
[Authorize(Policy = IRaCISPolicy.PM)]
|
||||
//[Authorize(Policy = IRaCISPolicy.PM)]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })]
|
||||
public async Task<IResponseOutput> DeleteTrialDocument(Guid trialDocumentId, Guid trialId)
|
||||
{
|
||||
|
||||
@@ -35,9 +35,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
.ForMember(d => d.SiteName, u => u.MapFrom(s => s.Site.SiteName))
|
||||
.ForMember(d => d.UploaderFirstName, u => u.MapFrom(s => s.Uploader.FirstName))
|
||||
.ForMember(d => d.UploaderLastName, u => u.MapFrom(s => s.Uploader.LastName))
|
||||
.ForMember(d => d.UploadedTime, u => u.MapFrom(s => s.CreateTime))
|
||||
|
||||
.ForMember(d => d.DTFCount, u => u.MapFrom(s => s.StudyDTFList.Count()));
|
||||
.ForMember(d => d.UploadedTime, u => u.MapFrom(s => s.CreateTime));
|
||||
|
||||
CreateMap<Subject, StudyDTO>();
|
||||
|
||||
@@ -61,7 +59,8 @@ namespace IRaCIS.Core.Application.Service
|
||||
CreateMap<DicomStudy, QAStudyInfoDTO>()
|
||||
.ForMember(o => o.UploadedTime, t => t.MapFrom(u => u.CreateTime))
|
||||
.ForMember(o => o.Uploader, t => t.MapFrom(u => u.Uploader.LastName + " / " + u.Uploader.FirstName))
|
||||
.ForMember(o => o.StudyId, t => t.MapFrom(u => u.Id));
|
||||
.ForMember(o => o.StudyId, t => t.MapFrom(u => u.Id))
|
||||
.ForMember(o => o.Modalities, t => t.MapFrom(u => string.Join('、', u.SeriesList.Select(t => t.Modality).Distinct()) ));
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace IRaCIS.Application.Services
|
||||
/// <summary> 根据CRO 名称查询所有CRO 列表 </summary>
|
||||
public async Task<IEnumerable<CroSelectDTO>> GetAllCROList()
|
||||
{
|
||||
return await _croRepository.ProjectTo<CroSelectDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
return await _croRepository.ProjectTo<CroSelectDTO>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,13 +35,15 @@ namespace IRaCIS.Application.Services
|
||||
VerifyMsg = _localizer["Hospital_DupName"]
|
||||
};
|
||||
|
||||
if (await _hospitalRepository.AnyAsync(x => x.SiteId == hospitalCommand.SiteId && hospitalCommand.SiteId != null))
|
||||
var exp1 = new EntityVerifyExp<Hospital>()
|
||||
{
|
||||
//---当前Site已经添加到其他Hospital了
|
||||
throw new BusinessValidationFailedException(_localizer["Hospital_SiteAdded"]);
|
||||
}
|
||||
VerifyExp = x => x.SiteId == hospitalCommand.SiteId && hospitalCommand.SiteId != null,
|
||||
//---已经存在同名的医院,请确认。
|
||||
VerifyMsg = _localizer["Hospital_SiteAdded"]
|
||||
};
|
||||
|
||||
var hospital = await _hospitalRepository.InsertOrUpdateAsync(hospitalCommand, true, exp);
|
||||
|
||||
var hospital = await _hospitalRepository.InsertOrUpdateAsync(hospitalCommand, true, exp,exp1);
|
||||
|
||||
return ResponseOutput.Ok(hospital.Id.ToString());
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace IRaCIS.Application.Services
|
||||
//{
|
||||
// sponsorLambda = sponsorLambda.And(t => t.SponsorName.Contains(sponsorSearchModel.SponsorName.Trim()));
|
||||
//}
|
||||
var sponsorQueryable = _sponsorRepository.ProjectTo<SponsorSelectDTO>(_mapper.ConfigurationProvider);
|
||||
var sponsorQueryable = _sponsorRepository.ProjectTo<SponsorSelectDTO>(_mapper.ConfigurationProvider,new { isEn_Us= _userInfo.IsEn_Us});
|
||||
return await sponsorQueryable.ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
public InstitutionConfig()
|
||||
{
|
||||
var isEn_Us = false;
|
||||
|
||||
CreateMap<HospitalCommand, Hospital>();
|
||||
CreateMap<SiteCommand, Site>();
|
||||
CreateMap<SponsorCommand, Sponsor>();
|
||||
@@ -15,8 +17,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
CreateMap<Hospital, HospitalDTO>();
|
||||
CreateMap<CRO, CROCompanyDTO>().ReverseMap();
|
||||
CreateMap<Sponsor, SponsorDTO>();
|
||||
CreateMap<CRO, CroSelectDTO>();
|
||||
CreateMap<Sponsor, SponsorSelectDTO>();
|
||||
CreateMap<CRO, CroSelectDTO>()
|
||||
.ForMember(t => t.CROName, c => c.MapFrom(d => isEn_Us ? d.CROName : d.CRONameCN));
|
||||
|
||||
CreateMap<Sponsor, SponsorSelectDTO>()
|
||||
.ForMember(t=>t.SponsorName,c=>c.MapFrom(d=> isEn_Us?d.SponsorName:d.SponsorNameCN));
|
||||
CreateMap<Site, SiteSelectionDTO>();
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2023-07-04 16:10:46
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using System;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using System.Collections.Generic;
|
||||
namespace IRaCIS.Core.Application.ViewModel
|
||||
{
|
||||
/// <summary> UserLogView 列表视图模型 </summary>
|
||||
public class UserLogView
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string IP { get; set; }
|
||||
|
||||
public string LoginFaildName { get; set; }
|
||||
public int OptType { get; set; }
|
||||
|
||||
|
||||
public string? LoginUserName { get; set; }
|
||||
|
||||
public UserTypeEnum? LoginUserTypeEnum { get; set; }
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
public Guid CreateUserId { get; set; }
|
||||
|
||||
|
||||
|
||||
public string? OptUserName { get; set; }
|
||||
|
||||
public UserTypeEnum? OptUserTypeEnum { get; set; }
|
||||
|
||||
public Guid? LoginUserId { get; set; }
|
||||
|
||||
public Guid? OptUserId { get; set; }
|
||||
}
|
||||
|
||||
///<summary>UserLogQuery 列表查询参数模型</summary>
|
||||
public class UserLogQuery : PageInput
|
||||
{
|
||||
public Guid? TrialId { get; set; }
|
||||
|
||||
public UserOptType? OptType { get; set; }
|
||||
|
||||
public string? IP { get; set; }
|
||||
|
||||
public string? LoginFaildName { get; set; }
|
||||
|
||||
public DateTime? BeginDate { get; set; }
|
||||
|
||||
public DateTime? EndDate { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
/// <summary> UserTypeRoleView 列表视图模型 </summary>
|
||||
public class UserTypeRoleView : UserTypeMenuAddOrEdit
|
||||
{
|
||||
public UserTypeEnum UserTypeEnum { get; set; }
|
||||
public List<UserTypeGroupInfo> UserTypeGroupList { get; set; } = new List<UserTypeGroupInfo>();
|
||||
|
||||
public new List<Guid> UserTypeGroupIdList => UserTypeGroupList.Select(t=>t.DictionaryId).ToList();
|
||||
@@ -37,6 +38,8 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
public class UserTypeMenuAddOrEdit: UserTypeRoleAddOrEdit
|
||||
{
|
||||
public UserTypeEnum UserTypeEnum { get; set; }
|
||||
|
||||
public List<Guid> MenuIds { get; set; } = new List<Guid>();
|
||||
|
||||
}
|
||||
@@ -52,6 +55,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public int Order { get; set; }
|
||||
|
||||
|
||||
|
||||
public List<Guid> UserTypeGroupIdList { get; set; } = new List<Guid>();
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2023-07-04 16:10:34
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
namespace IRaCIS.Core.Application.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// IUserLogService
|
||||
/// </summary>
|
||||
public interface IUserLogService
|
||||
{
|
||||
|
||||
Task<PageOutput<UserLogView>> GetUserLogList(UserLogQuery inQuery);
|
||||
|
||||
//Task<IResponseOutput> AddOrUpdateUserLog(UserLogAddOrEdit addOrEditUserLog);
|
||||
|
||||
//Task<IResponseOutput> DeleteUserLog(Guid userLogId);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ using Microsoft.Extensions.Caching.Memory;
|
||||
using IRaCIS.Core.Infra.Common.Cache;
|
||||
using Microsoft.Identity.Client;
|
||||
using static IRaCIS.Core.Domain.Share.StaticData;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
@@ -22,10 +23,14 @@ namespace IRaCIS.Application.Services
|
||||
private readonly IRepository<VerificationCode> _verificationCodeRepository;
|
||||
private readonly IRepository<Doctor> _doctorRepository;
|
||||
private readonly IRepository<TrialUser> _userTrialRepository;
|
||||
private readonly IRepository<UserLog> _userLogRepository;
|
||||
|
||||
|
||||
private readonly IMemoryCache _cache;
|
||||
|
||||
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
|
||||
|
||||
|
||||
public UserService(IRepository<User> userRepository,
|
||||
|
||||
IMailVerificationService mailVerificationService,
|
||||
@@ -33,10 +38,12 @@ namespace IRaCIS.Application.Services
|
||||
IRepository<Doctor> doctorRepository,
|
||||
IMemoryCache cache,
|
||||
IRepository<TrialUser> userTrialRepository,
|
||||
IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig
|
||||
|
||||
IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig,
|
||||
IRepository<UserLog> userLogRepository
|
||||
)
|
||||
{
|
||||
_userLogRepository = userLogRepository;
|
||||
|
||||
_verifyConfig = verifyConfig;
|
||||
_cache = cache;
|
||||
_userRepository = userRepository;
|
||||
@@ -44,6 +51,7 @@ namespace IRaCIS.Application.Services
|
||||
_verificationCodeRepository = verificationCodeRepository;
|
||||
_doctorRepository = doctorRepository;
|
||||
_userTrialRepository = userTrialRepository;
|
||||
_userLogRepository = userLogRepository;
|
||||
}
|
||||
|
||||
|
||||
@@ -165,9 +173,7 @@ namespace IRaCIS.Application.Services
|
||||
}
|
||||
else //验证码正确 并且 没有超时
|
||||
{
|
||||
//更新密码
|
||||
//var pwd = MD5Helper.Md5(newPwd);
|
||||
//var count = _doctorRepository.Update<Doctor>().Where(t => t.Id == doctor.Id).Set(d => d.Password == pwd).ExecuteAffrows();
|
||||
|
||||
|
||||
await VerifyUserEmailAsync(_userInfo.Id, _userInfo.UserTypeId, newEmail);
|
||||
|
||||
@@ -180,6 +186,8 @@ namespace IRaCIS.Application.Services
|
||||
//删除验证码历史记录
|
||||
await _verificationCodeRepository.BatchDeleteNoTrackingAsync(t => t.UserId == _userInfo.Id && t.CodeType == 0);
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = _userInfo.Id, OptType = UserOptType.UpdateUser }, true);
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
|
||||
}
|
||||
@@ -198,6 +206,8 @@ namespace IRaCIS.Application.Services
|
||||
Phone = newPhone
|
||||
});
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = _userInfo.Id, OptType = UserOptType.UpdateUser }, true);
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
@@ -213,19 +223,11 @@ namespace IRaCIS.Application.Services
|
||||
UserName = newUserName
|
||||
});
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = _userInfo.Id, OptType = UserOptType.UpdateUser }, true);
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Result 为true 的时候 认为链接没有失效
|
||||
///// </summary>
|
||||
///// <param name="userId"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpGet]
|
||||
//public async Task<IResponseOutput> VerifyCanInitSetUserNameAndPwd(Guid userId)
|
||||
//{
|
||||
// return ResponseOutput.Ok(await _userRepository.AnyAsync(t => t.Id == userId && t.EmailToken == _userInfo.UserToken && t.IsFirstAdd));
|
||||
//}
|
||||
|
||||
|
||||
|
||||
[HttpGet]
|
||||
@@ -233,8 +235,6 @@ namespace IRaCIS.Application.Services
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
await VerifyUserPwdAsync(userId, newPWd);
|
||||
|
||||
await VerifyUserNameAsync(userId, newUserName);
|
||||
@@ -251,6 +251,8 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
}, true);
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = _userInfo.Id, OptType = UserOptType.UpdateUser }, true);
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
@@ -290,6 +292,8 @@ namespace IRaCIS.Application.Services
|
||||
IsFirstAdd = true
|
||||
});
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId=userId, OptType = UserOptType.ResetPassword }, true);
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
@@ -400,6 +404,8 @@ namespace IRaCIS.Application.Services
|
||||
IsFirstAdd = false
|
||||
});
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId = userId,LoginPassword=newPwd, OptType = UserOptType.UnloginModifyPasswoed }, true);
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
|
||||
}
|
||||
@@ -434,23 +440,11 @@ namespace IRaCIS.Application.Services
|
||||
IsFirstAdd = false
|
||||
});
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId= _userInfo.Id, OptType = UserOptType.LoginModifyPassword }, true);
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
|
||||
|
||||
////医生密码
|
||||
//if (await _doctorRepository.AnyAsync(t => t.Id == _userInfo.Id && t.Password == editPwModel.OldPassWord))
|
||||
//{
|
||||
// var success = await _doctorRepository.BatchUpdateNoTrackingAsync(t => t.Id == _userInfo.Id, u => new Doctor()
|
||||
// {
|
||||
|
||||
// Password = editPwModel.NewPassWord
|
||||
// });
|
||||
|
||||
// return ResponseOutput.Result(success);
|
||||
//}
|
||||
|
||||
//return ResponseOutput.NotOk("Old password is wrong.");
|
||||
|
||||
}
|
||||
|
||||
@@ -477,7 +471,6 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
return await userQueryable.ToPagedListAsync(param.PageIndex, param.PageSize, param.SortField == string.Empty ? "UserName" : param.SortField, param.Asc);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -562,6 +555,9 @@ namespace IRaCIS.Application.Services
|
||||
{
|
||||
user.OrganizationName = AppSettings.DefaultInternalOrganizationName;
|
||||
}
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId= model.Id , OptType = UserOptType.UpdateUser }, true);
|
||||
|
||||
var success = await _userRepository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Ok(success);
|
||||
@@ -582,6 +578,8 @@ namespace IRaCIS.Application.Services
|
||||
return ResponseOutput.NotOk(_localizer["User_InProject"]);
|
||||
}
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId= userId, OptType = UserOptType.DeleteUser }, true);
|
||||
|
||||
var success = await _userRepository.BatchDeleteNoTrackingAsync(t => t.Id == userId);
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
@@ -597,6 +595,9 @@ namespace IRaCIS.Application.Services
|
||||
[HttpPost("{userId:guid}/{state:int}")]
|
||||
public async Task<IResponseOutput> UpdateUserState(Guid userId, UserStateEnum state)
|
||||
{
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = userId, OptType = state==UserStateEnum.Enable? UserOptType.AccountEnable: UserOptType.AccountLocked }, true);
|
||||
|
||||
var success = await _userRepository.BatchUpdateNoTrackingAsync(u => u.Id == userId, t => new User
|
||||
{
|
||||
Status = state
|
||||
@@ -618,8 +619,8 @@ namespace IRaCIS.Application.Services
|
||||
{
|
||||
|
||||
const string cachePrefix = "login-failures:";
|
||||
const int maxFailures = 3;
|
||||
const int lockoutMinutes = 1;
|
||||
int maxFailures = _verifyConfig.CurrentValue.LoginMaxFailCount;
|
||||
int lockoutMinutes = _verifyConfig.CurrentValue.LoginFailLockMinutes;
|
||||
|
||||
// 生成缓存键
|
||||
string cacheKey = $"{cachePrefix}{userName}";
|
||||
@@ -638,7 +639,9 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
if (failCount >= maxFailures)
|
||||
{
|
||||
throw new BusinessValidationFailedException($"密码连续错误3次,当前账号已被限制登录,请等待 {lockoutMinutes} 分钟后再试。");
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId = Guid.Empty, LoginFaildName = userName,LoginPassword=password, OptType = UserOptType.AccountLocked }, true);
|
||||
|
||||
throw new BusinessValidationFailedException($"密码连续错误{maxFailures}次,当前账号已被限制登录,请等待 {lockoutMinutes} 分钟后再试。");
|
||||
}
|
||||
|
||||
var userLoginReturnModel = new LoginReturnDTO();
|
||||
@@ -649,28 +652,12 @@ namespace IRaCIS.Application.Services
|
||||
if (loginUser == null)
|
||||
{
|
||||
|
||||
#region 屏蔽代码,现在没用到
|
||||
////此处下面 代码 为了支持医生也能登录 而且前端不加选择到底是管理用户 还是医生用户 奇怪的需求 无法理解
|
||||
|
||||
//var loginDoctor = await _doctorRepository.Where(u => u.Phone == userName && u.Password == password).ProjectTo<UserBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
|
||||
|
||||
//if (loginDoctor == null)
|
||||
//{
|
||||
// return ResponseOutput.NotOk(_localizer["User_CheckNameOrPw"], new LoginReturnDTO());
|
||||
//}
|
||||
//userLoginReturnModel.BasicInfo = loginDoctor;
|
||||
|
||||
//登录 清除缓存
|
||||
//_cache.Remove(userLoginReturnModel.BasicInfo.Id.ToString());
|
||||
//return ResponseOutput.Ok(userLoginReturnModel);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
//错误次数累加
|
||||
failCount++;
|
||||
_cache.Set(cacheKey, failCount, TimeSpan.FromMinutes(lockoutMinutes));
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId=Guid.Empty, LoginFaildName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError }, true);
|
||||
|
||||
return ResponseOutput.NotOk(_localizer["User_CheckNameOrPw"], new LoginReturnDTO());
|
||||
|
||||
|
||||
@@ -679,6 +666,8 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
if (loginUser.Status == 0)
|
||||
{
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = loginUser.Id, OptUserId = loginUser.Id, LoginFaildName = userName, OptType = UserOptType.LoginLockedAccount }, true);
|
||||
|
||||
//---该用户已经被禁用。
|
||||
return ResponseOutput.NotOk(_localizer["User_Disabled"], new LoginReturnDTO());
|
||||
}
|
||||
@@ -687,7 +676,7 @@ namespace IRaCIS.Application.Services
|
||||
//登录成功 清除缓存
|
||||
_cache.Set(cacheKey, 0, TimeSpan.FromMinutes(lockoutMinutes));
|
||||
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = loginUser.Id, OptUserId = loginUser.Id, OptType = UserOptType.Login }, true);
|
||||
|
||||
userLoginReturnModel.BasicInfo = loginUser;
|
||||
|
||||
@@ -697,35 +686,32 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<UserLogView>> GetUserLogList(UserLogQuery inQuery)
|
||||
{
|
||||
|
||||
var userLogQueryable =
|
||||
_userLogRepository
|
||||
.WhereIf(inQuery.TrialId != null, t => t.LoginUser.UserTrials.Any(c => c.TrialId == inQuery.TrialId && c.UserId == t.CreateUserId))
|
||||
.WhereIf(inQuery.OptType != null, t => t.OptType == inQuery.OptType)
|
||||
.WhereIf(inQuery.BeginDate != null, t => t.CreateTime >= inQuery.BeginDate)
|
||||
.WhereIf(inQuery.EndDate != null, t => t.CreateTime <= inQuery.EndDate)
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.LoginFaildName), t => t.LoginFaildName.Contains(inQuery.LoginFaildName))
|
||||
.WhereIf(!string.IsNullOrEmpty(inQuery.IP), t => t.IP.Contains(inQuery.IP))
|
||||
.ProjectTo<UserLogView>(_mapper.ConfigurationProvider);
|
||||
|
||||
var pageList = await userLogQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? "Id" : inQuery.SortField, inQuery.Asc);
|
||||
|
||||
//private bool loginIsLocked(string userName)
|
||||
//{
|
||||
return pageList;
|
||||
}
|
||||
|
||||
// //if (failCount == null)
|
||||
// //{
|
||||
// // failCount = 0;
|
||||
// //}
|
||||
// //else
|
||||
// //{
|
||||
// // failCount++;
|
||||
// //}
|
||||
[HttpGet]
|
||||
public async Task<IResponseOutput> LoginOut()
|
||||
{
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = _userInfo.Id, OptType = UserOptType.LoginOut },true);
|
||||
|
||||
// //// 更新缓存中的登录失败次数
|
||||
// //_cache.Set(cacheKey, failCount, TimeSpan.FromMinutes(lockoutMinutes));
|
||||
|
||||
// //if (failCount >= maxFailures)
|
||||
// //{
|
||||
// // // 如果登录失败次数达到了 3 次,则锁定用户
|
||||
// // _cache.Set(cacheKey + ":locked", true, TimeSpan.FromMinutes(lockoutMinutes));
|
||||
// //}
|
||||
|
||||
|
||||
|
||||
|
||||
// //return isLocked;
|
||||
//}
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Application.Contracts;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
@@ -15,18 +16,18 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
[ApiExplorerSettings(GroupName = "Management")]
|
||||
public class UserTypeRoleService : BaseService, IUserTypeService
|
||||
{
|
||||
private readonly IRepository<UserType> userTypeServiceRepository;
|
||||
private readonly IRepository<UserType> _userTypeRepository;
|
||||
|
||||
public UserTypeRoleService(IRepository<UserType> userTypeServiceRepository)
|
||||
public UserTypeRoleService(IRepository<UserType> userTypeRepository)
|
||||
{
|
||||
this.userTypeServiceRepository = userTypeServiceRepository;
|
||||
_userTypeRepository = userTypeRepository;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<List<UserTypeRoleView>> GetUserTypeRoleList(UserTypeQuery userTypeQuery)
|
||||
{
|
||||
|
||||
var userTypeRoleQueryable = userTypeServiceRepository
|
||||
var userTypeRoleQueryable = _userTypeRepository
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(userTypeQuery.SearchFilter), t => t.Description.Contains(userTypeQuery.SearchFilter!) || t.UserTypeName.Contains(userTypeQuery.SearchFilter!) || t.UserTypeShortName.Contains(userTypeQuery.SearchFilter!))
|
||||
|
||||
.WhereIf(userTypeQuery.GroupId!=null,t=>t.UserTypeGroupList.Any(t=>t.DictionaryId== userTypeQuery.GroupId))
|
||||
@@ -40,16 +41,22 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public async Task<IResponseOutput> AddOrUpdateUserTypeRole(UserTypeMenuAddOrEdit addOrEditUserTypeRole)
|
||||
{
|
||||
|
||||
var verifyExp1 = new EntityVerifyExp<UserType>()
|
||||
{
|
||||
VerifyExp = u => u.UserTypeEnum == addOrEditUserTypeRole.UserTypeEnum ,
|
||||
|
||||
VerifyMsg = "已存在该用户类型的角色。"
|
||||
};
|
||||
|
||||
var entity = new UserType();
|
||||
|
||||
if (addOrEditUserTypeRole.Id == null)
|
||||
{
|
||||
entity = _mapper.Map<UserType>(addOrEditUserTypeRole);
|
||||
|
||||
entity.UserTypeEnum = userTypeServiceRepository.Select(t => t.UserTypeEnum).DefaultIfEmpty().Max() + 1;
|
||||
|
||||
await _repository.AddAsync(entity);
|
||||
//entity.UserTypeEnum = userTypeServiceRepository.Select(t => t.UserTypeEnum).DefaultIfEmpty().Max() + 1;
|
||||
|
||||
await _userTypeRepository.InsertFromDTOAsync(addOrEditUserTypeRole,false, verifyExp1);
|
||||
|
||||
}
|
||||
else
|
||||
@@ -57,14 +64,17 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
if (addOrEditUserTypeRole.MenuIds.Count > 0)
|
||||
{
|
||||
entity = userTypeServiceRepository.Where(t => t.Id == addOrEditUserTypeRole.Id, true).Include(t => t.UserTypeMenuList).Include(t=>t.UserTypeGroupList).FirstOrDefault().IfNullThrowException();
|
||||
entity = _userTypeRepository.Where(t => t.Id == addOrEditUserTypeRole.Id, true).Include(t => t.UserTypeMenuList).Include(t=>t.UserTypeGroupList).FirstOrDefault().IfNullThrowException();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
entity = userTypeServiceRepository.Where(t => t.Id == addOrEditUserTypeRole.Id, true).FirstOrDefault().IfNullThrowException();
|
||||
entity = _userTypeRepository.Where(t => t.Id == addOrEditUserTypeRole.Id, true).FirstOrDefault().IfNullThrowException();
|
||||
}
|
||||
_mapper.Map(addOrEditUserTypeRole, entity);
|
||||
|
||||
|
||||
await _userTypeRepository.EntityVerifyAsync(entity.Id, verifyExp1);
|
||||
}
|
||||
|
||||
var success = await _repository.SaveChangesAsync();
|
||||
@@ -83,7 +93,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
return ResponseOutput.NotOk(_localizer["UserType_InUse"]);
|
||||
}
|
||||
|
||||
var success = await userTypeServiceRepository.BatchDeleteNoTrackingAsync(t => t.Id == userTypeId);
|
||||
var success = await _userTypeRepository.BatchDeleteNoTrackingAsync(t => t.Id == userTypeId);
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
@@ -139,7 +149,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
|
||||
|
||||
var query = userTypeServiceRepository.Where(x => x.UserTypeEnum != UserTypeEnum.SuperAdmin)
|
||||
var query = _userTypeRepository.Where(x => x.UserTypeEnum != UserTypeEnum.SuperAdmin)
|
||||
.WhereIf(userTypeSelectEnum != UserTypeSelectEnum.None, t => userTypeEnums.Contains(t.UserTypeEnum))
|
||||
.OrderBy(t => t.Order).ProjectTo<TrialUserType>(_mapper.ConfigurationProvider);
|
||||
|
||||
@@ -156,8 +166,8 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
/// <returns></returns>
|
||||
public async Task<List<TrialUserType>> GetTrialUserTypeList()
|
||||
{
|
||||
var query = userTypeServiceRepository.Where(x => x.UserTypeEnum != UserTypeEnum.SuperAdmin)
|
||||
//.Where(t => t.Type == UserTypeGroup.TrialUser)
|
||||
var query = _userTypeRepository.Where(x => x.UserTypeEnum != UserTypeEnum.SuperAdmin)
|
||||
.Where(t => !t.UserTypeGroupList.Any(t=> t.Group.Code=="3"))
|
||||
.OrderBy(t => t.Order).ProjectTo<TrialUserType>(_mapper.ConfigurationProvider);
|
||||
|
||||
return await query.ToListAsync();
|
||||
|
||||
@@ -119,7 +119,12 @@ namespace IRaCIS.Core.Application.Service
|
||||
.ForMember(d => d.UserTypeId, c => c.MapFrom(t => t));
|
||||
|
||||
|
||||
|
||||
CreateMap<UserLog, UserLogView>()
|
||||
.ForMember(d => d.LoginUserName, c => c.MapFrom(t => t.LoginUser.UserName))
|
||||
.ForMember(d => d.LoginUserTypeEnum, c => c.MapFrom(t => t.LoginUser.UserTypeEnum))
|
||||
.ForMember(d => d.OptUserName, c => c.MapFrom(t => t.OptUser.UserName))
|
||||
.ForMember(d => d.OptUserTypeEnum, c => c.MapFrom(t => t.OptUser.UserTypeEnum))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,20 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public Guid? HandleUserId { get; set; }
|
||||
}
|
||||
|
||||
public class GetNextIQCQualityInDto
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid SubjectId { get; set; }
|
||||
}
|
||||
|
||||
public class GetNextIQCQualityOutDto
|
||||
{
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
public Guid? VisitId { get; set; }
|
||||
}
|
||||
|
||||
public class CRCRequestToQCCommand
|
||||
{
|
||||
|
||||
@@ -71,6 +71,11 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public string TypeValue { get; set; }
|
||||
}
|
||||
|
||||
public class EmptyQCQuestionInDto
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
}
|
||||
|
||||
///<summary>TrialQCQuestionQuery 列表查询参数模型</summary>
|
||||
public class TrialQCQuestionQuery
|
||||
{
|
||||
|
||||
@@ -24,9 +24,9 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
private IReadingImageTaskService _IReadingImageTaskService;
|
||||
|
||||
public QCListService(
|
||||
IRepository<SubjectVisit> subjectVisitRepository,
|
||||
IRepository<Trial> trialRepository,
|
||||
IRepository<ClinicalDataTrialSet> clinicalDataTrialSet,
|
||||
IRepository<SubjectVisit> subjectVisitRepository,
|
||||
IRepository<Trial> trialRepository,
|
||||
IRepository<ClinicalDataTrialSet> clinicalDataTrialSet,
|
||||
IRepository<TrialQCQuestionAnswer> trialQCQuestionAnswerRepository,
|
||||
IRepository<TrialQCQuestion> trialQCQuestionRepository,
|
||||
IReadingImageTaskService IReadingImageTaskService,
|
||||
@@ -278,7 +278,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
//Expression<Func<DicomStudy, bool>> studyLambda = x => x.TrialId == visitSearchDTO.TrialId;
|
||||
////Expression<Func<VisitStage, bool>> visitPlanLambda = x => x.TrialId == subjectVisitSearch.TrialId;
|
||||
|
||||
//if (visitSearchDTO.SiteId != null && visitSearchDTO.SiteId != Guid.Empty)
|
||||
//if (visitSearchDTO.SiteId != null && visitSearchDTO.SiteId != Guid.Empty)shiwu
|
||||
//{
|
||||
// subjectVisitLambda = subjectVisitLambda.And(t => t.SiteId == visitSearchDTO.SiteId.Value);
|
||||
// studyLambda = studyLambda.And(t => t.SiteId == visitSearchDTO.SiteId.Value);
|
||||
@@ -451,7 +451,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
//.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState)
|
||||
.ProjectTo<QCVisitViewModel>(_mapper.ConfigurationProvider);
|
||||
|
||||
var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(SubjectVisit.SubjectId), nameof(SubjectVisit.VisitNum) };
|
||||
var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(QCVisitViewModel.AuditState) +" asc" };
|
||||
var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc, string.IsNullOrWhiteSpace(visitSearchDTO.SortField), defalutSortArray);
|
||||
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
IRepository<DicomStudy> dicomStudyRepository,
|
||||
IRepository<DicomSeries> dicomSeriesrepository,
|
||||
IRepository<Subject> subjectRepository,
|
||||
IRepository<ReadingClinicalData> readingClinicalDataRepository,
|
||||
IRepository<ReadingClinicalData> readingClinicalDataRepository,
|
||||
IRepository<QCChallengeDialog> qCChallengeDialogrepository,
|
||||
IRepository<CheckChallengeDialog> checkChallengeDialogrepository,
|
||||
IVisitTaskHelpeService visitTaskHelpeService
|
||||
@@ -68,7 +68,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
|
||||
[HttpGet("{trialId:guid}/{subjectVisitId:guid}/{currentQCType:int}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
public async Task<IResponseOutput> VerifyQCCanAddChallenge(Guid subjectVisitId, [FromRoute] CurrentQC currentQCType)
|
||||
{
|
||||
await VerifyIsCanQCAsync(null, subjectVisitId);
|
||||
@@ -92,7 +92,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPost("{trialId:guid}/{trialQCProcess:int}/{currentQCType:int}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
public async Task<IResponseOutput> AddOrUpdateQCChallenge(QCChallengeCommand qaQuestionCommand, Guid trialId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType)
|
||||
{
|
||||
await VerifyIsCanQCAsync(null, qaQuestionCommand.SubjectVisitId);
|
||||
@@ -101,7 +101,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
{
|
||||
if (await _qcChallengeRepository.AnyAsync(t => t.IsClosed == false && t.SubjectVisitId == qaQuestionCommand.SubjectVisitId && t.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload))
|
||||
{
|
||||
//---当前访视未关闭的质疑已设置了同意CRC重传影像。请在CRC完成影像重传后,先关闭原质疑,再添加新的质疑。
|
||||
//---当前访视未关闭的质疑已设置了同意CRC重传影像。请在CRC完成影像重传后,先关闭原质疑,再添加新的质疑。
|
||||
throw new BusinessValidationFailedException(_localizer["QCOperation_QuestionExist"]);
|
||||
|
||||
}
|
||||
@@ -152,7 +152,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
[HttpPut]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[UnitOfWork]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
public async Task<IResponseOutput> CloseQCChallenge(CloseQCChallengeInDto input)
|
||||
{
|
||||
|
||||
@@ -206,7 +206,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{trialId:guid}/{subjectVisitId:guid}/{qcChallengeId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
public async Task<IResponseOutput> DeleteQCChallenge(Guid qcChallengeId)
|
||||
{
|
||||
|
||||
@@ -234,7 +234,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPost("{trialId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.CRC_IQC)]
|
||||
// [Authorize(Policy = IRaCISPolicy.CRC_IQC)]
|
||||
public async Task<IResponseOutput> AddQCChallengeReply(QADialogCommand qaDialogCommand)
|
||||
{
|
||||
var qaReply = _mapper.Map<QCChallengeDialog>(qaDialogCommand);
|
||||
@@ -269,7 +269,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPost("{trialId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.PM_APM_CRC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.PM_APM_CRC)]
|
||||
public async Task<IResponseOutput> AddCheckChallengeReply(CheckChallengeDialogCommand checkDialogCommand)
|
||||
{
|
||||
|
||||
@@ -309,7 +309,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPut("{trialId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
public async Task<IResponseOutput> CloseCheckChallenge(CloseCheckChallengeDto input)
|
||||
{
|
||||
|
||||
@@ -345,7 +345,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPut("{trialId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
[UnitOfWork]
|
||||
public async Task<IResponseOutput> SetCheckPass(SetCheckPassDt data)
|
||||
{
|
||||
@@ -392,7 +392,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPut("{trialId:guid}/{subjectVisitId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
public async Task<IResponseOutput> CRCRequstCheckBack(Guid subjectVisitId)
|
||||
{
|
||||
var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException();
|
||||
@@ -436,7 +436,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
|
||||
|
||||
[HttpPut("{trialId:guid}/{subjectVisitId:guid}")]
|
||||
[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
public async Task<IResponseOutput> RejectCheckBack(Guid subjectVisitId)
|
||||
{
|
||||
@@ -471,7 +471,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPut("{trialId:guid}/{subjectVisitId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
[UnitOfWork]
|
||||
public async Task<IResponseOutput> CheckBack(Guid subjectVisitId)
|
||||
{
|
||||
@@ -525,7 +525,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
//_qcChallengeRepository.Delete(t => t.SubjectVisitId == subjectVisitId);
|
||||
//_qcChallengeDialogRepository.Delete(t => t.SubjectVisitId == subjectVisitId);
|
||||
//_checkChallengeDialogRepository.Delete(t => t.SubjectVisitId == subjectVisitId);
|
||||
//---PM/APM同意一致性核查回退。
|
||||
//---PM/APM同意一致性核查回退。
|
||||
await _repository.AddAsync(new CheckChallengeDialog() { SubjectVisitId = subjectVisitId, TalkContent = _localizer["QCOperation_PMAPMConsistency"], UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt });
|
||||
|
||||
await _repository.BatchDeleteAsync<TrialQCQuestionAnswer>(t => t.SubjectVisitId == subjectVisitId);
|
||||
@@ -550,7 +550,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// </summary>
|
||||
[HttpPost("{trialId:guid}/{subjectVisitId:guid}/{trialQCProcess:int}/{currentQCType:int}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
public async Task<IResponseOutput> AddOrUpdateQCQuestionAnswerList(QCQuestionAnswerCommand[] qcQuestionAnswerCommands, Guid trialId, Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType)
|
||||
{
|
||||
//验证是否能操作
|
||||
@@ -622,7 +622,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPut("{trialId:guid}/{subjectVisitId:guid}/{studyId:guid}/{seriesId:guid}/{state:int}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
public async Task<IResponseOutput> SetSeriesState(Guid subjectVisitId, Guid studyId, Guid seriesId, int state)
|
||||
{
|
||||
|
||||
@@ -689,7 +689,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPost("{trialId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.CRC_IQC)]
|
||||
// [Authorize(Policy = IRaCISPolicy.CRC_IQC)]
|
||||
public async Task<IResponseOutput> UpdateModality(UpdateModalityCommand updateModalityCommand)
|
||||
{
|
||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC)
|
||||
@@ -701,7 +701,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
{
|
||||
if (await _subjectVisitRepository.AnyAsync(t => t.Id == updateModalityCommand.SubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted))
|
||||
{
|
||||
//---提交之后,不允许修改!
|
||||
//---提交之后,不允许修改!
|
||||
throw new BusinessValidationFailedException(_localizer["QCOperation_NoModifyAfterSubmit"]);
|
||||
}
|
||||
}
|
||||
@@ -716,7 +716,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
|
||||
|
||||
study.BodyPartForEdit = updateModalityCommand.BodyPart;
|
||||
|
||||
|
||||
study.ModalityForEdit = updateModalityCommand.Modality;
|
||||
|
||||
await _repository.BatchUpdateAsync<DicomSeries>(t => t.StudyId == studyId, r => new DicomSeries() { BodyPartForEdit = updateModalityCommand.BodyPart });
|
||||
@@ -770,7 +770,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
[HttpPost, Route("{trialId:guid}/{subjectVisitId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[UnitOfWork]
|
||||
[Authorize(Policy = IRaCISPolicy.CRC_IQC)]
|
||||
// [Authorize(Policy = IRaCISPolicy.CRC_IQC)]
|
||||
public async Task<IResponseOutput> DeleteStudyList(Guid[] ids, Guid subjectVisitId, Guid trialId)
|
||||
{
|
||||
|
||||
@@ -791,7 +791,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
|
||||
await _dicomStudyRepository.DeleteAsync(study);
|
||||
|
||||
|
||||
|
||||
var succeess2 = await _repository.BatchDeleteAsync<DicomInstance>(t => t.StudyId == id);
|
||||
var success3 = await _dicomSeriesrepository.BatchDeleteNoTrackingAsync(t => t.StudyId == id);
|
||||
|
||||
@@ -814,7 +814,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
await _subjectVisitRepository.SaveChangesAsync();
|
||||
@@ -853,7 +853,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
|
||||
/// <summary>替换当前领取人 </summary>
|
||||
[HttpPut("{trialId:guid}/{subjectVisitId:guid}")]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
public async Task<IResponseOutput> ReplaceQCTaskActionUser(Guid trialId, Guid subjectVisitId)
|
||||
{
|
||||
@@ -878,6 +878,108 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 领取下一个质控任务
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<GetNextIQCQualityOutDto> CollectNextIQCQuality(GetNextIQCQualityInDto inDto)
|
||||
{
|
||||
var nextIQCQuality = await this.GetNextIQCQuality(inDto);
|
||||
|
||||
if (nextIQCQuality.VisitId != null)
|
||||
{
|
||||
var visit = await _subjectVisitRepository.Where(x => x.Id == nextIQCQuality.VisitId).FirstOrDefaultAsync();
|
||||
if (!visit.IsTake)
|
||||
{
|
||||
await ObtainOrCancelQCTask(inDto.TrialId, nextIQCQuality.VisitId.Value, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nextIQCQuality;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取下一个质控任务
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<GetNextIQCQualityOutDto> GetNextIQCQuality(GetNextIQCQualityInDto inDto)
|
||||
{
|
||||
var trialConfig = await _trialRepository
|
||||
.Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification })
|
||||
.FirstOrDefaultAsync(t => t.TrialId == inDto.TrialId)
|
||||
.IfNullThrowException();
|
||||
|
||||
SubjectVisit? subjectVisit = null;
|
||||
List<SubjectVisit>? visitList = null;
|
||||
switch (trialConfig.QCProcessEnum)
|
||||
{
|
||||
case TrialQCProcess.NotAudit:
|
||||
return new GetNextIQCQualityOutDto() { };
|
||||
break;
|
||||
case TrialQCProcess.SingleAudit:
|
||||
visitList = await _subjectVisitRepository.Where(x => x.TrialId == inDto.TrialId && (x.CurrentActionUserId == _userInfo.Id || (x.AuditState != AuditStateEnum.PrimaryQCPassed &&!x.IsTake))).Include(x=>x.Subject).ToListAsync();
|
||||
|
||||
subjectVisit = visitList.Where(x => x.SubjectId == inDto.SubjectId).OrderBy(x=>x.VisitNum).FirstOrDefault();
|
||||
if(subjectVisit!=null)
|
||||
{
|
||||
return new GetNextIQCQualityOutDto() {
|
||||
SubjectId= subjectVisit.SubjectId,
|
||||
VisitId= subjectVisit.Id
|
||||
};
|
||||
}
|
||||
|
||||
subjectVisit= visitList.OrderBy(x => x.Subject.Code).ThenBy(x=>x.VisitNum).FirstOrDefault();
|
||||
if (subjectVisit != null)
|
||||
{
|
||||
return new GetNextIQCQualityOutDto()
|
||||
{
|
||||
SubjectId = subjectVisit.SubjectId,
|
||||
VisitId = subjectVisit.Id
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return new GetNextIQCQualityOutDto() { };
|
||||
}
|
||||
break;
|
||||
case TrialQCProcess.DoubleAudit:
|
||||
|
||||
visitList = await _subjectVisitRepository.Where(x => x.TrialId == inDto.TrialId && (x.CurrentActionUserId == _userInfo.Id || (x.AuditState != AuditStateEnum.QCPassed))).Include(x => x.Subject).ToListAsync();
|
||||
if (subjectVisit != null)
|
||||
{
|
||||
return new GetNextIQCQualityOutDto()
|
||||
{
|
||||
SubjectId = subjectVisit.SubjectId,
|
||||
VisitId = subjectVisit.Id
|
||||
};
|
||||
}
|
||||
|
||||
subjectVisit = visitList.OrderBy(x => x.Subject.Code).ThenBy(x => x.VisitNum).FirstOrDefault();
|
||||
if (subjectVisit != null)
|
||||
{
|
||||
return new GetNextIQCQualityOutDto()
|
||||
{
|
||||
SubjectId = subjectVisit.SubjectId,
|
||||
VisitId = subjectVisit.Id
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return new GetNextIQCQualityOutDto() { };
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return new GetNextIQCQualityOutDto() { };
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 手动领取 或者取消 QC任务
|
||||
@@ -888,7 +990,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPut("{trialId:guid}/{subjectVisitId:guid}/{obtaionOrCancel:bool}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
public async Task<IResponseOutput> ObtainOrCancelQCTask(Guid trialId, Guid subjectVisitId, bool obtaionOrCancel)
|
||||
{
|
||||
|
||||
@@ -1111,7 +1213,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
public async Task<IResponseOutput> CRCRequestToQC(CRCRequestToQCCommand cRCRequestToQCCommand)
|
||||
{
|
||||
|
||||
@@ -1167,8 +1269,8 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
}
|
||||
|
||||
//基线 且配置了临床数据
|
||||
if (trialConfig.ClinicalInformationTransmissionEnum != 0 /*&& dbSubjectVisit.IsBaseLine*//*&&dbSubjectVisit.ClinicalDataSignUserId==null*/)
|
||||
{
|
||||
//if (trialConfig.ClinicalInformationTransmissionEnum != 0 /*&& dbSubjectVisit.IsBaseLine*//*&&dbSubjectVisit.ClinicalDataSignUserId==null*/)
|
||||
//{
|
||||
|
||||
|
||||
////找到需要确认的PDF 临床数据 如果没有CRC 没有上传 那么就添加一条没有文件的记录
|
||||
@@ -1204,7 +1306,12 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
|
||||
// CRC 上传的基线数据签名
|
||||
|
||||
await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(x => x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ReadingId == dbSubjectVisit.Id && x.IsSign==false, x => new ReadingClinicalData()
|
||||
await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(x =>
|
||||
|
||||
(x.ClinicalDataTrialSet.ClinicalDataLevel== ClinicalLevel.Subject|| x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)&&
|
||||
|
||||
|
||||
x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ReadingId == dbSubjectVisit.Id && x.IsSign==false, x => new ReadingClinicalData()
|
||||
{
|
||||
IsSign = true,
|
||||
ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned
|
||||
@@ -1226,7 +1333,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
//}
|
||||
|
||||
//return ResponseOutput.NotOk("没有签名临床数据,不允许提交");
|
||||
}
|
||||
//}
|
||||
|
||||
|
||||
|
||||
@@ -1418,7 +1525,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPost("{trialId:guid}/{subjectVisitId:guid}/{auditState:int}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
[UnitOfWork]
|
||||
public async Task<IResponseOutput> QCPassedOrFailed(Guid trialId, Guid subjectVisitId, [FromRoute] AuditStateEnum auditState)
|
||||
{
|
||||
@@ -1657,7 +1764,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPut("{trialId:guid}/{subjectVisitId:guid}/{setOrCancel:bool}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
public async Task<IResponseOutput> SetVisitUrgent(Guid trialId, Guid subjectVisitId, bool setOrCancel)
|
||||
{
|
||||
var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException();
|
||||
@@ -1695,7 +1802,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPut("{trialId:guid}/{subjectVisitId:guid}/{qcChallengeId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
public async Task<IResponseOutput> SetNeedReupload(Guid trialId, Guid qcChallengeId)
|
||||
{
|
||||
|
||||
@@ -1796,7 +1903,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
public async Task<IResponseOutput> SetReuploadFinished(CRCReuploadFinishedCommand cRCReuploadFinishedCommand)
|
||||
{
|
||||
|
||||
@@ -1874,7 +1981,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
|
||||
[HttpPut("{trialId:guid}/{subjectVisitId:guid}/{qcChallengeId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
public async Task<IResponseOutput> CRCRequestReUpload(Guid qcChallengeId)
|
||||
{
|
||||
var qcChallenge = (await _qcChallengeRepository.FirstOrDefaultAsync(t => t.Id == qcChallengeId)).IfNullThrowException();
|
||||
@@ -1959,7 +2066,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
||||
|
||||
|
||||
[HttpPost("{trialId:guid}")]
|
||||
[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
public async Task<IResponseOutput> ForwardSVDicomImage(Guid[] subjectVisitIdList)
|
||||
{
|
||||
|
||||
@@ -32,6 +32,18 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
this._qCQuestionRepository = qCQuestionRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空Qc问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> EmptyQCQuestion(EmptyQCQuestionInDto inDto)
|
||||
{
|
||||
await _trialQcQuestionRepository.DeleteFromQueryAsync(x => x.TrialId == inDto.TrialId);
|
||||
await _trialQcQuestionRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(true);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<(List<TrialQCQuestionConfigureView>, object)> GetTrialQCQuestionConfigureList(TrialQCQuestionQuery queryTrialQCQuestionConfigure)
|
||||
@@ -141,7 +153,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
/// <param name="trialId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{trialId:guid}")]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
public async Task<IResponseOutput> BatchAddTrialQCQuestionConfigure(List<TrialQCQuestionConfigureBatchAdd> batchList, Guid trialId)
|
||||
{
|
||||
@@ -248,7 +260,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
return childList;
|
||||
}
|
||||
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
public async Task<IResponseOutput> AddOrUpdateTrialQCQuestionConfigure(TrialQCQuestionAddOrEdit addOrEditTrialQCQuestionConfigure)
|
||||
{
|
||||
@@ -273,7 +285,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
|
||||
[HttpDelete("{trialId:guid}/{trialQCQuestionConfigureId:guid}")]
|
||||
[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
//[Authorize(Policy = IRaCISPolicy.IQC)]
|
||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||
public async Task<IResponseOutput> DeleteTrialQCQuestionConfigure(Guid trialQCQuestionConfigureId, Guid trialId)
|
||||
{
|
||||
|
||||
@@ -367,9 +367,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
.ForMember(d => d.CurrentActionUserName, u => u.MapFrom(s => s.CurrentActionUser.UserName))
|
||||
.ForMember(d => d.PreliminaryAuditUserName, u => u.MapFrom(s => s.PreliminaryAuditUser.UserName))
|
||||
.ForMember(d => d.ReviewAuditUserName, u => u.MapFrom(s => s.ReviewAuditUser.UserName))
|
||||
.ForMember(d => d.IsHaveClinicalData, u => u.MapFrom(t => t.IsBaseLine ? t.PreviousHistoryList.Any() || t.PreviousOtherList.Any()
|
||||
|| t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count() > 0)
|
||||
|| t.PreviousSurgeryList.Any() : false))
|
||||
.ForMember(d => d.IsHaveClinicalData, u => u.MapFrom(t => t.PreviousHistoryList.Any() || t.PreviousOtherList.Any()
|
||||
|| t.Subject.ClinicalFormList.Any(x => x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ReadingId == t.Id)
|
||||
|| t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count() > 0)
|
||||
|| t.PreviousSurgeryList.Any()))
|
||||
.ForMember(d => d.DicomStudyCount, u => u.MapFrom(t => t.StudyList.Count()))
|
||||
.ForMember(d => d.NoneDicomStudyCount, u => u.MapFrom(t => t.NoneDicomStudyList.Count(t => t.NoneDicomFileList.Any())));
|
||||
|
||||
@@ -385,9 +386,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
.ForMember(d => d.MedicalNo, u => u.MapFrom(s => s.Subject.MedicalNo))
|
||||
.ForMember(d => d.Sex, u => u.MapFrom(s => s.Subject.Sex))
|
||||
.ForMember(d => d.Age, u => u.MapFrom(t => t.Subject.Age))
|
||||
.ForMember(d => d.IsHaveClinicalData, u => u.MapFrom(t => t.IsBaseLine ? t.PreviousHistoryList.Any() || t.PreviousOtherList.Any()
|
||||
.ForMember(d => d.IsHaveClinicalData, u => u.MapFrom(t => t.PreviousHistoryList.Any() || t.PreviousOtherList.Any()
|
||||
|| t.Subject.ClinicalFormList.Any(x=>x.ClinicalDataTrialSet.UploadRole==UploadRole.CRC&& x.ReadingId==t.Id)
|
||||
|| t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count() > 0)
|
||||
|| t.PreviousSurgeryList.Any() : false))
|
||||
|| t.PreviousSurgeryList.Any()))
|
||||
|
||||
//.ForMember(d => d.VisitName, u => u.MapFrom(t =>t.InPlan? t.VisitStage.VisitName : t.VisitName))
|
||||
//.ForMember(d => d.VisitNum, u => u.MapFrom(t => t.InPlan ? t.VisitStage.VisitNum : t.VisitNum))
|
||||
|
||||
@@ -0,0 +1,931 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2023-06-15 15:06:06
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Infra.EFCore.Common;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using MassTransit;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using IRaCIS.Core.Application.Service.Reading.Interface;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// 临床答案
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "Reading")]
|
||||
public class ClinicalAnswerService : BaseService, IClinicalAnswerService
|
||||
{
|
||||
|
||||
private readonly IRepository<TrialClinicalQuestion> _trialClinicalQuestionRepository;
|
||||
|
||||
private readonly IRepository<SystemClinicalQuestion> _systemClinicalQuestionRepository;
|
||||
|
||||
|
||||
private readonly IRepository<SystemClinicalTableQuestion> _systemClinicalTableQuestionRepository;
|
||||
|
||||
private readonly IRepository<TrialClinicalTableQuestion> _trialClinicalTableQuestionRepository;
|
||||
|
||||
private readonly IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository;
|
||||
|
||||
private readonly IRepository<ClinicalForm> _clinicalFormRepository;
|
||||
private readonly IRepository<Subject> _subjectRepository;
|
||||
private readonly IRepository<ReadModuleCriterionFrom> _readModuleCriterionFromRepository;
|
||||
private readonly IRepository<ReadModule> _readModuleRepository;
|
||||
private readonly IRepository<ClinicalQuestionAnswer> _clinicalQuestionAnswerRepository;
|
||||
|
||||
private readonly IRepository<ClinicalTableAnswer> _clinicalTableAnswerRepository;
|
||||
|
||||
private readonly IRepository<ClinicalAnswerRowInfo> _clinicalAnswerRowInfoRepository;
|
||||
|
||||
private readonly IRepository<ReadingClinicalData> _readingClinicalDataRepository;
|
||||
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
|
||||
|
||||
private readonly IClinicalQuestionService _iClinicalQuestionService;
|
||||
|
||||
private readonly IReadingClinicalDataService _iReadingClinicalDataService;
|
||||
|
||||
|
||||
public ClinicalAnswerService(IRepository<TrialClinicalQuestion> trialClinicalQuestionRepository,
|
||||
IRepository<SystemClinicalTableQuestion> systemClinicalTableQuestionRepository,
|
||||
IRepository<TrialClinicalTableQuestion> trialClinicalTableQuestionRepository,
|
||||
IRepository<ReadingClinicalData> readingClinicalDataRepository,
|
||||
IRepository<ClinicalForm> clinicalFormRepository,
|
||||
IRepository<Subject> subjectRepository,
|
||||
IReadingClinicalDataService iReadingClinicalDataService,
|
||||
IRepository<ReadModuleCriterionFrom> readModuleCriterionFromRepository,
|
||||
IRepository<ReadModule> readModuleRepository,
|
||||
IRepository<SubjectVisit> subjectVisitRepository,
|
||||
IRepository<ClinicalTableAnswer> clinicalTableAnswerRepository,
|
||||
IRepository<ClinicalQuestionAnswer> clinicalQuestionAnswerRepository,
|
||||
IClinicalQuestionService iClinicalQuestionService,
|
||||
IRepository<ClinicalAnswerRowInfo> clinicalAnswerRowInfoRepository,
|
||||
IRepository<ClinicalDataTrialSet> clinicalDataTrialSetRepository,
|
||||
IRepository<SystemClinicalQuestion> systemClinicalQuestionRepository
|
||||
)
|
||||
{
|
||||
_subjectVisitRepository = subjectVisitRepository;
|
||||
_readingClinicalDataRepository = readingClinicalDataRepository;
|
||||
_clinicalAnswerRowInfoRepository = clinicalAnswerRowInfoRepository;
|
||||
_clinicalQuestionAnswerRepository = clinicalQuestionAnswerRepository;
|
||||
_systemClinicalTableQuestionRepository = systemClinicalTableQuestionRepository;
|
||||
_trialClinicalQuestionRepository = trialClinicalQuestionRepository;
|
||||
_trialClinicalTableQuestionRepository = trialClinicalTableQuestionRepository;
|
||||
_systemClinicalQuestionRepository = systemClinicalQuestionRepository;
|
||||
_clinicalDataTrialSetRepository = clinicalDataTrialSetRepository;
|
||||
_iReadingClinicalDataService = iReadingClinicalDataService;
|
||||
_clinicalFormRepository = clinicalFormRepository;
|
||||
this._subjectRepository = subjectRepository;
|
||||
this._readModuleCriterionFromRepository = readModuleCriterionFromRepository;
|
||||
this._readModuleRepository = readModuleRepository;
|
||||
_clinicalTableAnswerRepository = clinicalTableAnswerRepository;
|
||||
_iClinicalQuestionService = iClinicalQuestionService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CRC签名临床数据
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> CRCSignClinicalData(CRCSignClinicalDataInDto inDto)
|
||||
{
|
||||
|
||||
await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(x =>x.Id==inDto.ReadingClinicalDataId, x => new ReadingClinicalData()
|
||||
{
|
||||
IsSign = true,
|
||||
ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned
|
||||
});
|
||||
|
||||
await _readingClinicalDataRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Ok(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动添加CRC临床数据
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task AutoAddCRCClinical(AutoAddClinicalInDto inDto)
|
||||
{
|
||||
var dataTrialSetList = await _clinicalDataTrialSetRepository.Where(x =>x.TrialId == inDto.TrialId && x.UploadRole == UploadRole.CRC && x.IsConfirm)
|
||||
.IgnoreAutoIncludes().ToListAsync();
|
||||
var baseLine = await _subjectVisitRepository.Where(x => x.TrialId == inDto.TrialId)
|
||||
.WhereIf(inDto.SubjectId!=null,x=>x.SubjectId==inDto.SubjectId)
|
||||
|
||||
.Select(x => new
|
||||
{
|
||||
|
||||
x.SubjectId,
|
||||
VisitId = x.Id,
|
||||
x.IsBaseLine,
|
||||
}).ToListAsync();
|
||||
|
||||
var clinicalDataList =await _readingClinicalDataRepository
|
||||
.WhereIf(inDto.SubjectId != null, x => x.SubjectId == inDto.SubjectId)
|
||||
.Where(x =>x.TrialId==inDto.TrialId&&x.ClinicalDataTrialSet.UploadRole== UploadRole.CRC)
|
||||
.Select(x=>new
|
||||
{
|
||||
ClinicalDataTrialSetId=x.ClinicalDataTrialSetId,
|
||||
SubjectId=x.SubjectId,
|
||||
x.ReadingId,
|
||||
|
||||
}).ToListAsync();
|
||||
|
||||
List<ReadingClinicalData> readingClinicalDatas = new List<ReadingClinicalData>();
|
||||
|
||||
baseLine.Select(x => x.SubjectId).Distinct().ForEach(n =>
|
||||
{
|
||||
var baseLineVisitId = baseLine.Where(x => x.IsBaseLine && x.SubjectId == n).Select(x => x.VisitId).First();
|
||||
readingClinicalDatas.AddRange(
|
||||
dataTrialSetList.Where(x => x.ClinicalDataLevel == ClinicalLevel.Subject).Where(x => clinicalDataList.Where(y => y.ClinicalDataTrialSetId == x.Id && y.SubjectId == n).Count() == 0)
|
||||
.Select(x => new ReadingClinicalData()
|
||||
{
|
||||
ClinicalDataTrialSetId = x.Id,
|
||||
IsVisit = true,
|
||||
SubjectId = n,
|
||||
ReadingId = baseLineVisitId,
|
||||
TrialId = inDto.TrialId
|
||||
}).ToList());
|
||||
|
||||
|
||||
readingClinicalDatas.AddRange(
|
||||
dataTrialSetList.Where(x => x.ClinicalDataLevel == ClinicalLevel.ImageRead).Where(x => clinicalDataList.Where(y => y.ClinicalDataTrialSetId == x.Id && y.SubjectId == n).Count() == 0)
|
||||
.Select(x => new ReadingClinicalData()
|
||||
{
|
||||
ClinicalDataTrialSetId = x.Id,
|
||||
IsVisit = false,
|
||||
SubjectId = n,
|
||||
ReadingId = default(Guid),
|
||||
TrialId = inDto.TrialId
|
||||
}).ToList());
|
||||
|
||||
readingClinicalDatas.AddRange(
|
||||
dataTrialSetList.Where(x => x.ClinicalDataLevel == ClinicalLevel.OncologyRead).Where(x => clinicalDataList.Where(y => y.ClinicalDataTrialSetId == x.Id && y.SubjectId == n).Count() == 0)
|
||||
.Select(x => new ReadingClinicalData()
|
||||
{
|
||||
ClinicalDataTrialSetId = x.Id,
|
||||
IsVisit = false,
|
||||
SubjectId = n,
|
||||
ReadingId = default(Guid),
|
||||
TrialId = inDto.TrialId
|
||||
}).ToList());
|
||||
});
|
||||
|
||||
baseLine.ForEach(n =>
|
||||
{
|
||||
readingClinicalDatas.AddRange(
|
||||
dataTrialSetList.Where(x => x.ClinicalDataLevel == ClinicalLevel.SubjectVisit).Where(x => clinicalDataList.Where(y => y.ClinicalDataTrialSetId == x.Id && y.ReadingId == n.VisitId).Count() == 0)
|
||||
.Select(x => new ReadingClinicalData()
|
||||
{
|
||||
ClinicalDataTrialSetId = x.Id,
|
||||
IsVisit = true,
|
||||
SubjectId = n.SubjectId,
|
||||
ReadingId = n.VisitId,
|
||||
TrialId = inDto.TrialId
|
||||
}).ToList());
|
||||
});
|
||||
|
||||
|
||||
await _readingClinicalDataRepository.AddRangeAsync(readingClinicalDatas);
|
||||
await _readingClinicalDataRepository.SaveChangesAsync();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取CRC受试者临床数据
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<GetCRCSubjectClinicalOutDto>> GetCRCSubjectClinicalList(GetCRCSubjectClinicalInDto inDto)
|
||||
{
|
||||
|
||||
//await AutoAddCRCClinical(new AutoAddClinicalInDto()
|
||||
//{
|
||||
// TrialId = inDto.TrialId
|
||||
//}) ;
|
||||
|
||||
var subjects = await _subjectRepository.Where(x => x.TrialId == inDto.TrialId).Select(x => new GetCRCSubjectClinicalResultDto()
|
||||
{
|
||||
SubjectId = x.Id,
|
||||
SubjectCode = x.Code
|
||||
}).ToListAsync();
|
||||
|
||||
|
||||
var clinicalData= _readingClinicalDataRepository.Where(x=>x.TrialId == inDto.TrialId&&x.ClinicalDataTrialSet.UploadRole==UploadRole.CRC&&x.ClinicalDataTrialSet.ClinicalDataLevel!= ClinicalLevel.SubjectVisit)
|
||||
.Where(x=>!x.IsSign)
|
||||
.WhereIf(inDto.SubjectId!=null,x=>x.SubjectId==inDto.SubjectId)
|
||||
.WhereIf(inDto.SubjectCode != null, x => x.Subject.Code.Contains(inDto.SubjectCode??string.Empty))
|
||||
.Where(x=> x.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.Subject)
|
||||
.Include(x=>x.ClinicalDataTrialSet).Select(x=>new GetCRCSubjectClinicalOutDto() {
|
||||
SubjectId=x.SubjectId,
|
||||
SubjectCode=x.Subject.Code,
|
||||
TrialId=inDto.TrialId,
|
||||
ReadingId= x.ReadingId,
|
||||
ReadingClinicalDataId=x.Id,
|
||||
UploadRole = x.ClinicalDataTrialSet.UploadRole,
|
||||
ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
|
||||
ClinicalUploadType= x.ClinicalDataTrialSet.ClinicalUploadType,
|
||||
BaseLineVisitId= x.Subject.SubjectVisitList.Where(x=>x.IsBaseLine).Select(x=>x.Id).FirstOrDefault(),
|
||||
ClinicalDataTrialSetId = x.ClinicalDataTrialSet.Id,
|
||||
ClinicalDataSetEnName= x.ClinicalDataTrialSet.ClinicalDataSetEnName,
|
||||
ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName,
|
||||
});
|
||||
|
||||
var pageList = await clinicalData.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, string.IsNullOrWhiteSpace(inDto.SortField) ? nameof(GetCRCSubjectClinicalOutDto.SubjectCode) : inDto.SortField, inDto.Asc);
|
||||
// 一次查询报错 分两次写
|
||||
pageList.CurrentPageData.ForEach(x =>
|
||||
{
|
||||
x.ClinicalDataSetEnName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us);
|
||||
});
|
||||
var clinicalFormData = await _clinicalFormRepository.Where(x => x.TrialId == inDto.TrialId).ToListAsync();
|
||||
pageList.CurrentPageData.ForEach(n =>
|
||||
{
|
||||
n.ClinicalCount = clinicalFormData.Where(y => y.ClinicalDataTrialSetId == n.ClinicalDataTrialSetId && y.SubjectId == n.SubjectId).Count();
|
||||
});
|
||||
return pageList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取表单列表
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<GetClinicalQuestionAnswerListOutDto> GetClinicalQuestionFormList(GetClinicalQuestionAnswerListInDto inDto)
|
||||
{
|
||||
var result = new GetClinicalQuestionAnswerListOutDto();
|
||||
result.AnswerList = new List<Dictionary<string, string>>();
|
||||
result.QuestionList=await _trialClinicalQuestionRepository.Where(x=>x.TrialClinicalId==inDto.ClinicalDataTrialSetId
|
||||
&&x.ClinicalQuestionType!= ReadingQestionType.Group
|
||||
&& x.ClinicalQuestionType != ReadingQestionType.Table).OrderByDescending(x=>x.IsCheckDate).ThenBy(x=>x.ShowOrder)
|
||||
.ProjectTo<TrialClinicalQuestionDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
var answers = await _clinicalQuestionAnswerRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId)
|
||||
.Select(x => new
|
||||
{
|
||||
x.ClinicalFormId,
|
||||
x.ClinicalForm.CheckDate,
|
||||
x.QuestionId,
|
||||
x.Answer
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
var ClinicalFormIds = answers.OrderBy(x=>x.CheckDate).Select(x => x.ClinicalFormId).Distinct().ToList();
|
||||
ClinicalFormIds.ForEach(x =>
|
||||
{
|
||||
var dic = answers.Where(y => y.ClinicalFormId == x).ToDictionary(x => x.QuestionId.ToString(), x => x.Answer);
|
||||
dic.Add("ClinicalFormId", x.ToString());
|
||||
dic.Add("TrialId", inDto.TrialId.ToString());
|
||||
dic.Add("SubjectId", inDto.SubjectId.ToString());
|
||||
dic.Add("ClinicalDataTrialSetId", inDto.ClinicalDataTrialSetId.ToString());
|
||||
|
||||
result.AnswerList.Add(dic);
|
||||
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取临床数据表单问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<List<ClinicalQuestionPreviewDto>> GetClinicalFormInfo(GetClinicalFormInfoInDto inDto)
|
||||
{
|
||||
var formInfo = await _clinicalFormRepository.Where(x => x.Id == inDto.ClinicalFormId).FirstNotNullAsync();
|
||||
|
||||
var questionAnswer = await _clinicalQuestionAnswerRepository.Where(x => x.ClinicalFormId == inDto.ClinicalFormId).Select(x => new ClinicalFormQuestionAnswer
|
||||
{
|
||||
QuestionId = x.QuestionId,
|
||||
Answer = x.Answer
|
||||
}).ToListAsync();
|
||||
|
||||
var tableAnswer = await _clinicalTableAnswerRepository.Where(x => x.ClinicalFormId == inDto.ClinicalFormId).Select(x => new ClinicalFormTableQuestionAnswer
|
||||
{
|
||||
TableQuestionId = x.TableQuestionId,
|
||||
Answer = x.Answer,
|
||||
QuestionId = x.QuestionId,
|
||||
RowIndex = x.ClinicalAnswerRowInfo.RowIndex
|
||||
}).ToListAsync();
|
||||
|
||||
var questions = await _trialClinicalQuestionRepository.Where(x => x.TrialClinicalId == formInfo.ClinicalDataTrialSetId)
|
||||
.ProjectTo<ClinicalQuestionPreviewDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
var tableQuestions = await _trialClinicalTableQuestionRepository.Where(x => x.TrialClinicalId == formInfo.ClinicalDataTrialSetId)
|
||||
.ProjectTo<ClinicalTablePreviewDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
questions.ForEach(x => x.CreateTime = formInfo.CreateTime);
|
||||
var result = questions.Where(x => x.ClinicalQuestionType == ReadingQestionType.Group).ToList();
|
||||
|
||||
result.ForEach(x =>
|
||||
{
|
||||
_iClinicalQuestionService.FindChildQuestion(x, questions, tableQuestions, questionAnswer, tableAnswer);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 提交临床数据表单
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> SubmitClinicalForm(SubmitClinicalFormInDto inDto)
|
||||
{
|
||||
|
||||
|
||||
|
||||
ClinicalForm clinicalForm = new ClinicalForm() { };
|
||||
clinicalForm = new ClinicalForm()
|
||||
{
|
||||
ClinicalDataTrialSetId = inDto.ClinicalDataTrialSetId,
|
||||
SubjectId = inDto.SubjectId,
|
||||
TrialId= inDto.TrialId,
|
||||
Id = inDto.ClinicalFormId ?? NewId.NextGuid(),
|
||||
ReadingId = inDto.ReadingId,
|
||||
};
|
||||
|
||||
if (inDto.ClinicalFormId!=null&&(await _readModuleCriterionFromRepository.AnyAsync(x => x.ClinicalFormId == inDto.ClinicalFormId.Value)))
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalAnswer_translation"]);
|
||||
}
|
||||
|
||||
var existsClinical = await _clinicalFormRepository.Where(x =>
|
||||
x.SubjectId == inDto.SubjectId
|
||||
&& x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId
|
||||
).WhereIf(inDto.ReadingId != null, x => x.ReadingId == inDto.ReadingId)
|
||||
.Where(x => x.ClinicalDataTrialSet.UploadRole != UploadRole.CRC && !(x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.ImageRead
|
||||
|| x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.OncologyRead)).AnyAsync();
|
||||
|
||||
if (existsClinical)
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalAnswer_duplicateData"]);
|
||||
}
|
||||
try
|
||||
{
|
||||
var checkDateQuestionId = await _trialClinicalQuestionRepository.Where(x => x.TrialClinicalId == inDto.ClinicalDataTrialSetId && x.IsCheckDate).Select(x => x.Id).FirstNotNullAsync();
|
||||
clinicalForm.CheckDate = DateTime.Parse(inDto.QuestionAnswers.Where(x => x.QuestionId == checkDateQuestionId).Select(x => x.Answer).First());
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (clinicalForm.CheckDate != null)
|
||||
{
|
||||
if (await _readModuleRepository.AnyAsync(x =>x.SubjectId== inDto.SubjectId&& x.SubjectVisit.LatestScanDate <= clinicalForm.CheckDate && x.IsCRCConfirm))
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalAnswer_unableToAddOrUpdate"]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
List<ClinicalQuestionAnswer> clinicalQuestionAnswers = inDto.QuestionAnswers.Select(x => new ClinicalQuestionAnswer()
|
||||
{
|
||||
Answer=x.Answer,
|
||||
ClinicalDataTrialSetId=inDto.ClinicalDataTrialSetId,
|
||||
SubjectId=inDto.SubjectId,
|
||||
ClinicalFormId= clinicalForm.Id,
|
||||
QuestionId=x.QuestionId,
|
||||
}).ToList();
|
||||
|
||||
List<ClinicalAnswerRowInfo> clinicalAnswerRowInfos = new List<ClinicalAnswerRowInfo>();
|
||||
|
||||
List<ClinicalTableAnswer> clinicalTableAnswers = new List<ClinicalTableAnswer>();
|
||||
|
||||
inDto.TableQuestionAnswerList.ForEach(x => {
|
||||
var questionid = x.QuestionId;
|
||||
|
||||
for (int i = 0; i < x.TableQuestionAnswers.Count(); i++)
|
||||
{
|
||||
var rowInfo = new ClinicalAnswerRowInfo()
|
||||
{
|
||||
Id = NewId.NextGuid(),
|
||||
SubjectId = inDto.SubjectId,
|
||||
ClinicalFormId = clinicalForm.Id,
|
||||
QuestionId = questionid,
|
||||
RowIndex = i+1,
|
||||
};
|
||||
clinicalAnswerRowInfos.Add(rowInfo);
|
||||
|
||||
x.TableQuestionAnswers[i].ForEach(y => {
|
||||
|
||||
clinicalTableAnswers.Add(new ClinicalTableAnswer()
|
||||
{
|
||||
Answer=y.Answer,
|
||||
ClinicalFormId= clinicalForm.Id,
|
||||
QuestionId= questionid,
|
||||
RowId= rowInfo.Id,
|
||||
TableQuestionId=y.TableQuestionId,
|
||||
SubjectId= inDto.SubjectId,
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (inDto.ClinicalFormId != null)
|
||||
{
|
||||
await _clinicalFormRepository.BatchDeleteNoTrackingAsync(x => x.Id == inDto.ClinicalFormId);
|
||||
await _clinicalQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.ClinicalFormId == inDto.ClinicalFormId);
|
||||
await _clinicalAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.ClinicalFormId == inDto.ClinicalFormId);
|
||||
await _clinicalTableAnswerRepository.BatchDeleteNoTrackingAsync(x => x.ClinicalFormId == inDto.ClinicalFormId);
|
||||
}
|
||||
//if(inDto.ReadingId!=null)
|
||||
//{
|
||||
// await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(x => x.ReadingId == inDto.ReadingId && x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId, x => new ReadingClinicalData()
|
||||
// {
|
||||
// IsSign = true
|
||||
// });
|
||||
//}
|
||||
await _clinicalFormRepository.AddAsync(clinicalForm);
|
||||
await _clinicalQuestionAnswerRepository.AddRangeAsync(clinicalQuestionAnswers);
|
||||
await _clinicalAnswerRowInfoRepository.AddRangeAsync(clinicalAnswerRowInfos);
|
||||
await _clinicalTableAnswerRepository.AddRangeAsync(clinicalTableAnswers);
|
||||
await _clinicalTableAnswerRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Ok(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除表单数据
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> DeleteClinicalForm(DeleteClinicalFormInDto inDto)
|
||||
{
|
||||
|
||||
if (await _readModuleCriterionFromRepository.AnyAsync(x => x.ClinicalFormId == inDto.ClinicalFormId))
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalAnswer_unableToDelete"]);
|
||||
}
|
||||
|
||||
await _clinicalFormRepository.BatchDeleteNoTrackingAsync(x => x.Id == inDto.ClinicalFormId);
|
||||
await _clinicalQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.ClinicalFormId == inDto.ClinicalFormId);
|
||||
await _clinicalAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.ClinicalFormId == inDto.ClinicalFormId);
|
||||
await _clinicalTableAnswerRepository.BatchDeleteNoTrackingAsync(x => x.ClinicalFormId == inDto.ClinicalFormId);
|
||||
return ResponseOutput.Ok(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取PM待确认列表
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<GetCRCConfirmListOutDto>> GetPMConfirmList(GetPMConfirmListInDto inDto)
|
||||
{
|
||||
return await GetCRCConfirmList(new GetCRCConfirmListInDto()
|
||||
{
|
||||
TrialId = inDto.TrialId,
|
||||
IsCRCConfirm = true,
|
||||
IsPMConfirm = false,
|
||||
PageIndex = inDto.PageIndex,
|
||||
PageSize = inDto.PageSize,
|
||||
Asc = inDto.Asc,
|
||||
SortField = inDto.SortField,
|
||||
TrialReadingCriterionId = inDto.TrialReadingCriterionId
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取CRC确认列表
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<GetCRCConfirmListOutDto>> GetCRCConfirmList(GetCRCConfirmListInDto inDto)
|
||||
{
|
||||
if (inDto.ReadModuleId != null)
|
||||
{
|
||||
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync();
|
||||
inDto.TrialReadingCriterionId = readModule.TrialReadingCriterionId;
|
||||
}
|
||||
var query = _readModuleRepository.Where(x => x.TrialId == inDto.TrialId)
|
||||
.WhereIf(inDto.ReadModuleId != null, x => x.Id == inDto.ReadModuleId)
|
||||
.WhereIf(inDto.IsCRCConfirm != null, x => x.IsCRCConfirm == inDto.IsCRCConfirm)
|
||||
.WhereIf(inDto.IsPMConfirm != null, x => x.IsPMConfirm == inDto.IsPMConfirm)
|
||||
.WhereIf(inDto.SubjectCode != null, x => x.Subject.Code.Contains(inDto.SubjectCode??string.Empty))
|
||||
.WhereIf(inDto.TrialReadingCriterionId != null, x => x.TrialReadingCriterionId == inDto.TrialReadingCriterionId)
|
||||
.WhereIf(inDto.SubjectId != null, x => x.SubjectId == inDto.SubjectId)
|
||||
.WhereIf(inDto.StartTime != null, x => x.SubjectVisit.LatestScanDate >= inDto.StartTime)
|
||||
.WhereIf(inDto.EndTime != null, x => x.SubjectVisit.LatestScanDate <= inDto.EndTime)
|
||||
.Select(x => new GetCRCConfirmListOutDto()
|
||||
{
|
||||
|
||||
SubjectId = x.SubjectId,
|
||||
IsNotNeedPMConfirm=x.IsNotNeedPMConfirm,
|
||||
IsCRCConfirm = x.IsCRCConfirm,
|
||||
IsCRCApplicationRevoke=x.IsCRCApplicationRevoke,
|
||||
VisitBlindName=x.SubjectVisit.BlindName,
|
||||
LatestScanDate = x.SubjectVisit.LatestScanDate,
|
||||
ReadingSetType = x.ReadingSetType,
|
||||
IsPMConfirm = x.IsPMConfirm,
|
||||
SubjectCode = x.Subject.Code,
|
||||
ReadModuleId = x.Id,
|
||||
ModuleName=x.ModuleName,
|
||||
});
|
||||
|
||||
|
||||
var result = await query.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, new string[2] { "SubjectCode asc", "LatestScanDate asc" });
|
||||
|
||||
var formList = await _clinicalFormRepository.Where(x => x.TrialId == inDto.TrialId)
|
||||
.Where(x => x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC)
|
||||
.WhereIf(inDto.TrialReadingCriterionId!=null, x=>x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(y=>y.TrialReadingCriterionId== inDto.TrialReadingCriterionId))
|
||||
.Where(x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.ImageRead || x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.OncologyRead)
|
||||
.Include(x=>x.ClinicalDataTrialSet)
|
||||
.Select(x => new CRCClinicalForm
|
||||
{
|
||||
SubjectId=x.SubjectId,
|
||||
CheckDate = x.CheckDate,
|
||||
ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
|
||||
ClinicalFormId = x.Id,
|
||||
ClinicalDataTrialSetId= x.ClinicalDataTrialSet.Id,
|
||||
ClinicalDataSetName =x.ClinicalDataTrialSet.ClinicalDataSetName,
|
||||
ClinicalDataSetEnName=x.ClinicalDataTrialSet.ClinicalDataSetEnName,
|
||||
IsHaveTableQuestion=x.ClinicalDataTrialSet.TrialClinicalQuestionList.Any(y=>y.ClinicalQuestionType== ReadingQestionType.Table),
|
||||
}).ToListAsync();
|
||||
var confirmList = await _readModuleCriterionFromRepository.Where(x => x.TrialId == inDto.TrialId
|
||||
&&x.ClinicalForm.ClinicalDataTrialSet.UploadRole== UploadRole.CRC
|
||||
&&(x.ClinicalForm.ClinicalDataTrialSet.ClinicalDataLevel==ClinicalLevel.ImageRead|| x.ClinicalForm.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.OncologyRead))
|
||||
.Select(x => new GetCRCBeConfirm
|
||||
{
|
||||
CheckDate = x.ClinicalForm.CheckDate ?? default(DateTime),
|
||||
ClinicalDataSetName = x.ClinicalForm.ClinicalDataTrialSet.ClinicalDataSetName,
|
||||
ClinicalDataSetEnName = x.ClinicalForm.ClinicalDataTrialSet.ClinicalDataSetEnName,
|
||||
ClinicalFormId = x.ClinicalFormId,
|
||||
ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSet.Id,
|
||||
ReadModuleId=x.ReadModuleId,
|
||||
IsHaveTableQuestion=x.ClinicalForm.ClinicalDataTrialSet.TrialClinicalQuestionList.Any(y => y.ClinicalQuestionType == ReadingQestionType.Table)
|
||||
}).ToListAsync();
|
||||
|
||||
|
||||
result.CurrentPageData.ForEach(x =>
|
||||
{
|
||||
if (x.IsCRCConfirm)
|
||||
{
|
||||
x.ClinicalFormList = confirmList.Where(y => y.ReadModuleId == x.ReadModuleId).Select(y=>new GetCRCBeConfirmListOutDto() {
|
||||
CheckDate = y.CheckDate,
|
||||
ClinicalDataSetName= y.ClinicalDataSetName.LanguageName(y.ClinicalDataSetEnName, _userInfo.IsEn_Us),
|
||||
ClinicalDataSetEnName= y.ClinicalDataSetEnName,
|
||||
ClinicalFormId=y.ClinicalFormId,
|
||||
ClinicalDataTrialSetId=y.ClinicalDataTrialSetId,
|
||||
IsHaveTableQuestion=y.IsHaveTableQuestion,
|
||||
}).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x.ReadingSetType == ReadingSetType.ImageReading)
|
||||
{
|
||||
x.ClinicalFormList = formList.Where(y => y.ClinicalDataLevel == ClinicalLevel.ImageRead&&y.CheckDate <= x.LatestScanDate&&y.SubjectId==x.SubjectId)
|
||||
|
||||
.Select(y => new GetCRCBeConfirmListOutDto()
|
||||
{
|
||||
CheckDate = y.CheckDate ?? default(DateTime),
|
||||
ClinicalDataSetName = y.ClinicalDataSetName.LanguageName(y.ClinicalDataSetEnName, _userInfo.IsEn_Us),
|
||||
ClinicalDataSetEnName = y.ClinicalDataSetEnName,
|
||||
ClinicalFormId = y.ClinicalFormId,
|
||||
ClinicalDataTrialSetId = y.ClinicalDataTrialSetId,
|
||||
IsHaveTableQuestion = y.IsHaveTableQuestion,
|
||||
}).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
x.ClinicalFormList = formList.Where(y => y.ClinicalDataLevel == ClinicalLevel.OncologyRead&&y.CheckDate <= x.LatestScanDate && y.SubjectId == x.SubjectId)
|
||||
.Select(y => new GetCRCBeConfirmListOutDto()
|
||||
{
|
||||
CheckDate = y.CheckDate ?? default(DateTime),
|
||||
ClinicalDataSetName = y.ClinicalDataSetName.LanguageName(y.ClinicalDataSetEnName, _userInfo.IsEn_Us),
|
||||
ClinicalDataSetEnName = y.ClinicalDataSetEnName,
|
||||
ClinicalFormId = y.ClinicalFormId,
|
||||
ClinicalDataTrialSetId = y.ClinicalDataTrialSetId,
|
||||
IsHaveTableQuestion = y.IsHaveTableQuestion,
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取CRC待确认列表
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<List<GetCRCBeConfirmListOutDto>> GetCRCBeConfirmList(GetCRCBeConfirmListInDto inDto)
|
||||
{
|
||||
var result = (await this.GetCRCConfirmList(new GetCRCConfirmListInDto()
|
||||
{
|
||||
ReadModuleId = inDto.ReadModuleId,
|
||||
TrialId = inDto.TrialId,
|
||||
PageIndex=1,
|
||||
PageSize=9999,
|
||||
|
||||
})).CurrentPageData.SelectMany(x => x.ClinicalFormList).ToList();
|
||||
return result.OrderBy(x => x.ClinicalDataSetName).ThenBy(x => x.CheckDate).ToList();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取临床数据表格信息 查看没有表格问题的列表
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<(List<GetClinicalTableListOutDto>,object)> GetClinicalTableList(GetClinicalTableListInDto inDto)
|
||||
{
|
||||
|
||||
var readModule=await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync();
|
||||
|
||||
var confirmList = (await this.GetCRCConfirmList(new GetCRCConfirmListInDto()
|
||||
{
|
||||
ReadModuleId = inDto.ReadModuleId,
|
||||
TrialId = inDto.TrialId,
|
||||
PageIndex = 1,
|
||||
PageSize = 9999,
|
||||
|
||||
})).CurrentPageData.SelectMany(x => x.ClinicalFormList).ToList();
|
||||
|
||||
var clinicalDataTrialSetIds = confirmList.Select(x => x.ClinicalDataTrialSetId).Distinct().ToList();
|
||||
var clinicalFormIds = confirmList.Select(x => x.ClinicalFormId).ToList();
|
||||
|
||||
var questionList = await _trialClinicalQuestionRepository.Where(x => clinicalDataTrialSetIds.Contains( x.TrialClinicalId)
|
||||
&& x.ClinicalQuestionType != ReadingQestionType.Group
|
||||
&& x.ClinicalQuestionType != ReadingQestionType.Table).OrderBy(x=>x.TrialClinicalId).ThenBy(x => x.ShowOrder)
|
||||
.ProjectTo<TrialClinicalQuestionDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
var answers = await _clinicalQuestionAnswerRepository.Where(x => clinicalFormIds.Contains(x.ClinicalFormId))
|
||||
.Select(x => new
|
||||
{
|
||||
x.ClinicalDataTrialSetId,
|
||||
x.ClinicalFormId,
|
||||
x.ClinicalForm.CheckDate,
|
||||
x.QuestionId,
|
||||
x.Answer
|
||||
})
|
||||
.ToListAsync();
|
||||
List<GetClinicalTableListOutDto> result = new List<GetClinicalTableListOutDto>();
|
||||
clinicalDataTrialSetIds.ForEach(x => {
|
||||
GetClinicalTableListOutDto dto = new GetClinicalTableListOutDto();
|
||||
dto.ModuleName = readModule.ModuleName;
|
||||
dto.ClinicalDataSetName = confirmList.Where(y => y.ClinicalDataTrialSetId == x).Select(y => y.ClinicalDataSetName).First();
|
||||
dto.QuestionList = questionList.Where(y => y.TrialClinicalId == x).OrderBy(y => y.ShowOrder).ToList();
|
||||
dto.AnswerList = new List<Dictionary<string, string>>();
|
||||
var ClinicalFormIds= answers.Where(y => y.ClinicalDataTrialSetId == x).OrderBy(x => x.CheckDate).Select(x => x.ClinicalFormId).Distinct().ToList();
|
||||
ClinicalFormIds.ForEach(z =>
|
||||
{
|
||||
var dic = answers.Where(y => y.ClinicalFormId == z).OrderBy(y => y.CheckDate).ToDictionary(x => x.QuestionId.ToString(), x => x.Answer);
|
||||
dic.Add("ClinicalFormId", z.ToString());
|
||||
dic.Add("TrialId", inDto.TrialId.ToString());
|
||||
dic.Add("SubjectId", readModule.SubjectId.ToString());
|
||||
dic.Add("ClinicalDataTrialSetId", x.ToString());
|
||||
|
||||
dto.AnswerList.Add(dic);
|
||||
|
||||
});
|
||||
result.Add(dto);
|
||||
});
|
||||
return (result, new
|
||||
{
|
||||
readModule.ModuleName,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取临床数据表格信息 查看有表格问题的列表
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<(List<GetClinicalDateListOutDto>,object)> GetClinicalDateList(GetCRCBeConfirmListInDto inDto)
|
||||
{
|
||||
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync();
|
||||
var confirmList = (await this.GetCRCConfirmList(new GetCRCConfirmListInDto()
|
||||
{
|
||||
ReadModuleId = inDto.ReadModuleId,
|
||||
TrialId = inDto.TrialId,
|
||||
PageIndex = 1,
|
||||
PageSize = 9999,
|
||||
|
||||
})).CurrentPageData.SelectMany(x => x.ClinicalFormList).ToList();
|
||||
|
||||
var clinicalDataTrialSetIds = confirmList.Select(x => x.ClinicalDataTrialSetId).Distinct().ToList();
|
||||
|
||||
List<GetClinicalDateListOutDto> result = new List<GetClinicalDateListOutDto>();
|
||||
|
||||
clinicalDataTrialSetIds.ForEach(x =>
|
||||
{
|
||||
|
||||
result.Add(new GetClinicalDateListOutDto()
|
||||
{
|
||||
ClinicalDataSetName = confirmList.Where(y => y.ClinicalDataTrialSetId == x).Select(y => y.ClinicalDataSetName).First(),
|
||||
DateList = confirmList.Where(y => y.ClinicalDataTrialSetId == x).ToList()
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return (result,new {
|
||||
readModule.ModuleName,
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CRC 确认临床数据
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> CRCConfirmClinical(CRCConfirmClinicalInDto inDto)
|
||||
{
|
||||
|
||||
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync();
|
||||
|
||||
var confirmlist = (await this.GetCRCConfirmList(new GetCRCConfirmListInDto()
|
||||
{
|
||||
TrialId = inDto.TrialId,
|
||||
SubjectId= readModule.SubjectId,
|
||||
IsCRCConfirm=false,
|
||||
TrialReadingCriterionId = readModule.TrialReadingCriterionId,
|
||||
//ReadModuleId = inDto.ReadModuleId,
|
||||
PageIndex =1,
|
||||
PageSize=9999,
|
||||
})).CurrentPageData.ToList();
|
||||
|
||||
var presentData = confirmlist.Where(x => x.ReadModuleId == inDto.ReadModuleId).First();
|
||||
|
||||
confirmlist = confirmlist.Where(x => x.LatestScanDate <= presentData.LatestScanDate).ToList();
|
||||
|
||||
await _readModuleCriterionFromRepository.BatchDeleteNoTrackingAsync(x=>x.ReadModuleId== inDto.ReadModuleId);
|
||||
List<ReadModuleCriterionFrom> needAddList = new List<ReadModuleCriterionFrom>()
|
||||
{
|
||||
|
||||
};
|
||||
confirmlist.ForEach(x =>
|
||||
{
|
||||
x.ClinicalFormList.ForEach(y =>
|
||||
{
|
||||
needAddList.Add(new ReadModuleCriterionFrom()
|
||||
{
|
||||
ClinicalFormId = y.ClinicalFormId,
|
||||
ReadModuleId = x.ReadModuleId,
|
||||
SubjectId = x.SubjectId,
|
||||
TrialId = inDto.TrialId,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
foreach (var item in confirmlist)
|
||||
{
|
||||
await _readModuleRepository.UpdatePartialFromQueryAsync(x =>x.Id==item.ReadModuleId , x => new ReadModule()
|
||||
{
|
||||
IsCRCConfirm = true,
|
||||
IsPMConfirm=item.ClinicalFormList.Count()==0?true:false,
|
||||
IsNotNeedPMConfirm= item.ClinicalFormList.Count() == 0 ? true : false,
|
||||
});
|
||||
}
|
||||
|
||||
await _readModuleCriterionFromRepository.AddRangeAsync(needAddList);
|
||||
|
||||
await _readModuleCriterionFromRepository.SaveChangesAsync();
|
||||
await _iReadingClinicalDataService.DealVisiTaskClinicalDataSignedAsync(inDto.TrialId, inDto.SubjectId, inDto.ReadModuleId, false, readModule.TrialReadingCriterionId);
|
||||
return ResponseOutput.Ok(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CRC 取消确认
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> CRCCancelConfirmClinical(CRCCancelConfirmClinicalInDto inDto)
|
||||
{
|
||||
|
||||
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync();
|
||||
var dataList = (await this.GetCRCConfirmList(new GetCRCConfirmListInDto()
|
||||
{
|
||||
TrialId = inDto.TrialId,
|
||||
SubjectId = readModule.SubjectId,
|
||||
TrialReadingCriterionId = readModule.TrialReadingCriterionId,
|
||||
PageIndex = 1,
|
||||
PageSize = 9999,
|
||||
})).CurrentPageData;
|
||||
|
||||
var presentData = dataList.Where(x => x.ReadModuleId == inDto.ReadModuleId).First();
|
||||
|
||||
if (dataList.Any(x => x.IsCRCConfirm && x.LatestScanDate > presentData.LatestScanDate && x.ReadingSetType == presentData.ReadingSetType))
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalAnswer_unableToCancel"]);
|
||||
}
|
||||
|
||||
if(presentData.IsPMConfirm)
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalAnswer_unableToCancelPMConfirmed"]);
|
||||
}
|
||||
|
||||
if (presentData.IsNotNeedPMConfirm)
|
||||
{
|
||||
await _readModuleRepository.UpdatePartialFromQueryAsync(x => presentData.ReadModuleId == x.Id, x => new ReadModule()
|
||||
{
|
||||
IsPMConfirm = false,
|
||||
IsCRCConfirm = false,
|
||||
IsNotNeedPMConfirm = false,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
await _readModuleRepository.UpdatePartialFromQueryAsync(x => presentData.ReadModuleId == x.Id, x => new ReadModule()
|
||||
{
|
||||
IsCRCApplicationRevoke = true,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//await _readModuleCriterionFromRepository.BatchDeleteNoTrackingAsync(x=>x.ReadModuleId== presentData.ReadModuleId);
|
||||
|
||||
await _readModuleCriterionFromRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Ok(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PM确认临床数据
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> PMConfirmClinical(CRCConfirmClinicalInDto inDto)
|
||||
{
|
||||
var readModuleData = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync();
|
||||
if (!readModuleData.IsCRCConfirm)
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalAnswer_PMUnableToOperate"]);
|
||||
}
|
||||
|
||||
if (readModuleData.IsCRCApplicationRevoke && inDto.IsConfirm)
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalAnswer_PMUnableToConfirm"]);
|
||||
}
|
||||
|
||||
if (!readModuleData.IsCRCApplicationRevoke && !inDto.IsConfirm)
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalAnswer_PMUnableToWithdraw"]);
|
||||
}
|
||||
|
||||
if (inDto.IsConfirm)
|
||||
{
|
||||
await _readModuleRepository.UpdatePartialFromQueryAsync(x => inDto.ReadModuleId == x.Id, x => new ReadModule()
|
||||
{
|
||||
IsPMConfirm = true,
|
||||
IsClinicalDataBlind=inDto.IsClinicalDataBlind,
|
||||
IsClinicalDataComplete=inDto.IsClinicalDataComplete,
|
||||
});
|
||||
await _readModuleRepository.SaveChangesAsync();
|
||||
await _iReadingClinicalDataService.DealVisiTaskClinicalDataSignedAsync(inDto.TrialId, inDto.SubjectId, inDto.ReadModuleId, false, readModuleData.TrialReadingCriterionId);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _readModuleRepository.UpdatePartialFromQueryAsync(x => inDto.ReadModuleId == x.Id, x => new ReadModule()
|
||||
{
|
||||
IsCRCConfirm = false,
|
||||
IsCRCApplicationRevoke=false,
|
||||
});
|
||||
await _readModuleCriterionFromRepository.BatchDeleteNoTrackingAsync(x=>x.ReadModuleId== inDto.ReadModuleId);
|
||||
|
||||
await _readModuleRepository.SaveChangesAsync();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return ResponseOutput.Ok(true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using MassTransit;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Application.Interfaces;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
@@ -11,7 +14,7 @@ namespace IRaCIS.Application.Services
|
||||
[ApiExplorerSettings(GroupName = "Reading")]
|
||||
public class ClinicalDataSetService : BaseService
|
||||
{
|
||||
|
||||
public IClinicalQuestionService _iClinicalQuestionService;
|
||||
public IRepository<SubjectVisit> _subjectVisitRepository;
|
||||
|
||||
private readonly IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository;
|
||||
@@ -19,22 +22,28 @@ namespace IRaCIS.Application.Services
|
||||
private readonly IRepository<PreviousPDF> _previousPDFRepository;
|
||||
private readonly IRepository<Dictionary> _dictionaryRepository;
|
||||
private readonly IRepository<Trial> _trialRepository;
|
||||
|
||||
private readonly IRepository<TrialClinicalQuestion> _trialClinicalQuestionRepository;
|
||||
|
||||
private readonly IRepository<SystemClinicalQuestion> _systemClinicalQuestionRepository;
|
||||
|
||||
public ClinicalDataSetService(IRepository<SubjectVisit> subjectVisitRepository,
|
||||
|
||||
IClinicalQuestionService iClinicalQuestionService,
|
||||
IRepository<ClinicalDataTrialSet> ClinicalDataTrialSetRepository,
|
||||
IRepository<ClinicalDataSystemSet> ClinicalDataSystemSetRepository,
|
||||
IRepository<PreviousPDF> previousPDFRepository,
|
||||
IRepository<Dictionary> dictionaryRepository,
|
||||
IRepository<Trial> trialRepository
|
||||
IRepository<TrialClinicalQuestion> trialClinicalQuestionRepository,
|
||||
IRepository<SystemClinicalQuestion> systemClinicalQuestionRepository,
|
||||
|
||||
IRepository<Trial> trialRepository
|
||||
|
||||
|
||||
)
|
||||
{
|
||||
|
||||
_iClinicalQuestionService = iClinicalQuestionService;
|
||||
_subjectVisitRepository = subjectVisitRepository;
|
||||
|
||||
_trialClinicalQuestionRepository = trialClinicalQuestionRepository;
|
||||
_systemClinicalQuestionRepository = systemClinicalQuestionRepository;
|
||||
_clinicalDataTrialSetRepository = ClinicalDataTrialSetRepository;
|
||||
_clinicalDataSystemSetRepository = ClinicalDataSystemSetRepository;
|
||||
this._previousPDFRepository = previousPDFRepository;
|
||||
@@ -43,6 +52,77 @@ namespace IRaCIS.Application.Services
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 应用系统临床数据
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> ApplySystemClinical(ApplySystemClinicalInDto inDto)
|
||||
{
|
||||
|
||||
var isNeedVerify = await _clinicalDataSystemSetRepository.AnyAsync(x => x.Id == inDto.SystemClinicalId && (x.ClinicalDataLevel == ClinicalLevel.ImageRead || x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
|
||||
&& x.ClinicalUploadType == ClinicalUploadType.Structuring && x.UploadRole == UploadRole.CRC
|
||||
);
|
||||
|
||||
if (_systemClinicalQuestionRepository.Where(x => x.SystemClinicalId == inDto.SystemClinicalId).Count() == 0)
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalComment_dataNotConfigured"]);
|
||||
}
|
||||
if (isNeedVerify&&_systemClinicalQuestionRepository.Where(x => x.SystemClinicalId == inDto.SystemClinicalId && x.IsCheckDate).Count() != 1)
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalDataSet_Apply"]);
|
||||
|
||||
}
|
||||
|
||||
await _clinicalDataSystemSetRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.SystemClinicalId, x => new ClinicalDataSystemSet()
|
||||
{
|
||||
IsApply = true
|
||||
});
|
||||
|
||||
|
||||
await _clinicalDataSystemSetRepository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Ok(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 应用项目临床数据
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> ApplyTrialClinical(ApplyTrialClinicalInDto inDto)
|
||||
{
|
||||
|
||||
var isNeedVerify = await _clinicalDataTrialSetRepository.AnyAsync(x => x.Id == inDto.TrialClinicalId && (x.ClinicalDataLevel == ClinicalLevel.ImageRead|| x.ClinicalDataLevel==ClinicalLevel.OncologyRead)
|
||||
&& x.ClinicalUploadType == ClinicalUploadType.Structuring && x.UploadRole == UploadRole.CRC
|
||||
);
|
||||
|
||||
if (_trialClinicalQuestionRepository.Where(x => x.TrialClinicalId == inDto.TrialClinicalId).Count() == 0)
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalComment_dataNotConfigured"]);
|
||||
}
|
||||
|
||||
if (isNeedVerify&&_trialClinicalQuestionRepository.Where(x => x.TrialClinicalId == inDto.TrialClinicalId && x.IsCheckDate).Count() != 1)
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ClinicalDataSet_Apply"]);
|
||||
|
||||
}
|
||||
|
||||
await _clinicalDataTrialSetRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.TrialClinicalId, x => new ClinicalDataTrialSet()
|
||||
{
|
||||
IsApply = true
|
||||
});
|
||||
|
||||
|
||||
await _clinicalDataTrialSetRepository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Ok(true);
|
||||
}
|
||||
|
||||
|
||||
#region 系统
|
||||
/// <summary>
|
||||
@@ -53,7 +133,10 @@ namespace IRaCIS.Application.Services
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdateClinicalDataSystemSet(ClinicalDataSystemSetAddOrEdit indto)
|
||||
{
|
||||
|
||||
if (indto.ClinicalUploadType == ClinicalUploadType.Table || indto.ClinicalUploadType == ClinicalUploadType.PDF)
|
||||
{
|
||||
indto.IsApply = true;
|
||||
}
|
||||
var dictionary = await _dictionaryRepository.Where(x => x.Parent.Code == "ClinicalDataType" && x.Code == indto.ClinicalDataSetEnum.ToString()).FirstNotNullAsync();
|
||||
indto.ClinicalDataSetName = dictionary.ValueCN;
|
||||
indto.ClinicalDataSetEnName = dictionary.Value;
|
||||
@@ -61,6 +144,8 @@ namespace IRaCIS.Application.Services
|
||||
.WhereIf(indto.Id != null, x => x.Id != indto.Id)
|
||||
.Where(x => x.ClinicalDataSetName == indto.ClinicalDataSetName||x.ClinicalDataSetEnName==indto.ClinicalDataSetEnName);
|
||||
|
||||
|
||||
|
||||
if (await existsQuery.AnyAsync())
|
||||
{
|
||||
//---存在同类型的临床数据,操作失败
|
||||
@@ -129,6 +214,12 @@ namespace IRaCIS.Application.Services
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdateClinicalDataTrialSet(ClinicalDataTrialSetAddOrEdit indto)
|
||||
{
|
||||
|
||||
if (indto.ClinicalUploadType == ClinicalUploadType.Table || indto.ClinicalUploadType == ClinicalUploadType.PDF)
|
||||
{
|
||||
indto.IsApply = true;
|
||||
}
|
||||
|
||||
var existsQuery = _clinicalDataTrialSetRepository
|
||||
.WhereIf(indto.Id != null, x => x.Id != indto.Id)
|
||||
.Where(x => (x.ClinicalDataSetName == indto.ClinicalDataSetName||x.ClinicalDataSetEnName==indto.ClinicalDataSetEnName) && x.TrialId == indto.TrialId);
|
||||
@@ -138,6 +229,10 @@ namespace IRaCIS.Application.Services
|
||||
//---存在同类型的临床数据,操作失败
|
||||
return ResponseOutput.NotOk(_localizer["ClinicalDataSet_DupTypeFail"]);
|
||||
}
|
||||
if (indto.Id != null && indto.IsApply == null)
|
||||
{
|
||||
indto.IsApply = await _clinicalDataTrialSetRepository.Where(x => x.Id == indto.Id).Select(x => x.IsApply).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
//indto.CriterionEnumListStr = $"|{String.Join('|', indto.CriterionEnumList)}|";
|
||||
|
||||
@@ -260,7 +355,7 @@ namespace IRaCIS.Application.Services
|
||||
//不存在的时候,就将系统数据同步到项目临床数据配置
|
||||
if (!await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == trialId && x.SystemClinicalDataSetId != null))
|
||||
{
|
||||
var systemClinicalDataList = await _clinicalDataSystemSetRepository.AsQueryable().ToListAsync();
|
||||
var systemClinicalDataList = await _clinicalDataSystemSetRepository.Where(x=>x.IsApply).AsQueryable().ToListAsync();
|
||||
var systemIds = systemClinicalDataList.Select(x => x.Id).ToList();
|
||||
|
||||
var trialSystemClinicalDataSetIds = await _clinicalDataTrialSetRepository.Where(x => x.TrialId == trialId && x.SystemClinicalDataSetId != null).Select(x => x.SystemClinicalDataSetId.Value).ToListAsync();
|
||||
@@ -285,6 +380,7 @@ namespace IRaCIS.Application.Services
|
||||
FileName = x.FileName,
|
||||
Path = x.Path,
|
||||
TrialId = trialId,
|
||||
IsApply = x.IsApply,
|
||||
|
||||
//项目不采用 标准枚举字符串的方式
|
||||
//CriterionEnumListStr=x.CriterionEnumListStr
|
||||
@@ -299,6 +395,13 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
var result = await _clinicalDataTrialSetRepository.SaveChangesAsync();
|
||||
|
||||
|
||||
await _iClinicalQuestionService.SynchronizationQuestion(dataSets.Select(x => new SynchronizationQuestionDto()
|
||||
{
|
||||
SystemClinicalId = x.SystemClinicalDataSetId.Value,
|
||||
TrialClinicalId = x.Id,
|
||||
|
||||
}).ToList());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -0,0 +1,650 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2023-06-15 15:06:06
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Infra.EFCore.Common;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using MassTransit;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// 临床数据问题
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "Reading")]
|
||||
public class ClinicalQuestionService : BaseService, IClinicalQuestionService
|
||||
{
|
||||
|
||||
private readonly IRepository<TrialClinicalQuestion> _trialClinicalQuestionRepository;
|
||||
|
||||
private readonly IRepository<SystemClinicalQuestion> _systemClinicalQuestionRepository;
|
||||
|
||||
|
||||
private readonly IRepository<SystemClinicalTableQuestion> _systemClinicalTableQuestionRepository;
|
||||
|
||||
private readonly IRepository<TrialClinicalTableQuestion> _trialClinicalTableQuestionRepository;
|
||||
|
||||
public ClinicalQuestionService(IRepository<TrialClinicalQuestion> trialClinicalQuestionRepository,
|
||||
IRepository<SystemClinicalTableQuestion> systemClinicalTableQuestionRepository,
|
||||
IRepository<TrialClinicalTableQuestion> trialClinicalTableQuestionRepository,
|
||||
IRepository<SystemClinicalQuestion> systemClinicalQuestionRepository
|
||||
)
|
||||
{
|
||||
_systemClinicalTableQuestionRepository = systemClinicalTableQuestionRepository;
|
||||
_trialClinicalQuestionRepository = trialClinicalQuestionRepository;
|
||||
_trialClinicalTableQuestionRepository = trialClinicalTableQuestionRepository;
|
||||
_systemClinicalQuestionRepository = systemClinicalQuestionRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取问题计算关系
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<List<GetTrialClinicalQuestionCalculateRelationOutDto>> GetTrialClinicalQuestionCalculateRelation(GetTrialClinicalQuestionCalculateRelationInDto inDto)
|
||||
{
|
||||
|
||||
var result= await _trialClinicalQuestionRepository.Where(x => x.TrialClinicalId == inDto.TrialClinicalId)
|
||||
.Where( x=> x.ClinicalQuestionType == "number")
|
||||
.Where(x => x.CustomCalculateMark != null && x.CustomCalculateMark > ClinicalCalculateMark.None)
|
||||
.Select(x => new GetTrialClinicalQuestionCalculateRelationOutDto()
|
||||
{
|
||||
QuestionId = x.Id,
|
||||
QuestionName = x.QuestionName,
|
||||
CustomCalculateMark = x.CustomCalculateMark,
|
||||
CalculateQuestionList = x.CalculateQuestionList,
|
||||
}).ToListAsync();
|
||||
result = result.Where(x => x.CalculateQuestionList.Count() > 0).ToList();
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取计算问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<List<GetClinicalCalculateQuestionsOutDto>> GetClinicalCalculateQuestions(GetClinicalCalculateQuestionsInDto inDto)
|
||||
{
|
||||
var result = await _trialClinicalQuestionRepository
|
||||
|
||||
.Where(x => x.TrialClinicalId == inDto.TrialClinicalId)
|
||||
.WhereIf(!inDto.ClinicalQuestionType.IsNullOrEmpty(), x => x.ClinicalQuestionType == inDto.ClinicalQuestionType)
|
||||
.OrderBy(x => x.ShowOrder)
|
||||
.Select(x => new GetClinicalCalculateQuestionsOutDto
|
||||
()
|
||||
{
|
||||
QuestionId = x.Id,
|
||||
QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us)
|
||||
|
||||
}).ToListAsync();
|
||||
|
||||
var tablequestion = await _trialClinicalTableQuestionRepository.Where(x => x.TrialClinicalId == inDto.TrialClinicalId && x.ClinicalTableQuestionType == "number").Select(x =>
|
||||
new
|
||||
{
|
||||
TableQuestionId = x.Id,
|
||||
QuestionId= x.QuestionId,
|
||||
QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us)
|
||||
}).ToListAsync();
|
||||
|
||||
|
||||
result.ForEach(x =>
|
||||
{
|
||||
x.TableQuestions = tablequestion.Where(y => x.QuestionId == y.QuestionId).Select(y => new CalculateQuestion()
|
||||
{
|
||||
|
||||
QuestionId = y.QuestionId,
|
||||
QuestionName = y.QuestionName
|
||||
|
||||
}).ToList();
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统临床数据预览
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<(List<ClinicalQuestionPreviewDto>, bool)> GetSystemClinicalQuestionPreview(GetSystemClinicalQuestionPreviewDto inDto)
|
||||
{
|
||||
var questions = await _systemClinicalQuestionRepository.Where(x => x.SystemClinicalId == inDto.SystemClinicalId)
|
||||
.ProjectTo<ClinicalQuestionPreviewDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ToListAsync();
|
||||
|
||||
var tableQuestions= await _systemClinicalTableQuestionRepository.Where(x => x.SystemClinicalId == inDto.SystemClinicalId)
|
||||
.ProjectTo<ClinicalTablePreviewDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ToListAsync();
|
||||
|
||||
questions.ForEach(x => x.CreateTime = null);
|
||||
var result = questions.Where(x => x.ClinicalQuestionType == ReadingQestionType.Group).ToList();
|
||||
|
||||
result.ForEach(x =>
|
||||
{
|
||||
this.FindChildQuestion(x, questions, tableQuestions, new List<ClinicalFormQuestionAnswer>(), new List<ClinicalFormTableQuestionAnswer>());
|
||||
});
|
||||
|
||||
return (result, true);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目临床数据预览
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<(List<ClinicalQuestionPreviewDto>, bool)> GetTrialClinicalQuestionPreview(GetTrialClinicalQuestionPreviewDto inDto)
|
||||
{
|
||||
var questions = await _trialClinicalQuestionRepository.Where(x => x.TrialClinicalId == inDto.TrialClinicalId)
|
||||
.ProjectTo<ClinicalQuestionPreviewDto>(_mapper.ConfigurationProvider).OrderBy(x=>x.ShowOrder).ToListAsync();
|
||||
|
||||
var tableQuestions = await _trialClinicalTableQuestionRepository.Where(x => x.TrialClinicalId == inDto.TrialClinicalId)
|
||||
.ProjectTo<ClinicalTablePreviewDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ToListAsync();
|
||||
|
||||
questions.ForEach(x => x.CreateTime = null);
|
||||
var result = questions.Where(x => x.ClinicalQuestionType == ReadingQestionType.Group).OrderBy(x => x.ShowOrder).ToList();
|
||||
|
||||
result.ForEach(x =>
|
||||
{
|
||||
this.FindChildQuestion(x, questions, tableQuestions,new List<ClinicalFormQuestionAnswer> (),new List<ClinicalFormTableQuestionAnswer>());
|
||||
});
|
||||
|
||||
return (result, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取子元素
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <param name="questions"></param>
|
||||
/// <param name="tableQuestions"></param>
|
||||
public void FindChildQuestion(ClinicalQuestionPreviewDto item, List<ClinicalQuestionPreviewDto> questions, List<ClinicalTablePreviewDto> tableQuestions,List<ClinicalFormQuestionAnswer> answers, List<ClinicalFormTableQuestionAnswer> tableAnswers)
|
||||
{
|
||||
item.Childrens = questions.Where(x => (x.ParentId == item.Id)||(x.GroupId== item.Id&&x.ParentId==null)).OrderBy(x => x.ShowOrder).ToList();
|
||||
|
||||
item.RelationQuestions = questions.Where(x => x.RelevanceId == item.Id).ToList();
|
||||
|
||||
item.Answer = answers.Where(x => x.QuestionId == item.Id).Select(x => x.Answer).FirstOrDefault()??string.Empty;
|
||||
|
||||
var tableIndexs = tableAnswers.Where(x => x.QuestionId == item.Id).Select(x => x.RowIndex).Distinct().OrderBy(x=>x).ToList();
|
||||
|
||||
item.TableAnswer = new List<Dictionary<Guid, string>>();
|
||||
|
||||
tableIndexs.ForEach(x =>
|
||||
{
|
||||
item.TableAnswer.Add(tableAnswers.Where(y => y.RowIndex == x).ToDictionary(y => y.TableQuestionId, y => y.Answer));
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
item.TableQuestions = tableQuestions.Where(x => x.QuestionId == item.Id).OrderBy(x=>x.ShowOrder).OrderBy(x => x.ShowOrder).ToList();
|
||||
|
||||
item.RelationQuestions.ForEach(x => {
|
||||
this.FindChildQuestion(x, questions, tableQuestions, answers, tableAnswers);
|
||||
});
|
||||
|
||||
item.Childrens.ForEach(x => {
|
||||
this.FindChildQuestion(x, questions, tableQuestions, answers, tableAnswers);
|
||||
});
|
||||
}
|
||||
|
||||
#region 项目问题
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目临床问题
|
||||
/// </summary>
|
||||
/// <param name="inQuery"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<TrialClinicalQuestionDto>> GetTrialClinicalQuestionList(TrialClinicalQuestionQuery inQuery)
|
||||
{
|
||||
|
||||
var trialClinicalQuestionQueryable = _trialClinicalQuestionRepository.Where(x=>x.TrialClinicalId==inQuery.TrialClinicalId)
|
||||
.WhereIf(!inQuery.QuestionName.IsNullOrEmpty(), x => x.QuestionName.Contains(inQuery.QuestionName) || x.QuestionEnName.Contains(inQuery.QuestionName))
|
||||
.ProjectTo<TrialClinicalQuestionDto>(_mapper.ConfigurationProvider);
|
||||
var pageList = await trialClinicalQuestionQueryable
|
||||
.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(TrialClinicalQuestion.ShowOrder) : inQuery.SortField,
|
||||
inQuery.Asc);
|
||||
return pageList;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 新增或者修改项目临床问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdateTrialClinicalQuestion(TrialClinicalQuestionDto inDto)
|
||||
{
|
||||
if (inDto.IsVerify)
|
||||
{
|
||||
if (await _trialClinicalQuestionRepository.AnyAsync(x => x.TrialClinicalId == inDto.TrialClinicalId && x.Id != inDto.Id && x.QuestionName == inDto.QuestionName))
|
||||
{
|
||||
return ResponseOutput.NotOk(_localizer["ClinicalQuestion_Repeat"],string.Empty,ApiResponseCodeEnum.NeedTips);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (await _trialClinicalQuestionRepository.AnyAsync(x => x.TrialClinicalId == inDto.TrialClinicalId && x.Id != inDto.Id && x.ShowOrder == inDto.ShowOrder))
|
||||
{
|
||||
return ResponseOutput.NotOk("问题序号存在重复!");
|
||||
}
|
||||
|
||||
if (await _trialClinicalQuestionRepository.AnyAsync(x => x.TrialClinicalId == inDto.TrialClinicalId && x.Id != inDto.Id && x.IsCheckDate == inDto.IsCheckDate&&inDto.IsCheckDate))
|
||||
{
|
||||
return ResponseOutput.NotOk("已经添加过类型为检查日期的问题!");
|
||||
}
|
||||
|
||||
var entity = await _trialClinicalQuestionRepository.InsertOrUpdateAsync(inDto, true);
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除项目临床数据问题
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{id:guid}")]
|
||||
public async Task<IResponseOutput> DeleteTrialClinicalQuestion(Guid id)
|
||||
{
|
||||
var success = await _trialClinicalQuestionRepository.DeleteFromQueryAsync(t => t.Id == id, true);
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目问题分组
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<List<TrialClinicalQuestionDto>> GetTrialClinicalGroupQuestionList(GetTrialGroupDto inDto)
|
||||
{
|
||||
return await this._trialClinicalQuestionRepository.Where(x => x.TrialClinicalId == inDto.TrialClinicalId&&x.ClinicalQuestionType== "group")
|
||||
.ProjectTo<TrialClinicalQuestionDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目标准其他问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<List<TrialClinicalQuestionDto>> GetTrialClinicalOtherQuestionList(GetTrialGroupDto inDto)
|
||||
{
|
||||
var types = new List<string>()
|
||||
{
|
||||
"select","radio"
|
||||
};
|
||||
return await this._trialClinicalQuestionRepository.Where(x => x.TrialClinicalId == inDto.TrialClinicalId && types.Contains( x.ClinicalQuestionType))
|
||||
.ProjectTo<TrialClinicalQuestionDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 系统问题
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统临床问题
|
||||
/// </summary>
|
||||
/// <param name="inQuery"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<SystemClinicalQuestionDto>> GetSystemClinicalQuestionList(SystemClinicalQuestionQuery inQuery)
|
||||
{
|
||||
|
||||
var systemClinicalQuestionQueryable = _systemClinicalQuestionRepository
|
||||
.Where(x=>x.SystemClinicalId==inQuery.SystemClinicalId)
|
||||
.WhereIf(!inQuery.QuestionName.IsNullOrEmpty(), x => x.QuestionName.Contains(inQuery.QuestionName) || x.QuestionEnName.Contains(inQuery.QuestionName))
|
||||
.ProjectTo<SystemClinicalQuestionDto>(_mapper.ConfigurationProvider);
|
||||
var pageList = await systemClinicalQuestionQueryable
|
||||
.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(SystemClinicalQuestion.ShowOrder) : inQuery.SortField,
|
||||
inQuery.Asc);
|
||||
return pageList;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 新增或者修改系统临床问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdateSystemClinicalQuestion(SystemClinicalQuestionDto inDto)
|
||||
{
|
||||
|
||||
if (inDto.IsVerify)
|
||||
{
|
||||
if (await _systemClinicalQuestionRepository.AnyAsync(x => x.SystemClinicalId == inDto.SystemClinicalId && x.Id != inDto.Id && x.QuestionName == inDto.QuestionName))
|
||||
{
|
||||
return ResponseOutput.NotOk(_localizer["ClinicalQuestion_Repeat"], string.Empty, ApiResponseCodeEnum.NeedTips);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (await _systemClinicalQuestionRepository.AnyAsync(x => x.SystemClinicalId == inDto.SystemClinicalId && x.Id != inDto.Id && x.ShowOrder == inDto.ShowOrder))
|
||||
{
|
||||
return ResponseOutput.NotOk("问题序号存在重复!");
|
||||
}
|
||||
if (await _systemClinicalQuestionRepository.AnyAsync(x => x.SystemClinicalId == inDto.SystemClinicalId && x.Id != inDto.Id && x.IsCheckDate == inDto.IsCheckDate && inDto.IsCheckDate))
|
||||
{
|
||||
return ResponseOutput.NotOk("已经添加过类型为检查日期的问题!");
|
||||
}
|
||||
var entity = await _systemClinicalQuestionRepository.InsertOrUpdateAsync(inDto, true);
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 删除系统临床数据问题
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{id:guid}")]
|
||||
public async Task<IResponseOutput> DeleteSystemClinicalQuestion(Guid id)
|
||||
{
|
||||
var success = await _systemClinicalQuestionRepository.DeleteFromQueryAsync(t => t.Id == id, true);
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统问题分组
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<List<SystemClinicalQuestionDto>> GetSystemClinicalGroupQuestionList(GetSystemGroupDto inDto)
|
||||
{
|
||||
return await this._systemClinicalQuestionRepository.Where(x => x.SystemClinicalId == inDto.SystemClinicalId && x.ClinicalQuestionType =="group")
|
||||
.ProjectTo<SystemClinicalQuestionDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统其他问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<List<SystemClinicalQuestionDto>> GetSystemClinicalOtherQuestionList(GetSystemGroupDto inDto)
|
||||
{
|
||||
var types = new List<string>()
|
||||
{
|
||||
"select","radio"
|
||||
};
|
||||
return await this._systemClinicalQuestionRepository.Where(x => x.SystemClinicalId == inDto.SystemClinicalId && types.Contains(x.ClinicalQuestionType))
|
||||
.ProjectTo<SystemClinicalQuestionDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region 系统表格问题
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统表格问题
|
||||
/// </summary>
|
||||
/// <param name="inQuery"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<SystemClinicalTableQuestionDto>> GetSystemClinicalTableQuestionList(SystemClinicalTableQuestionQuery inQuery)
|
||||
{
|
||||
|
||||
var systemClinicalTableQuestionQueryable = this._systemClinicalTableQuestionRepository
|
||||
.Where(x => x.QuestionId == inQuery.QuestionId)
|
||||
.ProjectTo<SystemClinicalTableQuestionDto>(_mapper.ConfigurationProvider);
|
||||
|
||||
var pageList = await systemClinicalTableQuestionQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(SystemClinicalTableQuestion.ShowOrder) : inQuery.SortField,
|
||||
inQuery.Asc);
|
||||
|
||||
return pageList;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 新增或修改系统表格问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdateSystemClinicalTableQuestion(SystemClinicalTableQuestionDto inDto)
|
||||
{
|
||||
if (inDto.IsVerify)
|
||||
{
|
||||
if (await _systemClinicalTableQuestionRepository.AnyAsync(x => x.QuestionId == inDto.QuestionId && x.Id != inDto.Id && x.QuestionName == inDto.QuestionName))
|
||||
{
|
||||
return ResponseOutput.NotOk(_localizer["ClinicalQuestion_Repeat"], string.Empty, ApiResponseCodeEnum.NeedTips);
|
||||
}
|
||||
}
|
||||
|
||||
if (await _systemClinicalTableQuestionRepository.AnyAsync(x => x.QuestionId == inDto.QuestionId && x.Id != inDto.Id && x.ShowOrder == inDto.ShowOrder))
|
||||
{
|
||||
return ResponseOutput.NotOk("问题序号存在重复!");
|
||||
}
|
||||
|
||||
var entity = await _systemClinicalTableQuestionRepository.InsertOrUpdateAsync(inDto, true);
|
||||
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除系统表格问题
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{id:guid}")]
|
||||
public async Task<IResponseOutput> DeleteSystemClinicalTableQuestion(Guid id)
|
||||
{
|
||||
var success = await _systemClinicalTableQuestionRepository.DeleteFromQueryAsync(t => t.Id == id, true);
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region 项目表格问题
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目表格问题
|
||||
/// </summary>
|
||||
/// <param name="inQuery"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<TrialClinicalTableQuestionDto>> GetTrialClinicalTableQuestionList(TrialClinicalTableQuestionQuery inQuery)
|
||||
{
|
||||
|
||||
var trialClinicalTableQuestionQueryable = this._trialClinicalTableQuestionRepository
|
||||
.Where(x => x.QuestionId == inQuery.QuestionId)
|
||||
.ProjectTo<TrialClinicalTableQuestionDto>(_mapper.ConfigurationProvider);
|
||||
|
||||
var pageList = await trialClinicalTableQuestionQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(TrialClinicalTableQuestion.ShowOrder) : inQuery.SortField,
|
||||
inQuery.Asc);
|
||||
|
||||
return pageList;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 新增或修改项目表格问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdateTrialClinicalTableQuestion(TrialClinicalTableQuestionDto inDto)
|
||||
{
|
||||
if (inDto.IsVerify)
|
||||
{
|
||||
if (await _trialClinicalTableQuestionRepository.AnyAsync(x => x.QuestionId == inDto.QuestionId && x.Id != inDto.Id && x.QuestionName == inDto.QuestionName))
|
||||
{
|
||||
return ResponseOutput.NotOk(_localizer["ClinicalQuestion_Repeat"], string.Empty, ApiResponseCodeEnum.NeedTips);
|
||||
}
|
||||
}
|
||||
|
||||
if (await _trialClinicalTableQuestionRepository.AnyAsync(x => x.QuestionId == inDto.QuestionId && x.Id != inDto.Id && x.ShowOrder == inDto.ShowOrder))
|
||||
{
|
||||
return ResponseOutput.NotOk("问题序号存在重复!");
|
||||
}
|
||||
var entity = await _trialClinicalTableQuestionRepository.InsertOrUpdateAsync(inDto, true);
|
||||
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除项目表格问题
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{id:guid}")]
|
||||
public async Task<IResponseOutput> DeleteTrialClinicalTableQuestion(Guid id)
|
||||
{
|
||||
var success = await _trialClinicalTableQuestionRepository.DeleteFromQueryAsync(t => t.Id == id, true);
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region 同步系统问题
|
||||
|
||||
/// <summary>
|
||||
/// 同步系统问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task SynchronizationQuestion(List<SynchronizationQuestionDto> inDto)
|
||||
{
|
||||
var trialClinicalId = inDto.Select(x => x.TrialClinicalId).ToList();
|
||||
|
||||
var systemClinicalId = inDto.Select(x => x.SystemClinicalId).ToList();
|
||||
var questionRelationList =await _trialClinicalQuestionRepository.Where(x => trialClinicalId.Contains(x.TrialClinicalId)).Select(x => new QuestionDic()
|
||||
{
|
||||
SystemQuestionId=x.SystemClinicalQuestionId?? default(Guid),
|
||||
TrialQuestionId=x.Id,
|
||||
TrialClinicalId=x.TrialClinicalId,
|
||||
}).ToListAsync();
|
||||
|
||||
var tableQuestionRelationList = await _trialClinicalTableQuestionRepository.Where(x => trialClinicalId.Contains(x.TrialClinicalId)).Select(x => new QuestionDic()
|
||||
{
|
||||
SystemQuestionId = x.SystemTableQuestionId ?? default(Guid),
|
||||
TrialQuestionId = x.Id,
|
||||
TrialClinicalId = x.TrialClinicalId,
|
||||
}).ToListAsync();
|
||||
|
||||
var newTrialQuestionAll = await _systemClinicalQuestionRepository.Where(x => systemClinicalId.Contains(x.SystemClinicalId))
|
||||
.ProjectTo<TrialClinicalQuestionSynchronize>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
var newTrialTableQuestionAll = await _systemClinicalTableQuestionRepository.Where(x => systemClinicalId.Contains(x.SystemClinicalId))
|
||||
.ProjectTo<TrialClinicalTableQuestionSynchronize>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
|
||||
List<TrialClinicalQuestion> addTrialDataList = new List<TrialClinicalQuestion>();
|
||||
List<TrialClinicalTableQuestion> addTrialTableList = new List<TrialClinicalTableQuestion>();
|
||||
foreach (var item in inDto)
|
||||
{
|
||||
var questionRelation = questionRelationList.Where(x=>x.TrialClinicalId==item.TrialClinicalId).ToDictionary(
|
||||
x => x.SystemQuestionId,
|
||||
x => x.TrialQuestionId
|
||||
);
|
||||
|
||||
var newTrialQuestionList = newTrialQuestionAll.Where(x => x.SystemClinicalId == item.SystemClinicalId).ToList();
|
||||
newTrialQuestionList.ForEach(x =>
|
||||
{
|
||||
if (questionRelation.ContainsKey(x.Id))
|
||||
{
|
||||
x.Id = questionRelation[x.Id];
|
||||
}
|
||||
else
|
||||
{
|
||||
var newid = NewId.NextGuid();
|
||||
questionRelation.Add(x.Id, newid);
|
||||
x.Id = newid;
|
||||
}
|
||||
|
||||
x.TrialClinicalId = item.TrialClinicalId;
|
||||
});
|
||||
|
||||
var copyNewQuestionList = newTrialQuestionList.Clone();
|
||||
foreach (var x in newTrialQuestionList)
|
||||
{
|
||||
var question = x.Clone();
|
||||
if (question.ParentId != null)
|
||||
{
|
||||
question.ParentId = questionRelation[question.ParentId ?? default(Guid)];
|
||||
}
|
||||
if (question.GroupId != null)
|
||||
{
|
||||
question.GroupId = questionRelation[question.GroupId ?? default(Guid)];
|
||||
}
|
||||
if (question.RelevanceId != null)
|
||||
{
|
||||
question.RelevanceId = questionRelation[question.RelevanceId ?? default(Guid)];
|
||||
}
|
||||
addTrialDataList.Add(question);
|
||||
};
|
||||
|
||||
|
||||
|
||||
var tableQuestionRelation = tableQuestionRelationList.Where(x => x.TrialClinicalId == item.TrialClinicalId).ToDictionary(
|
||||
x => x.SystemQuestionId,
|
||||
x => x.TrialQuestionId
|
||||
);
|
||||
|
||||
var newTrialTableQuestionList = newTrialTableQuestionAll.Where(x => x.SystemClinicalId == item.SystemClinicalId)
|
||||
.ToList();
|
||||
|
||||
|
||||
newTrialTableQuestionList.ForEach(x =>
|
||||
{
|
||||
if (tableQuestionRelation.ContainsKey(x.Id))
|
||||
{
|
||||
x.Id = tableQuestionRelation[x.Id];
|
||||
}
|
||||
else
|
||||
{
|
||||
var newid = NewId.NextGuid();
|
||||
tableQuestionRelation.Add(x.Id, newid);
|
||||
x.Id = newid;
|
||||
}
|
||||
});
|
||||
|
||||
foreach (var x in newTrialTableQuestionList)
|
||||
{
|
||||
var tableQuestion = x.Clone();
|
||||
tableQuestion.TrialClinicalId = item.TrialClinicalId;
|
||||
|
||||
tableQuestion.QuestionId = copyNewQuestionList.Where(y => y.SystemClinicalQuestionId == x.QuestionId).Select(y => y.Id).FirstOrDefault();
|
||||
|
||||
|
||||
addTrialTableList.Add(tableQuestion);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
await _trialClinicalQuestionRepository.BatchDeleteNoTrackingAsync(x => trialClinicalId.Contains(x.TrialClinicalId));
|
||||
await _trialClinicalQuestionRepository.AddRangeAsync(addTrialDataList);
|
||||
await _trialClinicalTableQuestionRepository.BatchDeleteNoTrackingAsync(x => trialClinicalId.Contains(x.TrialClinicalId) );
|
||||
await _trialClinicalTableQuestionRepository.AddRangeAsync(addTrialTableList);
|
||||
await _trialClinicalQuestionRepository.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
+327
-76
@@ -8,6 +8,7 @@ using Panda.DynamicWebApi.Attributes;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Linq.Expressions;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using System.Linq.Dynamic.Core;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
@@ -24,6 +25,8 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
|
||||
private readonly IRepository<PreviousHistory> _previousHistoryRepository;
|
||||
private readonly IRepository<ReadModuleCriterionFrom> _readModuleCriterionFromRepository;
|
||||
private readonly IRepository<ClinicalForm> _clinicalFormRepository;
|
||||
private readonly IRepository<PreviousOther> _previousOtherRepository;
|
||||
private readonly IRepository<PreviousSurgery> _previousSurgeryRepository;
|
||||
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository;
|
||||
@@ -37,7 +40,8 @@ namespace IRaCIS.Application.Services
|
||||
IRepository<PreviousPDF> previousPDFRepository,
|
||||
IRepository<SubjectVisit> subjectVisitRepository,
|
||||
IRepository<PreviousHistory> previousHistoryRepository,
|
||||
|
||||
IRepository<ReadModuleCriterionFrom> readModuleCriterionFromRepository,
|
||||
IRepository<ClinicalForm> clinicalFormRepository,
|
||||
IRepository<PreviousOther> previousOtherRepository,
|
||||
IRepository<PreviousSurgery> previousSurgeryRepository,
|
||||
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository,
|
||||
@@ -53,6 +57,8 @@ namespace IRaCIS.Application.Services
|
||||
this._previousPDFRepository = previousPDFRepository;
|
||||
this._subjectVisitRepository = subjectVisitRepository;
|
||||
this._previousHistoryRepository = previousHistoryRepository;
|
||||
this._readModuleCriterionFromRepository = readModuleCriterionFromRepository;
|
||||
this._clinicalFormRepository = clinicalFormRepository;
|
||||
this._previousOtherRepository = previousOtherRepository;
|
||||
this._previousSurgeryRepository = previousSurgeryRepository;
|
||||
this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
|
||||
@@ -179,12 +185,6 @@ namespace IRaCIS.Application.Services
|
||||
[HttpPost]
|
||||
public async Task<List<GetCRCClinicalDataOutDto>> GetCRCClinicalData(GetCRCClinicalDataInDto inDto)
|
||||
{
|
||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator)
|
||||
{
|
||||
await this.AddCRCClinicalData(inDto);
|
||||
}
|
||||
|
||||
|
||||
List<GetCRCClinicalDataOutDto> cRCClinicalDataList = await _readingClinicalDataRepository.Where(x => x.ReadingId == inDto.SubjectVisitId)
|
||||
.WhereIf(inDto.IsBaseline, x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
|
||||
.WhereIf(!inDto.IsBaseline, x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
|
||||
@@ -201,29 +201,26 @@ namespace IRaCIS.Application.Services
|
||||
Path = x.ClinicalDataTrialSet.Path,
|
||||
IsBlind = x.IsBlind,
|
||||
IsComplete = x.IsComplete,
|
||||
ClinicalFromList=x.Subject.ClinicalFormList.Where(y=>y.ReadingId==x.ReadingId&&y.ClinicalDataTrialSetId==x.ClinicalDataTrialSetId).Select(y=> new ClinicalFromData() {
|
||||
CheckDate=y.CheckDate,
|
||||
ClinicalFormId=y.Id
|
||||
}).ToList(),
|
||||
PDFFileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
|
||||
{
|
||||
Id = y.Id,
|
||||
FileName = y.FileName,
|
||||
Path = y.Path,
|
||||
CreateTime = y.CreateTime,
|
||||
}).ToList()
|
||||
}).ToList(),
|
||||
|
||||
}).ToListAsync();
|
||||
|
||||
List<GetReadingClinicalDataListOutDto> clinicalData = (await this.GetReadingClinicalDataList(new GetReadingClinicalDataListIndto()
|
||||
{
|
||||
SubjectId = inDto.SubjectId,
|
||||
ReadingId = inDto.SubjectVisitId,
|
||||
TrialId = inDto.TrialId,
|
||||
})).Item1;
|
||||
|
||||
var previousHistoryList = await _previousHistoryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousHistoryView>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
var previousOtherList = await _previousOtherRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousOtherView>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
var previousSurgeryList = await _previousSurgeryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousSurgeryView>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
foreach (var item in cRCClinicalDataList)
|
||||
{
|
||||
//item.PDFFileList = clinicalData.Where(y => y.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).SelectMany(x => x.FileList).ToList();
|
||||
item.ClinicalTableData = new ClinicalDataTable()
|
||||
{
|
||||
PreviousHistoryList = previousHistoryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
||||
@@ -310,7 +307,7 @@ namespace IRaCIS.Application.Services
|
||||
}
|
||||
|
||||
//处理 任务 临床数据是否签名
|
||||
private async Task DealVisiTaskClinicalDataSignedAsync(Guid trialId, Guid subjectId, Guid readingId, bool isVisit, Guid trialReadingCritrialId)
|
||||
public async Task DealVisiTaskClinicalDataSignedAsync(Guid trialId, Guid subjectId, Guid readingId, bool isVisit, Guid trialReadingCritrialId)
|
||||
{
|
||||
//获取确认的临床数据配置
|
||||
var trialClinicalDataSetList = _clinicalDataTrialSetRepository.Where(t => t.TrialId == trialId && t.IsConfirm).Include(t => t.TrialClinicalDataSetCriteriaList).ToList();
|
||||
@@ -328,6 +325,8 @@ namespace IRaCIS.Application.Services
|
||||
{
|
||||
var isBaseLine = await _subjectVisitRepository.Where(t => t.Id == readingId).Select(t => t.IsBaseLine).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
|
||||
//判断是否基线
|
||||
if (isBaseLine)
|
||||
{
|
||||
@@ -356,21 +355,43 @@ namespace IRaCIS.Application.Services
|
||||
else
|
||||
{
|
||||
//判断是影像学 还是肿瘤学阅片
|
||||
var readingSetType = await _readModuleRepository.Where(t => t.Id == readingId).Select(t => t.ReadingSetType).FirstOrDefaultAsync();
|
||||
var readModule = await _readModuleRepository.Where(t => t.Id == readingId).FirstNotNullAsync();
|
||||
|
||||
//CRC 阅片期自定义结构化录入是否签名
|
||||
bool crcReadModuleSign = true;
|
||||
|
||||
//影像学
|
||||
if (readingSetType == ReadingSetType.ImageReading)
|
||||
if (readModule.ReadingSetType == ReadingSetType.ImageReading)
|
||||
{
|
||||
needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && t.ClinicalDataLevel == ClinicalLevel.ImageRead).Count();
|
||||
|
||||
// 不存在需要CRC上传的临床数据 或者 PM已确认
|
||||
crcReadModuleSign =
|
||||
!trialClinicalDataSetList.Any(x =>
|
||||
x.UploadRole == UploadRole.CRC
|
||||
&& x.ClinicalDataLevel == ClinicalLevel.ImageRead
|
||||
&& x.ClinicalUploadType == ClinicalUploadType.Structuring
|
||||
&& x.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId)) || readModule.IsPMConfirm;
|
||||
|
||||
|
||||
}
|
||||
//肿瘤学
|
||||
else
|
||||
{
|
||||
needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && t.ClinicalDataLevel == ClinicalLevel.OncologyRead).Count();
|
||||
|
||||
// 不存在需要CRC上传的临床数据 或者 PM已确认
|
||||
crcReadModuleSign =
|
||||
!trialClinicalDataSetList.Any(x =>
|
||||
x.UploadRole == UploadRole.CRC
|
||||
&& x.ClinicalDataLevel == ClinicalLevel.OncologyRead
|
||||
&& x.ClinicalUploadType == ClinicalUploadType.Structuring
|
||||
&& x.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId)) || readModule.IsPMConfirm;
|
||||
|
||||
}
|
||||
|
||||
//可能仅仅CRC 基线 没有PM
|
||||
if (needSignCount == haveSignedCount /*&& needSignCount != 0*/)
|
||||
if (needSignCount == haveSignedCount && crcReadModuleSign/*&& needSignCount != 0*/)
|
||||
{
|
||||
//将该标准 该subject 该阅片期|肿瘤学 任务临床数据状态变更
|
||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCritrialId && t.SouceReadModuleId == readingId, u => new VisitTask()
|
||||
@@ -380,38 +401,65 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCritrialId && t.SouceReadModuleId == readingId, u => new VisitTask()
|
||||
{
|
||||
IsClinicalDataSign = false
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Expression<Func<VisitTask, bool>> visitTaskLambda = x => x.TrialId == trialId && x.SubjectId == subjectId && x.TrialReadingCriterionId == trialReadingCritrialId;
|
||||
|
||||
|
||||
|
||||
|
||||
//维护 IsFrontTaskNeedSignButNotSign 在添加任务哪里用触发器也维护了
|
||||
var visitTaskIdQueryable = _visitTaskRepository.Where(visitTaskLambda) //该Subject 该标准的任务
|
||||
//小于自己任务号的任务 存在需要签名 但是没签名
|
||||
.Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)
|
||||
&& t.IsFrontTaskNeedSignButNotSign == false )
|
||||
.Select(t => t.Id);
|
||||
|
||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => visitTaskIdQueryable.Contains(t.Id), u => new VisitTask()
|
||||
//有序阅片才维护 IsFrontTaskNeedSignButNotSign 这个状态
|
||||
if (_readingQuestionCriterionTrialRepository.Any(t=>t.Id==trialReadingCritrialId && t.IsReadingTaskViewInOrder == true))
|
||||
{
|
||||
IsFrontTaskNeedSignButNotSign = true
|
||||
});
|
||||
|
||||
|
||||
Expression<Func<VisitTask, bool>> visitTaskLambda = x => x.TrialId == trialId && x.SubjectId == subjectId && x.TrialReadingCriterionId == trialReadingCritrialId;
|
||||
|
||||
|
||||
//维护 IsFrontTaskNeedSignButNotSign 在添加任务哪里用触发器也维护了
|
||||
var visitTaskIdQueryable = _visitTaskRepository.Where(visitTaskLambda) //该Subject 该标准的任务
|
||||
//小于自己任务号的任务 存在需要签名 但是没签名
|
||||
.Where(t => t.IsFrontTaskNeedSignButNotSign == false &&
|
||||
|
||||
(t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)
|
||||
|
||||
// 前序存在 未一致性核查未通过的
|
||||
|| t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum>sv.VisitNum)
|
||||
|
||||
))
|
||||
.Select(t => t.Id);
|
||||
|
||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => visitTaskIdQueryable.Contains(t.Id), u => new VisitTask()
|
||||
{
|
||||
IsFrontTaskNeedSignButNotSign = true
|
||||
});
|
||||
|
||||
|
||||
|
||||
var visitTaskIdQueryable2 = _visitTaskRepository.Where(visitTaskLambda) //该Subject 该标准的任务
|
||||
//小于自己任务号的任务 存在需要签名 但是没签名
|
||||
.Where(t => !t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)
|
||||
&& t.IsFrontTaskNeedSignButNotSign == true )
|
||||
.Select(t => t.Id);
|
||||
var visitTaskIdQueryable2 = _visitTaskRepository.Where(visitTaskLambda) //该Subject 该标准的任务
|
||||
|
||||
.Where(t => t.IsFrontTaskNeedSignButNotSign == true &&
|
||||
|
||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => visitTaskIdQueryable2.Contains(t.Id), u => new VisitTask()
|
||||
{
|
||||
IsFrontTaskNeedSignButNotSign = false
|
||||
});
|
||||
//前序任务 不存在需要签名 但是没签名
|
||||
!t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)
|
||||
|
||||
// 前序 不存在 未一致性核查未通过的
|
||||
&& !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum)
|
||||
)
|
||||
.Select(t => t.Id);
|
||||
|
||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => visitTaskIdQueryable2.Contains(t.Id), u => new VisitTask()
|
||||
{
|
||||
IsFrontTaskNeedSignButNotSign = false
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -586,10 +634,6 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
var clinicalDataList = await this.GetTrialClinicalDataSelect(getTrialClinicalDataSelectIndto);
|
||||
|
||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC)
|
||||
{
|
||||
inDto.UploadRole = UploadRole.CRC;
|
||||
}
|
||||
var isBaseLine = await _subjectVisitRepository.AnyAsync(x => x.Id == inDto.ReadingId && x.IsBaseLine);
|
||||
|
||||
|
||||
@@ -626,23 +670,23 @@ namespace IRaCIS.Application.Services
|
||||
inDto.ReadingId = visitTask.SouceReadModuleId ?? visitTask.SourceSubjectVisitId;
|
||||
}
|
||||
|
||||
|
||||
var resultQuery = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId)
|
||||
.WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId)
|
||||
.WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId)
|
||||
.WhereIf(inDto.SelectIsSign, x => x.IsSign == true)
|
||||
.Where(x => x.ReadingId == inDto.ReadingId || (x.SubjectId == inDto.SubjectId && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject))
|
||||
.Where(x => x.ReadingId == inDto.ReadingId)
|
||||
.Select(x => new GetReadingClinicalDataListOutDto()
|
||||
{
|
||||
ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
|
||||
SubjectId = x.SubjectId,
|
||||
ReadingId = x.ReadingId,
|
||||
ClinicalDataSetEnName=x.ClinicalDataTrialSet.ClinicalDataSetEnName,
|
||||
ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName,
|
||||
ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us),
|
||||
ClinicalDataTrialSetId = x.ClinicalDataTrialSetId,
|
||||
IsSign = x.IsSign,
|
||||
ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
|
||||
CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList,
|
||||
TrialClinicalDataSetCriteriaList=x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList,
|
||||
TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList,
|
||||
Id = x.Id,
|
||||
UploadRole = x.ClinicalDataTrialSet.UploadRole,
|
||||
IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC,
|
||||
@@ -652,33 +696,141 @@ namespace IRaCIS.Application.Services
|
||||
FileName = y.FileName,
|
||||
Path = y.Path,
|
||||
CreateTime = y.CreateTime,
|
||||
}).ToList()
|
||||
}).ToList(),
|
||||
|
||||
});
|
||||
|
||||
var result = new List<GetReadingClinicalDataListOutDto>();
|
||||
if (!inDto.IsOnlyGetCRCReadModule)
|
||||
{
|
||||
result = await resultQuery.ToListAsync();
|
||||
}
|
||||
|
||||
var readingIds = result.Select(x => x.ReadingId).ToList();
|
||||
var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId??default(Guid))).ToListAsync();
|
||||
result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x => {
|
||||
|
||||
x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId&&y.ClinicalDataTrialSetId==x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
|
||||
{
|
||||
CheckDate = y.CheckDate,
|
||||
ClinicalFormId = y.Id
|
||||
}).ToList();
|
||||
x.FileCount = x.ClinicalFromList.Count();
|
||||
});
|
||||
|
||||
|
||||
// 这里处理CRC上传 阅片期的临床数据
|
||||
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId)
|
||||
.WhereIf(inDto.SelectIsSign,x=>x.IsPMConfirm)
|
||||
.WhereIf(!inDto.SelectIsSign, x => x.IsCRCConfirm)
|
||||
.FirstOrDefaultAsync();
|
||||
if (readModule != null)
|
||||
{
|
||||
var moduleCriterionFromList = await _readModuleCriterionFromRepository
|
||||
.WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalForm.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId)
|
||||
.Where(x => x.ReadModuleId == readModule.Id).Select(x => new{
|
||||
ClinicalFormId= x.ClinicalFormId,
|
||||
CheckDate= x.ClinicalForm.CheckDate,
|
||||
ClinicalDataTrialSetId= x.ClinicalForm.ClinicalDataTrialSetId
|
||||
|
||||
|
||||
}).ToListAsync();
|
||||
|
||||
|
||||
var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC && x.ClinicalUploadType == ClinicalUploadType.Structuring)
|
||||
.WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead)
|
||||
.WhereIf(readModule.ReadingSetType == ReadingSetType.TumorReading, x => x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
|
||||
.Where(x=>x.TrialClinicalDataSetCriteriaList.Any(y=>y.TrialReadingCriterionId==readModule.TrialReadingCriterionId))
|
||||
.Select(x => new GetReadingClinicalDataListOutDto()
|
||||
{
|
||||
|
||||
ClinicalDataLevel = x.ClinicalDataLevel,
|
||||
SubjectId = inDto.SubjectId,
|
||||
ReadingId = default(Guid),
|
||||
IsCRCApplicationRevoke=readModule.IsCRCApplicationRevoke,
|
||||
IsCRCConfirm= readModule.IsCRCConfirm,
|
||||
IsPMConfirm= readModule.IsPMConfirm,
|
||||
ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us),
|
||||
ClinicalDataSetEnName = x.ClinicalDataSetEnName,
|
||||
ClinicalDataTrialSetId = x.Id,
|
||||
IsSign = readModule.IsPMConfirm,
|
||||
ClinicalUploadType = x.ClinicalUploadType,
|
||||
Id = default(Guid),
|
||||
UploadRole = x.UploadRole,
|
||||
IsCRCUpload = x.UploadRole == UploadRole.CRC,
|
||||
IsNeedMerge = true,
|
||||
ReadModuleId = readModule.Id,
|
||||
//FileCount = x.FileCount,
|
||||
|
||||
//ReadingClinicalDataState = x.ReadingClinicalDataState,
|
||||
|
||||
//FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
|
||||
//{
|
||||
// Id = y.Id,
|
||||
// FileName = y.FileName,
|
||||
// Path = y.Path,
|
||||
// CreateTime = y.CreateTime,
|
||||
//}).ToList()
|
||||
|
||||
}).ToListAsync();
|
||||
|
||||
clinicalresult.ForEach(x =>
|
||||
{
|
||||
x.FileCount = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Count();
|
||||
x.ClinicalFromList = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).OrderBy(y => y.CheckDate).Select(x => new ClinicalFromData
|
||||
{
|
||||
CheckDate = x.CheckDate,
|
||||
ClinicalFormId = x.ClinicalFormId
|
||||
|
||||
}).ToList();
|
||||
x.IsSign = readModule.IsPMConfirm ? true : false;
|
||||
x.ReadingClinicalDataState = readModule.IsPMConfirm ? ReadingClinicalDataStatus.HaveSigned : ReadingClinicalDataStatus.HaveChecked;
|
||||
|
||||
});
|
||||
|
||||
result.AddRange(clinicalresult);
|
||||
}
|
||||
|
||||
|
||||
|
||||
var result = await resultQuery.ToListAsync();
|
||||
// 根据标准
|
||||
if (inDto.VisitTaskId != null)
|
||||
{
|
||||
var visitTaskInfo = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId);
|
||||
|
||||
result = result.Where(x => x.TrialClinicalDataSetCriteriaList.Any(z=>z.TrialReadingCriterionId==visitTaskInfo.TrialReadingCriterionId)).ToList();
|
||||
|
||||
result = result.Where(x => x.TrialClinicalDataSetCriteriaList.Any(z => z.TrialReadingCriterionId == visitTaskInfo.TrialReadingCriterionId)).ToList();
|
||||
}
|
||||
|
||||
|
||||
result = result.Where(x => !(x.ClinicalUploadType == ClinicalUploadType.PDF && x.FileList.Count() == 0)).ToList();
|
||||
// 需要排除表格为空的数据
|
||||
|
||||
|
||||
var readingIds = result.Select(x => x.ReadingId).ToList();
|
||||
|
||||
var tablecount = (await _previousHistoryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).CountAsync()) +
|
||||
(await _previousOtherRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).CountAsync()) +
|
||||
(await _previousSurgeryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).CountAsync());
|
||||
|
||||
if (tablecount == 0)
|
||||
if (inDto.GetClinicalType != null)
|
||||
{
|
||||
result = result.Where(x => x.ClinicalUploadType != ClinicalUploadType.Table).ToList();
|
||||
switch (inDto.GetClinicalType)
|
||||
{
|
||||
case GetClinicalType.PMUpload:
|
||||
result = result.Where(x => x.UploadRole == UploadRole.PM).ToList();
|
||||
break;
|
||||
case GetClinicalType.CRCConfirm:
|
||||
result = result.Where(x => x.UploadRole == UploadRole.CRC&&x.IsCRCConfirm&&!x.IsPMConfirm).ToList();
|
||||
break;
|
||||
case GetClinicalType.HasSign:
|
||||
result = result.Where(x => x.IsSign).ToList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var previousHistoryList = await _previousHistoryRepository.Where(x => x.SubjectVisitId == inDto.ReadingId).ProjectTo<PreviousHistoryView>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
var previousOtherList = await _previousOtherRepository.Where(x => x.SubjectVisitId == inDto.ReadingId).ProjectTo<PreviousOtherView>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
var previousSurgeryList = await _previousSurgeryRepository.Where(x => x.SubjectVisitId == inDto.ReadingId).ProjectTo<PreviousSurgeryView>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
foreach (var item in result)
|
||||
{
|
||||
item.ClinicalTableData = new ClinicalDataTable()
|
||||
{
|
||||
PreviousHistoryList = previousHistoryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
||||
PreviousOtherList = previousOtherList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
||||
PreviousSurgeryList = previousSurgeryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -692,14 +844,9 @@ namespace IRaCIS.Application.Services
|
||||
[NonDynamicMethod]
|
||||
public async Task<List<GetReadingClinicalDataListOutDto>> GetReadingClinicalList(GetReadingClinicalDataListIndto inDto)
|
||||
{
|
||||
|
||||
//var criterionType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).Select(x => x.CriterionType).FirstNotNullAsync();
|
||||
|
||||
|
||||
var resultQuery = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId)
|
||||
.Where(x => x.ReadingId == inDto.ReadingId || (x.SubjectId == inDto.SubjectId && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject))
|
||||
//.WhereIf(inDto.UploadRole == UploadRole.CRC, x => x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC)
|
||||
|
||||
.Where(x => x.ReadingId == inDto.ReadingId)
|
||||
.WhereIf(inDto.ClinicalDataTrialSetId!=null, x=>x.ClinicalDataTrialSetId==inDto.TrialReadingCriterionId)
|
||||
.Where(x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t=>t.TrialReadingCriterionId==inDto.TrialReadingCriterionId))
|
||||
.Select(x => new GetReadingClinicalDataListOutDto()
|
||||
{
|
||||
@@ -730,7 +877,111 @@ namespace IRaCIS.Application.Services
|
||||
});
|
||||
|
||||
var result = await resultQuery.ToListAsync();
|
||||
//result = result.Where(x => !(x.UploadRole == UploadRole.CRC && x.ClinicalUploadType == ClinicalUploadType.PDF && x.FileList.Count() == 0)).ToList();
|
||||
|
||||
|
||||
var readingIds = result.Select(x => x.ReadingId).ToList();
|
||||
var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId ?? default(Guid))).ToListAsync();
|
||||
result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x => {
|
||||
|
||||
x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
|
||||
{
|
||||
CheckDate = y.CheckDate,
|
||||
ClinicalFormId = y.Id
|
||||
}).ToList();
|
||||
x.FileCount = x.ClinicalFromList.Count();
|
||||
});
|
||||
|
||||
// 这里处理CRC上传 阅片期的临床数据
|
||||
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId&&x.IsCRCConfirm)
|
||||
.FirstOrDefaultAsync();
|
||||
if (readModule != null)
|
||||
{
|
||||
var moduleCriterionFromList = await _readModuleCriterionFromRepository.Where(x => x.ReadModuleId == readModule.Id)
|
||||
|
||||
.WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalForm.ClinicalDataTrialSetId == inDto.TrialReadingCriterionId)
|
||||
.Select(x => new {
|
||||
ClinicalFormId = x.ClinicalFormId,
|
||||
CheckDate = x.ClinicalForm.CheckDate,
|
||||
ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSetId
|
||||
|
||||
|
||||
}).ToListAsync();
|
||||
|
||||
|
||||
var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC&&x.ClinicalUploadType== ClinicalUploadType.Structuring)
|
||||
.WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading,x=>x.ClinicalDataLevel== ClinicalLevel.ImageRead)
|
||||
.WhereIf(readModule.ReadingSetType == ReadingSetType.TumorReading, x => x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
|
||||
.Where(x => x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == readModule.TrialReadingCriterionId))
|
||||
.Select(x => new GetReadingClinicalDataListOutDto()
|
||||
{
|
||||
|
||||
ClinicalDataLevel = x.ClinicalDataLevel,
|
||||
SubjectId = inDto.SubjectId,
|
||||
ReadingId = default(Guid),
|
||||
IsCRCApplicationRevoke= readModule.IsCRCApplicationRevoke,
|
||||
IsCRCConfirm = readModule.IsCRCConfirm,
|
||||
IsPMConfirm=readModule.IsPMConfirm,
|
||||
|
||||
ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us),
|
||||
ClinicalDataSetEnName = x.ClinicalDataSetEnName,
|
||||
ClinicalDataTrialSetId = x.Id,
|
||||
IsSign = readModule.IsPMConfirm,
|
||||
ClinicalUploadType = x.ClinicalUploadType,
|
||||
Id = default(Guid),
|
||||
UploadRole = x.UploadRole,
|
||||
IsCRCUpload = x.UploadRole == UploadRole.CRC,
|
||||
IsNeedMerge = true,
|
||||
ReadModuleId = readModule.Id,
|
||||
//FileCount = x.FileCount,
|
||||
|
||||
//ReadingClinicalDataState = x.ReadingClinicalDataState,
|
||||
|
||||
//FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
|
||||
//{
|
||||
// Id = y.Id,
|
||||
// FileName = y.FileName,
|
||||
// Path = y.Path,
|
||||
// CreateTime = y.CreateTime,
|
||||
//}).ToList()
|
||||
|
||||
}).ToListAsync();
|
||||
|
||||
clinicalresult.ForEach(x =>
|
||||
{
|
||||
x.FileCount = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Count();
|
||||
x.ClinicalFromList = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).OrderBy(y => y.CheckDate).Select(x => new ClinicalFromData
|
||||
{
|
||||
CheckDate = x.CheckDate,
|
||||
ClinicalFormId = x.ClinicalFormId
|
||||
|
||||
}).ToList();
|
||||
|
||||
x.IsSign = readModule.IsPMConfirm ?true : false;
|
||||
x.ReadingClinicalDataState = readModule.IsPMConfirm ? ReadingClinicalDataStatus.HaveSigned : ReadingClinicalDataStatus.HaveChecked;
|
||||
|
||||
});
|
||||
|
||||
result.AddRange(clinicalresult);
|
||||
}
|
||||
|
||||
|
||||
if (inDto.GetClinicalType != null)
|
||||
{
|
||||
switch (inDto.GetClinicalType)
|
||||
{
|
||||
case GetClinicalType.PMUpload:
|
||||
result = result.Where(x => x.UploadRole == UploadRole.PM).ToList();
|
||||
break;
|
||||
case GetClinicalType.CRCConfirm:
|
||||
result = result.Where(x => x.UploadRole == UploadRole.CRC&&x.IsCRCConfirm&&!x.IsPMConfirm).ToList();
|
||||
break;
|
||||
case GetClinicalType.HasSign:
|
||||
result = result.Where(x => x.IsSign).ToList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,379 @@
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
{
|
||||
|
||||
public class CRCSignClinicalDataInDto
|
||||
{
|
||||
public Guid ReadingClinicalDataId { get; set; }
|
||||
}
|
||||
public class AutoAddClinicalInDto
|
||||
{
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
//public Guid? VisitId { get; set; }
|
||||
|
||||
public Guid TrialId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetCRCSubjectClinicalInDto:PageInput
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
public string? SubjectCode { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetCRCSubjectClinicalOutDto
|
||||
{
|
||||
public Guid SubjectId { get; set; }
|
||||
|
||||
public Guid ReadingClinicalDataId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上传角色
|
||||
/// </summary>
|
||||
public UploadRole UploadRole { get; set; }
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 访视Id 或者模块Id
|
||||
/// </summary>
|
||||
public Guid ReadingId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 临床级别
|
||||
/// </summary>
|
||||
public ClinicalLevel ClinicalDataLevel { get; set; }
|
||||
|
||||
|
||||
public Guid? BaseLineVisitId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上传方式
|
||||
/// </summary>
|
||||
public ClinicalUploadType ClinicalUploadType { get; set; }
|
||||
|
||||
public string SubjectCode { get; set; }
|
||||
public Guid ClinicalDataTrialSetId { get; set; }
|
||||
|
||||
public string ClinicalDataSetName { get; set; }
|
||||
|
||||
public string ClinicalDataSetEnName { get; set; }
|
||||
|
||||
public int ClinicalCount { get; set; } = 0;
|
||||
}
|
||||
|
||||
|
||||
public class GetCRCSubjectClinicalResultDto
|
||||
{
|
||||
public Guid SubjectId { get; set; }
|
||||
|
||||
public string SubjectCode { get; set; }
|
||||
|
||||
public List<GetCRCSubjectClinicalOutDto> ClinicalDataList { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public class GetClinicalQuestionAnswerListInDto
|
||||
{
|
||||
public Guid SubjectId { get; set; }
|
||||
|
||||
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid ClinicalDataTrialSetId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetClinicalQuestionAnswerListOutDto
|
||||
{
|
||||
public List<TrialClinicalQuestionDto> QuestionList { get; set; }
|
||||
|
||||
public List<Dictionary<string, string>> AnswerList { get; set; }
|
||||
}
|
||||
|
||||
public class GetClinicalFormInfoInDto
|
||||
{
|
||||
public Guid ClinicalFormId { get; set; }
|
||||
}
|
||||
|
||||
public class GetClinicalFormInfoOutDto
|
||||
{
|
||||
public List<ClinicalQuestionPreviewDto> Question { get; set; }
|
||||
}
|
||||
|
||||
public class ClinicalFormQuestionAnswer
|
||||
{
|
||||
public Guid QuestionId { get; set; }
|
||||
|
||||
public string Answer { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class ClinicalFormTableQuestionAnswer
|
||||
{
|
||||
public Guid TableQuestionId { get; set; }
|
||||
|
||||
public int RowIndex { get; set; }
|
||||
|
||||
public Guid QuestionId { get; set; }
|
||||
|
||||
public string Answer { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class GetPMConfirmListInDto: PageInput
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid TrialReadingCriterionId { get; set; }
|
||||
}
|
||||
|
||||
public class GetCRCConfirmListInDto:PageInput
|
||||
{
|
||||
|
||||
public bool? IsCRCConfirm { get; set; }
|
||||
|
||||
public bool? IsPMConfirm { get; set; }
|
||||
|
||||
public Guid? TrialReadingCriterionId { get; set; }
|
||||
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
public DateTime? StartTime { get; set; }
|
||||
public DateTime? EndTime { get; set; }
|
||||
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid? ReadModuleId { get; set; }
|
||||
|
||||
public string? SubjectCode { get; set; }
|
||||
}
|
||||
|
||||
public class CRCCancelConfirmClinicalInDto
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid ReadModuleId { get; set; }
|
||||
}
|
||||
|
||||
public class GetClinicalDateListOutDto
|
||||
{
|
||||
public string ClinicalDataSetName { get; set; }
|
||||
|
||||
|
||||
public List<GetCRCBeConfirmListOutDto> DateList { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetCRCBeConfirmListInDto
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid ReadModuleId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetClinicalTableListInDto
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid ReadModuleId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetClinicalTableListOutDto: GetClinicalQuestionAnswerListOutDto
|
||||
{
|
||||
public string ClinicalDataSetName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模块名称
|
||||
/// </summary>
|
||||
public string ModuleName { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetCRCBeConfirm: GetCRCBeConfirmListOutDto
|
||||
{
|
||||
public Guid ReadModuleId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetCRCBeConfirmListOutDto
|
||||
{
|
||||
public Guid ClinicalDataTrialSetId { get; set; }
|
||||
|
||||
public Guid ClinicalFormId { get; set; }
|
||||
|
||||
public string ClinicalDataSetName { get; set; }
|
||||
|
||||
public string ClinicalDataSetEnName { get; set; }
|
||||
|
||||
public DateTime CheckDate { get; set; }
|
||||
|
||||
public bool IsHaveTableQuestion { get; set; }
|
||||
}
|
||||
|
||||
public class CRCConfirmClinicalInDto
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid SubjectId { get; set; }
|
||||
|
||||
public Guid ReadModuleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 临床数据是否完整
|
||||
/// </summary>
|
||||
public bool? IsClinicalDataComplete { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 临床数据是否盲化
|
||||
/// </summary>
|
||||
public bool? IsClinicalDataBlind { get; set; }
|
||||
|
||||
public bool IsConfirm { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class CRCClinicalForm
|
||||
{
|
||||
/// <summary>
|
||||
/// 受试者Id
|
||||
/// </summary>
|
||||
public Guid SubjectId { get; set; }
|
||||
public DateTime? CheckDate { get; set; }
|
||||
|
||||
public Guid ClinicalFormId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 临床级别
|
||||
/// </summary>
|
||||
public ClinicalLevel ClinicalDataLevel { get; set; }
|
||||
|
||||
|
||||
public Guid ClinicalDataTrialSetId { get; set; }
|
||||
|
||||
public string ClinicalDataSetName { get; set; }
|
||||
|
||||
public bool IsHaveTableQuestion { get; set; }
|
||||
|
||||
public string ClinicalDataSetEnName { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetCRCConfirmListOutDto
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 受试者ID
|
||||
/// </summary>
|
||||
public Guid SubjectId { get; set; }
|
||||
|
||||
public bool IsNotNeedPMConfirm { get; set; } = false;
|
||||
public Guid ReadModuleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模块名称
|
||||
/// </summary>
|
||||
public string ModuleName { get; set; }
|
||||
|
||||
public string VisitBlindName { get; set; }
|
||||
|
||||
public bool IsPMConfirm { get; set; }
|
||||
|
||||
public ReadingSetType ReadingSetType { get; set; }
|
||||
|
||||
public bool IsCRCConfirm { get; set; } = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// CRC是否正在申请撤回
|
||||
/// </summary>
|
||||
public bool IsCRCApplicationRevoke { get; set; } = false;
|
||||
|
||||
public string SubjectCode { get; set; }
|
||||
|
||||
public bool IsHaveTableQuestion
|
||||
{
|
||||
get
|
||||
{
|
||||
return ClinicalFormList.Any(x => x.IsHaveTableQuestion);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 最晚拍片日期
|
||||
/// </summary>
|
||||
public DateTime? LatestScanDate { get; set; }
|
||||
|
||||
public List<string> ClinicalNameList
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ClinicalFormList.Select(x => x.ClinicalDataSetName).Distinct().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<GetCRCBeConfirmListOutDto> ClinicalFormList { get; set; }
|
||||
|
||||
public int FormCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ClinicalFormList.Count();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DeleteClinicalFormInDto
|
||||
{
|
||||
public Guid ClinicalFormId { get; set; }
|
||||
}
|
||||
public class SubmitClinicalFormInDto
|
||||
{
|
||||
/// <summary>
|
||||
/// VisitId
|
||||
/// </summary>
|
||||
public Guid? ReadingId { get; set; }
|
||||
|
||||
public Guid? ClinicalFormId { get; set; }
|
||||
|
||||
public Guid SubjectId { get; set; }
|
||||
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid ClinicalDataTrialSetId { get; set; }
|
||||
|
||||
|
||||
public List<ClinicalFormQuestionAnswer> QuestionAnswers { get; set; }
|
||||
|
||||
public List<ClinicalQuestionForm> TableQuestionAnswerList { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class ClinicalQuestionForm
|
||||
{
|
||||
public Guid QuestionId { get; set; }
|
||||
|
||||
public List<List<ClinicalTableQuestionForm>> TableQuestionAnswers { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class ClinicalTableQuestionForm
|
||||
{
|
||||
public Guid TableQuestionId { get; set; }
|
||||
|
||||
public string Answer { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否应用
|
||||
/// </summary>
|
||||
public bool? IsApply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
@@ -73,10 +77,23 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
//public List<int> CriterionEnumList { get; set; }
|
||||
}
|
||||
|
||||
public class ApplySystemClinicalInDto
|
||||
{
|
||||
public Guid SystemClinicalId { get; set; }
|
||||
}
|
||||
|
||||
public class ApplyTrialClinicalInDto
|
||||
{
|
||||
public Guid TrialClinicalId { get; set; }
|
||||
}
|
||||
public class ClinicalDataSystemSetAddOrEdit
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否应用
|
||||
/// </summary>
|
||||
public bool IsApply { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 枚举
|
||||
|
||||
@@ -0,0 +1,583 @@
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
{
|
||||
|
||||
|
||||
|
||||
#region 获取计算问题
|
||||
|
||||
public class GetTrialClinicalQuestionCalculateRelationInDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 项目临床数据Id
|
||||
/// </summary>
|
||||
public Guid TrialClinicalId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetTrialClinicalQuestionCalculateRelationOutDto
|
||||
{
|
||||
public Guid QuestionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 问题名称
|
||||
/// </summary>
|
||||
public string QuestionName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义计算标记
|
||||
/// </summary>
|
||||
public ClinicalCalculateMark? CustomCalculateMark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数值类型
|
||||
/// </summary>
|
||||
public ValueOfType? ValueType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 单位
|
||||
/// </summary>
|
||||
public ValueUnit? Unit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义单位
|
||||
/// </summary>
|
||||
public string CustomUnit { get; set; } = string.Empty;
|
||||
|
||||
public List<CalculateInfo> CalculateQuestionList { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetClinicalCalculateQuestionsOutDto
|
||||
{
|
||||
public Guid QuestionId { get; set; }
|
||||
|
||||
public string QuestionName { get; set; }
|
||||
|
||||
public List<CalculateQuestion> TableQuestions { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetClinicalCalculateQuestionsInDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 项目临床数据Id
|
||||
/// </summary>
|
||||
public Guid TrialClinicalId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 临床问题类型(分组,单选。)
|
||||
/// </summary>
|
||||
public string ClinicalQuestionType { get; set; } = string.Empty;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 预览
|
||||
|
||||
|
||||
public class GetSystemClinicalQuestionPreviewDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统临床数据Id
|
||||
/// </summary>
|
||||
public Guid SystemClinicalId { get; set; }
|
||||
}
|
||||
|
||||
public class GetTrialClinicalQuestionPreviewDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 项目临床数据Id
|
||||
/// </summary>
|
||||
public Guid TrialClinicalId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 项目预览问题Dto
|
||||
/// </summary>
|
||||
public class ClinicalQuestionPreviewDto : TrialClinicalQuestionDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统临床数据Id
|
||||
/// </summary>
|
||||
public Guid SystemClinicalId { get; set; }
|
||||
|
||||
public string Answer { get; set; } = string.Empty;
|
||||
|
||||
public DateTime? CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子问题
|
||||
/// </summary>
|
||||
public List<ClinicalQuestionPreviewDto> Childrens { get; set; } = new List<ClinicalQuestionPreviewDto>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 关联问题
|
||||
/// </summary>
|
||||
public List<ClinicalQuestionPreviewDto> RelationQuestions { get; set; } = new List<ClinicalQuestionPreviewDto>();
|
||||
|
||||
/// <summary>
|
||||
/// 表格问题
|
||||
/// </summary>
|
||||
public List<ClinicalTablePreviewDto> TableQuestions { get; set; } = new List<ClinicalTablePreviewDto>();
|
||||
|
||||
public List<Dictionary<Guid,string>> TableAnswer { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 项目临床数据问题
|
||||
/// </summary>
|
||||
public class ClinicalTablePreviewDto : TrialClinicalTableQuestionDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统临床数据Id
|
||||
/// </summary>
|
||||
public Guid SystemClinicalId { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 外层问题
|
||||
/// <summary>
|
||||
/// 临床问题基本信息
|
||||
/// </summary>
|
||||
public class ClinicalQuestionBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
|
||||
public bool IsVerify { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 问题名称
|
||||
/// </summary>
|
||||
public string QuestionName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 问题英文名称
|
||||
/// </summary>
|
||||
public string QuestionEnName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 分组名称
|
||||
/// </summary>
|
||||
public string? GroupName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 分组英文名称
|
||||
/// </summary>
|
||||
public string? GroupEnName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 临床问题类型(分组,单选。)
|
||||
/// </summary>
|
||||
public string ClinicalQuestionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 问题标识
|
||||
/// </summary>
|
||||
public ClinicalQuestionMark? ClinicalQuestionMarkEnum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大长度
|
||||
/// </summary>
|
||||
public int? MaxAnswerLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大行数
|
||||
/// </summary>
|
||||
public int? MaxQuestionCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 临床数据选项类型(无,自定义)
|
||||
/// </summary>
|
||||
public ClinicalOptionType ClinicalOptionTypeEnum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分组Id
|
||||
/// </summary>
|
||||
public Guid? GroupId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义选项
|
||||
/// </summary>
|
||||
public string TypeValue { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 字典Code
|
||||
/// </summary>
|
||||
public string DictionaryCode { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public int ShowOrder { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 是否必填
|
||||
/// </summary>
|
||||
public IsRequired IsRequired { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联Value
|
||||
/// </summary>
|
||||
public string RelevanceValue { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 关联ID
|
||||
/// </summary>
|
||||
public Guid? RelevanceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 父问题Id
|
||||
/// </summary>
|
||||
public Guid? ParentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 父问题触发值
|
||||
/// </summary>
|
||||
public string ParentTriggerValue { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 显示类型
|
||||
/// </summary>
|
||||
public ClinicalQuestionShow ClinicalQuestionShowEnum { get; set; } = ClinicalQuestionShow.Show;
|
||||
|
||||
/// <summary>
|
||||
/// 是否是检查日期
|
||||
/// </summary>
|
||||
public bool IsCheckDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 小数点位数
|
||||
/// </summary>
|
||||
public int? DigitPlaces { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 单位
|
||||
/// </summary>
|
||||
public string Unit { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 自定义计算标记
|
||||
/// </summary>
|
||||
public ClinicalCalculateMark? CustomCalculateMark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义计算问题
|
||||
/// </summary>
|
||||
public string CalculateQuestions { get; set; } = "[]";
|
||||
|
||||
[NotMapped]
|
||||
public List<CalculateInfo> CalculateQuestionList
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
var result = JsonConvert.DeserializeObject<List<CalculateInfo>>(this.CalculateQuestions);
|
||||
return result == null ? new List<CalculateInfo>() : result;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
return new List<CalculateInfo>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询临床数据基类
|
||||
/// </summary>
|
||||
public class ClinicalQuestionQueryBase : PageInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 问题名称
|
||||
/// </summary>
|
||||
public string QuestionName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目临床数据
|
||||
/// </summary>
|
||||
public class TrialClinicalQuestionQuery : ClinicalQuestionQueryBase
|
||||
{
|
||||
public Guid TrialClinicalId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目分组
|
||||
/// </summary>
|
||||
public class GetTrialGroupDto
|
||||
{
|
||||
public Guid TrialClinicalId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 项目临床数据问题
|
||||
/// </summary>
|
||||
public class TrialClinicalQuestionDto : ClinicalQuestionBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 项目临床数据Id
|
||||
/// </summary>
|
||||
public Guid TrialClinicalId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统临床数据
|
||||
/// </summary>
|
||||
public class SystemClinicalQuestionQuery : ClinicalQuestionQueryBase
|
||||
{
|
||||
public Guid SystemClinicalId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 系统临床数据问题
|
||||
/// </summary>
|
||||
public class SystemClinicalQuestionDto : ClinicalQuestionBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统临床数据Id
|
||||
/// </summary>
|
||||
public Guid SystemClinicalId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统分组
|
||||
/// </summary>
|
||||
public class GetSystemGroupDto
|
||||
{
|
||||
public Guid SystemClinicalId { get; set; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region 表格问题
|
||||
public class ClinicalTableQuestionBase
|
||||
|
||||
{
|
||||
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
public bool IsVerify { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 问题名称
|
||||
/// </summary>
|
||||
public string QuestionName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 问题英文名称
|
||||
/// </summary>
|
||||
public string QuestionEnName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 临床问题类型(分组,单选。)
|
||||
/// </summary>
|
||||
public string ClinicalTableQuestionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 问题标识
|
||||
/// </summary>
|
||||
public ClinicalTableQuestionMark? ClinicalTableQuestionMarkEnum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大长度
|
||||
/// </summary>
|
||||
public int? MaxAnswerLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 临床数据选项类型(无,自定义)
|
||||
/// </summary>
|
||||
public ClinicalOptionType ClinicalOptionTypeEnum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义选项
|
||||
/// </summary>
|
||||
public string TypeValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字典Code
|
||||
/// </summary>
|
||||
public string DictionaryCode { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public int ShowOrder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否必填
|
||||
/// </summary>
|
||||
public IsRequired IsRequired { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建人
|
||||
/// </summary>
|
||||
public Guid CreateUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 外层问题Id
|
||||
/// </summary>
|
||||
public Guid QuestionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 小数点位数
|
||||
/// </summary>
|
||||
public int? DigitPlaces { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 单位
|
||||
/// </summary>
|
||||
public string Unit { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 项目临床数据问题
|
||||
/// </summary>
|
||||
public class TrialClinicalTableQuestionDto : ClinicalTableQuestionBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 项目临床数据Id
|
||||
/// </summary>
|
||||
public Guid TrialClinicalId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义计算标记
|
||||
/// </summary>
|
||||
public ClinicalCalculateMark? ClinicalCalculateMarkEnum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义计算问题
|
||||
/// </summary>
|
||||
public string CalculateQuestions { get; set; } = "[]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 系统临床数据问题
|
||||
/// </summary>
|
||||
public class SystemClinicalTableQuestionDto : ClinicalTableQuestionBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统临床数据Id
|
||||
/// </summary>
|
||||
public Guid SystemClinicalId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 查询临床数据基类
|
||||
/// </summary>
|
||||
public class ClinicalTableQuestionQueryBase : PageInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 问题名称
|
||||
/// </summary>
|
||||
public string QuestionName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 外层问题Id
|
||||
/// </summary>
|
||||
public Guid QuestionId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目临床数据
|
||||
/// </summary>
|
||||
public class TrialClinicalTableQuestionQuery : ClinicalTableQuestionQueryBase
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统临床数据
|
||||
/// </summary>
|
||||
public class SystemClinicalTableQuestionQuery : ClinicalTableQuestionQueryBase
|
||||
{
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region 同步临床数据
|
||||
|
||||
|
||||
public class TrialClinicalTableQuestionSynchronize : TrialClinicalTableQuestion
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统临床数据Id
|
||||
/// </summary>
|
||||
public Guid SystemClinicalId { get; set; }
|
||||
}
|
||||
|
||||
public class TrialClinicalQuestionSynchronize : TrialClinicalQuestion
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统临床数据Id
|
||||
/// </summary>
|
||||
public Guid SystemClinicalId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class SynchronizationQuestionDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统临床数据Id
|
||||
/// </summary>
|
||||
public Guid SystemClinicalId { get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 项目临床数据Id
|
||||
/// </summary>
|
||||
public Guid TrialClinicalId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class QuestionDic
|
||||
{
|
||||
public Guid SystemQuestionId { get; set; }
|
||||
|
||||
public Guid TrialQuestionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 项目临床数据Id
|
||||
/// </summary>
|
||||
public Guid TrialClinicalId { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -252,15 +252,15 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
|
||||
public class GetReadModuleDtoOut
|
||||
{
|
||||
public string SubjectCode { get; set; }
|
||||
public string? SubjectCode { get; set; }
|
||||
|
||||
public string TrialSiteCode { get; set; }
|
||||
public string? TrialSiteCode { get; set; }
|
||||
|
||||
public string SiteCode { get; set; }
|
||||
public string? SiteCode { get; set; }
|
||||
|
||||
public Guid SiteId { get; set; }
|
||||
public Guid? SiteId { get; set; }
|
||||
|
||||
public Guid SubjectId { get; set; }
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
public List<ReadModuleView> Data { get; set; }
|
||||
|
||||
|
||||
@@ -9,6 +9,39 @@ using System.Collections.Generic;
|
||||
namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
{
|
||||
|
||||
public class GetPPDInfoInDto
|
||||
{
|
||||
public Guid VisitTaskId { get; set; }
|
||||
|
||||
public Guid QuestionId { get; set; }
|
||||
|
||||
public decimal RowIndex { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class GetPPDInfoOutDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 最低的PPD
|
||||
/// </summary>
|
||||
public decimal? NadirPPD { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最低PPD的访视
|
||||
/// </summary>
|
||||
public string? LowPPDVisit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 该病灶PPD值最小的访视的长径
|
||||
/// </summary>
|
||||
public decimal? LowPPDLDi { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 该病灶PPD值最小的访视的短径
|
||||
/// </summary>
|
||||
public decimal? LowPPDSDi { get; set; }
|
||||
}
|
||||
|
||||
public class CalculateTaskInDto
|
||||
{
|
||||
public Guid VisitTaskId { get; set; }
|
||||
|
||||
@@ -10,8 +10,8 @@ using System.Threading.Tasks;
|
||||
namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
{
|
||||
|
||||
public class AddOrUpdateReadingClinicalDataDto
|
||||
{
|
||||
public class AddOrUpdateReadingClinicalDataDto
|
||||
{
|
||||
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
@@ -113,9 +113,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
/// </summary>
|
||||
public bool? IsComplete { get; set; }
|
||||
|
||||
//public List<GetReadingClinicalDataListOutDto> ReadingClinicalDataList { get; set; }
|
||||
public List<ClinicalFromData> ClinicalFromList { get; set; }
|
||||
|
||||
public List<GetFileDto> PDFFileList { get; set; } = new List<GetFileDto>();
|
||||
//public List<GetReadingClinicalDataListOutDto> ReadingClinicalDataList { get; set; }
|
||||
|
||||
public List<GetFileDto> PDFFileList { get; set; } = new List<GetFileDto>();
|
||||
|
||||
public ClinicalDataTable ClinicalTableData { get; set; }
|
||||
}
|
||||
@@ -127,9 +129,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
|
||||
public List<PreviousOtherView> PreviousOtherList { get; set; }
|
||||
|
||||
public List<PreviousSurgeryView> PreviousSurgeryList{ get; set; }
|
||||
public List<PreviousSurgeryView> PreviousSurgeryList { get; set; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +139,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
public class GetCRCClinicalDataInDto
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
|
||||
[NotDefault]
|
||||
public Guid TrialId { get; set; }
|
||||
@@ -163,7 +165,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
/// <summary>
|
||||
/// 文件名称
|
||||
/// </summary>
|
||||
public string FileName { get; set; }
|
||||
public string FileName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 路径
|
||||
@@ -182,29 +184,52 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
|
||||
public Guid? ReadingId { get; set; }
|
||||
|
||||
public Guid? VisitTaskId { get; set; }
|
||||
/// <summary>
|
||||
/// 临床数据类型Id
|
||||
/// </summary>
|
||||
public Guid? ClinicalDataTrialSetId { get; set; }
|
||||
|
||||
public Guid? ReadingClinicalDataId { get; set; }
|
||||
public Guid? VisitTaskId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 1 PM上传的所有的 2CRC上传的所有已确认的 3 所有已经签名的
|
||||
/// </summary>
|
||||
public GetClinicalType? GetClinicalType { get; set; }
|
||||
|
||||
public Guid? ReadingClinicalDataId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 只查询已经签名的临床数据
|
||||
/// 只获取CRC上传的阅片模块结构化录入
|
||||
/// </summary>
|
||||
public bool SelectIsSign { get; set; } = true;
|
||||
public bool IsOnlyGetCRCReadModule { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 只查询已经签名的临床数据
|
||||
/// </summary>
|
||||
public bool SelectIsSign { get; set; } = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取访视列表
|
||||
/// </summary>
|
||||
public class GetReadingClinicalDataListIndto
|
||||
public class GetReadingClinicalDataListIndto
|
||||
{
|
||||
[NotDefault]
|
||||
[NotDefault]
|
||||
public Guid SubjectId { get; set; }
|
||||
[NotDefault]
|
||||
public Guid ReadingId { get; set; }
|
||||
|
||||
public UploadRole? UploadRole { get; set; }
|
||||
/// <summary>
|
||||
/// 临床数据类型Id
|
||||
/// </summary>
|
||||
public Guid? ClinicalDataTrialSetId { get; set; }
|
||||
|
||||
[NotDefault]
|
||||
/// <summary>
|
||||
/// 1 PM上传的所有的 2CRC上传的所有已确认的 3 所有已经签名的
|
||||
/// </summary>
|
||||
public GetClinicalType? GetClinicalType { get; set; }
|
||||
|
||||
[NotDefault]
|
||||
public Guid TrialReadingCriterionId { get; set; }
|
||||
|
||||
public Guid TrialId { get; set; }
|
||||
@@ -220,7 +245,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
public bool IsBaseLine { get; set; }
|
||||
}
|
||||
|
||||
public class GetReadingClinicalDataPDFListIndto:PageInput
|
||||
public class GetReadingClinicalDataPDFListIndto : PageInput
|
||||
{
|
||||
public Guid ReadingClinicalDataId { get; set; }
|
||||
}
|
||||
@@ -283,7 +308,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
|
||||
|
||||
public class PMClinicalDataConfirmCommand
|
||||
{
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -310,11 +335,18 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
/// </summary>
|
||||
public Guid ReadingId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CRC是否正在申请撤回
|
||||
/// </summary>
|
||||
public bool IsCRCApplicationRevoke { get; set; } = false;
|
||||
public bool IsCRCConfirm { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 项目配置临床类型Name
|
||||
/// </summary>
|
||||
public string ClinicalDataSetName { get; set; }
|
||||
public bool IsPMConfirm { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 项目配置临床类型Name
|
||||
/// </summary>
|
||||
public string ClinicalDataSetName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 英文名称
|
||||
@@ -363,11 +395,15 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
/// </summary>
|
||||
public bool IsCRCUpload { get; set; }
|
||||
|
||||
public bool IsNeedMerge { get; set; } = false;
|
||||
|
||||
public Guid ReadModuleId { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 是否签名
|
||||
/// </summary>
|
||||
public bool IsSign { get; set; }
|
||||
public bool IsSign { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -395,6 +431,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
// }
|
||||
//}
|
||||
|
||||
public List<ClinicalFromData> ClinicalFromList { get; set; }
|
||||
|
||||
public List<GetFileDto> FileList { get; set; } = new List<GetFileDto>();
|
||||
|
||||
|
||||
@@ -404,6 +442,19 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
}
|
||||
|
||||
|
||||
public class ClinicalFromData
|
||||
{
|
||||
/// <summary>
|
||||
/// 表单Id
|
||||
/// </summary>
|
||||
public Guid ClinicalFormId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 检查日期
|
||||
/// </summary>
|
||||
public DateTime? CheckDate { get; set; }
|
||||
}
|
||||
|
||||
public class GetFileDto
|
||||
{
|
||||
|
||||
|
||||
@@ -332,6 +332,54 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
public List<AdditionalQuestionAnswer> AnswerList { get; set; } = new List<AdditionalQuestionAnswer>();
|
||||
}
|
||||
|
||||
public class GetCustomTagInDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 任务Id
|
||||
/// </summary>
|
||||
public Guid VisitTaskId { get; set; }
|
||||
}
|
||||
|
||||
public class ReadingCustomTagDto
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务Id
|
||||
/// </summary>
|
||||
public Guid VisitTaskId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// StudyId
|
||||
/// </summary>
|
||||
public Guid? StudyId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// SeriesId
|
||||
/// </summary>
|
||||
public Guid? SeriesId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// InstanceId
|
||||
/// </summary>
|
||||
public Guid? InstanceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MeasureData
|
||||
/// </summary>
|
||||
public string MeasureData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CreateTime
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CreateUserId
|
||||
/// </summary>
|
||||
public Guid CreateUserId { get; set; }
|
||||
}
|
||||
|
||||
public class GetManualListInDto
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
@@ -79,6 +79,14 @@ namespace IRaCIS.Core.Application.ViewModel
|
||||
public Guid Id { get; set; }
|
||||
}
|
||||
|
||||
public class BatchDeteteCriterionMedicineQuestionInDto
|
||||
{
|
||||
public Guid TrialReadingCriterionId { get; set; }
|
||||
|
||||
public List<Guid> Ids { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class TrialDataFromSystem : ReadingMedicineTrialQuestion
|
||||
{
|
||||
public Guid SystemQuestionId { get; set; }
|
||||
@@ -311,6 +319,11 @@ namespace IRaCIS.Core.Application.ViewModel
|
||||
public List<GetMedicineQuestionPreviewOutDto> Childrens { get; set; }
|
||||
}
|
||||
|
||||
public class EmptMedicineTrialQuestionInDto
|
||||
{
|
||||
public Guid TrialReadingCriterionId { get; set; }
|
||||
}
|
||||
|
||||
///<summary>ReadingMedicineTrialQuestionQuery 列表查询参数模型</summary>
|
||||
public class ReadingMedicineTrialQuestionQuery:PageInput
|
||||
{
|
||||
|
||||
@@ -514,11 +514,12 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
/// </summary>
|
||||
public string QuestionEnName { get; set; } = string.Empty;
|
||||
|
||||
|
||||
|
||||
public List<string> ParentTriggerValueList { get; set; }
|
||||
public List<string> RelevanceValueList { get; set; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class ReadingCriterionPageView
|
||||
{
|
||||
@@ -1038,10 +1039,13 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
/// </summary>
|
||||
public ValueOfType? ValueType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
public List<string> ParentTriggerValueList { get; set; }
|
||||
public List<string> RelevanceValueList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据来源
|
||||
@@ -1730,7 +1734,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
/// 问题英文分组
|
||||
/// </summary>
|
||||
public string GroupEnName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public List<string> ParentTriggerValueList { get; set; }
|
||||
public List<string> RelevanceValueList { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service.Reading.Interface
|
||||
{
|
||||
public interface IClinicalAnswerService
|
||||
{
|
||||
Task<IResponseOutput> CRCSignClinicalData(CRCSignClinicalDataInDto inDto);
|
||||
|
||||
Task AutoAddCRCClinical(AutoAddClinicalInDto inDto);
|
||||
|
||||
Task<IResponseOutput> PMConfirmClinical(CRCConfirmClinicalInDto inDto);
|
||||
|
||||
Task<IResponseOutput> SubmitClinicalForm(SubmitClinicalFormInDto inDto);
|
||||
|
||||
Task<IResponseOutput> CRCConfirmClinical(CRCConfirmClinicalInDto inDto);
|
||||
|
||||
Task<IResponseOutput> CRCCancelConfirmClinical(CRCCancelConfirmClinicalInDto inDto);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-08-12 14:07:43
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
namespace IRaCIS.Core.Application.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// IClinicalQuestionService
|
||||
/// </summary>
|
||||
public interface IClinicalQuestionService
|
||||
{
|
||||
|
||||
|
||||
Task SynchronizationQuestion(List<SynchronizationQuestionDto> inDto);
|
||||
|
||||
|
||||
void FindChildQuestion(ClinicalQuestionPreviewDto item, List<ClinicalQuestionPreviewDto> questions, List<ClinicalTablePreviewDto> tableQuestions, List<ClinicalFormQuestionAnswer> answers, List<ClinicalFormTableQuestionAnswer> tableAnswers);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -23,5 +23,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
// Task<(List<GetReadingClinicalDataListOutDto>, object)> GetReadingClinicalDataList(GetReadingClinicalDataListIndto inDto);
|
||||
|
||||
Task<List<GetReadingClinicalDataListOutDto>> GetReadingClinicalList(GetReadingClinicalDataListIndto inDto);
|
||||
|
||||
Task DealVisiTaskClinicalDataSignedAsync(Guid trialId, Guid subjectId, Guid readingId, bool isVisit, Guid trialReadingCritrialId);
|
||||
}
|
||||
}
|
||||
+39
-13
@@ -138,16 +138,29 @@ namespace IRaCIS.Core.Application.Service
|
||||
return ResponseOutput.Result(result);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
|
||||
#region 项目
|
||||
#region 项目
|
||||
|
||||
/// 获取项目的医学审核问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
/// <summary>
|
||||
/// 清空医学审核问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> EmptMedicineTrialQuestion(EmptMedicineTrialQuestionInDto inDto)
|
||||
{
|
||||
await _readingMedicineTrialQuestionRepository.DeleteFromQueryAsync(x => x.TrialReadingCriterionId == inDto.TrialReadingCriterionId);
|
||||
await _readingMedicineTrialQuestionRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(true);
|
||||
}
|
||||
|
||||
/// 获取项目的医学审核问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<(PageOutput<ReadingMedicineTrialQuestionView>, object)> GetReadingMedicineTrialQuestionList(ReadingMedicineTrialQuestionQuery inDto)
|
||||
{
|
||||
var query = _readingMedicineTrialQuestionRepository.AsQueryable()
|
||||
@@ -452,13 +465,26 @@ namespace IRaCIS.Core.Application.Service
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量删除项目标准医学审核问题
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> BatchDeteteCriterionMedicineQuestion(BatchDeteteCriterionMedicineQuestionInDto inDto)
|
||||
{
|
||||
await _readingMedicineTrialQuestionRepository.BatchDeleteNoTrackingAsync(x => inDto.Ids.Contains(x.Id));
|
||||
var result= await _readingMedicineTrialQuestionRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从系统里面选择问题添加到项目里面
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
|
||||
/// <summary>
|
||||
/// 从系统里面选择问题添加到项目里面
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddTrialDataFromSystem(AddTrialDataFromSystemInDto inDto)
|
||||
{
|
||||
// 直接写??
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user