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

Test_IRC_Net10
hang 2026-08-17 10:48:25 +08:00
commit 669280368a
40 changed files with 47125 additions and 101 deletions

View File

@ -43,7 +43,7 @@ namespace IRaCIS.Core.SCP.Filter
else else
{ {
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (context.Exception.InnerException is null ? (context.Exception.Message /*+ context.Exception.StackTrace*/) context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (context.Exception.InnerException is null ? (context.Exception.Message /*+ context.Exception.StackTrace*/)
: (context.Exception.InnerException?.Message /*+ context.Exception.InnerException?.StackTrace*/)), ApiResponseCodeEnum.ProgramException)); : (context.Exception.InnerException?.Message /*+ context.Exception.InnerException?.StackTrace*/)), ApiResponseCodeEnum.BackEndAnomaly));
} }

View File

@ -43,7 +43,7 @@ namespace IRaCIS.Core.SCP.Filter
else else
{ {
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (context.Exception.InnerException is null ? (context.Exception.Message /*+ context.Exception.StackTrace*/) context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (context.Exception.InnerException is null ? (context.Exception.Message /*+ context.Exception.StackTrace*/)
: (context.Exception.InnerException?.Message /*+ context.Exception.InnerException?.StackTrace*/)), ApiResponseCodeEnum.ProgramException)); : (context.Exception.InnerException?.Message /*+ context.Exception.InnerException?.StackTrace*/)), ApiResponseCodeEnum.BackEndAnomaly));
} }

View File

@ -351,6 +351,23 @@ namespace IRaCIS.Core.API.Controllers
return result; return result;
} }
/// <summary>
/// 提交阅片裁判表单
/// </summary>
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingImageTask/SubmitJudgeForm")]
[TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task<IResponseOutput> SubmitJudgeForm(DataInspectionDto<SetJudgeFormInDto> opt)
{
var singid = await _inspectionService.RecordSing(opt.SignInfo);
var result = await _iReadingImageTaskService.SubmitJudgeForm(opt.Data);
await _inspectionService.CompletedSign(singid, result);
return result;
}
/// <summary> /// <summary>
/// 配置 基础逻辑信息并确认 /// 配置 基础逻辑信息并确认

View File

@ -127,5 +127,6 @@
"DuplicationWindowMs": 500, "DuplicationWindowMs": 500,
"CacheTimeSeconds": 5, "CacheTimeSeconds": 5,
"ExcludedPaths": [] "ExcludedPaths": []
} },
"FrontWebConfig": "222"
} }

View File

@ -75,7 +75,7 @@ public class ModelActionFilter(IStringLocalizer _localizer, IConfiguration _conf
//---提供给接口的参数无效。 //---提供给接口的参数无效。
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ModelAction_InvalidAPIParameter"] + JsonConvert.SerializeObject(validationErrors))); context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ModelAction_InvalidAPIParameter"] + JsonConvert.SerializeObject(validationErrors), ApiResponseCodeEnum.BackEndAnomaly));
} }
} }
} }

View File

@ -49,7 +49,7 @@ public class ProjectExceptionFilter(ILogger<ProjectExceptionFilter> _logger, ISt
else else
{ {
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (exception.InnerException is null ? (exception.Message) context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (exception.InnerException is null ? (exception.Message)
: (exception.Message + "Inner ExceptionMsg:" + exception.InnerException?.Message)), ApiResponseCodeEnum.ProgramException)); : (exception.Message + "Inner ExceptionMsg:" + exception.InnerException?.Message)), ApiResponseCodeEnum.BackEndAnomaly));
try try
{ {

View File

@ -58,7 +58,7 @@ public class GlobalExceptionHandler(IStringLocalizer _localizer, ILogger<GlobalE
else else
{ {
httpContext.Response.WriteAsJsonAsync(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (exception.InnerException is null ? (exception.Message ) httpContext.Response.WriteAsJsonAsync(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (exception.InnerException is null ? (exception.Message )
: (exception.InnerException?.Message)), ApiResponseCodeEnum.ProgramException)); : (exception.InnerException?.Message)), ApiResponseCodeEnum.BackEndAnomaly));
} }

View File

@ -28,7 +28,7 @@ public static class ExcelExportHelper
/// <param name="translateType"></param> /// <param name="translateType"></param>
/// <param name="criterionType"></param> /// <param name="criterionType"></param>
/// <returns></returns> /// <returns></returns>
public static async Task<IActionResult> DataExportAsync(string code, ExcelExportInfo data, string exportFileNamePrefix, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null) public static async Task<IActionResult> DataExportAsync(string code, ExcelExportInfo data, string exportFileNamePrefix, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null, List<int> removeExcelIndexList = null)
{ {
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US; var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
@ -136,7 +136,7 @@ public static class ExcelExportHelper
#region 根据中英文 删除模板sheet #region 根据中英文 删除模板sheet
// 打开模板文件 // 打开模板文件
var templateFile = new FileStream(tplPath, FileMode.Open, FileAccess.Read); using var templateFile = new FileStream(tplPath, FileMode.Open, FileAccess.Read);
// 获取文件流 // 获取文件流
var templateStream = new MemoryStream(); var templateStream = new MemoryStream();
@ -158,6 +158,17 @@ public static class ExcelExportHelper
workbook.Worksheets.Delete(2); // 删除第2个索引2 workbook.Worksheets.Delete(2); // 删除第2个索引2
} }
if (removeExcelIndexList != null)
{
var worksheet = workbook.Worksheet(1); // 索引从1开始
foreach (int colIndex in removeExcelIndexList.OrderByDescending(t => t))
{
// 删除整列
worksheet.Column(colIndex).Delete();
}
}
//中文替换项目术语 //中文替换项目术语
if (data.TrialObjectNameList?.Count > 0) if (data.TrialObjectNameList?.Count > 0)
{ {
@ -932,14 +943,14 @@ public static class ExcelExportHelper
//if (sheetCount == 2) //if (sheetCount == 2)
//{ //{
if (inDto.IsEnglish) if (inDto.IsEnglish)
{ {
workbook.Worksheet(1).Delete(); // 删除第一个工作表 workbook.Worksheet(1).Delete(); // 删除第一个工作表
} }
else else
{ {
workbook.Worksheet(2).Delete(); // 删除第二个工作表 workbook.Worksheet(2).Delete(); // 删除第二个工作表
} }
//} //}
#endregion #endregion

View File

@ -43,7 +43,7 @@
<param name="next"></param> <param name="next"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.ExcelExportHelper.DataExportAsync(System.String,IRaCIS.Application.Contracts.ExcelExportInfo,System.String,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument},Microsoft.AspNetCore.Hosting.IWebHostEnvironment,IRaCIS.Application.Interfaces.IDictionaryService,System.Type,System.Nullable{IRaCIS.Core.Domain.Share.CriterionType})"> <member name="M:IRaCIS.Core.Application.Service.ExcelExportHelper.DataExportAsync(System.String,IRaCIS.Application.Contracts.ExcelExportInfo,System.String,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument},Microsoft.AspNetCore.Hosting.IWebHostEnvironment,IRaCIS.Application.Interfaces.IDictionaryService,System.Type,System.Nullable{IRaCIS.Core.Domain.Share.CriterionType},System.Collections.Generic.List{System.Int32})">
<summary> <summary>
</summary> </summary>
@ -579,6 +579,12 @@
<param name="emailConfig"></param> <param name="emailConfig"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.Common.DeployConfigService.GetWebConfigInfo">
<summary>
获取前端配置
</summary>
<returns></returns>
</member>
<member name="P:IRaCIS.Core.Application.Service.Common.TU_TR_RSBaseModel.ResearchProgramNo"> <member name="P:IRaCIS.Core.Application.Service.Common.TU_TR_RSBaseModel.ResearchProgramNo">
<summary> <summary>
方案编号 STUDYID 方案编号 STUDYID
@ -849,6 +855,20 @@
裁决日期 CODTC 裁决日期 CODTC
</summary> </summary>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.GetSiteSurveyEquipmentList_Export(IRaCIS.Core.Application.Contracts.SiteSurveyEquipmentQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteEquipmentSurvey},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteSurvey},IRaCIS.Application.Interfaces.IDictionaryService)">
<summary>
获取中心设备信息
</summary>
<param name="inQuery"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.GetSiteSurveyInfoList_Export(IRaCIS.Core.Application.Contracts.SiteSurveyInfoQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteSurvey},IRaCIS.Application.Interfaces.IDictionaryService)">
<summary>
调研表基本信息
</summary>
<param name="inQuery"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.GetTrialQCQuestionAnserList_Export(IRaCIS.Core.Application.Contracts.GetQCQuestionAnswerQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialQCQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserRole},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialQCQuestion},IRaCIS.Application.Interfaces.IDictionaryService)"> <member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.GetTrialQCQuestionAnserList_Export(IRaCIS.Core.Application.Contracts.GetQCQuestionAnswerQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialQCQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserRole},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialQCQuestion},IRaCIS.Application.Interfaces.IDictionaryService)">
<summary> <summary>
质控问题答案导出 质控问题答案导出
@ -3974,6 +3994,16 @@
<param name="visitTaskId"></param> <param name="visitTaskId"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.ReadingCalculate.GeneralCalculateService.IsSameCustomRowAnswer(IRaCIS.Core.Domain.Models.ReadingTableAnswerRowInfo,IRaCIS.Core.Domain.Models.ReadingTableAnswerRowInfo,System.Collections.Generic.List{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},System.Collections.Generic.List{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer})">
<summary>
自定义病灶判断是否是同一个病灶 除了根据器官判断还需要根据复制前值的答案是否相等
</summary>
<param name="currentRow"></param>
<param name="historyRow"></param>
<param name="currentAnswerList"></param>
<param name="historyAnswerList"></param>
<returns></returns>
</member>
<member name="F:IRaCIS.Core.Application.Service.ReadingCalculate.ReadingCalculateService.CalculateServiceDic"> <member name="F:IRaCIS.Core.Application.Service.ReadingCalculate.ReadingCalculateService.CalculateServiceDic">
<summary> <summary>
标准和服务对应 标准和服务对应
@ -14818,6 +14848,13 @@
IR影像阅片 IR影像阅片
</summary> </summary>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.Test(IRaCIS.Core.Application.Service.Reading.Dto.GetReportsChartSummaryInDto)">
<summary>
测试异常
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetReportsChartData(IRaCIS.Core.Application.Service.Reading.Dto.GetReportsChartDataInDto)"> <member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetReportsChartData(IRaCIS.Core.Application.Service.Reading.Dto.GetReportsChartDataInDto)">
<summary> <summary>
获取报告图表数据 获取报告图表数据
@ -19430,7 +19467,7 @@
TrialSiteSurveyService TrialSiteSurveyService
</summary> </summary>
</member> </member>
<member name="M:IRaCIS.Core.Application.Contracts.TrialSiteSurveyService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteSurvey},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteUserSurvey},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserRole},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.IdentityUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialIdentityUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSite},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Doctor},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VerificationCode},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUserRole},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteUserRole},Medallion.Threading.IDistributedLockProvider,IRaCIS.Core.Application.Auth.ITokenService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserType},IRaCIS.Core.Application.Service.IMailVerificationService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserLog},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer)"> <member name="M:IRaCIS.Core.Application.Contracts.TrialSiteSurveyService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteSurvey},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SiteSurveyLog},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteEquipmentSurvey},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteUserSurvey},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserRole},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.IdentityUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialIdentityUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSite},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Doctor},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VerificationCode},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUserRole},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteUserRole},Medallion.Threading.IDistributedLockProvider,IRaCIS.Core.Application.Auth.ITokenService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserType},IRaCIS.Core.Application.Service.IMailVerificationService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserLog},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer)">
<summary> <summary>
TrialSiteSurveyService TrialSiteSurveyService
</summary> </summary>
@ -19551,6 +19588,34 @@
<param name="siteSurvyeSubmit"></param> <param name="siteSurvyeSubmit"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Contracts.TrialSiteSurveyService.GetSiteSurveyLogList(IRaCIS.Core.Application.Contracts.SiteSurveyLogQuery)">
<summary>
获取中心调研日志
</summary>
<param name="inQuery"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Contracts.TrialSiteSurveyService.GetSiteSurveyEquipmentList(IRaCIS.Core.Application.Contracts.SiteSurveyEquipmentQuery)">
<summary>
获取中心设备信息
</summary>
<param name="inQuery"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Contracts.TrialSiteSurveyService.GetSiteSurveyInfoList(IRaCIS.Core.Application.Contracts.SiteSurveyInfoQuery)">
<summary>
调研表基本信息
</summary>
<param name="inQuery"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Contracts.TrialSiteSurveyService.GetTrialIsSPMJoin(System.Guid)">
<summary>
SPM 是否参与流程
</summary>
<param name="trialId"></param>
<returns></returns>
</member>
<member name="T:IRaCIS.Core.Application.Contracts.TrialSiteUserSurveyService"> <member name="T:IRaCIS.Core.Application.Contracts.TrialSiteUserSurveyService">
<summary> <summary>
TrialSiteUserSurveyService TrialSiteUserSurveyService

View File

@ -269,9 +269,45 @@ public class SiteSurverRejectedEventConsumer(
if (context.Message.IsHaveSPMOrCPM) if (context.Message.IsHaveSPMOrCPM)
{ {
//PM 驳回到SPM ////PM 驳回到SPM
if (siteSurveyInfo.State == TrialSiteSurveyEnum.CRCSubmitted) //if (siteSurveyInfo.State == TrialSiteSurveyEnum.CRCSubmitted)
//{
// var sPMOrCPMList = _trialUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialUser.IsDeleted == false)
// .Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM)
// .Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum, t.UserRole.IdentityUser.UserWorkLanguage }).ToList();
// var lan_SPMOrCPMList = sPMOrCPMList.Where(t => t.UserWorkLanguage == workLanguage);
// foreach (var user in lan_SPMOrCPMList)
// {
// messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
// }
// toUserName = string.Join('、', lan_SPMOrCPMList.Select(t => t.FullName));
//}
////SPM 驳回到CRC
//else if (siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit)
//{
// //使用中心国家语言 一致才发送
// if ((siteInfo.Country == StaticData.SiteCountry.US && isEn_US) || (siteInfo.Country == StaticData.SiteCountry.CN && isEn_US == false))
// {
// messageToSend.To.Add(new MailboxAddress(toUserName, siteSurveyInfo.Email));
// }
//}
// PM 驳回到CRC
if (siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit)
{ {
//使用中心国家语言 一致才发送
if ((siteInfo.Country == StaticData.SiteCountry.US && isEn_US) || (siteInfo.Country == StaticData.SiteCountry.CN && isEn_US == false))
{
messageToSend.To.Add(new MailboxAddress(toUserName, siteSurveyInfo.Email));
}
var sPMOrCPMList = _trialUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialUser.IsDeleted == false) var sPMOrCPMList = _trialUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialUser.IsDeleted == false)
.Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM) .Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM)
@ -281,24 +317,10 @@ public class SiteSurverRejectedEventConsumer(
foreach (var user in lan_SPMOrCPMList) foreach (var user in lan_SPMOrCPMList)
{ {
messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail)); messageToSend.Cc.Add(new MailboxAddress(user.FullName, user.EMail));
}
toUserName = string.Join('、', lan_SPMOrCPMList.Select(t => t.FullName));
}
//SPM 驳回到CRC
else if (siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit)
{
//使用中心国家语言 一致才发送
if ((siteInfo.Country == StaticData.SiteCountry.US && isEn_US) || (siteInfo.Country == StaticData.SiteCountry.CN && isEn_US == false))
{
messageToSend.To.Add(new MailboxAddress(toUserName, siteSurveyInfo.Email));
} }
} }
} }
else else
{ {
@ -312,6 +334,11 @@ public class SiteSurverRejectedEventConsumer(
} }
} }
Uri uri = new Uri(_systemEmailConfig.SiteUrl);
// 获取 Scheme + Host不包含路径
string baseUrl = uri.GetLeftPart(UriPartial.Authority);
//发件地址 //发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail)); messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
@ -330,8 +357,9 @@ public class SiteSurverRejectedEventConsumer(
siteInfo.TrialSiteCode, //中心编号 siteInfo.TrialSiteCode, //中心编号
siteInfo.TrialSiteAliasName,//中心名称 siteInfo.TrialSiteAliasName,//中心名称
siteSurveyInfo.LatestBackReason, //驳回原因 siteSurveyInfo.LatestBackReason, //驳回原因
_systemEmailConfig.SiteUrl, //链接 $"{baseUrl}/researchLogin?trialId={trialId}", //链接
(siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit ? "inline - block" : "none") (siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit ? "inline - block" : "none"),
trialInfo.LinkVerificationCode.IsNullOrEmpty()? trialInfo.ResearchProgramNo: trialInfo.LinkVerificationCode
); );
return (topicStr, htmlBodyStr); return (topicStr, htmlBodyStr);

View File

@ -767,6 +767,7 @@ namespace IRaCIS.Core.Application.Service
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt, nameof(VisitTask)), TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt, nameof(VisitTask)),
ReadingCategory = ReadingCategory.Visit, ReadingCategory = ReadingCategory.Visit,
TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId,
IsNeedClinicalDataSign = isNeedClinicalDataSign, IsNeedClinicalDataSign = isNeedClinicalDataSign,
IsClinicalDataSign = isClinicalDataSign, IsClinicalDataSign = isClinicalDataSign,
@ -1421,6 +1422,7 @@ namespace IRaCIS.Core.Application.Service
// AllocateTime = DateTime.Now, // AllocateTime = DateTime.Now,
//DoctorUserId = reReadingVisitTask.DoctorUserId, //DoctorUserId = reReadingVisitTask.DoctorUserId,
IsIRImageDownloaded= reReadingVisitTask.IsIRImageDownloaded,
}); });
generateTaskCommand.Action(newTask); generateTaskCommand.Action(newTask);

View File

@ -31,7 +31,7 @@ public class DeployConfigService(IMapper _mapper, IConfiguration _configuration,
//return config; //return config;
var path = Path.Combine( _hostEnvironment.ContentRootPath,$"appsettings.{_hostEnvironment.EnvironmentName}.json"); var path = Path.Combine(_hostEnvironment.ContentRootPath, $"appsettings.{_hostEnvironment.EnvironmentName}.json");
var json = File.ReadAllText(path); var json = File.ReadAllText(path);
@ -123,7 +123,7 @@ public class DeployConfigService(IMapper _mapper, IConfiguration _configuration,
[HttpPost] [HttpPost]
public async Task<IResponseOutput> UpdateSystemEmailConfig(SystemEmailSendConfig emailConfig) public async Task<IResponseOutput> UpdateSystemEmailConfig(SystemEmailSendConfig emailConfig)
{ {
var path = Path.Combine(_hostEnvironment.ContentRootPath,$"appsettings.{_hostEnvironment.EnvironmentName}.json"); var path = Path.Combine(_hostEnvironment.ContentRootPath, $"appsettings.{_hostEnvironment.EnvironmentName}.json");
//var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json"; //var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json";
var @lock = _distributedLockProvider.CreateLock("WriteConfigFile"); var @lock = _distributedLockProvider.CreateLock("WriteConfigFile");
@ -171,4 +171,57 @@ public class DeployConfigService(IMapper _mapper, IConfiguration _configuration,
return ResponseOutput.Ok(); return ResponseOutput.Ok();
} }
/// <summary>
/// 获取前端配置
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public async Task<string> GetWebConfigInfo()
{
var path = Path.Combine(_hostEnvironment.ContentRootPath, $"appsettings.{_hostEnvironment.EnvironmentName}.json");
var json = File.ReadAllText(path);
var obj = JObject.Parse(json);
return obj["FrontWebConfig"]!.ToString();
}
public class WebConfigCommand
{
public string ConfigStr { get; set; }
}
public async Task<IResponseOutput> UpdateWebConfigInfo(WebConfigCommand incommand)
{
var path = Path.Combine(_hostEnvironment.ContentRootPath, $"appsettings.{_hostEnvironment.EnvironmentName}.json");
//var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json";
var @lock = _distributedLockProvider.CreateLock("WriteConfigFile");
using (await @lock.AcquireAsync())
{
string text = System.IO.File.ReadAllText(path);
// 修改
JObject obj = JObject.Parse(text);
// SystemEmailSendConfig 相关配置
obj["FrontWebConfig"] = incommand.ConfigStr;
// 重新写入appsettings.json
string result = obj.ToString();
System.IO.File.WriteAllText(path, result);
}
return ResponseOutput.Ok();
}
} }

View File

@ -10,6 +10,7 @@ using IRaCIS.Core.Infra.EFCore.Common;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using static IRaCIS.Core.Application.Service.ExcelExportHelper; using static IRaCIS.Core.Application.Service.ExcelExportHelper;
@ -40,6 +41,191 @@ namespace IRaCIS.Core.Application.Service.Common
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService
{ {
#region 中心调研导出
[HttpPost]
public async Task<IActionResult> GetTrialSiteSurveyList_Export(TrialSiteSurveyQueryDTO inQuery,
[FromServices] IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
[FromServices] IDictionaryService _dictionaryService)
{
var trialSiteSurveyQueryable = _trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId).IgnoreQueryFilters()
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.UserKeyInfo), t => t.UserName.Contains(inQuery.UserKeyInfo) || t.Phone.Contains(inQuery.UserKeyInfo) || t.Email.Contains(inQuery.UserKeyInfo))
.WhereIf(inQuery.State != null, t => t.State == inQuery.State)
.WhereIf(inQuery.UpdateTimeBegin != null, t => t.UpdateTime >= inQuery.UpdateTimeBegin)
.WhereIf(inQuery.UpdateTimeEnd != null, t => t.UpdateTime <= inQuery.UpdateTimeEnd)
.ProjectTo<TrialSiteSurveyView>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us })
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.PreliminaryUserName), t => t.PreliminaryUser.RealName.Contains(inQuery.PreliminaryUserName))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.ReviewerUserName), t => t.ReviewerUser.RealName.Contains(inQuery.ReviewerUserName))
;
//var defalutSortArray = new string[] { /*nameof(TrialSiteSurveyView.LanguageType) + " desc", nameof(TrialSiteSurveyView.ShowOrder)*/ };
var list = await trialSiteSurveyQueryable.SortToListAsync(inQuery /*,defalutSortArray*/);
var exportInfo = new ExcelExportInfo();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteSurvey_BasicInfo_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialSiteSurveyView));
}
/// <summary>
/// 获取中心设备信息
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> GetSiteSurveyEquipmentList_Export(SiteSurveyEquipmentQuery inQuery,
[FromServices] IRepository<TrialSiteEquipmentSurvey> _trialSiteEquipmentSurveyRepository,
[FromServices] IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
[FromServices] IDictionaryService _dictionaryService)
{
//找到该中心最新的调研记录
var groupSelectIdQuery =
_trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
.GroupBy(t => t.TrialSiteId)
.Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First());
var query = _trialSiteEquipmentSurveyRepository.Where(t => t.TrialSiteSurvey.TrialId == inQuery.TrialId)
.IgnoreQueryFilters().Where(t => groupSelectIdQuery.Contains(t.TrialSiteSurveyId))
.WhereIf(inQuery.IsDeleted != null, t => t.TrialSiteSurvey.IsDeleted == inQuery.IsDeleted)
.WhereIf(inQuery.State != null, t => t.TrialSiteSurvey.State == inQuery.State)
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteSurvey.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.TrialSiteCode.IsNotNullOrEmpty(), t => t.TrialSiteSurvey.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode))
.WhereIf(inQuery.TrialSiteName.IsNotNullOrEmpty(), t => t.TrialSiteSurvey.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteName) ||
t.TrialSiteSurvey.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteName))
.ProjectTo<SiteSurveyEquipmentDto>(_mapper.ConfigurationProvider);
var siteSurveryConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty;
var config = JsonConvert.DeserializeObject<TrialExtraConfig>(siteSurveryConfig) ?? new TrialExtraConfig();
var fields = new List<(string FieldName, int excelIndex)>()
{
("Parameters", 9),
("ManufacturerType", 10),
("ScannerType", 11),
("MagneticFieldStrengthType", 12),
("BodyCoilChannelCount", 13),
("HasDedicatedPdfFatQuantificationSequence", 14),
("PdfFatQuantificationSequenceType", 15),
//("OtherSequenceSpecification", 15),
("HasT2R2Correction", 16),
("CanFullyExportPdfParameterMapsAndRawDicom", 17),
("Note", 18),
};
var viewNameList = config.EquipmentControlFieldList.Where(t => t.IsView == true).Select(t => t.FiledName).ToList();
var columnsToDelete = fields.Where(f => !viewNameList.Any(t => f.FieldName == t)).Select(f => f.excelIndex).Distinct().OrderByDescending(i => i).ToList();
//var defalutSortArray = new string[] { /*nameof(TrialSiteSurveyView.LanguageType) + " desc", nameof(TrialSiteSurveyView.ShowOrder)*/ };
var list = await query.SortToListAsync(inQuery /*,defalutSortArray*/);
var exportInfo = new ExcelExportInfo();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteSurvey_Equipment_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SiteSurveyEquipmentDto), removeExcelIndexList: columnsToDelete);
}
/// <summary>
/// 调研表基本信息
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> GetSiteSurveyInfoList_Export(SiteSurveyInfoQuery inQuery,
[FromServices] IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
[FromServices] IDictionaryService _dictionaryService)
{
//找到该中心最新的调研记录
var groupSelectIdQuery =
_trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
.GroupBy(t => t.TrialSiteId)
.Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First());
var query = _trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId).IgnoreQueryFilters()
.Where(t => groupSelectIdQuery.Contains(t.Id))
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
.WhereIf(inQuery.State != null, t => t.State == inQuery.State)
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.TrialSiteCode.IsNotNullOrEmpty(), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode))
.WhereIf(inQuery.TrialSiteName.IsNotNullOrEmpty(), t => t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteName) ||
t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteName))
.ProjectTo<TrialSiteSurveyView>(_mapper.ConfigurationProvider);
var siteSurveryConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty;
var config = JsonConvert.DeserializeObject<TrialExtraConfig>(siteSurveryConfig) ?? new TrialExtraConfig();
var fields = new List<(string FieldName, int excelIndex)>()
{
("AverageEngravingCycle", 8),
("IsRoutineMRIPDEE", 9),
("MRIPDFFScanTime", 10),
("MRIPDFFLeadTime", 11),
("MRIPDFFOther", 12),
("IsAuthorizeRadiologistsParticipate", 13),
("AssignFixedTechnologists", 14),
("IsConfirmImagingTechnologist", 15),
("NotConfirmReson", 16),
("EfficacyEvaluatorType", 17),
("IsFollowStudyParameters", 18),
("NotFollowReson", 19),
("ISStrictManualBurnFlag", 20),
("NotStrictManualBurnFlagReason",21)
};
//var viewNameList = config.NotShowFieldList;
var columnsToDelete = fields.Where(f => config.NotShowFieldList.Any(t => f.FieldName == t)).Select(f => f.excelIndex).Distinct().OrderByDescending(i => i).ToList();
//var defalutSortArray = new string[] { /*nameof(TrialSiteSurveyView.LanguageType) + " desc", nameof(TrialSiteSurveyView.ShowOrder)*/ };
var list = await query.SortToListAsync(inQuery /*,defalutSortArray*/);
var exportInfo = new ExcelExportInfo();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteSurvey_Info_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialSiteSurveyView), removeExcelIndexList: columnsToDelete);
}
#endregion
/// <summary> /// <summary>
/// 质控问题答案导出 /// 质控问题答案导出
/// </summary> /// </summary>
@ -1197,7 +1383,7 @@ namespace IRaCIS.Core.Application.Service.Common
t.VisitTaskList.Where(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == dto.TrialReadingCriterionId && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned).Count() == (int)trialReadingCriterion.ReadingType ? t.VisitTaskList.Where(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == dto.TrialReadingCriterionId && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned).Count() == (int)trialReadingCriterion.ReadingType ?
ReadingStatusEnum.ReadCompleted : t.VisitTaskList.Where(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == dto.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.ReadingCategory == ReadingCategory.Visit && t.TaskAllocationState == TaskAllocationState.Allocated).Count() == (int)trialReadingCriterion.ReadingType ? ReadingStatusEnum.ImageReading : ReadingStatusEnum.ReadCompleted : t.VisitTaskList.Where(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == dto.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.ReadingCategory == ReadingCategory.Visit && t.TaskAllocationState == TaskAllocationState.Allocated).Count() == (int)trialReadingCriterion.ReadingType ? ReadingStatusEnum.ImageReading :
t.ReadingStatus t.ReadingStatus
}).OrderBy(t=>t.VisitTaskNum).ToList(), }).OrderBy(t => t.VisitTaskNum).ToList(),
ModuleList = subject.ReadModuleList.Where(t => t.TrialReadingCriterionId == dto.TrialReadingCriterionId).Select(t => new SubjectProgressDto.MouduleProgress() ModuleList = subject.ReadModuleList.Where(t => t.TrialReadingCriterionId == dto.TrialReadingCriterionId).Select(t => new SubjectProgressDto.MouduleProgress()
{ {
@ -2863,7 +3049,7 @@ namespace IRaCIS.Core.Application.Service.Common
{ {
//仲裁阅片 才有裁判阅片明细表 同时要把模板里面的三列给去掉 //仲裁阅片 才有裁判阅片明细表 同时要把模板里面的三列给去掉
//removeColumnIndexList = new List<int>() { 6, 7, 8 }; //removeColumnIndexList = new List<int>() { 6, 7, 8 };
removeColumnIndexList = new List<int>() { 7, 8 ,9}; removeColumnIndexList = new List<int>() { 7, 8, 9 };
} }
//阅片结果表 和阅片结果明细表 没有肿瘤学的时候需要移除肿瘤学三个字段 //阅片结果表 和阅片结果明细表 没有肿瘤学的时候需要移除肿瘤学三个字段

View File

@ -2199,6 +2199,21 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary> /// </summary>
public DefaultSegmentNameDto DefaultSegmentName { get; set; } public DefaultSegmentNameDto DefaultSegmentName { get; set; }
/// <summary>
/// 仲裁模式
/// </summary>
public JudgeMode JudgeModeEnum { get; set; } = JudgeMode.SelectOne;
/// <summary>
/// 裁判规则
/// </summary>
public JudgeRule JudgeRuleEnum { get; set; } = JudgeRule.Consistent;
/// <summary>
/// 仲裁对象
/// </summary>
public ArbitrationRule ArbitrationRule { get; set; } = ArbitrationRule.Reading;
} }
public class GetReadingImgInDto public class GetReadingImgInDto
@ -2437,6 +2452,83 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public Guid VisitTaskId { get; set; } public Guid VisitTaskId { get; set; }
} }
public class GetSingleVisitJudgeAnswerInDto
{
[NotDefault]
public Guid VisitTaskId { get; set; }
}
public class GetSingleVisitJudgeAnswerOutDto
{
public Guid R1VisitTaskId { get; set; }
public Guid R2VisitTaskId { get; set; }
public List<SingleVisitJudgeAnswerItemDto> QuestionList { get; set; } = new List<SingleVisitJudgeAnswerItemDto>();
}
public class SingleVisitJudgeAnswerItemDto
{
public Guid ReadingQuestionId { get; set; }
public string QuestionName { get; set; } = string.Empty;
public string Type { get; set; } = string.Empty;
public string TypeValue { get; set; } = string.Empty;
public int ShowOrder { get; set; }
public string R1Answer { get; set; } = string.Empty;
public string R2Answer { get; set; } = string.Empty;
public TableQuestionType? QuestionGenre { get; set; }
public string DictionaryCode { get; set; } = string.Empty;
public ValueUnit? Unit { get; set; }
public string? CustomUnit { get; set; }
public ValueOfType? ValueType { get; set; }
public JudgeReadingQuestionType QuestionType { get; set; } = JudgeReadingQuestionType.Question;
}
public class GetJudgeFormInDto
{
[NotDefault]
public Guid VisitTaskId { get; set; }
}
public class GetJudgeFormOutDto
{
public string JudgeResultRemark { get; set; } = string.Empty;
public List<string> JudgeResultImagePathList { get; set; } = new List<string>();
public List<JudgeFormQuestionDto> QuestionList { get; set; } = new List<JudgeFormQuestionDto>();
}
public class JudgeFormQuestionDto
{
public Guid ReadingQuestionId { get; set; }
public string QuestionName { get; set; } = string.Empty;
public string Type { get; set; } = string.Empty;
public string TypeValue { get; set; } = string.Empty;
public int ShowOrder { get; set; }
public string Answer { get; set; } = string.Empty;
public TableQuestionType? QuestionGenre { get; set; }
public string DictionaryCode { get; set; } = string.Empty;
public ValueUnit? Unit { get; set; }
public string? CustomUnit { get; set; }
public ValueOfType? ValueType { get; set; }
public JudgeReadingQuestionType QuestionType { get; set; } = JudgeReadingQuestionType.Question;
}
public class SetJudgeFormInDto
{
[NotDefault]
public Guid VisitTaskId { get; set; }
public string JudgeResultRemark { get; set; } = string.Empty;
public List<string> JudgeResultImagePathList { get; set; } = new List<string>();
public List<JudgeFormAnswerDto> QuestionList { get; set; } = new List<JudgeFormAnswerDto>();
}
public class JudgeFormAnswerDto
{
public Guid ReadingQuestionId { get; set; }
public string Answer { get; set; } = string.Empty;
}
public class JudgeReadingInfoDto public class JudgeReadingInfoDto
{ {
public string VisitName { get; set; } public string VisitName { get; set; }
@ -2908,12 +3000,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
} }
public class AnswerCombinationDto
{
public List<string> AnswerGroupA { get; set; }
public List<string> AnswerGroupB { get; set; }
}
public class TaskAnswerDto public class TaskAnswerDto
{ {

View File

@ -6,6 +6,82 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Application.Service.Reading.Dto namespace IRaCIS.Core.Application.Service.Reading.Dto
{ {
public class GetTrialQuestionVisitJudgeRuleInDto
{
[NotDefault]
public Guid TrialId { get; set; }
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
public decimal VisitNum { get; set; }
public Guid? ReadingQuestionId { get; set; }
}
public class SetTrialQuestionVisitJudgeRuleInDto
{
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
public decimal VisitNum { get; set; }
public List<TrialQuestionVisitJudgeRuleItemDto> QuestionList { get; set; } = new List<TrialQuestionVisitJudgeRuleItemDto>();
}
public class TrialQuestionVisitJudgeRuleItemDto
{
public Guid ReadingQuestionTrialId { get; set; }
public string QuestionName { get; set; } = string.Empty;
public int ShowOrder { get; set; }
public List<string> AnswerGroup { get; set; } = new List<string>();
public JudgeTypeEnum JudgeType { get; set; }
public decimal? JudgeDifferenceValue { get; set; }
public JudgeDifferenceType JudgeDifferenceType { get; set; }
/// <summary>
/// 类型
/// </summary>
public string Type { get; set; } = string.Empty;
public string PageName { get; set; }
public string TypeValue { get; set; }
/// <summary>
/// 问题类型
/// </summary>
public TableQuestionType? QuestionGenre { get; set; }
/// <summary>
/// 字典code
/// </summary>
public string DictionaryCode { get; set; } = string.Empty;
/// <summary>
/// 单位
/// </summary>
public ValueUnit? Unit { get; set; }
public string CustomUnit { get; set; } = string.Empty;
/// <summary>
/// 答案组合
/// </summary>
public List<AnswerCombinationDto> AnswerCombination { get; set; }
}
public class TumorAssessmentView : AddOrUpdateTumorAssessmentInDto public class TumorAssessmentView : AddOrUpdateTumorAssessmentInDto
{ {
@ -702,6 +778,16 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public Guid TrialReadingCriterionId { get; set; } public Guid TrialReadingCriterionId { get; set; }
} }
public class SetTrialJudgeRuleInfoInDto
{
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
public JudgeMode JudgeModeEnum { get; set; } = JudgeMode.SelectOne;
public JudgeRule JudgeRuleEnum { get; set; } = JudgeRule.Consistent;
public JudgeGenerate JudgeGenerateEnum { get; set; } = JudgeGenerate.Instant;
}
public class GetTrialJudgyInfoOutDto public class GetTrialJudgyInfoOutDto
{ {
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
@ -717,6 +803,24 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// 仲裁规则 /// 仲裁规则
/// </summary> /// </summary>
public ArbitrationRule ArbitrationRule { get; set; } public ArbitrationRule ArbitrationRule { get; set; }
/// <summary>
/// 仲裁模式
/// </summary>
public JudgeMode JudgeModeEnum { get; set; } = JudgeMode.SelectOne;
/// <summary>
/// 裁判规则
/// </summary>
public JudgeRule JudgeRuleEnum { get; set; } = JudgeRule.Consistent;
/// <summary>
/// 裁判任务生成
/// </summary>
public JudgeGenerate JudgeGenerateEnum { get; set; } = JudgeGenerate.Instant;
public bool IsSigned { get; set; } = false;
} }
public enum NeedSynchronize public enum NeedSynchronize

View File

@ -15,6 +15,7 @@ namespace IRaCIS.Core.Application.Contracts
Task TriggerJudgeQuestion(Guid visitTaskId); Task TriggerJudgeQuestion(Guid visitTaskId);
Task<IResponseOutput> SubmitVisitTaskQuestions(SubmitVisitTaskQuestionsInDto inDto); Task<IResponseOutput> SubmitVisitTaskQuestions(SubmitVisitTaskQuestionsInDto inDto);
Task<IResponseOutput> SubmitJudgeForm(SetJudgeFormInDto inDto);
Task<IResponseOutput> SubmitJudgeVisitTaskResult(SaveJudgeVisitTaskResult inDto); Task<IResponseOutput> SubmitJudgeVisitTaskResult(SaveJudgeVisitTaskResult inDto);
Task<GetOncologyReadingInfoOutDto> GetOncologyReadingInfo(GetOncologyReadingInfoInDto inDto); Task<GetOncologyReadingInfoOutDto> GetOncologyReadingInfo(GetOncologyReadingInfoInDto inDto);

View File

@ -370,13 +370,32 @@ namespace IRaCIS.Core.Application.Service.RC
TrialId = x.TrialId, TrialId = x.TrialId,
IsReadingTaskViewInOrder = x.IsReadingTaskViewInOrder, IsReadingTaskViewInOrder = x.IsReadingTaskViewInOrder,
ArbitrationRule = x.ArbitrationRule, ArbitrationRule = x.ArbitrationRule,
IsArbitrationReading = x.IsArbitrationReading IsArbitrationReading = x.IsArbitrationReading,
JudgeModeEnum = x.JudgeModeEnum,
JudgeRuleEnum = x.JudgeRuleEnum,
JudgeGenerateEnum = x.JudgeGenerateEnum,
IsSigned = x.IsSigned,
}).FirstNotNullAsync(); }).FirstNotNullAsync();
return result; return result;
} }
/// <summary>
/// 编辑裁判规则配置
/// </summary>
[HttpPost]
public async Task<IResponseOutput> SetTrialJudgeRuleInfo(SetTrialJudgeRuleInfoInDto inDto)
{
await _readingQuestionCriterionTrialRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.TrialReadingCriterionId, x => new ReadingQuestionCriterionTrial()
{
JudgeModeEnum = inDto.JudgeModeEnum,
JudgeRuleEnum = inDto.JudgeRuleEnum,
JudgeGenerateEnum = inDto.JudgeGenerateEnum,
});
return ResponseOutput.Ok(await _readingQuestionCriterionTrialRepository.SaveChangesAsync());
}
/// <summary> /// <summary>
/// 新增修改项目问题标准(项目) /// 新增修改项目问题标准(项目)
/// </summary> /// </summary>
@ -482,7 +501,6 @@ namespace IRaCIS.Core.Application.Service.RC
return ResponseOutput.Ok(result); return ResponseOutput.Ok(result);
} }
#endregion #endregion
#region 项目阅片标准问题分页 #region 项目阅片标准问题分页

View File

@ -1,3 +1,4 @@
using DocumentFormat.OpenXml.Office.SpreadSheetML.Y2023.MsForms;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
@ -33,10 +34,105 @@ namespace IRaCIS.Core.Application.Service
IRepository<OrganInfo> _organInfoRepository, IRepository<OrganInfo> _organInfoRepository,
IRepository<ReadingTableQuestionSystem> _readingTableQuestionSystemRepository, IRepository<ReadingTableQuestionSystem> _readingTableQuestionSystemRepository,
IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswer, IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswer,
IRepository<PreviousPDF> _previousPDFRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IReadingQuestionService IRepository<PreviousPDF> _previousPDFRepository,
IRepository<ReadingQuestionVisitJudgeRule> _readingQuestionVisitJudgeRuleRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IReadingQuestionService
{ {
#region 项目访视裁判规则
/// <summary>
/// 获取项目阅片标准各访视的裁判规则配置。
/// 未配置规则的访视问题也会返回,供前端直接进行配置。
/// </summary>
[HttpPost]
public async Task<List<TrialQuestionVisitJudgeRuleItemDto>> GetTrialQuestionVisitJudgeRule(GetTrialQuestionVisitJudgeRuleInDto inDto)
{
var questionList = await _readingQuestionTrialRepository
.Where(x=>!x.ExcludeShowVisitList.Contains(inDto.VisitNum))
.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion)
.WhereIf(inDto.ReadingQuestionId != null, x => x.Id == inDto.ReadingQuestionId)
.OrderBy(x => x.ShowOrder)
.Select(x => new TrialQuestionVisitJudgeRuleItemDto
{
ReadingQuestionTrialId = x.Id,
QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
ShowOrder = x.ShowOrder,
Type = x.Type,
TypeValue = x.TypeValue,
QuestionGenre = x.QuestionGenre,
DictionaryCode = x.DictionaryCode,
Unit = x.Unit,
CustomUnit = x.CustomUnit,
})
.ToListAsync();
var questionIds = questionList.Select(x => x.ReadingQuestionTrialId).ToList();
var ruleList = await _readingQuestionVisitJudgeRuleRepository
.Where(x => x.VisitNum == inDto.VisitNum && questionIds.Contains(x.ReadingQuestionId))
.ToListAsync();
return questionList.Select(question =>
{
var rule = ruleList.FirstOrDefault(x => x.ReadingQuestionId == question.ReadingQuestionTrialId);
return new TrialQuestionVisitJudgeRuleItemDto
{
ReadingQuestionTrialId = question.ReadingQuestionTrialId,
QuestionName = question.QuestionName,
ShowOrder = question.ShowOrder,
Type = question.Type,
PageName = question.PageName,
TypeValue = question.TypeValue,
QuestionGenre = question.QuestionGenre,
DictionaryCode = question.DictionaryCode,
Unit = question.Unit,
CustomUnit = question.CustomUnit,
AnswerGroup = rule?.AnswerGroup ?? new List<string>(),
AnswerCombination = rule?.AnswerCombination ?? new List<AnswerCombinationDto>(),
JudgeType = rule?.JudgeType ?? JudgeTypeEnum.None,
JudgeDifferenceValue = rule?.JudgeDifferenceValue,
JudgeDifferenceType = rule?.JudgeDifferenceType ?? default,
};
}).ToList();
}
/// <summary>
/// 编辑项目阅片标准各访视的裁判规则配置。
/// </summary>
[HttpPost]
public async Task<IResponseOutput> SetTrialQuestionVisitJudgeRule(SetTrialQuestionVisitJudgeRuleInDto inDto)
{
var questionIds = await _readingQuestionTrialRepository
.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion)
.Select(x => x.Id)
.ToListAsync();
await _readingQuestionVisitJudgeRuleRepository.BatchDeleteNoTrackingAsync(x =>
x.VisitNum == inDto.VisitNum && questionIds.Contains(x.ReadingQuestionId));
var rules = inDto.QuestionList.Select(question => new ReadingQuestionVisitJudgeRule
{
Id = NewId.NextGuid(),
ReadingQuestionId = question.ReadingQuestionTrialId,
VisitNum = inDto.VisitNum,
AnswerGroup = question.AnswerGroup ?? new List<string>(),
AnswerCombination = question.AnswerCombination ?? new List<AnswerCombinationDto>(),
JudgeType = question.JudgeType,
JudgeDifferenceValue = question.JudgeDifferenceValue,
JudgeDifferenceType = question.JudgeDifferenceType,
}).ToList();
if (rules.Count > 0)
{
await _readingQuestionVisitJudgeRuleRepository.AddRangeAsync(rules);
}
return ResponseOutput.Result(await _readingQuestionVisitJudgeRuleRepository.SaveChangesAsync());
}
#endregion
#region 获取计算问题 #region 获取计算问题

View File

@ -66,6 +66,7 @@ namespace IRaCIS.Core.Application.Service
IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository, IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository,
IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository, IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository,
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository, IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
IRepository<ReadingQuestionVisitJudgeRule> _readingQuestionVisitJudgeRuleRepository,
IRepository<ReadingQuestionSystem> _readingQuestionSystem, IRepository<ReadingQuestionSystem> _readingQuestionSystem,
IRepository<CriterionKeyFileRead> _criterionKeyFileReadRepository, IRepository<CriterionKeyFileRead> _criterionKeyFileReadRepository,
IRepository<TrialCriterionKeyFile> _trialCriterionKeyFileRepository, IRepository<TrialCriterionKeyFile> _trialCriterionKeyFileRepository,
@ -81,6 +82,20 @@ namespace IRaCIS.Core.Application.Service
{ {
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue; private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
/// <summary>
/// 测试异常
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<IResponseOutput> Test(GetReportsChartSummaryInDto inDto)
{
var a = 0;
var v = 1 / a;
return ResponseOutput.Ok();
}
/// <summary> /// <summary>
/// 获取报告图表数据 /// 获取报告图表数据
/// </summary> /// </summary>
@ -3920,6 +3935,10 @@ namespace IRaCIS.Core.Application.Service
x.ReadingToolList, x.ReadingToolList,
x.CircleRadius, x.CircleRadius,
x.DefaultSegmentName, x.DefaultSegmentName,
x.JudgeGenerateEnum,
x.JudgeModeEnum,
x.JudgeRuleEnum,
x.ArbitrationRule,
}).FirstNotNullAsync(); }).FirstNotNullAsync();
task.IsReadingShowPreviousResults = criterionInfo.IsReadingShowPreviousResults; task.IsReadingShowPreviousResults = criterionInfo.IsReadingShowPreviousResults;
@ -3983,6 +4002,9 @@ namespace IRaCIS.Core.Application.Service
task.IsViewStudyPart = visitTaskInfo.ReadingCategory == ReadingCategory.Judge || visitTaskInfo.IsViewStudyPart; task.IsViewStudyPart = visitTaskInfo.ReadingCategory == ReadingCategory.Judge || visitTaskInfo.IsViewStudyPart;
task.IsReadKeyFile = await _criterionKeyFileReadRepository.AnyAsync(x => x.IdentityUserId == _userInfo.IdentityUserId && x.TrialCriterionId == task.TrialReadingCriterionId); task.IsReadKeyFile = await _criterionKeyFileReadRepository.AnyAsync(x => x.IdentityUserId == _userInfo.IdentityUserId && x.TrialCriterionId == task.TrialReadingCriterionId);
task.IsHaveKeyFile = await _trialCriterionKeyFileRepository.AnyAsync(x => x.TrialCriterionId == task.TrialReadingCriterionId); task.IsHaveKeyFile = await _trialCriterionKeyFileRepository.AnyAsync(x => x.TrialCriterionId == task.TrialReadingCriterionId);
task.JudgeModeEnum = criterionInfo.JudgeModeEnum;
task.JudgeRuleEnum = criterionInfo.JudgeRuleEnum;
task.ArbitrationRule = criterionInfo.ArbitrationRule;
// 添加默认答案 // 添加默认答案
if (inDto.VisitTaskId == null && visitTaskInfo.ReadingTaskState != ReadingTaskState.HaveSigned) if (inDto.VisitTaskId == null && visitTaskInfo.ReadingTaskState != ReadingTaskState.HaveSigned)
{ {

View File

@ -91,6 +91,200 @@ namespace IRaCIS.Core.Application.Service
#region 获取裁判阅片任务信息 #region 获取裁判阅片任务信息
/// <summary>
/// 获取单访视裁判答案
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<GetSingleVisitJudgeAnswerOutDto> GetSingleVisitJudgeAnswer(GetSingleVisitJudgeAnswerInDto inDto)
{
var judgeDataInfo = await _readingJudgeInfoRepository
.Where(x => x.JudgeTaskId == inDto.VisitTaskId)
.FirstNotNullAsync();
var taskIds = new List<Guid> { judgeDataInfo.TaskIdOne, judgeDataInfo.TaskIdTwo };
var readingTasks = await _visitTaskRepository
.Where(x => taskIds.Contains(x.Id))
.Select(x => new
{
x.Id,
x.ArmEnum,
x.TrialReadingCriterionId,
x.VisitTaskNum,
})
.ToListAsync();
var r1Task = readingTasks.First(x => x.ArmEnum == Arm.DoubleReadingArm1);
var r2Task = readingTasks.First(x => x.ArmEnum == Arm.DoubleReadingArm2);
var judgeRule = await _readingQuestionCriterionTrialRepository
.Where(x => x.Id == r1Task.TrialReadingCriterionId)
.Select(x => x.JudgeRuleEnum)
.FirstNotNullAsync();
var displayQuestions = await GetJudgeDisplayQuestions(r1Task.TrialReadingCriterionId, r1Task.VisitTaskNum, judgeRule);
var judgeAnswers = displayQuestions
.Select(x => new SingleVisitJudgeAnswerItemDto
{
ReadingQuestionId = x.Id,
QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
Type = x.Type,
TypeValue = x.TypeValue,
ShowOrder = x.ShowOrder,
QuestionGenre = x.QuestionGenre,
DictionaryCode = x.DictionaryCode,
Unit = x.Unit,
CustomUnit = x.CustomUnit,
ValueType = x.ValueType,
})
.ToList();
var displayQuestionIds = judgeAnswers.Select(x => x.ReadingQuestionId).ToList();
var answerList = await _readingTaskQuestionAnswerRepository
.Where(x => taskIds.Contains(x.VisitTaskId) && displayQuestionIds.Contains(x.ReadingQuestionTrialId))
.Select(x => new
{
x.VisitTaskId,
x.ReadingQuestionTrialId,
x.Answer,
})
.ToListAsync();
judgeAnswers.ForEach(question =>
{
question.R1Answer = answerList.FirstOrDefault(x => x.VisitTaskId == r1Task.Id && x.ReadingQuestionTrialId == question.ReadingQuestionId)?.Answer ?? string.Empty;
question.R2Answer = answerList.FirstOrDefault(x => x.VisitTaskId == r2Task.Id && x.ReadingQuestionTrialId == question.ReadingQuestionId)?.Answer ?? string.Empty;
});
return new GetSingleVisitJudgeAnswerOutDto
{
R1VisitTaskId = r1Task.Id,
R2VisitTaskId = r2Task.Id,
QuestionList = judgeAnswers,
};
}
/// <summary>
/// 获取裁判表单
/// </summary>
[HttpPost]
public async Task<GetJudgeFormOutDto> GetJudgeForm(GetJudgeFormInDto inDto)
{
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var judgeRule = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskInfo.TrialReadingCriterionId).Select(x => x.JudgeRuleEnum).FirstNotNullAsync();
var questionList = await GetJudgeDisplayQuestions(taskInfo.TrialReadingCriterionId, taskInfo.VisitTaskNum, judgeRule);
var questionIds = questionList.Select(x => x.Id).ToList();
var answers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && questionIds.Contains(x.ReadingQuestionTrialId)).ToListAsync();
return new GetJudgeFormOutDto
{
JudgeResultRemark = taskInfo.JudgeResultRemark,
JudgeResultImagePathList = taskInfo.JudgeResultImagePathList,
QuestionList = questionList.Select(x => new JudgeFormQuestionDto
{
ReadingQuestionId = x.Id,
QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
Type = x.Type,
TypeValue = x.TypeValue,
ShowOrder = x.ShowOrder,
Answer = answers.FirstOrDefault(answer => answer.ReadingQuestionTrialId == x.Id)?.Answer ?? string.Empty,
QuestionGenre = x.QuestionGenre,
DictionaryCode = x.DictionaryCode,
Unit = x.Unit,
CustomUnit = x.CustomUnit,
ValueType = x.ValueType,
}).ToList(),
};
}
/// <summary>
/// 编辑裁判表单
/// </summary>
[HttpPost]
public async Task<IResponseOutput> SetJudgeForm(SetJudgeFormInDto inDto)
{
await SaveJudgeForm(inDto);
await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
{
JudgeResultRemark = inDto.JudgeResultRemark,
JudgeResultImagePath = string.Join(',', inDto.JudgeResultImagePathList),
});
return ResponseOutput.Result(await _readingTaskQuestionAnswerRepository.SaveChangesAsync());
}
private async Task SaveJudgeForm(SetJudgeFormInDto inDto)
{
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var judgeRule = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskInfo.TrialReadingCriterionId).Select(x => x.JudgeRuleEnum).FirstNotNullAsync();
var displayQuestionIds = (await GetJudgeDisplayQuestions(taskInfo.TrialReadingCriterionId, taskInfo.VisitTaskNum, judgeRule)).Select(x => x.Id).ToList();
var submittedQuestionIds = inDto.QuestionList.Select(x => x.ReadingQuestionId).ToList();
await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && submittedQuestionIds.Contains(x.ReadingQuestionTrialId));
if (inDto.QuestionList.Count > 0)
{
await _readingTaskQuestionAnswerRepository.AddRangeAsync(inDto.QuestionList.Select(x => new ReadingTaskQuestionAnswer
{
ReadingQuestionTrialId = x.ReadingQuestionId,
ReadingQuestionCriterionTrialId = taskInfo.TrialReadingCriterionId,
TrialId = taskInfo.TrialId,
SubjectId = taskInfo.SubjectId,
VisitTaskId = inDto.VisitTaskId,
Answer = x.Answer,
}).ToList());
}
}
/// <summary>
/// 提交裁判表单
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SubmitJudgeForm(SetJudgeFormInDto inDto)
{
await SaveJudgeForm(inDto);
await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
{
JudgeResultRemark = inDto.JudgeResultRemark,
ReadingTaskState = ReadingTaskState.HaveSigned,
SignTime=DateTime.Now,
JudgeResultImagePath = string.Join(',', inDto.JudgeResultImagePathList),
});
await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
await SignatureAfter(inDto.VisitTaskId);
return ResponseOutput.Ok();
}
private async Task<List<ReadingQuestionTrial>> GetJudgeDisplayQuestions(Guid trialReadingCriterionId, decimal visitNum, JudgeRule judgeRule)
{
var questionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialReadingCriterionId && x.IsJudgeQuestion)
.Where(x=>x.ShowQuestion== ShowQuestion.Show)
.OrderBy(x => x.ShowOrder).ToListAsync();
var questionIds = questionList.Select(x => x.Id).ToList();
var visitJudgeRules = judgeRule == JudgeRule.Difference
? await _readingQuestionVisitJudgeRuleRepository.Where(x => questionIds.Contains(x.ReadingQuestionId) && (x.VisitNum == visitNum || x.VisitNum == -1)).ToListAsync()
: new List<ReadingQuestionVisitJudgeRule>();
return questionList.Where(x => !x.ExcludeShowVisitList.Contains(visitNum))
.Where(x => judgeRule == JudgeRule.Consistent
? x.JudgeType != JudgeTypeEnum.NotApplicable
: (visitJudgeRules.FirstOrDefault(rule => rule.ReadingQuestionId == x.Id && rule.VisitNum == visitNum)
?? visitJudgeRules.FirstOrDefault(rule => rule.ReadingQuestionId == x.Id && rule.VisitNum == -1))?.JudgeType != JudgeTypeEnum.NotApplicable)
.ToList();
}
/// <summary> /// <summary>
/// 获取裁判阅片任务信息 /// 获取裁判阅片任务信息
/// </summary> /// </summary>
@ -476,8 +670,15 @@ namespace IRaCIS.Core.Application.Service
}); });
var result = await _visitTaskRepository.SaveChangesAsync(); var result = await _visitTaskRepository.SaveChangesAsync();
await SignatureAfter(inDto.VisitTaskId);
return ResponseOutput.Ok(result);
}
private async Task SignatureAfter(Guid visitTaskId)
{
// 需要判断是否添加肿瘤学任务 // 需要判断是否添加肿瘤学任务
var taskInfo = await _visitTaskRepository.Where(x => x.JudgeVisitTaskId == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync(); var taskInfo = await _visitTaskRepository.Where(x => x.JudgeVisitTaskId == visitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
if (taskInfo.ReadingCategory == ReadingCategory.Visit) if (taskInfo.ReadingCategory == ReadingCategory.Visit)
{ {
@ -514,11 +715,9 @@ namespace IRaCIS.Core.Application.Service
// 创建任务关联关系 // 创建任务关联关系
await this.CreateTaskRelated(inDto.VisitTaskId); await this.CreateTaskRelated(visitTaskId);
await SafeMailHelper.Run(async () => await _trialEmailNoticeConfigService.BaseBusinessScenarioSendEmailAsync(inDto.VisitTaskId)); await SafeMailHelper.Run(async () => await _trialEmailNoticeConfigService.BaseBusinessScenarioSendEmailAsync(visitTaskId));
return ResponseOutput.Ok(result);
} }
/// <summary> /// <summary>
@ -624,6 +823,7 @@ namespace IRaCIS.Core.Application.Service
x.ArbitrationRule, x.ArbitrationRule,
x.IsGlobalReading, x.IsGlobalReading,
x.IsReadingPeriod, x.IsReadingPeriod,
x.JudgeRuleEnum,
}).FirstNotNullAsync(); }).FirstNotNullAsync();
var noteEqual = false; var noteEqual = false;
@ -667,6 +867,7 @@ namespace IRaCIS.Core.Application.Service
VisitTaskId = questionAnswer.VisitTaskId, VisitTaskId = questionAnswer.VisitTaskId,
}; };
var globalVisitAnswerlist = await globalVisitQuestionQuery.ToListAsync(); var globalVisitAnswerlist = await globalVisitQuestionQuery.ToListAsync();
await ApplyVisitJudgeRules(globalVisitAnswerlist, criterionInfo.JudgeRuleEnum);
var taskNums = globalVisitAnswerlist.Select(x => x.VisitTaskNum).Distinct().OrderBy(x => x).ToList(); var taskNums = globalVisitAnswerlist.Select(x => x.VisitTaskNum).Distinct().OrderBy(x => x).ToList();
@ -697,11 +898,13 @@ namespace IRaCIS.Core.Application.Service
AnswerCombination = question.AnswerCombination, AnswerCombination = question.AnswerCombination,
JudgeType = question.JudgeType, JudgeType = question.JudgeType,
QuestionId = question.Id, QuestionId = question.Id,
JudgeDifferenceValue = question.JudgeDifferenceValue, JudgeDifferenceValue = question.JudgeDifferenceValue,
JudgeDifferenceType = question.JudgeDifferenceType, JudgeDifferenceType = question.JudgeDifferenceType,
VisitTaskId = questionAnswet.VisitTaskId, VisitTaskId = questionAnswet.VisitTaskId,
}; VisitTaskNum = questionAnswet.VisitTask.VisitTaskNum,
};
var questionAnswerlist = await query.ToListAsync(); var questionAnswerlist = await query.ToListAsync();
await ApplyVisitJudgeRules(questionAnswerlist, criterionInfo.JudgeRuleEnum);
// 将答案进行分组 // 将答案进行分组
List<GroupTaskAnswerDto> groupTasks = questionAnswerlist.GroupBy(x => new { x.JudgeDifferenceValue, x.JudgeDifferenceType, x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination }).Select(x => new GroupTaskAnswerDto List<GroupTaskAnswerDto> groupTasks = questionAnswerlist.GroupBy(x => new { x.JudgeDifferenceValue, x.JudgeDifferenceType, x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination }).Select(x => new GroupTaskAnswerDto
@ -749,6 +952,8 @@ namespace IRaCIS.Core.Application.Service
} }
else else
{ {
await ApplyVisitJudgeRules(item.AfterQuestionList, item.VisitNum, criterionInfo.JudgeRuleEnum);
await ApplyVisitJudgeRules(twoItem.AfterQuestionList, twoItem.VisitNum, criterionInfo.JudgeRuleEnum);
var newlist = item.AfterQuestionList.Where(x => x.QuestionId != null && x.IsJudgeQuestion).ToList().Union( var newlist = item.AfterQuestionList.Where(x => x.QuestionId != null && x.IsJudgeQuestion).ToList().Union(
twoItem.AfterQuestionList.Where(x => x.QuestionId != null && x.IsJudgeQuestion).ToList() twoItem.AfterQuestionList.Where(x => x.QuestionId != null && x.IsJudgeQuestion).ToList()
).ToList(); ).ToList();
@ -811,6 +1016,8 @@ namespace IRaCIS.Core.Application.Service
}; };
var visitTaskQuestions = await query.ToListAsync(); var visitTaskQuestions = await query.ToListAsync();
await ApplyVisitJudgeRules(visitTaskQuestions, lastTask.VisitNum, criterionInfo.JudgeRuleEnum);
await ApplyVisitJudgeRules(lastTask.AfterQuestionList, lastTask.VisitNum, criterionInfo.JudgeRuleEnum);
var newlist = visitTaskQuestions.Where(x => x.QuestionId != null).ToList().Union( var newlist = visitTaskQuestions.Where(x => x.QuestionId != null).ToList().Union(
lastTask.AfterQuestionList.Where(x => x.QuestionId != null).ToList() lastTask.AfterQuestionList.Where(x => x.QuestionId != null).ToList()
@ -929,6 +1136,102 @@ namespace IRaCIS.Core.Application.Service
} }
/// <summary>
/// 应用访视裁判规则 以及剔除排除的问题
/// </summary>
private async Task ApplyVisitJudgeRules(List<TaskAnswerDto> answerList, JudgeRule judgeRule)
{
if (answerList.Count == 0)
{
return;
}
var questionIds = answerList.Select(x => x.QuestionId).Distinct().ToList();
var questions = await _readingQuestionTrialRepository.Where(x => questionIds.Contains(x.Id)).Select(x => new
{
x.Id,
x.ExcludeShowVisitList,
}).ToListAsync();
var excludedQuestionIds = answerList
.Where(x => questions.FirstOrDefault(question => question.Id == x.QuestionId)?.ExcludeShowVisitList.Contains(x.VisitTaskNum) == true)
.Select(x => x.QuestionId)
.Distinct()
.ToList();
answerList.RemoveAll(x => excludedQuestionIds.Contains(x.QuestionId));
if (judgeRule != JudgeRule.Difference || answerList.Count == 0)
{
return;
}
questionIds = answerList.Select(x => x.QuestionId).Distinct().ToList();
var visitNums = answerList.Select(x => x.VisitTaskNum).Distinct().ToList();
var visitRules = await _readingQuestionVisitJudgeRuleRepository
.Where(x => questionIds.Contains(x.ReadingQuestionId) && (visitNums.Contains(x.VisitNum) || x.VisitNum == -1))
.ToListAsync();
answerList.ForEach(answer =>
{
var rule = visitRules.FirstOrDefault(x => x.ReadingQuestionId == answer.QuestionId && x.VisitNum == answer.VisitTaskNum)
?? visitRules.FirstOrDefault(x => x.ReadingQuestionId == answer.QuestionId && x.VisitNum == -1);
if (rule != null)
{
answer.AnswerGroup = JsonConvert.SerializeObject(rule.AnswerGroup);
answer.AnswerCombination = JsonConvert.SerializeObject(rule.AnswerCombination);
answer.JudgeType = rule.JudgeType;
answer.JudgeDifferenceValue = rule.JudgeDifferenceValue;
answer.JudgeDifferenceType = rule.JudgeDifferenceType;
}
});
}
/// <summary>
/// 应用访视裁判规则 以及剔除排除的问题
/// </summary>
private async Task ApplyVisitJudgeRules(List<GlobalQuestionInfo> questionList, decimal visitNum, JudgeRule judgeRule)
{
if (questionList.Count == 0)
{
return;
}
var questionIds = questionList.Where(x => x.QuestionId != null).Select(x => x.QuestionId!.Value).Distinct().ToList();
var excludedQuestionIds = await _readingQuestionTrialRepository
.Where(x => questionIds.Contains(x.Id) && x.ExcludeShowVisitList.Contains(visitNum))
.Select(x => x.Id)
.ToListAsync();
questionList.RemoveAll(x => x.QuestionId != null && excludedQuestionIds.Contains(x.QuestionId.Value));
if (judgeRule != JudgeRule.Difference || questionList.Count == 0)
{
return;
}
questionIds = questionList.Where(x => x.QuestionId != null).Select(x => x.QuestionId!.Value).Distinct().ToList();
var visitRules = await _readingQuestionVisitJudgeRuleRepository
.Where(x => questionIds.Contains(x.ReadingQuestionId) && (x.VisitNum == visitNum || x.VisitNum == -1))
.ToListAsync();
questionList.ForEach(question =>
{
if (question.QuestionId == null)
{
return;
}
var rule = visitRules.FirstOrDefault(x => x.ReadingQuestionId == question.QuestionId && x.VisitNum == visitNum)
?? visitRules.FirstOrDefault(x => x.ReadingQuestionId == question.QuestionId && x.VisitNum == -1);
if (rule != null)
{
question.AnswerGroup = JsonConvert.SerializeObject(rule.AnswerGroup);
question.AnswerCombination = JsonConvert.SerializeObject(rule.AnswerCombination);
question.JudgeType = rule.JudgeType;
question.JudgeDifferenceValue = rule.JudgeDifferenceValue;
question.JudgeDifferenceType = rule.JudgeDifferenceType;
}
});
}
/// <summary> /// <summary>
/// 发送微信通知 /// 发送微信通知

View File

@ -258,7 +258,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
if (historyTaskId != Guid.Empty) if (historyTaskId != Guid.Empty)
{ {
var historyTableRowList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == historyTaskId).ToListAsync(); var criterionType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskinfo.TrialReadingCriterionId).Select(x => x.CriterionType).FirstOrDefaultAsync();
var historyTableRowList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == historyTaskId).Include(x => x.ReadingQuestionTrial).ToListAsync();
var historyTableAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == historyTaskId).ToListAsync(); var historyTableAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == historyTaskId).ToListAsync();
@ -278,7 +279,11 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
{ {
continue; continue;
} }
var historyRow = historyTableRowList.Where(x =>
// 自定义标准(SelfDefine)的病灶IdentityRowId不可靠 除了根据器官判断还需要根据复制前值的答案是否相等 优先用答案匹配
var historyRow = historyTableRowList
.WhereIf(criterionType == CriterionType.SelfDefine, x => IsSameCustomRowAnswer(item, x, tableAnswerList, historyTableAnswerList))
.Where(x =>
x.QuestionId == item.QuestionId && x.QuestionId == item.QuestionId &&
x.RowIndex == item.RowIndex && x.RowIndex == item.RowIndex &&
x.IdentityRowId == item.IdentityRowId && x.IdentityRowId == item.IdentityRowId &&
@ -311,6 +316,77 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
} }
} }
// 将失效任务在当前访视新增的病灶添加过来
// 例如现在是访视三,把失效任务访视三中在访视三新增的病灶(FristAddTaskId == historyTaskId)添加过来
var historyAddRowList = historyTableRowList.Where(x => x.FristAddTaskId == historyTaskId && x.SplitOrMergeType != SplitOrMergeType.Merged).ToList();
var historyRowIdSet = historyTableRowList.Select(x => x.Id).ToHashSet();
foreach (var historyRow in historyAddRowList)
{
// 判断当前任务是否已经存在该病灶 失效任务新增的病灶IdentityRowId是新建的不会与当前任务重复
bool isExist = tableRowList.Any(x => x.QuestionId == historyRow.QuestionId && x.IdentityRowId != null && x.IdentityRowId == historyRow.IdentityRowId);
if (isExist)
{
continue;
}
// 通过CopyTableAnswerRowInfo映射复制行字段
var copyRow = _mapper.Map<CopyTableAnswerRowInfo>(historyRow);
copyRow.Id = NewId.NextGuid();
copyRow.VisitTaskId = taskinfo.Id;
copyRow.MeasureData = historyRow.MeasureData.Replace(historyTaskId.ToString(), taskinfo.Id.ToString());
copyRow.IsCurrentTaskAdd = true;
copyRow.FristAddTaskId = taskinfo.Id;
var newRow = _mapper.Map<ReadingTableAnswerRowInfo>(copyRow);
// CopyTableAnswerRowInfo没有Other和PET/CT融合字段 单独复制
newRow.OtherMeasureData = historyRow.OtherMeasureData.Replace(historyTaskId.ToString(), taskinfo.Id.ToString());
newRow.OtherInstanceId = historyRow.OtherInstanceId;
newRow.OtherSeriesId = historyRow.OtherSeriesId;
newRow.OtherStudyId = historyRow.OtherStudyId;
newRow.OtherMarkTool = historyRow.OtherMarkTool;
newRow.OtherPicturePath = historyRow.OtherPicturePath;
newRow.OtherNumberOfFrames = historyRow.OtherNumberOfFrames;
newRow.PTSeriesId = historyRow.PTSeriesId;
newRow.CTSeriesId = historyRow.CTSeriesId;
tableRowList.Add(newRow);
if (!lesionRelationship.ContainsKey(historyRow.Id))
{
lesionRelationship.Add(historyRow.Id, newRow.Id);
}
// 复制该病灶的表格答案
historyTableAnswerList.Where(x => x.RowId == historyRow.Id).ForEach(x =>
{
tableAnswerList.Add(new ReadingTableQuestionAnswer()
{
Id = NewId.NextGuid(),
Answer = x.Answer,
QuestionId = x.QuestionId,
VisitTaskId = taskinfo.Id,
TrialId = x.TrialId,
RowIndex = x.RowIndex,
TableQuestionId = x.TableQuestionId,
RowId = newRow.Id,
});
});
}
// 处理新增病灶的分割合并关系 新增病灶已经在tableRowList里 通过SplitRowId/MergeRowId是否指向失效任务的行来识别
tableRowList.ForEach(x =>
{
if (x.SplitRowId != null && historyRowIdSet.Contains(x.SplitRowId.Value))
{
x.SplitRowId = lesionRelationship.ContainsKey(x.SplitRowId.Value) ? lesionRelationship[x.SplitRowId.Value] : (Guid?)null;
}
if (x.MergeRowId != null && historyRowIdSet.Contains(x.MergeRowId.Value))
{
x.MergeRowId = lesionRelationship.ContainsKey(x.MergeRowId.Value) ? lesionRelationship[x.MergeRowId.Value] : (Guid?)null;
}
});
// 复制外层问题 // 复制外层问题
answerList.ForEach(x => answerList.ForEach(x =>
{ {
@ -920,5 +996,31 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
}); });
return taskInfoList; return taskInfoList;
} }
/// <summary>
/// 自定义病灶判断是否是同一个病灶 除了根据器官判断还需要根据复制前值的答案是否相等
/// </summary>
/// <param name="currentRow"></param>
/// <param name="historyRow"></param>
/// <param name="currentAnswerList"></param>
/// <param name="historyAnswerList"></param>
/// <returns></returns>
private bool IsSameCustomRowAnswer(ReadingTableAnswerRowInfo currentRow, ReadingTableAnswerRowInfo historyRow,
List<ReadingTableQuestionAnswer> currentAnswerList, List<ReadingTableQuestionAnswer> historyAnswerList)
{
// 复制前值的答案即当前任务从上一次有效访视复制过来的答案自定义阅片只有IsCopy的问题会复制值非空的就是复制前值
var currentAnswers = currentAnswerList.Where(x => x.RowId == currentRow.Id && !x.Answer.IsNullOrEmpty())
.GroupBy(x => x.TableQuestionId).ToDictionary(x => x.Key, x => x.First().Answer);
var historyAnswers = historyAnswerList.Where(x => x.RowId == historyRow.Id && !x.Answer.IsNullOrEmpty())
.GroupBy(x => x.TableQuestionId).ToDictionary(x => x.Key, x => x.First().Answer);
// 没有复制前值可以比较时 只根据器官判断
if (currentAnswers.Count == 0)
{
return true;
}
return currentAnswers.All(x => historyAnswers.TryGetValue(x.Key, out var historyAnswer) && historyAnswer == x.Value);
}
} }
} }

View File

@ -29,6 +29,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
IGeneralCalculateService _generalCalculateService, IGeneralCalculateService _generalCalculateService,
IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository, IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository,
IVisitTaskHelpeService _visitTaskHelpeService, IVisitTaskHelpeService _visitTaskHelpeService,
IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository,
IHttpContextAccessor httpContext, IHttpContextAccessor httpContext,
ILogger<IRECIST1Point1CalculateService> _logger, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ICriterionCalculateService ILogger<IRECIST1Point1CalculateService> _logger, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ICriterionCalculateService
{ {
@ -1083,6 +1084,23 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
{ {
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.Subject).Include(x => x.TrialReadingCriterion).FirstNotNullAsync(); var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.Subject).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
var noneDicomFiles = await _noneDicomStudyFileRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId)
.Select(x => new { x.FileType, x.FileName }).ToListAsync();
var hasZip = noneDicomFiles.Any(x => x.FileType == "application/zip"
|| x.FileType == "application/x-zip-compressed"
|| x.FileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase));
var hasImage = noneDicomFiles.Any(x => x.FileType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)
|| x.FileName.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase)
|| x.FileName.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase)
|| x.FileName.EndsWith(".png", StringComparison.OrdinalIgnoreCase)
|| x.FileName.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase)
|| x.FileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase));
if (!hasZip || !hasImage)
{
throw new BusinessValidationFailedException(_localizer["IVUSCriterionImageFileVerify"]);
}
var question = await _readingQuestionTrialRepository.Where(x => x.LesionType == LesionType.ROI && x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId).FirstNotNullAsync(); var question = await _readingQuestionTrialRepository.Where(x => x.LesionType == LesionType.ROI && x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId).FirstNotNullAsync();

View File

@ -35,6 +35,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
IGeneralCalculateService _generalCalculateService, IGeneralCalculateService _generalCalculateService,
IVisitTaskHelpeService _visitTaskHelpeService, IVisitTaskHelpeService _visitTaskHelpeService,
IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository, IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository,
IRepository<TaskStudy> _taskStudyRepository,
IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository,
ILogger<IRECIST1Point1CalculateService> _logger, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ICriterionCalculateService ILogger<IRECIST1Point1CalculateService> _logger, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ICriterionCalculateService
{ {
/// <summary> /// <summary>
@ -1597,6 +1599,18 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
{ {
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.Subject).Include(x => x.TrialReadingCriterion).FirstNotNullAsync(); var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.Subject).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
var noneDicomFiles = await _noneDicomStudyFileRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId)
.Select(x => new { x.FileType, x.FileName }).ToListAsync();
var hasDicom = await _taskStudyRepository.AnyAsync(x => x.VisitTaskId == inDto.VisitTaskId);
var hasZip = noneDicomFiles.Any(x => x.FileType == "application/zip"
|| x.FileType == "application/x-zip-compressed"
|| x.FileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase));
if (!hasDicom || !hasZip)
{
throw new BusinessValidationFailedException(_localizer["OCTCriterionImageFileVerify"]);
}
var question = await _readingQuestionTrialRepository.Where(x => x.LesionType == LesionType.ROI && x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId).FirstNotNullAsync(); var question = await _readingQuestionTrialRepository.Where(x => x.LesionType == LesionType.ROI && x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId).FirstNotNullAsync();

View File

@ -3,6 +3,8 @@
// 生成时间 2021-12-23 13:21:04 // 生成时间 2021-12-23 13:21:04
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//-------------------------------------------------------------------- //--------------------------------------------------------------------
using IRaCIS.Core.Application.Helper;
namespace IRaCIS.Core.Application.Contracts namespace IRaCIS.Core.Application.Contracts
{ {
/// <summary> TrialSiteEquipmentSurveyView 列表视图模型 </summary> /// <summary> TrialSiteEquipmentSurveyView 列表视图模型 </summary>
@ -49,33 +51,44 @@ namespace IRaCIS.Core.Application.Contracts
public string ScannerType { get; set; } = string.Empty; public string ScannerType { get; set; } = string.Empty;
public string Note { get; set; } = string.Empty; public string Note { get; set; } = string.Empty;
[DictionaryTranslate("SiteSurvey_ScanEquipmentType")]
[Comment("扫描设备-New")] [Comment("扫描设备-New")]
public int? EquipmentTypeEnum { get; set; } public int? EquipmentTypeEnum { get; set; }
public string OtherEquipmentType { get; set; } public string OtherEquipmentType { get; set; }
[Comment("扫描设备厂商")] [Comment("扫描设备厂商")]
[DictionaryTranslate("ManufacturerType")]
public int? ManufacturerType { get; set; } public int? ManufacturerType { get; set; }
[Comment("磁场强度 (1.5T / 3.0T)")] [Comment("磁场强度 (1.5T / 3.0T)")]
[DictionaryTranslate("MagneticFieldStrengthType")]
public int? MagneticFieldStrengthType { get; set; } public int? MagneticFieldStrengthType { get; set; }
[DictionaryTranslate("BodyCoilChannelCount")]
[Comment("体部线圈通道数 (≥16 或 16)")] [Comment("体部线圈通道数 (≥16 或 16)")]
public int? BodyCoilChannelCount { get; set; } public int? BodyCoilChannelCount { get; set; }
[DictionaryTranslate("YesOrNo")]
[Comment("是否具备专用的PDFF脂肪定量序列CSE-MRI序列")] [Comment("是否具备专用的PDFF脂肪定量序列CSE-MRI序列")]
public bool? HasDedicatedPdfFatQuantificationSequence { get; set; } public bool? HasDedicatedPdfFatQuantificationSequence { get; set; }
[DictionaryTranslate("PdfFatQuantificationSequenceType")]
[Comment("专用的PDFF脂肪定量序列类型 (当 HasDedicatedPdfFatQuantificationSequence = true 时有效)")] [Comment("专用的PDFF脂肪定量序列类型 (当 HasDedicatedPdfFatQuantificationSequence = true 时有效)")]
public int? PdfFatQuantificationSequenceType { get; set; } public int? PdfFatQuantificationSequenceType { get; set; }
[Comment("其他序列详细说明 (当 PdfFatQuantificationSequenceType = Other 时建议填写)")] [Comment("其他序列详细说明 (当 PdfFatQuantificationSequenceType = Other 时建议填写)")]
public string OtherSequenceSpecification { get; set; } public string OtherSequenceSpecification { get; set; }
[DictionaryTranslate("YesOrNo")]
[Comment("是否包含 T2/R2 校正(用于铁沉积校正)")] [Comment("是否包含 T2/R2 校正(用于铁沉积校正)")]
public bool? HasT2R2Correction { get; set; } public bool? HasT2R2Correction { get; set; }
[DictionaryTranslate("YesOrNo")]
[Comment("是否可完整导出 PDFF 参数图及全部原始 DICOM 数据")] [Comment("是否可完整导出 PDFF 参数图及全部原始 DICOM 数据")]
public bool? CanFullyExportPdfParameterMapsAndRawDicom { get; set; } public bool? CanFullyExportPdfParameterMapsAndRawDicom { get; set; }
} }

View File

@ -5,6 +5,7 @@
//-------------------------------------------------------------------- //--------------------------------------------------------------------
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
@ -131,13 +132,15 @@ namespace IRaCIS.Core.Application.Contracts
/// <summary> TrialSiteSurveyView 列表视图模型 </summary> /// <summary> TrialSiteSurveyView 列表视图模型 </summary>
public class TrialSiteSurveyView: TrialSiteSurveyAddOrEdit public class TrialSiteSurveyView : TrialSiteSurveyAddOrEdit
{ {
public string TrialSiteCode { get; set; } = String.Empty; public string TrialSiteCode { get; set; } = String.Empty;
public string TrialSiteAliasName { get; set; } = String.Empty; public string TrialSiteAliasName { get; set; } = String.Empty;
public string SiteName { get; set; } = string.Empty; public string SiteName { get; set; } = string.Empty;
[DictionaryTranslate("YesOrNo")]
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }
public DateTime CreateTime { get; set; } public DateTime CreateTime { get; set; }
@ -145,7 +148,7 @@ namespace IRaCIS.Core.Application.Contracts
public DateTime UpdateTime { get; set; } public DateTime UpdateTime { get; set; }
public Guid UpdateUserId { get; set; } public Guid UpdateUserId { get; set; }
[DictionaryTranslate("ResearchRecord")]
public TrialSiteSurveyEnum State { get; set; } public TrialSiteSurveyEnum State { get; set; }
public string LatestBackReason { get; set; } = string.Empty; public string LatestBackReason { get; set; } = string.Empty;
@ -326,14 +329,21 @@ namespace IRaCIS.Core.Application.Contracts
public string UserName { get; set; } = string.Empty; public string UserName { get; set; } = string.Empty;
public string Phone { get; set; } = string.Empty; public string Phone { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty; public string Email { get; set; } = string.Empty;
public int AverageEngravingCycle { get; set; } public int AverageEngravingCycle { get; set; }
[DictionaryTranslate("YesOrNo")]
public bool IsConfirmImagingTechnologist { get; set; } public bool IsConfirmImagingTechnologist { get; set; }
public string NotConfirmReson { get; set; } = string.Empty; public string NotConfirmReson { get; set; } = string.Empty;
[DictionaryTranslate("EfficacyEvaluatorType")]
public int EfficacyEvaluatorType { get; set; } public int EfficacyEvaluatorType { get; set; }
[DictionaryTranslate("YesOrNo")]
public bool IsFollowStudyParameters { get; set; } public bool IsFollowStudyParameters { get; set; }
public string NotFollowReson { get; set; } = string.Empty; public string NotFollowReson { get; set; } = string.Empty;
[DictionaryTranslate("YesOrNo")]
[Comment("MRI-PDEE 是否为本中心该适应症的常规诊疗检查项目")] [Comment("MRI-PDEE 是否为本中心该适应症的常规诊疗检查项目")]
public bool? IsRoutineMRIPDEE { get; set; } public bool? IsRoutineMRIPDEE { get; set; }
@ -346,14 +356,17 @@ namespace IRaCIS.Core.Application.Contracts
[Comment("MRI-PDEE 其他")] [Comment("MRI-PDEE 其他")]
public string MRIPDFFOther { get; set; } public string MRIPDFFOther { get; set; }
[DictionaryTranslate("YesOrNo")]
[Comment("是否授权影像科老师参与")] [Comment("是否授权影像科老师参与")]
public bool? IsAuthorizeRadiologistsParticipate { get; set; } public bool? IsAuthorizeRadiologistsParticipate { get; set; }
[DictionaryTranslate("YesOrNo")]
[Comment("保持 1-2 名固定技师")] [Comment("保持 1-2 名固定技师")]
public bool? AssignFixedTechnologists { get; set; } public bool? AssignFixedTechnologists { get; set; }
[DictionaryTranslate("YesOrNo")]
[Comment("是否严格按照影像手册参数完成刻盘")] [Comment("是否严格按照影像手册参数完成刻盘")]
public bool? ISStrictManualBurnFlag { get; set; } public bool? ISStrictManualBurnFlag { get; set; }
@ -450,6 +463,92 @@ namespace IRaCIS.Core.Application.Contracts
} }
public class SiteSurveyLogQuery:SortInput
{
[NotDefault]
public Guid TrialSiteSurveyId { get; set; }
public Guid? Id { get; set; }
}
public class SiteSurveyLogDTO
{
public Guid Id { get; set; }
public Guid TrialSiteSurveyId { get; set; }
public string Name { get; set; }
public UserTypeEnum UserType { get; set; }
public SiteSurveyOptTyp OptType { get; set; }
public string Reason { get; set; }
[MaxLength]
public string Json { get; set; }
[Comment("更新调研表之前的调研表")]
public Guid? OriginTrialSiteSurveyId { get; set; }
public string CreateTime { get; set; }
}
public class SiteSurveyEquipmentDto : TrialSiteEquipmentSurveyView
{
public string TrialSiteCode { get; set; }
public string TrialSiteName { get; set; } = String.Empty;
public string TrialSiteAliasName { get; set; } = String.Empty;
public string UserName { get; set; } = string.Empty;
public string Phone { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
[DictionaryTranslate("YesOrNo")]
public bool IsDeleted { get; set; }
[DictionaryTranslate("ResearchRecord")]
public TrialSiteSurveyEnum State { get; set; }
}
public class SiteSurveyEquipmentQuery : PageInput
{
[NotDefault]
public Guid TrialId { get; set; }
public Guid? TrialSiteId { get; set; }
public string? TrialSiteCode { get; set; }
public string? TrialSiteName { get; set; }
public bool? IsDeleted { get; set; }
public TrialSiteSurveyEnum? State { get; set; }
}
public class SiteSurveyInfoQuery : PageInput
{
[NotDefault]
public Guid TrialId { get; set; }
public Guid? TrialSiteId { get; set; }
public string? TrialSiteCode { get; set; }
public string? TrialSiteName { get; set; }
public bool? IsDeleted { get; set; }
public TrialSiteSurveyEnum? State { get; set; }
}
public class SiteSurveyInfoDto
{
}
} }

View File

@ -3,6 +3,9 @@
// 生成时间 2021-12-23 13:20:59 // 生成时间 2021-12-23 13:20:59
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//-------------------------------------------------------------------- //--------------------------------------------------------------------
using DocumentFormat.OpenXml.Office2013.Excel;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Vml;
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
@ -22,6 +25,8 @@ namespace IRaCIS.Core.Application.Contracts
/// </summary> /// </summary>
[ApiExplorerSettings(GroupName = "Trial")] [ApiExplorerSettings(GroupName = "Trial")]
public class TrialSiteSurveyService(IRepository<TrialSiteSurvey> _trialSiteSurveyRepository, public class TrialSiteSurveyService(IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
IRepository<SiteSurveyLog> _siteSurveyLogRepository,
IRepository<TrialSiteEquipmentSurvey> _trialSiteEquipmentSurveyRepository,
IRepository<TrialSiteUserSurvey> _trialSiteUserSurveyRepository, IRepository<TrialSiteUserSurvey> _trialSiteUserSurveyRepository,
IRepository<UserRole> _userRoleRepository, IRepository<UserRole> _userRoleRepository,
IRepository<IdentityUser> _identityUserRepository, IRepository<IdentityUser> _identityUserRepository,
@ -474,6 +479,7 @@ namespace IRaCIS.Core.Application.Contracts
public async Task<IResponseOutput> SubmissionRejection(TrialSiteSubmitBackCommand trialSiteSubmitBackCommand, [FromServices] IMailVerificationService _IMailVerificationService) public async Task<IResponseOutput> SubmissionRejection(TrialSiteSubmitBackCommand trialSiteSubmitBackCommand, [FromServices] IMailVerificationService _IMailVerificationService)
{ {
var trialId = trialSiteSubmitBackCommand.TrialId;
var trialSiteSurveyId = trialSiteSubmitBackCommand.TrialSiteSurveyId; var trialSiteSurveyId = trialSiteSubmitBackCommand.TrialSiteSurveyId;
var survey = await _trialSiteSurveyRepository.FirstOrDefaultAsync(t => t.Id == trialSiteSurveyId); var survey = await _trialSiteSurveyRepository.FirstOrDefaultAsync(t => t.Id == trialSiteSurveyId);
@ -492,36 +498,48 @@ namespace IRaCIS.Core.Application.Contracts
} }
else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM) else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM)
{ {
var isTrialSPMJoin = await _trialRepository.AnyAsync(t => t.Id == trialSiteSubmitBackCommand.TrialId && t.IsSPMJoinSiteSurvey); // var isTrialSPMJoin = await _trialRepository.AnyAsync(t => t.Id == trialSiteSubmitBackCommand.TrialId && t.IsSPMJoinSiteSurvey);
var hasSPMOrCPM = await _trialRepository.Where(t => t.Id == trialSiteSubmitBackCommand.TrialId).AnyAsync(t => t.TrialIdentityUserList.SelectMany(t => t.TrialUserRoleList).Any(t => // var hasSPMOrCPM = await _trialRepository.Where(t => t.Id == trialSiteSubmitBackCommand.TrialId).AnyAsync(t => t.TrialIdentityUserList.SelectMany(t => t.TrialUserRoleList).Any(t =>
t.UserRole.IdentityUser.Status == UserStateEnum.Enable //t.UserRole.IdentityUser.Status == UserStateEnum.Enable
&& t.UserRole.IsUserRoleDisabled == false //&& t.UserRole.IsUserRoleDisabled == false
&& (t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM)) //&& (t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM))
); //);
var isSPMjoin = isTrialSPMJoin && hasSPMOrCPM; // var isSPMjoin = isTrialSPMJoin && hasSPMOrCPM;
if (isSPMjoin) // if (isSPMjoin)
{ // {
survey.State = TrialSiteSurveyEnum.CRCSubmitted; // survey.State = TrialSiteSurveyEnum.CRCSubmitted;
survey.ReviewerUserId = null; // survey.ReviewerUserId = null;
survey.ReviewerTime = null; // survey.ReviewerTime = null;
} // }
else // else
{ // {
survey.State = TrialSiteSurveyEnum.ToSubmit; // survey.State = TrialSiteSurveyEnum.ToSubmit;
survey.PreliminaryUserId = null; // survey.PreliminaryUserId = null;
survey.ReviewerUserId = null; // survey.ReviewerUserId = null;
survey.PreliminaryTime = null; // survey.PreliminaryTime = null;
survey.ReviewerTime = null; // survey.ReviewerTime = null;
// }
survey.State = TrialSiteSurveyEnum.ToSubmit;
survey.PreliminaryUserId = null;
survey.ReviewerUserId = null;
survey.PreliminaryTime = null;
survey.ReviewerTime = null;
}
} }
var info = await GetSiteSurveyInfo(trialSiteSurveyId, trialId);
await _siteSurveyLogRepository.AddAsync(new SiteSurveyLog() { TrialSiteSurveyId = trialSiteSurveyId, Name = $"{_userInfo.FullName} ({_userInfo.UserName})", UserType = (UserTypeEnum)_userInfo.UserTypeEnumInt, OptType = SiteSurveyOptTyp.Reject, Reason = survey.LatestBackReason, Json = info.ToJsonStr() });
await _trialSiteSurveyRepository.SaveChangesAsync(); await _trialSiteSurveyRepository.SaveChangesAsync();
return ResponseOutput.Ok(); return ResponseOutput.Ok();
@ -547,6 +565,10 @@ namespace IRaCIS.Core.Application.Contracts
survey.IsDeleted = true; survey.IsDeleted = true;
var info = await GetSiteSurveyInfo(trialSiteSurveyId, survey.TrialId);
await _siteSurveyLogRepository.AddAsync(new SiteSurveyLog() { TrialSiteSurveyId = trialSiteSurveyId, Name = $"{_userInfo.FullName} ({_userInfo.UserName})", UserType = (UserTypeEnum)_userInfo.UserTypeEnumInt, OptType = SiteSurveyOptTyp.Over, Json = info.ToJsonStr() });
await _trialSiteSurveyRepository.SaveChangesAsync(); await _trialSiteSurveyRepository.SaveChangesAsync();
return ResponseOutput.Ok(); return ResponseOutput.Ok();
@ -612,6 +634,9 @@ namespace IRaCIS.Core.Application.Contracts
//从项目site 中找到已存在的 加到历史人员中 //从项目site 中找到已存在的 加到历史人员中
addSurvey.TrialSiteUserSurveyList = userList; addSurvey.TrialSiteUserSurveyList = userList;
//添加创建日志
addSurvey.SiteSurveyLogList.Add(new SiteSurveyLog() { Name = userInfo.EmailOrPhone, OptType = SiteSurveyOptTyp.Create });
currentEntity = await _trialSiteSurveyRepository.AddAsync(addSurvey); currentEntity = await _trialSiteSurveyRepository.AddAsync(addSurvey);
} }
@ -649,7 +674,7 @@ namespace IRaCIS.Core.Application.Contracts
//找到最新的调研表 //找到最新的调研表
var currentLatest = await _trialSiteSurveyRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId, true) var currentLatest = await _trialSiteSurveyRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId, true)
.Include(u => u.TrialSiteEquipmentSurveyList).Include(u => u.TrialSiteUserSurveyList).OrderByDescending(t => t.CreateTime).FirstOrDefaultAsync(); .Include(u => u.TrialSiteEquipmentSurveyList).Include(u => u.TrialSiteUserSurveyList).Include(t => t.SiteSurveyLogList).OrderByDescending(t => t.CreateTime).FirstOrDefaultAsync();
if (currentLatest == null) if (currentLatest == null)
{ {
@ -674,6 +699,11 @@ namespace IRaCIS.Core.Application.Contracts
{ {
} }
//更新调研表日志 - 老的调研表
var info1 = await GetSiteSurveyInfo(currentLatest.Id, currentLatest.TrialId);
currentLatest.SiteSurveyLogList.Add(new SiteSurveyLog() { Name = userInfo.ReplaceUserEmailOrPhone, OptType = SiteSurveyOptTyp.Over, Json = info1.ToJsonStr() });
var copy = currentLatest.Clone(); var copy = currentLatest.Clone();
copy.State = TrialSiteSurveyEnum.ToSubmit; copy.State = TrialSiteSurveyEnum.ToSubmit;
@ -685,10 +715,21 @@ namespace IRaCIS.Core.Application.Contracts
copy.Id = Guid.Empty; copy.Id = Guid.Empty;
copy.CreateTime = DateTime.Now; copy.CreateTime = DateTime.Now;
copy.PreliminaryUserId = null;
copy.ReviewerUserId = null;
copy.PreliminaryTime = null;
copy.ReviewerTime = null;
if (userInfo.ReplaceUserEmailOrPhone != userInfo.EmailOrPhone) if (userInfo.ReplaceUserEmailOrPhone != userInfo.EmailOrPhone)
{ {
copy.UserName = String.Empty; copy.UserName = String.Empty;
copy.Phone = String.Empty; copy.Phone = String.Empty;
//更新调研表日志
var info = await GetSiteSurveyInfo(currentLatest.Id, currentLatest.TrialId);
copy.SiteSurveyLogList.ForEach(t => { t.Id = Guid.Empty; });
copy.SiteSurveyLogList.Add(new SiteSurveyLog() { Name = userInfo.EmailOrPhone, OptType = SiteSurveyOptTyp.Update, OriginTrialSiteSurveyId = currentLatest.Id, Json = info.ToJsonStr() });
} }
@ -885,12 +926,25 @@ namespace IRaCIS.Core.Application.Contracts
} }
//审批调研表日志
var info = await GetSiteSurveyInfo(trialSiteSurveyId, trialId);
await _siteSurveyLogRepository.AddAsync(new SiteSurveyLog() { TrialSiteSurveyId = trialSiteSurveyId, Name = trialSiteSurvey.UserName, OptType = SiteSurveyOptTyp.Submit, Json = info.ToJsonStr() });
} }
else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM) else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM)
{ {
await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.CRCSubmitted, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.SPMApproved, PreliminaryUserId = _userInfo.UserRoleId, PreliminaryTime = DateTime.Now }); await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.CRCSubmitted, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.SPMApproved, PreliminaryUserId = _userInfo.UserRoleId, PreliminaryTime = DateTime.Now });
//审批调研表日志
var info = await GetSiteSurveyInfo(trialSiteSurveyId, trialId);
await _siteSurveyLogRepository.AddAsync(new SiteSurveyLog() { TrialSiteSurveyId = trialSiteSurveyId, Name = $"{_userInfo.FullName} ({_userInfo.UserName})", UserType = (UserTypeEnum)_userInfo.UserTypeEnumInt, OptType = SiteSurveyOptTyp.Approved, Json = info.ToJsonStr() });
} }
else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM) else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM)
{ {
@ -903,7 +957,16 @@ namespace IRaCIS.Core.Application.Contracts
//将历史锁定的调研表废弃 //将历史锁定的调研表废弃
await _trialSiteSurveyRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteSurvey.TrialSiteId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock && t.Id != trialSiteSurveyId, z => new TrialSiteSurvey() { IsDeleted = true }); await _trialSiteSurveyRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteSurvey.TrialSiteId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock && t.Id != trialSiteSurveyId, z => new TrialSiteSurvey() { IsDeleted = true });
//审批调研表日志
var info = await GetSiteSurveyInfo(trialSiteSurveyId, trialId);
await _siteSurveyLogRepository.AddAsync(new SiteSurveyLog() { TrialSiteSurveyId = trialSiteSurveyId, Name = $"{_userInfo.FullName} ({_userInfo.UserName})", UserType = (UserTypeEnum)_userInfo.UserTypeEnumInt, OptType = SiteSurveyOptTyp.Approved, Json = info.ToJsonStr() });
} }
await _trialSiteSurveyRepository.SaveChangesAsync(); await _trialSiteSurveyRepository.SaveChangesAsync();
return ResponseOutput.Ok(); return ResponseOutput.Ok();
} }
@ -1149,12 +1212,19 @@ namespace IRaCIS.Core.Application.Contracts
var queitUserTypeIdList = needQuitUserList.Select(t => t.UserTypeId).ToList(); var queitUserTypeIdList = needQuitUserList.Select(t => t.UserTypeId).ToList();
foreach (var item in needQuitUserList)
await _trialSiteUserRoleRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId && queitUserTypeIdList.Contains(t.UserRole.UserTypeId), c => new TrialSiteUserRole()
{ {
IsDeleted = true, await _trialSiteUserRoleRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId
DeletedTime = DateTime.Now, && t.UserRole.UserTypeId == item.UserTypeId
}); && t.UserRole.IdentityUserId == item.SystemUserId, c => new TrialSiteUserRole()
{
IsDeleted = true,
DeletedTime = DateTime.Now,
});
}
await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.SPMApproved, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.PMCreatedAndLock, ReviewerUserId = _userInfo.UserRoleId, ReviewerTime = DateTime.Now }); await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.SPMApproved, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.PMCreatedAndLock, ReviewerUserId = _userInfo.UserRoleId, ReviewerTime = DateTime.Now });
@ -1398,5 +1468,105 @@ namespace IRaCIS.Core.Application.Contracts
/// <summary>
/// 获取中心调研日志
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<SiteSurveyLogDTO>> GetSiteSurveyLogList(SiteSurveyLogQuery inQuery)
{
return _siteSurveyLogRepository.Where(t => t.TrialSiteSurveyId == inQuery.TrialSiteSurveyId)
.WhereIf(inQuery.Id != null, t => t.Id == inQuery.Id)
.ProjectTo<SiteSurveyLogDTO>(_mapper.ConfigurationProvider).OrderBy(t => t.CreateTime).ToList();
}
/// <summary>
/// 获取中心设备信息
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> GetSiteSurveyEquipmentList(SiteSurveyEquipmentQuery inQuery)
{
//找到该中心最新的调研记录
var groupSelectIdQuery =
_trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
.GroupBy(t => t.TrialSiteId)
.Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First());
var pageList = await _trialSiteEquipmentSurveyRepository.Where(t => t.TrialSiteSurvey.TrialId == inQuery.TrialId).IgnoreQueryFilters()
.Where(t => groupSelectIdQuery.Contains(t.TrialSiteSurveyId))
.WhereIf(inQuery.IsDeleted != null, t => t.TrialSiteSurvey.IsDeleted == inQuery.IsDeleted)
.WhereIf(inQuery.State != null, t => t.TrialSiteSurvey.State == inQuery.State)
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteSurvey.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.TrialSiteCode.IsNotNullOrEmpty(), t => t.TrialSiteSurvey.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode))
.WhereIf(inQuery.TrialSiteName.IsNotNullOrEmpty(), t => t.TrialSiteSurvey.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteName) ||
t.TrialSiteSurvey.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteName))
.ProjectTo<SiteSurveyEquipmentDto>(_mapper.ConfigurationProvider).ToPagedListAsync(inQuery);
var siteSurveryConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty;
var config = JsonConvert.DeserializeObject<TrialExtraConfig>(siteSurveryConfig) ?? new TrialExtraConfig();
return ResponseOutput.Ok(pageList, config);
}
/// <summary>
/// 调研表基本信息
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> GetSiteSurveyInfoList(SiteSurveyInfoQuery inQuery)
{
//找到该中心最新的调研记录
var groupSelectIdQuery =
_trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
.GroupBy(t => t.TrialSiteId)
.Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First());
var pageList = await _trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId).IgnoreQueryFilters()
.Where(t => groupSelectIdQuery.Contains(t.Id))
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
.WhereIf(inQuery.State != null, t => t.State == inQuery.State)
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.TrialSiteCode.IsNotNullOrEmpty(), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode))
.WhereIf(inQuery.TrialSiteName.IsNotNullOrEmpty(), t => t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteName) ||
t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteName))
.ProjectTo<TrialSiteSurveyView>(_mapper.ConfigurationProvider).ToPagedListAsync(inQuery);
var siteSurveryConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty;
var config = JsonConvert.DeserializeObject<TrialExtraConfig>(siteSurveryConfig) ?? new TrialExtraConfig();
return ResponseOutput.Ok(pageList, config);
}
/// <summary>
/// SPM 是否参与流程
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
public async Task<bool> GetTrialIsSPMJoin(Guid trialId)
{
var hasSPMOrCPM = await _trialRepository.Where(t => t.Id == trialId).AnyAsync(t => t.TrialIdentityUserList.SelectMany(t => t.TrialUserRoleList).Any(t =>
t.UserRole.IdentityUser.Status == UserStateEnum.Enable
&& t.UserRole.IsUserRoleDisabled == false
&& (t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM))
);
var isTrialSPMJoin = await _trialRepository.AnyAsync(t => t.Id == trialId && t.IsSPMJoinSiteSurvey);
var isSPMjoin = isTrialSPMJoin && hasSPMOrCPM;
return isSPMjoin;
}
} }
} }

View File

@ -98,6 +98,21 @@ namespace IRaCIS.Core.Application.AutoMapper
CreateMap<SiteSurveyUserImportDto, IdentityUser>(); CreateMap<SiteSurveyUserImportDto, IdentityUser>();
CreateMap<SiteSurveyLog, SiteSurveyLogDTO>();
CreateMap<TrialSiteEquipmentSurvey, SiteSurveyEquipmentDto>()
.ForMember(d => d.IsDeleted, u => u.MapFrom(s => s.TrialSiteSurvey.IsDeleted))
.ForMember(d => d.State, u => u.MapFrom(s => s.TrialSiteSurvey.State))
.ForMember(d => d.Email, u => u.MapFrom(s => s.TrialSiteSurvey.Email))
.ForMember(d => d.Phone, u => u.MapFrom(s => s.TrialSiteSurvey.Phone))
.ForMember(d => d.UserName, u => u.MapFrom(s => s.TrialSiteSurvey.UserName))
.ForMember(d => d.TrialSiteAliasName, u => u.MapFrom(s => s.TrialSiteSurvey.TrialSite.TrialSiteAliasName))
.ForMember(d => d.TrialSiteName, u => u.MapFrom(s => s.TrialSiteSurvey.TrialSite.TrialSiteName))
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSiteSurvey.TrialSite.TrialSiteCode));
} }
} }
} }

View File

@ -3381,6 +3381,11 @@ namespace IRaCIS.Core.Domain.Share
/// </summary> /// </summary>
PercentageDifference = 5, PercentageDifference = 5,
/// <summary>
/// 不适用
/// </summary>
NotApplicable = 6,
} }

View File

@ -316,6 +316,11 @@ public class VisitTask : BaseFullAuditEntity
/// </summary> /// </summary>
public bool IsCopyLesionAnswer { get; set; } = false; public bool IsCopyLesionAnswer { get; set; } = false;
/// <summary>
/// 是否计算过裁判
/// </summary>
public bool IsCalculatedJudge { get; set; } = false;
#region 完全随机增加字段 #region 完全随机增加字段
[Comment("完全随机阅片号")] [Comment("完全随机阅片号")]

View File

@ -196,6 +196,73 @@ public class ReadingQuestionCriterionTrial : BaseAddAuditEntity
/// 定圆工具默认半径 /// 定圆工具默认半径
/// </summary> /// </summary>
public decimal CircleRadius { get; set; } = 10; public decimal CircleRadius { get; set; } = 10;
/// <summary>
/// 仲裁模式
/// </summary>
public JudgeMode JudgeModeEnum { get; set; } = JudgeMode.SelectOne;
/// <summary>
/// 裁判规则
/// </summary>
public JudgeRule JudgeRuleEnum { get; set; } = JudgeRule.Consistent;
/// <summary>
/// 裁判任务生成
/// </summary>
public JudgeGenerate JudgeGenerateEnum { get; set; } = JudgeGenerate.Instant;
}
/// <summary>
/// 裁判任务生成时间
/// </summary>
public enum JudgeGenerate
{
/// <summary>
/// 及时
/// </summary>
Instant = 0,
/// <summary>
/// 阶段性
/// </summary>
Phased = 1,
}
/// <summary>
/// 仲裁模式
/// </summary>
public enum JudgeMode
{
/// <summary>
/// 整体结果择一判定
/// </summary>
SelectOne = 0,
/// <summary>
/// 指标组合判定
/// </summary>
Combined = 1,
}
/// <summary>
/// 裁判规则
/// </summary>
public enum JudgeRule
{
/// <summary>
/// 跨访视一致规则
/// </summary>
Consistent = 0,
/// <summary>
/// 访视间差异规则
/// </summary>
Difference = 1,
} }

View File

@ -0,0 +1,67 @@
using IRaCIS.Core.Domain.Share;
using System.Linq;
namespace IRaCIS.Core.Domain.Models;
[Comment("项目阅片访视裁判规则")]
[Table("ReadingQuestionVisitJudgeRule")]
public class ReadingQuestionVisitJudgeRule : BaseAddAuditEntity
{
#region 导航属性
[Comment("分页标准")]
[ForeignKey("ReadingQuestionId")]
[JsonIgnore]
public ReadingQuestionTrial ReadingQuestionTrial { get; set; }
#endregion
/// <summary>
/// 问题Id
/// </summary>
[Comment("问题Id")]
public Guid ReadingQuestionId { get; set; }
/// <summary>
/// 访视Num
/// </summary>
public decimal VisitNum { get; set; }
/// <summary>
/// 答案分组
/// </summary>
[MaxLength]
[Comment("答案分组")]
public List<string> AnswerGroup { get; set; } = new List<string>();
/// <summary>
/// 答案组合
/// </summary>
[Comment("答案组合")]
[MaxLength]
public List<AnswerCombinationDto> AnswerCombination { get; set; } = new List<AnswerCombinationDto>();
/// <summary>
/// 裁判类型
/// </summary>
[Comment("裁判类型")]
public JudgeTypeEnum JudgeType { get; set; } = JudgeTypeEnum.AnswerDisaffinity;
/// <summary>
/// 裁判百分比或绝对值的相差值
/// </summary>
[Comment("裁判百分比或绝对值的相差值")]
public decimal? JudgeDifferenceValue { get; set; } = 0;
/// <summary>
/// 裁判百分比或绝对值的相差值匹配规则
/// </summary>
[Comment("裁判百分比或绝对值的相差值匹配规则")]
public JudgeDifferenceType JudgeDifferenceType { get; set; }
}
public class AnswerCombinationDto
{
public List<string> AnswerGroupA { get; set; }
public List<string> AnswerGroupB { get; set; }
}

View File

@ -23,6 +23,10 @@ public class TrialSiteSurvey : BaseFullDeleteAuditEntity
[JsonIgnore] [JsonIgnore]
public CommonUploadRecord SiteSurveyFile { get; set; } public CommonUploadRecord SiteSurveyFile { get; set; }
[JsonIgnore]
public List<SiteSurveyLog> SiteSurveyLogList { get; set; }=new List<SiteSurveyLog>();
#endregion #endregion
public Guid TrialSiteId { get; set; } public Guid TrialSiteId { get; set; }
@ -64,7 +68,7 @@ public class TrialSiteSurvey : BaseFullDeleteAuditEntity
public bool? IsRoutineMRIPDEE { get; set; } public bool? IsRoutineMRIPDEE { get; set; }
[Comment("MRI-PDFF 单次检查时长")] [Comment("MRI-PDFF 单次检查时长")]
public string MRIPDFFScanTime { get; set; } public string MRIPDFFScanTime { get; set; }
[Comment("MRI-PDFF 预约等待时长")] [Comment("MRI-PDFF 预约等待时长")]
public string MRIPDFFLeadTime { get; set; } public string MRIPDFFLeadTime { get; set; }
@ -88,3 +92,43 @@ public class TrialSiteSurvey : BaseFullDeleteAuditEntity
public string NotStrictManualBurnFlagReason { get; set; } public string NotStrictManualBurnFlagReason { get; set; }
} }
public class SiteSurveyLog : BaseAddAuditEntity
{
[JsonIgnore]
[ForeignKey("TrialSiteSurveyId")]
public TrialSiteSurvey TrialSiteSurvey { get; set; }
public Guid TrialSiteSurveyId { get; set; }
public string Name { get; set; }
public UserTypeEnum UserType { get; set; }
public SiteSurveyOptTyp OptType { get; set; }
public string Reason { get; set; }
[MaxLength]
public string Json { get; set; }
[Comment("更新调研表之前的调研表")]
public Guid? OriginTrialSiteSurveyId { get; set; }
}
public enum SiteSurveyOptTyp
{
Create = 0,
Submit = 1,
Approved = 2,
Reject = 3,
Update = 4,
Over=5,
}

View File

@ -119,6 +119,14 @@ public class IRaCISDBContext : DbContext
); );
}); });
modelBuilder.Entity<ReadingQuestionVisitJudgeRule>(entity =>
{
entity.Property(e => e.AnswerCombination).HasConversion(
v => v == null ? null : JsonConvert.SerializeObject(v),
v => string.IsNullOrEmpty(v) ? new List<AnswerCombinationDto>() { } : JsonConvert.DeserializeObject<List<AnswerCombinationDto>>(v)
);
});
#region pgsql codefirst 配置 暂时屏蔽 #region pgsql codefirst 配置 暂时屏蔽
//if (base.Database.IsNpgsql()) //if (base.Database.IsNpgsql())
//{ //{
@ -421,6 +429,8 @@ public class IRaCISDBContext : DbContext
public virtual DbSet<ReadingQuestionTrial> ReadingQuestionTrial { get; set; } public virtual DbSet<ReadingQuestionTrial> ReadingQuestionTrial { get; set; }
public virtual DbSet<ReadingQuestionVisitJudgeRule> ReadingQuestionVisitJudgeRule { get; set; }
public virtual DbSet<ReadingClinicalDataPDF> ReadingClinicalDataPDF { get; set; } public virtual DbSet<ReadingClinicalDataPDF> ReadingClinicalDataPDF { get; set; }
public virtual DbSet<ReadingConsistentClinicalData> ReadingConsistentClinicalData { get; set; } public virtual DbSet<ReadingConsistentClinicalData> ReadingConsistentClinicalData { get; set; }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,61 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace IRaCIS.Core.Infra.EFCore.Migrations
{
/// <inheritdoc />
public partial class siteSurveylog : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "SiteSurveyLog",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TrialSiteSurveyId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(400)", maxLength: 400, nullable: false),
UserType = table.Column<int>(type: "int", nullable: false),
OptType = table.Column<int>(type: "int", nullable: false),
Reason = table.Column<string>(type: "nvarchar(400)", maxLength: 400, nullable: false),
Json = table.Column<string>(type: "nvarchar(max)", nullable: false),
OriginTrialSiteSurveyId = table.Column<Guid>(type: "uniqueidentifier", nullable: true, comment: "更新调研表之前的调研表"),
CreateUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
CreateTime = table.Column<DateTime>(type: "datetime2", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_SiteSurveyLog", x => x.Id)
.Annotation("SqlServer:Clustered", false);
table.ForeignKey(
name: "FK_SiteSurveyLog_TrialSiteSurvey_TrialSiteSurveyId",
column: x => x.TrialSiteSurveyId,
principalTable: "TrialSiteSurvey",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_SiteSurveyLog_User_CreateUserId",
column: x => x.CreateUserId,
principalTable: "User",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_SiteSurveyLog_CreateTime",
table: "SiteSurveyLog",
column: "CreateTime")
.Annotation("SqlServer:Clustered", true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "SiteSurveyLog");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,95 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace IRaCIS.Core.Infra.EFCore.Migrations
{
/// <inheritdoc />
public partial class JudgeRule : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsCalculatedJudge",
table: "VisitTask",
type: "bit",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<int>(
name: "JudgeGenerateEnum",
table: "ReadingQuestionCriterionTrial",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "JudgeModeEnum",
table: "ReadingQuestionCriterionTrial",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "JudgeRuleEnum",
table: "ReadingQuestionCriterionTrial",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateTable(
name: "ReadingQuestionVisitJudgeRule",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
ReadingQuestionId = table.Column<Guid>(type: "uniqueidentifier", nullable: false, comment: "问题Id"),
VisitNum = table.Column<decimal>(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
AnswerGroup = table.Column<string>(type: "nvarchar(max)", nullable: false, comment: "答案分组"),
AnswerCombination = table.Column<string>(type: "nvarchar(max)", nullable: false, comment: "答案组合"),
JudgeType = table.Column<int>(type: "int", nullable: false, comment: "裁判类型"),
JudgeDifferenceValue = table.Column<decimal>(type: "decimal(18,2)", precision: 18, scale: 2, nullable: true, comment: "裁判百分比或绝对值的相差值"),
JudgeDifferenceType = table.Column<int>(type: "int", nullable: false, comment: "裁判百分比或绝对值的相差值匹配规则"),
CreateUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
CreateTime = table.Column<DateTime>(type: "datetime2", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ReadingQuestionVisitJudgeRule", x => x.Id)
.Annotation("SqlServer:Clustered", false);
},
comment: "项目阅片访视裁判规则");
migrationBuilder.CreateIndex(
name: "IX_ReadingQuestionVisitJudgeRule_CreateTime",
table: "ReadingQuestionVisitJudgeRule",
column: "CreateTime")
.Annotation("SqlServer:Clustered", true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ReadingQuestionVisitJudgeRule");
migrationBuilder.DropColumn(
name: "IsCalculatedJudge",
table: "VisitTask");
migrationBuilder.DropColumn(
name: "JudgeGenerateEnum",
table: "ReadingQuestionCriterionTrial");
migrationBuilder.DropColumn(
name: "JudgeModeEnum",
table: "ReadingQuestionCriterionTrial");
migrationBuilder.DropColumn(
name: "JudgeRuleEnum",
table: "ReadingQuestionCriterionTrial");
}
}
}

View File

@ -6834,6 +6834,15 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.HasColumnType("bit") .HasColumnType("bit")
.HasComment("eCRF报告是否显示在图像页面"); .HasComment("eCRF报告是否显示在图像页面");
b.Property<int>("JudgeGenerateEnum")
.HasColumnType("int");
b.Property<int>("JudgeModeEnum")
.HasColumnType("int");
b.Property<int>("JudgeRuleEnum")
.HasColumnType("int");
b.Property<DateTime?>("ReadingInfoSignTime") b.Property<DateTime?>("ReadingInfoSignTime")
.HasColumnType("datetime2") .HasColumnType("datetime2")
.HasComment("阅片信息签名时间"); .HasComment("阅片信息签名时间");
@ -7466,6 +7475,62 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
}); });
}); });
modelBuilder.Entity("IRaCIS.Core.Domain.Models.ReadingQuestionVisitJudgeRule", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.PrimitiveCollection<string>("AnswerCombination")
.IsRequired()
.HasColumnType("nvarchar(max)")
.HasComment("答案组合");
b.PrimitiveCollection<string>("AnswerGroup")
.IsRequired()
.HasColumnType("nvarchar(max)")
.HasComment("答案分组");
b.Property<DateTime>("CreateTime")
.HasColumnType("datetime2");
b.Property<Guid>("CreateUserId")
.HasColumnType("uniqueidentifier");
b.Property<int>("JudgeDifferenceType")
.HasColumnType("int")
.HasComment("裁判百分比或绝对值的相差值匹配规则");
b.Property<decimal?>("JudgeDifferenceValue")
.HasPrecision(18, 2)
.HasColumnType("decimal(18,2)")
.HasComment("裁判百分比或绝对值的相差值");
b.Property<int>("JudgeType")
.HasColumnType("int")
.HasComment("裁判类型");
b.Property<Guid>("ReadingQuestionId")
.HasColumnType("uniqueidentifier")
.HasComment("问题Id");
b.Property<decimal>("VisitNum")
.HasPrecision(18, 2)
.HasColumnType("decimal(18,2)");
b.HasKey("Id");
SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
b.HasIndex("CreateTime");
SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
b.ToTable("ReadingQuestionVisitJudgeRule", t =>
{
t.HasComment("项目阅片访视裁判规则");
});
});
modelBuilder.Entity("IRaCIS.Core.Domain.Models.ReadingSystemCriterionDictionary", b => modelBuilder.Entity("IRaCIS.Core.Domain.Models.ReadingSystemCriterionDictionary", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")
@ -9827,6 +9892,55 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
}); });
}); });
modelBuilder.Entity("IRaCIS.Core.Domain.Models.SiteSurveyLog", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreateTime")
.HasColumnType("datetime2");
b.Property<Guid>("CreateUserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Json")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<int>("OptType")
.HasColumnType("int");
b.Property<Guid?>("OriginTrialSiteSurveyId")
.HasColumnType("uniqueidentifier")
.HasComment("更新调研表之前的调研表");
b.Property<string>("Reason")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<Guid>("TrialSiteSurveyId")
.HasColumnType("uniqueidentifier");
b.Property<int>("UserType")
.HasColumnType("int");
b.HasKey("Id");
SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
b.HasIndex("CreateTime");
SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
b.ToTable("SiteSurveyLog");
});
modelBuilder.Entity("IRaCIS.Core.Domain.Models.Sponsor", b => modelBuilder.Entity("IRaCIS.Core.Domain.Models.Sponsor", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")
@ -16633,6 +16747,9 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.HasColumnType("bit") .HasColumnType("bit")
.HasComment("阅片结果是否和原数据有差异"); .HasComment("阅片结果是否和原数据有差异");
b.Property<bool>("IsCalculatedJudge")
.HasColumnType("bit");
b.Property<bool>("IsCanEditUrgentState") b.Property<bool>("IsCanEditUrgentState")
.HasColumnType("bit") .HasColumnType("bit")
.HasComment("是否和编辑加急状态"); .HasComment("是否和编辑加急状态");
@ -18978,6 +19095,25 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
b.Navigation("RelevanceReadingQuestionTrial"); b.Navigation("RelevanceReadingQuestionTrial");
}); });
modelBuilder.Entity("IRaCIS.Core.Domain.Models.ReadingQuestionVisitJudgeRule", b =>
{
b.HasOne("IRaCIS.Core.Domain.Models.UserRole", "CreateUserRole")
.WithMany()
.HasForeignKey("CreateUserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("IRaCIS.Core.Domain.Models.ReadingQuestionTrial", "ReadingQuestionTrial")
.WithMany()
.HasForeignKey("ReadingQuestionId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CreateUserRole");
b.Navigation("ReadingQuestionTrial");
});
modelBuilder.Entity("IRaCIS.Core.Domain.Models.ReadingSystemCriterionDictionary", b => modelBuilder.Entity("IRaCIS.Core.Domain.Models.ReadingSystemCriterionDictionary", b =>
{ {
b.HasOne("IRaCIS.Core.Domain.Models.UserRole", "CreateUserRole") b.HasOne("IRaCIS.Core.Domain.Models.UserRole", "CreateUserRole")
@ -19563,6 +19699,25 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
b.Navigation("Hospital"); b.Navigation("Hospital");
}); });
modelBuilder.Entity("IRaCIS.Core.Domain.Models.SiteSurveyLog", b =>
{
b.HasOne("IRaCIS.Core.Domain.Models.UserRole", "CreateUserRole")
.WithMany()
.HasForeignKey("CreateUserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("IRaCIS.Core.Domain.Models.TrialSiteSurvey", "TrialSiteSurvey")
.WithMany("SiteSurveyLogList")
.HasForeignKey("TrialSiteSurveyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CreateUserRole");
b.Navigation("TrialSiteSurvey");
});
modelBuilder.Entity("IRaCIS.Core.Domain.Models.Sponsor", b => modelBuilder.Entity("IRaCIS.Core.Domain.Models.Sponsor", b =>
{ {
b.HasOne("IRaCIS.Core.Domain.Models.UserRole", "CreateUserRole") b.HasOne("IRaCIS.Core.Domain.Models.UserRole", "CreateUserRole")
@ -22356,6 +22511,8 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
modelBuilder.Entity("IRaCIS.Core.Domain.Models.TrialSiteSurvey", b => modelBuilder.Entity("IRaCIS.Core.Domain.Models.TrialSiteSurvey", b =>
{ {
b.Navigation("SiteSurveyLogList");
b.Navigation("TrialSiteEquipmentSurveyList"); b.Navigation("TrialSiteEquipmentSurveyList");
b.Navigation("TrialSiteUserSurveyList"); b.Navigation("TrialSiteUserSurveyList");

View File

@ -64,6 +64,11 @@ namespace IRaCIS.Core.Infrastructure.Extention
/// </summary> /// </summary>
NotRemind = -4, NotRemind = -4,
/// <summary>
/// 后端异常 不提醒
/// </summary>
BackEndAnomaly=-5,
} }

View File

@ -325,7 +325,11 @@ public static class StaticData
public const string TrialVisit_InfluenceStudys_Export = "TrialVisit_InfluenceStudys_Export"; public const string TrialVisit_InfluenceStudys_Export = "TrialVisit_InfluenceStudys_Export";
public const string TrialSiteSurvey_BasicInfo_Export = "TrialSiteSurvey_BasicInfo_Export";
public const string TrialSiteSurvey_Info_Export = "TrialSiteSurvey_Info_Export";
public const string TrialSiteSurvey_Equipment_Export = "TrialSiteSurvey_Equipment_Export";
} }