Compare commits
129 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4b21ef4f14 | |||
| 1e2869abb5 | |||
| 8bd46c6c18 | |||
| f7b4382a62 | |||
| 63d3ca4971 | |||
| 29518ddea6 | |||
| 20dd2ffd5d | |||
| e406511755 | |||
| e4abc61456 | |||
| c0c4df1254 | |||
| cc826afff1 | |||
| 53c18c4c4c | |||
| 0c9f29d3b4 | |||
| 14f03facd2 | |||
| b469be1b14 | |||
| c3e5b0c4b8 | |||
| 5ee992efb4 | |||
| 44b28f2d0a | |||
| b1db5bebd3 | |||
| 3f3caaaffe | |||
| b3d5b5f75e | |||
| ee5708f905 | |||
| 140a7bb3fd | |||
| 65ac1498b1 | |||
| 0f15eaabff | |||
| 54c8f71af7 | |||
| b31178c0c0 | |||
| 0af6919b5a | |||
| 393c915884 | |||
| ed274d2812 | |||
| 072e076bea | |||
| d6b5badccd | |||
| d237da548f | |||
| dee6bebcb7 | |||
| 40a98048bb | |||
| 1ea978eccd | |||
| bc8aeb8d7c | |||
| c35ec016dd | |||
| 283524cb4f | |||
| 10c9f6b8cc | |||
| e291953d09 | |||
| 1094c8ce2a | |||
| 747bb29729 | |||
| 4cab822a52 | |||
| adaa085e56 | |||
| 1f97243482 | |||
| b272a748ec | |||
| b121db89f0 | |||
| 35e6a47f2d | |||
| afeebf662b | |||
| 23ae346cee | |||
| d52c23b5c4 | |||
| 70e851e10d | |||
| a371db7522 | |||
| b755d12d7c | |||
| 30e3a363a8 | |||
| 6f692c34c2 | |||
| 6dac36ba1a | |||
| 2623a42ea7 | |||
| 8613c0a064 | |||
| e159f8a82b | |||
| 416793018f | |||
| c714a81edf | |||
| d9b5298572 | |||
| 38ec3d55ae | |||
| 046715fd07 | |||
| 07bd02d3c8 | |||
| b6ad1722f6 | |||
| 240b8218f0 | |||
| 8345b5b47d | |||
| 54f6fc1b12 | |||
| 2b59cb5d02 | |||
| d9d0ceac76 | |||
| 35400b4952 | |||
| 1d33619a85 | |||
| a4f3c4bb81 | |||
| 166c5f3f9c | |||
| 54c7e6cc7c | |||
| 859c9e4161 | |||
| b33fb79718 | |||
| 24faa2d887 | |||
| e9d3dda160 | |||
| 53ad439257 | |||
| d577410bb4 | |||
| df0e4ddcfa | |||
| 9948ea8df3 | |||
| 763220dcef | |||
| 208dab27dc | |||
| 3c816e989e | |||
| c44c333997 | |||
| 5fc700123f | |||
| 49437034a3 | |||
| 74486c8e30 | |||
| d6fc7f7911 | |||
| 2b5066f967 | |||
| a577589a92 | |||
| 62f02528c2 | |||
| 5b950914e3 | |||
| 99942982f6 | |||
| 18e9005c3d | |||
| d9f6dd22e1 | |||
| f5579c3deb | |||
| 60c0c66d22 | |||
| a2c17da35e | |||
| 20f46f2dab | |||
| cbf63c0f9c | |||
| f3db7525f9 | |||
| 694325e6b9 | |||
| 138702f077 | |||
| a739f856b4 | |||
| 68af0578d0 | |||
| 9042017a90 | |||
| 59b053faa9 | |||
| 63b9f4e775 | |||
| efe2e7f063 | |||
| 19b1d022e0 | |||
| 9e1372dc01 | |||
| a6a409c750 | |||
| fdcb81306d | |||
| ff395f1d56 | |||
| e346593ebb | |||
| fab6c8c55a | |||
| 282e56e5fc | |||
| a600f11422 | |||
| 2db4a293ed | |||
| 8641a11b53 | |||
| 980248d899 | |||
| 372ee55241 | |||
| ed8d2e285f |
@@ -89,7 +89,6 @@ public class FileUploadRecordService(IRepository<FileUploadRecord> _fileUploadRe
|
||||
|
||||
public async Task<IResponseOutput> AddOrUpdateFileUploadRecord(FileUploadRecordAddOrEdit addOrEditFileUploadRecord)
|
||||
{
|
||||
return ResponseOutput.Ok();
|
||||
|
||||
addOrEditFileUploadRecord.IP = _userInfo.IP;
|
||||
|
||||
|
||||
@@ -351,6 +351,23 @@ namespace IRaCIS.Core.API.Controllers
|
||||
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>
|
||||
/// 配置 基础逻辑信息并确认
|
||||
|
||||
@@ -213,6 +213,13 @@
|
||||
<param name="opt"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.SubmitJudgeForm(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.SetJudgeFormInDto})">
|
||||
<summary>
|
||||
提交阅片裁判表单
|
||||
</summary>
|
||||
<param name="opt"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.ConfigTrialBasicInfoConfirm(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Contracts.BasicTrialConfig})">
|
||||
<summary>
|
||||
配置 基础逻辑信息并确认
|
||||
|
||||
@@ -4,30 +4,16 @@ using IRaCIS.Core.API.HostService;
|
||||
using IRaCIS.Core.Application.BusinessFilter;
|
||||
using IRaCIS.Core.Application.BusinessFilter.LegacyController.Database.Api;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Application.MassTransit.Consumer;
|
||||
using IRaCIS.Core.Application.Service;
|
||||
using IRaCIS.Core.Application.Service.BusinessFilter;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using MassTransit;
|
||||
using MassTransit.NewIdProviders;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using UAParser;
|
||||
|
||||
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
|
||||
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
|
||||
@@ -95,6 +81,8 @@ builder.Services.AddSingleton<FileSyncQueue>();
|
||||
builder.Services.AddHostedService<SyncFileRecoveryService>();
|
||||
builder.Services.AddHostedService<FileSyncWorker>();
|
||||
|
||||
builder.Services.AddSingleton(_ => Parser.GetDefault());
|
||||
|
||||
//minimal api 异常处理
|
||||
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
|
||||
//builder.Services.AddProblemDetails();
|
||||
|
||||
@@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Serilog;
|
||||
using System.Linq;
|
||||
using UAParser;
|
||||
|
||||
namespace IRaCIS.Core.API
|
||||
{
|
||||
@@ -17,11 +18,14 @@ namespace IRaCIS.Core.API
|
||||
{
|
||||
app.UseMiddleware<RequestResponseLoggingMiddleware>();
|
||||
|
||||
// 从 DI 容器中获取 Parser 实例
|
||||
var uaParser = app.ApplicationServices.GetRequiredService<Parser>();
|
||||
|
||||
app.UseSerilogRequestLogging(opts
|
||||
=>
|
||||
{
|
||||
|
||||
opts.MessageTemplate = "{FullName} {UserType} {UserIp} {Host} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
|
||||
opts.MessageTemplate = "{FullName} {UserType} {UserIp} {Host} {RequestMethod} {RequestPath}{QueryString} {RequestBody} {OS} {Browser} {DeviceType} responded {StatusCode} in {Elapsed:0.0000} ms";
|
||||
|
||||
opts.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
|
||||
{
|
||||
@@ -33,10 +37,9 @@ namespace IRaCIS.Core.API
|
||||
|
||||
|
||||
// Only set it if available. You're not sending sensitive data in a querystring right?!
|
||||
if (request.QueryString.HasValue)
|
||||
{
|
||||
diagnosticContext.Set("QueryString", request.QueryString.Value);
|
||||
}
|
||||
|
||||
diagnosticContext.Set("QueryString", request.QueryString.Value ?? "");
|
||||
|
||||
|
||||
diagnosticContext.Set("FullName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.FullName)?.Value);
|
||||
|
||||
@@ -52,6 +55,38 @@ namespace IRaCIS.Core.API
|
||||
|
||||
diagnosticContext.Set("UserIp", clientIp);
|
||||
|
||||
|
||||
// ==================== 新增:解析 User-Agent ====================
|
||||
try
|
||||
{
|
||||
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
|
||||
|
||||
if (!string.IsNullOrEmpty(userAgent))
|
||||
{
|
||||
var clientInfo = uaParser.Parse(userAgent);
|
||||
|
||||
diagnosticContext.Set("OS", clientInfo.OS.ToString());
|
||||
diagnosticContext.Set("Browser", clientInfo.UA.ToString());
|
||||
//diagnosticContext.Set("DeviceType", clientInfo.Device.ToString());
|
||||
diagnosticContext.Set("DeviceType", userAgent.Contains("Mobile") ? "Mobile": "Desktop");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
diagnosticContext.Set("OS", "Unknown");
|
||||
diagnosticContext.Set("Browser", "Unknown");
|
||||
diagnosticContext.Set("DeviceType", "Unknown");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 解析失败时记录异常,但不要影响主流程
|
||||
diagnosticContext.Set("OS", "ParseError");
|
||||
diagnosticContext.Set("Browser", "ParseError");
|
||||
diagnosticContext.Set("DeviceType", "ParseError");
|
||||
}
|
||||
// ==============================================================
|
||||
|
||||
#region 非必要不记录
|
||||
//diagnosticContext.Set("Protocol", request.Protocol);
|
||||
//diagnosticContext.Set("Scheme", request.Scheme);
|
||||
|
||||
@@ -44,11 +44,11 @@
|
||||
"RegionId": "cn-shanghai",
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tFUCCmz5TwghZHsj45Y",
|
||||
"AccessKeySecret": "8evrBy1fVfzJG25i67Jm0xqn9Xcw2T",
|
||||
"RoleArn": "acs:ram::1078130221702011:role/uat-oss-access",
|
||||
"BucketName": "tl-med-irc-event-store",
|
||||
"ViewEndpoint": "https://tl-med-rc-event-cache.oss-cn-shanghai.aliyuncs.com",
|
||||
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
|
||||
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
|
||||
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
|
||||
"BucketName": "zy-irc-store",
|
||||
"ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
|
||||
"Region": "oss-cn-shanghai",
|
||||
"DurationSeconds": 7200
|
||||
},
|
||||
@@ -70,7 +70,7 @@
|
||||
"OpenUserComplexPassword": true,
|
||||
"OpenSignDocumentBeforeWork": true,
|
||||
|
||||
"OpenLoginLimit": false,
|
||||
"OpenLoginLimit": true,
|
||||
"LoginMaxFailCount": 5,
|
||||
"LoginFailLockMinutes": 30,
|
||||
"AutoLoginOutMinutes": 120,
|
||||
@@ -96,7 +96,7 @@
|
||||
"FromEmail": "irc@extimaging.com",
|
||||
"FromName": "EIC Imaging System",
|
||||
"AuthorizationCode": "ExtImg@2022",
|
||||
"SiteUrl": "http://irc.extimaging.com/login",
|
||||
"SiteUrl": "http://irc.event.extimaging.com/login",
|
||||
|
||||
"PlatformName": "EICS",
|
||||
"PlatformNameCN": "展影云平台",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
"IsOpenStoreSync": false,
|
||||
"IsOpenStoreSync": true,
|
||||
"ApiDeployRegion": "CN",
|
||||
"SyncConfigList": [
|
||||
{
|
||||
@@ -41,7 +41,7 @@
|
||||
"Target": "AliyunOSS",
|
||||
"UploadRegion": "US",
|
||||
"TargetRegion": "CN",
|
||||
"IsOpenSync": false
|
||||
"IsOpenSync": true
|
||||
}
|
||||
],
|
||||
"AliyunOSS": {
|
||||
@@ -127,5 +127,6 @@
|
||||
"DuplicationWindowMs": 500,
|
||||
"CacheTimeSeconds": 5,
|
||||
"ExcludedPaths": []
|
||||
}
|
||||
},
|
||||
"FrontWebConfig": "222"
|
||||
}
|
||||
+6
-6
@@ -37,13 +37,13 @@ public class TrialGlobalLimitActionFilter(IFusionCache _fusionCache, IUserInfo _
|
||||
|
||||
#region 特殊用户类型拦截
|
||||
// 用户类型检查
|
||||
//if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA && _userInfo.RequestUrl.ToLower() != "TrialDocument/userConfirm".ToLower())
|
||||
//{
|
||||
// //对不起,您的账户没有操作权限
|
||||
// context.Result = new JsonResult(ResponseOutput.NotOk(I18n.T("TrialResource_NoAccessPermission")));
|
||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA && _userInfo.RequestUrl.ToLower() != "TrialDocument/userConfirm".ToLower())
|
||||
{
|
||||
//对不起,您的账户没有操作权限
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(I18n.T("TrialResource_NoAccessPermission")));
|
||||
|
||||
// return;
|
||||
//}
|
||||
return;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
@@ -47,12 +47,12 @@ public class TrialGlobalLimitEndpointFilter(IFusionCache _fusionCache, IUserInfo
|
||||
}
|
||||
|
||||
#region 特殊用户类型拦截
|
||||
//// 用户类型检查
|
||||
//if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA && _userInfo.RequestUrl.ToLower() != "TrialDocument/userConfirm".ToLower())
|
||||
//{
|
||||
// //对不起,您的账户没有操作权限
|
||||
// return Results.Json(ResponseOutput.NotOk(I18n.T("TrialResource_NoAccessPermission")));
|
||||
//}
|
||||
// 用户类型检查
|
||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA && _userInfo.RequestUrl.ToLower() != "TrialDocument/userConfirm".ToLower())
|
||||
{
|
||||
//对不起,您的账户没有操作权限
|
||||
return Results.Json(ResponseOutput.NotOk(I18n.T("TrialResource_NoAccessPermission")));
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public static class ExcelExportHelper
|
||||
/// <param name="translateType"></param>
|
||||
/// <param name="criterionType"></param>
|
||||
/// <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;
|
||||
|
||||
@@ -136,7 +136,7 @@ public static class ExcelExportHelper
|
||||
#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();
|
||||
@@ -158,6 +158,17 @@ public static class ExcelExportHelper
|
||||
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)
|
||||
{
|
||||
@@ -930,17 +941,17 @@ public static class ExcelExportHelper
|
||||
|
||||
int sheetCount = workbook.Worksheets.Count;
|
||||
|
||||
if (sheetCount == 2)
|
||||
//if (sheetCount == 2)
|
||||
//{
|
||||
if (inDto.IsEnglish)
|
||||
{
|
||||
if (inDto.IsEnglish)
|
||||
{
|
||||
workbook.Worksheet(1).Delete(); // 删除第一个工作表
|
||||
}
|
||||
else
|
||||
{
|
||||
workbook.Worksheet(2).Delete(); // 删除第二个工作表
|
||||
}
|
||||
workbook.Worksheet(1).Delete(); // 删除第一个工作表
|
||||
}
|
||||
else
|
||||
{
|
||||
workbook.Worksheet(2).Delete(); // 删除第二个工作表
|
||||
}
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -1080,12 +1080,15 @@ public static class DicomSortHelper
|
||||
IEnumerable<T> source,
|
||||
Func<T, string?> ippSelector,
|
||||
Func<T, string?> iopSelector,
|
||||
Func<T, int?> instanceNumberSelector)
|
||||
Func<T, int?> instanceNumberSelector,string seriesDescription)
|
||||
{
|
||||
var list = source.ToList();
|
||||
if (list.Count < 2)
|
||||
return list;
|
||||
|
||||
if(seriesDescription.Contains("Dixon", StringComparison.OrdinalIgnoreCase))
|
||||
return list.OrderBy(instanceNumberSelector).ToList();
|
||||
|
||||
var first = list[0];
|
||||
|
||||
var reference = ParseVector(ippSelector(first));
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<param name="next"></param>
|
||||
<returns></returns>
|
||||
</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>
|
||||
@@ -579,6 +579,12 @@
|
||||
<param name="emailConfig"></param>
|
||||
<returns></returns>
|
||||
</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">
|
||||
<summary>
|
||||
方案编号 STUDYID
|
||||
@@ -849,6 +855,20 @@
|
||||
裁决日期 CODTC
|
||||
</summary>
|
||||
</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)">
|
||||
<summary>
|
||||
质控问题答案导出
|
||||
@@ -1767,7 +1787,7 @@
|
||||
<param name="_trialRepository"></param>
|
||||
<param name="_oSSService"></param>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.TrialImageDownloadService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Application.Helper.IOSSService,Microsoft.AspNetCore.Hosting.IWebHostEnvironment,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomSeries},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance})">
|
||||
<member name="M:IRaCIS.Core.Application.Service.TrialImageDownloadService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Application.Helper.IOSSService,Microsoft.AspNetCore.Hosting.IWebHostEnvironment,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomSeries},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask})">
|
||||
<summary>
|
||||
项目影像后台下载,不打包
|
||||
</summary>
|
||||
@@ -2940,11 +2960,11 @@
|
||||
<param name="modality"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.DownloadAndUploadService.DownloadImageSuccess(System.Guid,System.Nullable{System.Guid})">
|
||||
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.DownloadAndUploadService.DownloadImageSuccess(IRaCIS.Core.Application.Contracts.DownloadImageSuccessCommand)">
|
||||
<summary>
|
||||
影像下载成功回调
|
||||
</summary>
|
||||
<param name="trialImageDownloadId"></param>
|
||||
<param name="incommand"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.DownloadAndUploadService.GetTrialDownloadList(IRaCIS.Core.Application.Contracts.TrialIamgeDownQuery)">
|
||||
@@ -4562,6 +4582,13 @@
|
||||
<param name="inDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingCalculate.IVUSCalculateService.GetIVUSTemplatesZip(IRaCIS.Core.Application.Service.Reading.Dto.GetExportTemplateInDto)">
|
||||
<summary>
|
||||
获取当前分组、受试者、标准下所有有效任务的IVUS模板压缩包
|
||||
</summary>
|
||||
<param name="inDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingCalculate.IVUSCalculateService.UploadIVUSTemplate">
|
||||
<summary>
|
||||
导入IVUS数据
|
||||
@@ -6221,6 +6248,13 @@
|
||||
<param name="inDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingCalculate.OCTCalculateService.GetOCTFCTTemplatesZip(IRaCIS.Core.Application.Service.Reading.Dto.GetExportTemplateInDto)">
|
||||
<summary>
|
||||
获取当前分组、受试者、标准下所有有效任务的OCT-FCT模板压缩包
|
||||
</summary>
|
||||
<param name="inDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingCalculate.OCTCalculateService.UploadOCTFCTTemplate">
|
||||
<summary>
|
||||
导入OCT-FCT数据
|
||||
@@ -9032,6 +9066,36 @@
|
||||
斑块破裂
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TemplateData.TargetSegment">
|
||||
<summary>
|
||||
靶段
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TemplateData.TargetSegmentRemarks">
|
||||
<summary>
|
||||
靶段备注
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TemplateData.ROIAllLength">
|
||||
<summary>
|
||||
ROI段落总长度
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TemplateData.PullbackFrameCount">
|
||||
<summary>
|
||||
回撤中的图像帧数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TemplateData.PlaqueType">
|
||||
<summary>
|
||||
斑块类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TemplateData.AdjustReason">
|
||||
<summary>
|
||||
访视点备注(如有)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.OCTFCTUploadData.FrameNumber">
|
||||
<summary>
|
||||
帧数
|
||||
@@ -10472,6 +10536,21 @@
|
||||
默认SegmentName
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetReadingTaskDto.JudgeModeEnum">
|
||||
<summary>
|
||||
仲裁模式
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetReadingTaskDto.JudgeRuleEnum">
|
||||
<summary>
|
||||
裁判规则
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetReadingTaskDto.ArbitrationRule">
|
||||
<summary>
|
||||
仲裁对象
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Core.Application.Service.Reading.Dto.GetTrialConfirmCriterionListOutDto">
|
||||
<summary>
|
||||
返回对象
|
||||
@@ -10542,6 +10621,16 @@
|
||||
裁判结果的备注
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetJudgeFormOutDto.TriggerJudgeQuestionIds">
|
||||
<summary>
|
||||
本次生成裁判的触发问题(包含自动计算题追溯到的源问题)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.JudgeFormQuestionDto.IsTriggerJudge">
|
||||
<summary>
|
||||
是否为本次生成裁判的触发问题
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GlobalVisitJudgeQuestion.ShowOrder">
|
||||
<summary>
|
||||
排序
|
||||
@@ -11917,6 +12006,41 @@
|
||||
阅片期名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.CopyTrialQuestionVisitJudgeRuleInDto.SourceVisitNum">
|
||||
<summary>
|
||||
来源访视
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.CopyTrialQuestionVisitJudgeRuleInDto.TargetVisitNum">
|
||||
<summary>
|
||||
目标访视
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TrialQuestionVisitJudgeRuleItemDto.Type">
|
||||
<summary>
|
||||
类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TrialQuestionVisitJudgeRuleItemDto.QuestionGenre">
|
||||
<summary>
|
||||
问题类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TrialQuestionVisitJudgeRuleItemDto.DictionaryCode">
|
||||
<summary>
|
||||
字典code
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TrialQuestionVisitJudgeRuleItemDto.Unit">
|
||||
<summary>
|
||||
单位
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TrialQuestionVisitJudgeRuleItemDto.AnswerCombination">
|
||||
<summary>
|
||||
答案组合
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateTumorAssessmentInDto.CriterionId">
|
||||
<summary>
|
||||
标准ID
|
||||
@@ -12278,6 +12402,21 @@
|
||||
仲裁规则
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetTrialJudgyInfoOutDto.JudgeModeEnum">
|
||||
<summary>
|
||||
仲裁模式
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetTrialJudgyInfoOutDto.JudgeRuleEnum">
|
||||
<summary>
|
||||
裁判规则
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetTrialJudgyInfoOutDto.JudgeGenerateEnum">
|
||||
<summary>
|
||||
裁判任务生成
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:IRaCIS.Core.Application.Service.Reading.Dto.NeedSynchronize.Need">
|
||||
<summary>
|
||||
需要
|
||||
@@ -14308,6 +14447,11 @@
|
||||
<param name="inDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.RC.ReadingQuestionService.SetTrialJudgeRuleInfo(IRaCIS.Core.Application.Service.Reading.Dto.SetTrialJudgeRuleInfoInDto)">
|
||||
<summary>
|
||||
编辑裁判规则配置
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.RC.ReadingQuestionService.AddOrUpdateReadingQuestionCriterionTrial(IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionCriterionTrialInDto)">
|
||||
<summary>
|
||||
新增修改项目问题标准(项目)
|
||||
@@ -14409,11 +14553,34 @@
|
||||
阅片问题.标准
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingQuestionService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ClinicalDataTrialSet},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ClinicalDataSystemSet},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Dictionary},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CriterionNidusSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SystemCriterionDictionaryCode},IRaCIS.Core.Application.Contracts.IReadingImageTaskService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingSystemCriterionDictionary},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingCriterionPage},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TumorAssessment_RECIST1Point1},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.PreviousPDF},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer)">
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingQuestionService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ClinicalDataTrialSet},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ClinicalDataSystemSet},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Dictionary},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CriterionNidusSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SystemCriterionDictionaryCode},IRaCIS.Core.Application.Contracts.IReadingImageTaskService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingSystemCriterionDictionary},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingCriterionPage},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TumorAssessment_RECIST1Point1},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.PreviousPDF},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionVisitJudgeRule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitStage},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer)">
|
||||
<summary>
|
||||
阅片问题.标准
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingQuestionService.GetTrialQuestionVisitJudgeRule(IRaCIS.Core.Application.Service.Reading.Dto.GetTrialQuestionVisitJudgeRuleInDto)">
|
||||
<summary>
|
||||
获取项目阅片标准各访视的裁判规则配置。
|
||||
未配置规则的访视问题也会返回,供前端直接进行配置。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingQuestionService.SetTrialQuestionVisitJudgeRule(IRaCIS.Core.Application.Service.Reading.Dto.SetTrialQuestionVisitJudgeRuleInDto)">
|
||||
<summary>
|
||||
编辑项目阅片标准各访视的裁判规则配置。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingQuestionService.CopyTrialQuestionVisitJudgeRule(IRaCIS.Core.Application.Service.Reading.Dto.CopyTrialQuestionVisitJudgeRuleInDto)">
|
||||
<summary>
|
||||
复制其他访视的项目阅片标准裁判规则配置。
|
||||
目标访视不适用的问题保留其已有的不适用规则,不参与复制。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingQuestionService.ApplyBaseLineTrialQuestionVisitJudgeRule(IRaCIS.Core.Application.Service.Reading.Dto.ApplyBaseLineTrialQuestionVisitJudgeRuleInDto)">
|
||||
<summary>
|
||||
将基线访视(VisitNum = 0)的裁判规则配置应用到其他所有访视。
|
||||
仅复制在基线和目标访视均适用的问题;目标访视不适用的问题保留其已有规则。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingQuestionService.SetTrialQuestionExportResult(IRaCIS.Core.Application.Service.Reading.Dto.SetTrialQuestionExportResultInDto)">
|
||||
<summary>
|
||||
设置项目问题导出
|
||||
@@ -14530,6 +14697,12 @@
|
||||
<param name="indto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingQuestionService.AddNAJudgeRule(IRaCIS.Core.Domain.Models.ReadingQuestionTrial)">
|
||||
<summary>
|
||||
添加问题的不适用规则
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingQuestionService.GetReadingQuestionTrialList(IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionTrialViewInDto)">
|
||||
<summary>
|
||||
获取项目问题(项目)
|
||||
@@ -14783,7 +14956,7 @@
|
||||
<param name="inDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMarkBinding},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserLog},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingOncologyTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Segmentation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SegmentBinding},IRaCIS.Core.Application.Service.IVisitTaskHelpeService,IRaCIS.Core.Application.Service.IVisitTaskService,IRaCIS.Core.Application.Contracts.IReadingClinicalDataService,IRaCIS.Core.Application.Service.IReadingCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserFeedBack},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingGlobalTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingCriterionPage},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskRelation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingJudgeInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadModule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUserRole},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeUserType},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeConfig},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganTrialInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialDocument},IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoCalculateService,IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoWithoutPETCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTrialCriterionDictionary},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableAnswerRowInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CriterionKeyFileRead},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialCriterionKeyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Application.Service.IGeneralCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskStudy},Microsoft.Extensions.Configuration.IConfiguration,IRaCIS.Core.Application.Service.ImageAndDoc.IDownloadAndUploadService,IRaCIS.Core.Application.Interfaces.ITrialEmailNoticeConfigService,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer,ZiggyCreatures.Caching.Fusion.IFusionCache)">
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitStage},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMarkBinding},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserLog},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingOncologyTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Segmentation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SegmentBinding},IRaCIS.Core.Application.Service.IVisitTaskHelpeService,IRaCIS.Core.Application.Service.IVisitTaskService,IRaCIS.Core.Application.Contracts.IReadingClinicalDataService,IRaCIS.Core.Application.Service.IReadingCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserFeedBack},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingGlobalTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingCriterionPage},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskRelation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingJudgeInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadModule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUserRole},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeUserType},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeConfig},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganTrialInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialDocument},IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoCalculateService,IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoWithoutPETCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTrialCriterionDictionary},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableAnswerRowInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionVisitJudgeRule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CriterionKeyFileRead},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialCriterionKeyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Application.Service.IGeneralCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskStudy},Microsoft.Extensions.Configuration.IConfiguration,IRaCIS.Core.Application.Service.ImageAndDoc.IDownloadAndUploadService,IRaCIS.Core.Application.Interfaces.ITrialEmailNoticeConfigService,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer,ZiggyCreatures.Caching.Fusion.IFusionCache)">
|
||||
<summary>
|
||||
IR影像阅片
|
||||
</summary>
|
||||
@@ -15199,6 +15372,13 @@
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.PhasedGenerationJudge(System.Guid)">
|
||||
<summary>
|
||||
统一生成裁判任务
|
||||
</summary>
|
||||
<param name=""></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetTrialCriterionJudgeQuestionList(IRaCIS.Core.Application.Service.Reading.Dto.GetTrialCriterionJudgeQuestionListInDto)">
|
||||
<summary>
|
||||
获取项目标准的裁判问题
|
||||
@@ -15213,6 +15393,35 @@
|
||||
<param name="inDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetSingleVisitJudgeAnswer(IRaCIS.Core.Application.Service.Reading.Dto.GetSingleVisitJudgeAnswerInDto)">
|
||||
<summary>
|
||||
获取单访视裁判答案
|
||||
</summary>
|
||||
<param name="inDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetJudgeForm(IRaCIS.Core.Application.Service.Reading.Dto.GetJudgeFormInDto)">
|
||||
<summary>
|
||||
获取裁判表单
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetTriggerJudgeQuestionIds(System.Collections.Generic.List{System.Guid},System.Collections.Generic.List{IRaCIS.Core.Domain.Models.ReadingQuestionTrial},System.Decimal,IRaCIS.Core.Domain.Models.JudgeRule)">
|
||||
<summary>
|
||||
重新按当前访视的裁判规则计算实际触发裁判的问题。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.SetJudgeForm(IRaCIS.Core.Application.Service.Reading.Dto.SetJudgeFormInDto)">
|
||||
<summary>
|
||||
编辑裁判表单
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.SubmitJudgeForm(IRaCIS.Core.Application.Service.Reading.Dto.SetJudgeFormInDto)">
|
||||
<summary>
|
||||
提交裁判表单
|
||||
</summary>
|
||||
<param name="inDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetJudgeReadingInfo(IRaCIS.Core.Application.Service.Reading.Dto.GetJudgeReadingInfo)">
|
||||
<summary>
|
||||
获取裁判阅片任务信息
|
||||
@@ -15246,6 +15455,16 @@
|
||||
<param name="visitTaskId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.ApplyVisitJudgeRules(System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.TaskAnswerDto},IRaCIS.Core.Domain.Models.JudgeRule)">
|
||||
<summary>
|
||||
应用访视裁判规则 以及剔除排除的问题
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.ApplyVisitJudgeRules(System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.GlobalQuestionInfo},System.Decimal,IRaCIS.Core.Domain.Models.JudgeRule)">
|
||||
<summary>
|
||||
应用访视裁判规则 以及剔除排除的问题
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.SendWeComNotifier(System.Guid,System.String)">
|
||||
<summary>
|
||||
发送微信通知
|
||||
@@ -15260,7 +15479,7 @@
|
||||
<param name="visiTaskId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.ComputeJudgeResult(System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.GroupTaskAnswerDto},System.Guid)">
|
||||
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.ComputeJudgeResult(System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.GroupTaskAnswerDto},System.Guid,System.Collections.Generic.HashSet{System.Guid},System.Boolean)">
|
||||
<summary>
|
||||
计算返回的结果 为True表示不相等
|
||||
</summary>
|
||||
@@ -16591,7 +16810,7 @@
|
||||
<param name="regions"></param>
|
||||
<param name="options"></param>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Helper.DicomSortHelper.SortSlices``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.String},System.Func{``0,System.String},System.Func{``0,System.Nullable{System.Int32}})">
|
||||
<member name="M:IRaCIS.Core.Application.Helper.DicomSortHelper.SortSlices``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.String},System.Func{``0,System.String},System.Func{``0,System.Nullable{System.Int32}},System.String)">
|
||||
<summary>
|
||||
DICOM Slice 排序(IPP + IOP)
|
||||
自动 fallback InstanceNumber
|
||||
@@ -19340,7 +19559,7 @@
|
||||
TrialSiteSurveyService
|
||||
</summary>
|
||||
</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>
|
||||
TrialSiteSurveyService
|
||||
</summary>
|
||||
@@ -19461,6 +19680,34 @@
|
||||
<param name="siteSurvyeSubmit"></param>
|
||||
<returns></returns>
|
||||
</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">
|
||||
<summary>
|
||||
TrialSiteUserSurveyService
|
||||
|
||||
@@ -269,9 +269,45 @@ public class SiteSurverRejectedEventConsumer(
|
||||
|
||||
if (context.Message.IsHaveSPMOrCPM)
|
||||
{
|
||||
//PM 驳回到SPM
|
||||
if (siteSurveyInfo.State == TrialSiteSurveyEnum.CRCSubmitted)
|
||||
////PM 驳回到SPM
|
||||
//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)
|
||||
.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)
|
||||
{
|
||||
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));
|
||||
|
||||
messageToSend.Cc.Add(new MailboxAddress(user.FullName, user.EMail));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
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));
|
||||
|
||||
@@ -330,8 +357,9 @@ public class SiteSurverRejectedEventConsumer(
|
||||
siteInfo.TrialSiteCode, //中心编号
|
||||
siteInfo.TrialSiteAliasName,//中心名称
|
||||
siteSurveyInfo.LatestBackReason, //驳回原因
|
||||
_systemEmailConfig.SiteUrl, //链接
|
||||
(siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit ? "inline - block" : "none")
|
||||
$"{baseUrl}/researchLogin?trialId={trialId}", //链接
|
||||
(siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit ? "inline - block" : "none"),
|
||||
trialInfo.LinkVerificationCode.IsNullOrEmpty()? trialInfo.ResearchProgramNo: trialInfo.LinkVerificationCode
|
||||
);
|
||||
|
||||
return (topicStr, htmlBodyStr);
|
||||
|
||||
@@ -767,6 +767,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt, nameof(VisitTask)),
|
||||
ReadingCategory = ReadingCategory.Visit,
|
||||
|
||||
|
||||
TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId,
|
||||
IsNeedClinicalDataSign = isNeedClinicalDataSign,
|
||||
IsClinicalDataSign = isClinicalDataSign,
|
||||
@@ -1421,6 +1422,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
// AllocateTime = DateTime.Now,
|
||||
//DoctorUserId = reReadingVisitTask.DoctorUserId,
|
||||
|
||||
IsIRImageDownloaded= reReadingVisitTask.IsIRImageDownloaded,
|
||||
});
|
||||
|
||||
generateTaskCommand.Action(newTask);
|
||||
|
||||
@@ -2109,6 +2109,16 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
|
||||
}
|
||||
|
||||
if (origenalTask.ReadingCategory == ReadingCategory.Judge)
|
||||
{
|
||||
//拷贝原始表单
|
||||
if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id)
|
||||
{
|
||||
CopyForms(newTask, origenalTask);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2190,6 +2200,9 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
|
||||
|
||||
|
||||
CopyImages(newTask, influenceTask);
|
||||
|
||||
|
||||
//裁判任务 需要进行特殊处理 在重阅逻辑里面处理
|
||||
|
||||
if (visitTaskReReadingAppply != null)
|
||||
@@ -2197,7 +2210,6 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
|
||||
//申请表 设置新任务Id
|
||||
visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id;
|
||||
|
||||
|
||||
if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id)
|
||||
{
|
||||
if (origenalTask.ReadingCategory == ReadingCategory.Visit)
|
||||
|
||||
@@ -31,7 +31,7 @@ public class DeployConfigService(IMapper _mapper, IConfiguration _configuration,
|
||||
//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);
|
||||
|
||||
@@ -123,7 +123,7 @@ public class DeployConfigService(IMapper _mapper, IConfiguration _configuration,
|
||||
[HttpPost]
|
||||
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 @lock = _distributedLockProvider.CreateLock("WriteConfigFile");
|
||||
@@ -171,4 +171,51 @@ public class DeployConfigService(IMapper _mapper, IConfiguration _configuration,
|
||||
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 async Task<IResponseOutput> UpdateWebConfigInfo(string configStr)
|
||||
{
|
||||
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"] = configStr;
|
||||
|
||||
// 重新写入appsettings.json
|
||||
string result = obj.ToString();
|
||||
|
||||
System.IO.File.WriteAllText(path, result);
|
||||
|
||||
}
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ using IRaCIS.Core.Infra.EFCore.Common;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
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
|
||||
{
|
||||
|
||||
|
||||
#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>
|
||||
@@ -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 ?
|
||||
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
|
||||
}).OrderBy(t=>t.VisitTaskNum).ToList(),
|
||||
}).OrderBy(t => t.VisitTaskNum).ToList(),
|
||||
|
||||
ModuleList = subject.ReadModuleList.Where(t => t.TrialReadingCriterionId == dto.TrialReadingCriterionId).Select(t => new SubjectProgressDto.MouduleProgress()
|
||||
{
|
||||
@@ -2763,11 +2949,11 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
if (criterion.CriterionType == CriterionType.OCT)
|
||||
{
|
||||
list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_ReadingLession_Export, ExportCatogory = ExportResult.OCT_ReadingLession_Export });
|
||||
list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_CDISC_Export, ExportCatogory = ExportResult.OCT_CDISC_Export });
|
||||
//list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_CDISC_Export, ExportCatogory = ExportResult.OCT_CDISC_Export });
|
||||
}
|
||||
if (criterion.CriterionType == CriterionType.IVUS)
|
||||
{
|
||||
list.Add(new ExportDocumentDes() { Code = StaticData.Export.IVUS_CDISC_Export, ExportCatogory = ExportResult.IVUS_CDISC_Export });
|
||||
//list.Add(new ExportDocumentDes() { Code = StaticData.Export.IVUS_CDISC_Export, ExportCatogory = ExportResult.IVUS_CDISC_Export });
|
||||
}
|
||||
if (criterion.CriterionGroup != CriterionGroup.Tumor /*&& criterion.CriterionType != CriterionType.OCT && criterion.CriterionType != CriterionType.IVUS*/)
|
||||
{
|
||||
@@ -2863,7 +3049,7 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||
{
|
||||
//仲裁阅片 才有裁判阅片明细表 同时要把模板里面的三列给去掉
|
||||
//removeColumnIndexList = new List<int>() { 6, 7, 8 };
|
||||
removeColumnIndexList = new List<int>() { 7, 8 ,9};
|
||||
removeColumnIndexList = new List<int>() { 7, 8, 9 };
|
||||
}
|
||||
|
||||
//阅片结果表 和阅片结果明细表 没有肿瘤学的时候需要移除肿瘤学三个字段
|
||||
|
||||
@@ -30,7 +30,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
public class TrialImageDownloadService(IRepository<Trial> _trialRepository, IRepository<SubjectVisit> _subjectVisitRepository, IOSSService _oSSService, IWebHostEnvironment _hostEnvironment,
|
||||
IRepository<DicomStudy> _studyRepository,
|
||||
IRepository<DicomSeries> _seriesRepository,
|
||||
IRepository<DicomInstance> _instanceRepository) : BaseService
|
||||
IRepository<DicomInstance> _instanceRepository,
|
||||
IRepository<TaskInstance> _taskInstanceRepository,
|
||||
IRepository<VisitTask> _visitTaskRepository
|
||||
) : BaseService
|
||||
{
|
||||
|
||||
|
||||
@@ -491,6 +494,325 @@ namespace IRaCIS.Core.Application.Service
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[AllowAnonymous]
|
||||
public async Task<IResponseOutput> DownloadExcelTrialTaskImageZIPStream(Guid trialId)
|
||||
{
|
||||
var trialInfo = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo }).FirstOrDefault();
|
||||
|
||||
#region 设置目录
|
||||
|
||||
var rootFolder = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
Directory.CreateDirectory(rootFolder);
|
||||
|
||||
// 获取无效字符(系统定义的)
|
||||
string invalidChars = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
|
||||
|
||||
// 用正则表达式替换所有非法字符为下划线或空字符
|
||||
string pattern = $"[{Regex.Escape(invalidChars)}]";
|
||||
|
||||
var regexNo = Regex.Replace(trialInfo.ResearchProgramNo, pattern, "_");
|
||||
|
||||
// 创建一个临时文件夹来存放文件
|
||||
string trialFolderPath = Path.Combine(rootFolder, $"{regexNo}");//_{NewId.NextGuid()}
|
||||
Directory.CreateDirectory(trialFolderPath);
|
||||
|
||||
#endregion
|
||||
|
||||
var oldVisits = MiniExcel.Query<SubjectTaskExcel>(Path.Combine(rootFolder, "Old.xlsx")).ToList();
|
||||
|
||||
var downloadTasks = MiniExcel.Query<SubjectTaskExcel>(Path.Combine(rootFolder, "download.xlsx")).ToList().Where(t => t.SubjectCode.IsNotNullOrEmpty() && t.TaskName.IsNotNullOrEmpty() && t.TaskBlindName.IsNotNullOrEmpty()).ToList();
|
||||
|
||||
downloadTasks = downloadTasks.Where(t => !oldVisits.Any(old => old.SubjectCode == t.SubjectCode && old.TaskBlindName == t.TaskBlindName && old.TaskName.Trim().ToLower() == t.TaskName.Trim().ToLower())).ToList();
|
||||
|
||||
var visitIndex = 0;
|
||||
var skipCount = 0;
|
||||
foreach (var downloadTask in downloadTasks)
|
||||
{
|
||||
visitIndex++;
|
||||
var downloadInfo = _trialRepository.Where(t => t.Id == trialId).Select(t => new
|
||||
{
|
||||
t.ResearchProgramNo,
|
||||
t.TrialCode,
|
||||
|
||||
TaskList = t.VisitTaskList.Where(t => t.TaskState == TaskState.Effect && t.DoctorUser.UserName == downloadTask.UserName
|
||||
&& t.IsAnalysisCreate == false)
|
||||
.Where(t => t.TaskName.Trim() == downloadTask.TaskName.Trim()
|
||||
&& t.Subject.Code.Trim() == downloadTask.SubjectCode.Trim()
|
||||
&& t.TaskBlindName.Trim() == downloadTask.TaskBlindName.Trim()
|
||||
)
|
||||
.Select(vt => new
|
||||
{
|
||||
VisitTaskId = vt.Id,
|
||||
TrialSiteCode = vt.SourceSubjectVisit.TrialSite.TrialSiteCode,
|
||||
SubjectCode = vt.Subject.Code,
|
||||
UserName = vt.DoctorUser.UserName,
|
||||
vt.TaskName,
|
||||
vt.TaskBlindName,
|
||||
VisitName = vt.SourceSubjectVisit.VisitName,
|
||||
VisitNum = vt.SourceSubjectVisit.VisitNum,
|
||||
StudyList = vt.TaskStudyList.Select(u => new
|
||||
{
|
||||
StudyId = u.Id,
|
||||
u.PatientId,
|
||||
u.StudyTime,
|
||||
u.StudyCode,
|
||||
u.StudyInstanceUid,
|
||||
u.StudyDIRPath,
|
||||
|
||||
SeriesList = u.SeriesList.Select(z => new
|
||||
{
|
||||
z.Modality,
|
||||
|
||||
InstancePathList = z.InstanceList.Select(k => new
|
||||
{
|
||||
InstanceId = k.Id,
|
||||
k.Path,
|
||||
k.IsEncapsulated,
|
||||
k.NumberOfFrames,
|
||||
}).ToList()
|
||||
})
|
||||
|
||||
}).ToList(),
|
||||
|
||||
NoneDicomStudyList = vt.SourceSubjectVisit.NoneDicomStudyList.Where(t => t.IsReading && t.Modality != "OCT").Select(nd => new
|
||||
{
|
||||
nd.Modality,
|
||||
nd.StudyCode,
|
||||
nd.ImageDate,
|
||||
|
||||
FileList = nd.TaskNoneDicomFileList.Where(t => t.IsReading && t.VisitTaskId == vt.Id).Select(file => new
|
||||
{
|
||||
file.FileName,
|
||||
file.Path,
|
||||
file.FileType
|
||||
}).ToList()
|
||||
}).ToList()
|
||||
}).OrderBy(t => t.SubjectCode).ThenBy(t => t.VisitNum).ToList()
|
||||
|
||||
}).FirstOrDefault();
|
||||
|
||||
if (downloadInfo == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
#region 排除已经下载的
|
||||
|
||||
var logFilePath = Path.Combine(rootFolder, $"{trialId}_{regexNo}_download_log.csv");
|
||||
|
||||
if (File.Exists(logFilePath))
|
||||
{
|
||||
var existVisits = MiniExcel.Query<SubjectTaskExcel>(logFilePath, configuration: new MiniExcelLibs.Csv.CsvConfiguration()
|
||||
{
|
||||
StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312"))
|
||||
}).ToList();
|
||||
|
||||
if (existVisits.Any(old => old.TaskName == downloadTask.TaskName
|
||||
&& old.SubjectCode == downloadTask.SubjectCode
|
||||
&& old.TaskBlindName.Trim().ToLower() == downloadTask.TaskBlindName.Trim().ToLower()
|
||||
&& old.UserName.Trim().ToLower() == downloadTask.UserName.Trim().ToLower()
|
||||
))
|
||||
{
|
||||
Log.Logger.Warning($"[{visitIndex}] Excel显示已下载,跳过当前:{downloadTask.SubjectCode} {downloadTask.TaskName} {downloadTask.TaskBlindName} {downloadTask.UserName}");
|
||||
skipCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
foreach (var taskItem in downloadInfo.TaskList)
|
||||
{
|
||||
if (taskItem.StudyList.Count() == 0 && taskItem.NoneDicomStudyList.SelectMany(t=>t.FileList).Count() == 0)
|
||||
{
|
||||
Log.Logger.Warning($"[{visitIndex}]查询无检查,跳过当前访视:{downloadTask.SubjectCode} {downloadTask.TaskName} {downloadTask.TaskBlindName} {downloadTask.UserName}");
|
||||
skipCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
#region 导出访视
|
||||
|
||||
var zipItems = new List<ZipItem>();
|
||||
|
||||
var visitFolderName = $"{taskItem.SubjectCode}_{taskItem.TaskBlindName.Trim()}";
|
||||
|
||||
#region DICOM
|
||||
|
||||
foreach (var studyInfo in taskItem.StudyList)
|
||||
{
|
||||
var dirDic = new Dictionary<string, string>();
|
||||
|
||||
var studyFolderName = $"{studyInfo.StudyCode}_{studyInfo.StudyTime:yyyy-MM-dd}_{string.Join('_', studyInfo.SeriesList.Select(t => t.Modality).Distinct())}";
|
||||
|
||||
#region DICOMDIR
|
||||
|
||||
|
||||
if (!_taskInstanceRepository.Where(t => taskItem.VisitTaskId == t.VisitTaskId).Any(c => c.TransferSytaxUID == string.Empty))
|
||||
{
|
||||
var list = _visitTaskRepository.Where(t => t.Id == taskItem.VisitTaskId).SelectMany(t => t.TaskStudyList)
|
||||
.SelectMany(t => t.InstanceList.Where(t => t.StudyId == studyInfo.StudyId))
|
||||
.Select(t => new StudyDIRInfo()
|
||||
{
|
||||
|
||||
DicomStudyId = t.TaskStudy.Id,
|
||||
|
||||
PatientId = downloadInfo.TrialCode + "-" + t.TaskStudy.Subject.Code,
|
||||
PatientName = t.TaskStudy.PatientName,
|
||||
PatientBirthDate = t.TaskStudy.PatientBirthDate,
|
||||
PatientSex = t.TaskStudy.PatientSex,
|
||||
|
||||
StudyInstanceUid = t.StudyInstanceUid,
|
||||
StudyId = t.TaskStudy.StudyId,
|
||||
DicomStudyDate = t.TaskStudy.DicomStudyDate,
|
||||
DicomStudyTime = t.TaskStudy.DicomStudyTime,
|
||||
AccessionNumber = t.TaskStudy.AccessionNumber,
|
||||
|
||||
StudyDescription = t.TaskStudy.Description,
|
||||
|
||||
SeriesInstanceUid = t.TaskSeries.SeriesInstanceUid,
|
||||
Modality = t.TaskSeries.Modality,
|
||||
DicomSeriesDate = t.TaskSeries.DicomSeriesDate,
|
||||
DicomSeriesTime = t.TaskSeries.DicomSeriesTime,
|
||||
SeriesNumber = t.TaskSeries.SeriesNumber,
|
||||
SeriesDescription = t.TaskSeries.Description,
|
||||
|
||||
InstanceId = t.Id,
|
||||
SopInstanceUid = t.SopInstanceUid,
|
||||
SOPClassUID = t.SOPClassUID,
|
||||
InstanceNumber = t.InstanceNumber,
|
||||
MediaStorageSOPClassUID = t.MediaStorageSOPClassUID,
|
||||
MediaStorageSOPInstanceUID = t.MediaStorageSOPInstanceUID,
|
||||
TransferSytaxUID = t.TransferSytaxUID,
|
||||
|
||||
}).ToList();
|
||||
|
||||
foreach (var group in list.GroupBy(t => new { t.StudyInstanceUid, t.DicomStudyId }))
|
||||
{
|
||||
|
||||
using var ms = new MemoryStream();
|
||||
|
||||
await DicomDIRHelper.GenerateStudyDIR(group.ToList(), dirDic, outputStream: ms);
|
||||
|
||||
var dicomDirBytes = ms.ToArray();
|
||||
|
||||
zipItems.Add(new ZipItem
|
||||
{
|
||||
ZipEntryPath = $"{visitFolderName}/{studyFolderName}/DICOMDIR",
|
||||
|
||||
CustomWriter = async entryStream =>
|
||||
{
|
||||
await entryStream.WriteAsync(dicomDirBytes);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (var seriesInfo in studyInfo.SeriesList)
|
||||
{
|
||||
foreach (var instanceInfo in seriesInfo.InstancePathList)
|
||||
{
|
||||
zipItems.Add(new ZipItem
|
||||
{
|
||||
OssPath = instanceInfo.Path,
|
||||
|
||||
IsEncapsulated = instanceInfo.IsEncapsulated,
|
||||
|
||||
ZipEntryPath = $"{visitFolderName}/" + $"{studyFolderName}/" + $"IMAGE/" + $"{dirDic[instanceInfo.InstanceId.ToString()]}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region NoneDicom
|
||||
|
||||
foreach (var study in taskItem.NoneDicomStudyList)
|
||||
{
|
||||
var studyFolderName = $"{study.StudyCode}_" + $"{study.ImageDate:yyyy-MM-dd}_" + $"{study.Modality}";
|
||||
|
||||
foreach (var file in study.FileList)
|
||||
{
|
||||
zipItems.Add(new ZipItem
|
||||
{
|
||||
OssPath = HttpUtility.UrlDecode(file.Path),
|
||||
|
||||
ZipEntryPath = $"{visitFolderName}/" + $"{studyFolderName}/" + $"{Path.GetFileName(file.FileName)}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region zip
|
||||
|
||||
|
||||
var zipPath = Path.Combine(trialFolderPath, visitFolderName + ".zip");
|
||||
|
||||
Log.Logger.Warning($"[{visitIndex}] {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 开始打包下载访视:{visitFolderName}");
|
||||
|
||||
try
|
||||
{
|
||||
await CreateVisitZipAsync(zipPath, zipItems);
|
||||
|
||||
//Log.Logger.Warning($"zip exists={File.Exists(zipPath)} size={new FileInfo(zipPath).Length}");
|
||||
|
||||
Log.Logger.Warning($"[{visitIndex}] {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 下载完成:{visitFolderName}");
|
||||
|
||||
DownloadLogger.TaskWrite(logFilePath, taskItem.SubjectCode, taskItem.TaskName, taskItem.TaskBlindName, taskItem.UserName, "Success");
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Logger.Warning($"出现异常{ex}自动删除压缩包:{visitFolderName}");
|
||||
//如果有异常,删除失败的压缩包
|
||||
if (File.Exists(zipPath))
|
||||
{
|
||||
File.Delete(zipPath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Logger.Error(ex, $"导出失败:{downloadTask.SubjectCode} {downloadTask.TaskName} {downloadTask.TaskBlindName} {downloadTask.UserName}");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -542,6 +864,53 @@ namespace IRaCIS.Core.Application.Service
|
||||
writer.WriteLine(line);
|
||||
}
|
||||
|
||||
|
||||
public static void TaskWrite(
|
||||
string logFilePath,
|
||||
string subjectCode,
|
||||
string taskName,
|
||||
string taskBlindName,
|
||||
string userName,
|
||||
string? message = null)
|
||||
{
|
||||
bool fileExists = File.Exists(logFilePath);
|
||||
|
||||
// 一次性打开文件流
|
||||
using var stream = new FileStream(
|
||||
logFilePath,
|
||||
FileMode.Append,
|
||||
FileAccess.Write,
|
||||
FileShare.ReadWrite);
|
||||
|
||||
// 首次创建时写入 BOM
|
||||
if (!fileExists)
|
||||
{
|
||||
var bom = new UTF8Encoding(true).GetPreamble();
|
||||
stream.Write(bom, 0, bom.Length);
|
||||
}
|
||||
|
||||
using var writer = new StreamWriter(stream, new UTF8Encoding(false));
|
||||
|
||||
// 写入表头
|
||||
if (!fileExists)
|
||||
{
|
||||
writer.WriteLine("Time,SubjectCode,TaskName,TaskBlindName,UserName,Message");
|
||||
}
|
||||
|
||||
// 写入数据
|
||||
string line = string.Join(",",
|
||||
[
|
||||
Escape(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
|
||||
subjectCode,
|
||||
taskName,
|
||||
taskBlindName,
|
||||
userName,
|
||||
Escape(message)
|
||||
]);
|
||||
|
||||
writer.WriteLine(line);
|
||||
}
|
||||
|
||||
private static string Escape(string? value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc.DTO
|
||||
{
|
||||
public class SubjectImageUploadDTO
|
||||
{
|
||||
public bool? IsIRImageDownloaded { get; set; }
|
||||
|
||||
public Guid VisitTaskId { get; set; }
|
||||
|
||||
public Guid TrialSiteId { get; set; }
|
||||
|
||||
@@ -676,6 +676,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
public class TaskNoneDicomStudyDTO : NoneDicomStudyBasicInfo
|
||||
{
|
||||
public bool? IsIRImageDownloaded { get; set; }
|
||||
public Guid VisitTaskId { get; set; }
|
||||
|
||||
public int UploadedFileCount { get; set; }
|
||||
@@ -1073,6 +1074,13 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
|
||||
public class DownloadImageSuccessCommand
|
||||
{
|
||||
public Guid TrialImageDownloadId { get; set; }
|
||||
|
||||
public List<Guid> VisitTaskIdList { get; set; }
|
||||
}
|
||||
|
||||
public class SubjectVisitTaskInfo
|
||||
{
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
@@ -1093,6 +1101,8 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
public bool? IsUrgent { get; set; }
|
||||
|
||||
public int? State { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1122,6 +1132,10 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public int? NoneDicomStudyCount { get; set; }
|
||||
|
||||
public int? MarkNoneDicomStudyCount { get; set; }
|
||||
|
||||
public DateTime? LatestDownloadTime { get; set; }
|
||||
|
||||
public DateTime? LatestUploadTime { get; set; }
|
||||
}
|
||||
|
||||
public class SubjectVisitMarkStudyDto
|
||||
|
||||
@@ -119,11 +119,11 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
var subjectCode = string.Empty;
|
||||
var subjectId = inQuery.SubjectId;
|
||||
bool? isIRImageDownloaded = true;
|
||||
bool? isIRImageDownloaded = null;
|
||||
|
||||
if(inQuery.VisitTaskId != null)
|
||||
if (inQuery.VisitTaskId != null)
|
||||
{
|
||||
//isIRImageDownloaded= _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId).Select(t => t.IsIRImageDownloaded).FirstOrDefault();
|
||||
isIRImageDownloaded = _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId).Select(t => t.IsIRImageDownloaded).FirstOrDefault();
|
||||
}
|
||||
|
||||
if (criterionInfo.IsReadingTaskViewInOrder == ReadingOrder.Random)
|
||||
@@ -228,12 +228,13 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
|
||||
var query = _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed
|
||||
/* && t.DoctorUserId == _userInfo.UserRoleId*/ && t.TaskState == TaskState.Effect)
|
||||
&& t.DoctorUserId == _userInfo.UserRoleId && t.TaskState == TaskState.Effect)
|
||||
//满足 有序,或者随机只看到当前任务的dicom 非dicom检查
|
||||
.WhereIf(criterionInfo.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)
|
||||
.Select(u => new SubjectImageUploadDTO()
|
||||
{
|
||||
VisitTaskId = u.Id,
|
||||
IsIRImageDownloaded = u.IsIRImageDownloaded,
|
||||
|
||||
SubejctId = u.SubjectId,
|
||||
|
||||
@@ -331,7 +332,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
}
|
||||
|
||||
|
||||
return ResponseOutput.Ok(list, new { TrialModality = criterionInfo.Modalitys, IsReadingTaskViewInOrder = criterionInfo.IsReadingTaskViewInOrder, IsIRImageDownloaded= isIRImageDownloaded });
|
||||
return ResponseOutput.Ok(list, new { TrialModality = criterionInfo.Modalitys, IsReadingTaskViewInOrder = criterionInfo.IsReadingTaskViewInOrder, IsIRImageDownloaded = isIRImageDownloaded });
|
||||
}
|
||||
|
||||
|
||||
@@ -391,9 +392,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
};
|
||||
|
||||
|
||||
//var addEntity = await _studyMonitorRepository.AddAsync(studyMonitor, true);
|
||||
var addEntity = await _studyMonitorRepository.AddAsync(studyMonitor, true);
|
||||
|
||||
return ResponseOutput.Ok(Guid.NewGuid());
|
||||
return ResponseOutput.Ok(addEntity.Id);
|
||||
|
||||
}
|
||||
|
||||
@@ -580,25 +581,25 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
var trialId = incommand.TrialId;
|
||||
|
||||
|
||||
//var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId);
|
||||
//studyMonitor.UploadFinishedTime = DateTime.Now;
|
||||
//studyMonitor.ArchiveFinishedTime = DateTime.Now;
|
||||
//studyMonitor.FailedFileCount = incommand.FailedFileCount;
|
||||
//studyMonitor.IsSuccess = incommand.FailedFileCount == 0;
|
||||
//studyMonitor.RecordPath = incommand.RecordPath;
|
||||
//studyMonitor.FileSize = incommand.Study.SeriesList.SelectMany(t => t.InstanceList).Sum(t => t.FileSize);
|
||||
var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId);
|
||||
studyMonitor.UploadFinishedTime = DateTime.Now;
|
||||
studyMonitor.ArchiveFinishedTime = DateTime.Now;
|
||||
studyMonitor.FailedFileCount = incommand.FailedFileCount;
|
||||
studyMonitor.IsSuccess = incommand.FailedFileCount == 0;
|
||||
studyMonitor.RecordPath = incommand.RecordPath;
|
||||
studyMonitor.FileSize = incommand.Study.SeriesList.SelectMany(t => t.InstanceList).Sum(t => t.FileSize);
|
||||
|
||||
var studyId = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString(), visiTaskId.ToString());
|
||||
var findStudy = await _taskStudyRepository.FirstOrDefaultAsync(t => t.Id == studyId);
|
||||
|
||||
|
||||
//studyMonitor.StudyId = studyId;
|
||||
//studyMonitor.StudyCode = findStudy?.StudyCode ?? "";
|
||||
studyMonitor.StudyId = studyId;
|
||||
studyMonitor.StudyCode = findStudy?.StudyCode ?? "";
|
||||
|
||||
//studyMonitor.IsDicomReUpload = findStudy != null;
|
||||
studyMonitor.IsDicomReUpload = findStudy != null;
|
||||
|
||||
//上传
|
||||
if (findStudy == null)
|
||||
if (studyMonitor.IsDicomReUpload == false)
|
||||
{
|
||||
|
||||
|
||||
@@ -640,7 +641,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
await _taskStudyRepository.AddAsync(study);
|
||||
|
||||
|
||||
//studyMonitor.StudyCode = study.StudyCode;
|
||||
studyMonitor.StudyCode = study.StudyCode;
|
||||
|
||||
|
||||
foreach (var seriesItem in incommand.Study.SeriesList)
|
||||
@@ -689,9 +690,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
|
||||
|
||||
////重传的时候也要赋值检查Id
|
||||
//studyMonitor.StudyId = findStudy.Id;
|
||||
//studyMonitor.StudyCode = findStudy.StudyCode;
|
||||
//重传的时候也要赋值检查Id
|
||||
studyMonitor.StudyId = findStudy.Id;
|
||||
studyMonitor.StudyCode = findStudy.StudyCode;
|
||||
|
||||
//特殊处理逻辑
|
||||
findStudy.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Union(findStudy.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct());
|
||||
@@ -739,7 +740,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
//找到该序列已经存在的instanceId
|
||||
var existInstanceIdList = _taskInstanceRepository.Where(t => t.SeriesId == dicomSeries.Id).Select(t => t.Id).ToList();
|
||||
|
||||
|
||||
foreach (var instanceItem in seriesItem.InstanceList)
|
||||
{
|
||||
var insntance = _mapper.Map<TaskInstance>(instanceItem);
|
||||
@@ -765,14 +765,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
}
|
||||
findStudy.InstanceCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
//更新,需要删除缓存,并更新路径
|
||||
|
||||
await _oSSService.DeleteFromPrefix(insntance.Path, true);
|
||||
|
||||
await _taskInstanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == instanceId, u => new TaskInstance() { Path = insntance.Path });
|
||||
}
|
||||
|
||||
}
|
||||
// 不管是新的序列 还是 该序列 掉了Instance 重传的时候 检查的instance 数量都会增加
|
||||
@@ -945,7 +937,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
var info = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
|
||||
.Select(t => new { t.IsImageFilter, t.CriterionType, t.TrialId, t.CriterionModalitys, t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
|
||||
|
||||
var config = await _subjectRepository.Where(t => t.Id == subjectId).Select(t => new { t.Trial.ImageFormatList, t.Trial.StudyNameList, t.Trial.IsShowStudyName, IsIRImageDownloaded= isIRImageDownloaded }).FirstOrDefaultAsync();
|
||||
var config = await _subjectRepository.Where(t => t.Id == subjectId).Select(t => new { t.Trial.ImageFormatList, t.Trial.StudyNameList, t.Trial.IsShowStudyName, IsIRImageDownloaded = isIRImageDownloaded }).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
//靶段标注上传,查看访视级别,上传绑定访视级别
|
||||
@@ -1010,7 +1002,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
|
||||
|
||||
var list = _noneDicomStudyReposiotry.Where(t => t.SubjectId == subjectId && t.SubjectVisit.CheckState == CheckStateEnum.CVPassed)
|
||||
var list = _noneDicomStudyReposiotry.Where(t => t.IsReading)
|
||||
.Where(t => t.SubjectId == subjectId && t.SubjectVisit.CheckState == CheckStateEnum.CVPassed)
|
||||
.WhereIf(inQuery.SubjectVisitId != null, t => t.SubjectVisitId == inQuery.SubjectVisitId)
|
||||
//.WhereIf(info.IsImageFilter, t => ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|"))
|
||||
.Select(u => new TaskNoneDicomStudyDTO()
|
||||
@@ -1039,12 +1032,13 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
ReadingFileCount = u.NoneDicomFileList.Where(t => t.IsReading).Count(),
|
||||
|
||||
}).ToList();
|
||||
}).OrderBy(t => t.VisitName).ThenBy(t => t.Modality).ToList();
|
||||
|
||||
var noneDicomStudyIdList = list.Select(t => t.Id).ToList();
|
||||
var noneDicomStudyIdList = list.Where(t => !(t.Modality != "IVUS" && t.ReadingFileCount == 0)).Select(t => t.Id).ToList();
|
||||
|
||||
|
||||
var noneDicomStudyList = _noneDicomStudyFileReposiotry.Where(t => t.ImageLabelNoneDicomStudyId != null)
|
||||
var noneDicomStudyList = _noneDicomStudyFileReposiotry.Where(t => t.IsReading)
|
||||
.Where(t => t.ImageLabelNoneDicomStudyId != null)
|
||||
.Where(t => noneDicomStudyIdList.Contains((Guid)t.ImageLabelNoneDicomStudyId!))
|
||||
.Select(u => new NoneDicomFileInfo
|
||||
{
|
||||
@@ -1068,10 +1062,10 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
else
|
||||
{
|
||||
var query = from u in _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId
|
||||
&& t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed /*&& t.DoctorUserId == doctorUserId*/ && t.TaskState == TaskState.Effect)
|
||||
&& t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.DoctorUserId == doctorUserId && t.TaskState == TaskState.Effect)
|
||||
//满足 有序,或者随机只看到当前任务的dicom 非dicom检查
|
||||
.WhereIf(info.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)
|
||||
join ns in _noneDicomStudyReposiotry.Where(t => t.SubjectId == subjectId).WhereIf(info.IsImageFilter, t => ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|"))
|
||||
join ns in _noneDicomStudyReposiotry.Where(t => t.SubjectId == subjectId).Where(t => t.IsReading).WhereIf(info.IsImageFilter, t => ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|"))
|
||||
on u.SourceSubjectVisitId equals ns.SubjectVisitId
|
||||
|
||||
select new TaskNoneDicomStudyDTO()
|
||||
@@ -1083,6 +1077,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
ReadingTaskState = u.ReadingTaskState,
|
||||
SourceSubjectVisitId = u.SourceSubjectVisitId,
|
||||
VisitTaskId = u.Id,
|
||||
IsIRImageDownloaded = u.IsIRImageDownloaded,
|
||||
|
||||
Id = ns.Id,
|
||||
Description = ns.Description,
|
||||
@@ -1378,7 +1373,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
VisitName = item.VisitName,
|
||||
|
||||
//取dicom
|
||||
DicomStudyList = item.DicomStudyList,
|
||||
DicomStudyList = item.DicomStudyList.Where(t => t.ReadingSeriesCount > 0).ToList(),
|
||||
}).ToList();
|
||||
|
||||
var noneStudyList = list.Where(item => item.NoneDicomStudyList.Count > 0)
|
||||
@@ -1391,12 +1386,12 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
VisitName = item.VisitName,
|
||||
|
||||
//非dicom
|
||||
NoneDicomStudyList = item.NoneDicomStudyList,
|
||||
NoneDicomStudyList = item.NoneDicomStudyList.Where(t => t.ReadingFileCount > 0).ToList(),
|
||||
}).ToList();
|
||||
|
||||
|
||||
result.AddRange(dicomStudyList);
|
||||
result.AddRange(noneStudyList);
|
||||
result.AddRange(dicomStudyList.Where(t => t.DicomStudyList.Count > 0));
|
||||
result.AddRange(noneStudyList.Where(t => t.NoneDicomStudyList.Count > 0));
|
||||
#endregion
|
||||
|
||||
return ResponseOutput.Ok(result);
|
||||
@@ -1497,7 +1492,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
CriterionModalitys = item.CriterionModalitys,
|
||||
SourceSubjectVisitId = item.SourceSubjectVisitId,
|
||||
//取dicom
|
||||
DicomStudyList = item.DicomStudyList,
|
||||
DicomStudyList = item.DicomStudyList.Where(t => t.ReadingSeriesCount > 0).ToList(),
|
||||
}).ToList();
|
||||
|
||||
var noneStudyList = list.Where(item => item.NoneDicomStudyList.Count > 0)
|
||||
@@ -1512,12 +1507,12 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
CriterionModalitys = item.CriterionModalitys,
|
||||
SourceSubjectVisitId = item.SourceSubjectVisitId,
|
||||
//非dicom
|
||||
NoneDicomStudyList = item.NoneDicomStudyList,
|
||||
NoneDicomStudyList = item.NoneDicomStudyList.Where(t => t.ReadingFileCount > 0).ToList()
|
||||
}).ToList();
|
||||
|
||||
|
||||
result.AddRange(dicomStudyList);
|
||||
result.AddRange(noneStudyList);
|
||||
result.AddRange(dicomStudyList.Where(t => t.DicomStudyList.Count > 0));
|
||||
result.AddRange(noneStudyList.Where(t => t.NoneDicomStudyList.Count > 0));
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -1675,7 +1670,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
#endregion
|
||||
|
||||
var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id) && t.CheckState == CheckStateEnum.CVPassed))
|
||||
//一致性分析,导致查询出来两条数据
|
||||
//一致性分析,导致查询出来两条数据
|
||||
join visitTask in _visitTaskRepository.Where(t => taskIdList.Contains(t.Id)) on sv.Id equals visitTask.SourceSubjectVisitId into cc
|
||||
from leftVisitTask in cc.DefaultIfEmpty()
|
||||
select new ImageDownloadDto()
|
||||
@@ -1897,16 +1892,18 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
/// <summary>
|
||||
/// 影像下载成功回调
|
||||
/// </summary>
|
||||
/// <param name="trialImageDownloadId"></param>
|
||||
/// <param name="incommand"></param>
|
||||
|
||||
/// <returns></returns>
|
||||
public async Task<IResponseOutput> DownloadImageSuccess(Guid trialImageDownloadId, Guid? visitTaskId)
|
||||
public async Task<IResponseOutput> DownloadImageSuccess(DownloadImageSuccessCommand incommand)
|
||||
{
|
||||
await _trialImageDownloadRepository.UpdatePartialFromQueryAsync(t => t.Id == trialImageDownloadId, u => new TrialImageDownload()
|
||||
await _trialImageDownloadRepository.UpdatePartialFromQueryAsync(t => t.Id == incommand.TrialImageDownloadId, u => new TrialImageDownload()
|
||||
{ DownloadEndTime = DateTime.Now, IsSuccess = true }, true);
|
||||
|
||||
if (visitTaskId != null)
|
||||
if (incommand.VisitTaskIdList != null && incommand.VisitTaskIdList.Count > 0)
|
||||
{
|
||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTaskId.Value, u => new VisitTask() { IsIRImageDownloaded = true });
|
||||
incommand.VisitTaskIdList = incommand.VisitTaskIdList.Distinct().ToList();
|
||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => incommand.VisitTaskIdList.Contains(t.Id), u => new VisitTask() { IsIRImageDownloaded = true });
|
||||
}
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
@@ -2465,18 +2462,42 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
SubjectCode = t.Code,
|
||||
IsUrgent = t.IsUrgent,
|
||||
|
||||
LatestDownloadTime = t.TrialImageDownloadList.Where(t => t.CreateUserRole.UserTypeEnum == UserTypeEnum.IndependentReviewer)
|
||||
.OrderByDescending(t => t.CreateTime).Select(t => (DateTime?)t.CreateTime).FirstOrDefault(),
|
||||
|
||||
LatestUploadTime = t.SubjectVisitList
|
||||
.Where(v => v.SubmitState == SubmitStateEnum.Submitted && v.CheckState == CheckStateEnum.CVPassed)
|
||||
.SelectMany(v => v.TaskStudyList)
|
||||
.Select(s => (DateTime?)s.CreateTime) // 假设字段名为 CreateTime,根据实际情况调整
|
||||
.Union(
|
||||
t.SubjectVisitList
|
||||
.Where(v => v.SubmitState == SubmitStateEnum.Submitted && v.CheckState == CheckStateEnum.CVPassed)
|
||||
.SelectMany(v => v.NoneDicomStudyList)
|
||||
.Where(n => n.ImageLabelNoneDicomFileList.Any())
|
||||
.Select(s => (DateTime?)s.CreateTime) // 假设字段名为 CreateTime,根据实际情况调整
|
||||
)
|
||||
.OrderByDescending(time => time)
|
||||
.FirstOrDefault(),
|
||||
|
||||
VisitCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).Count(),
|
||||
|
||||
MarkIVUSVisitCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).Count(t => t.NoneDicomStudyList.Where(t => t.Modality == "IVUS").SelectMany(c => c.ImageLabelNoneDicomFileList).Any()),
|
||||
|
||||
MarkOCTVisitCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).Count(t => t.NoneDicomStudyList.Where(t => t.Modality == "OCT").SelectMany(c => c.ImageLabelNoneDicomFileList).Any()),
|
||||
|
||||
DicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).SelectMany(t => t.StudyList).Count(),
|
||||
//MarkDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted).SelectMany(t => t.TaskStudyList).Count(),
|
||||
//DicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).SelectMany(t => t.StudyList).Count(),
|
||||
|
||||
NoneDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).SelectMany(t => t.NoneDicomStudyList).Count(),
|
||||
//MarkNoneDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted).SelectMany(t => t.NoneDicomStudyList).Where(t => t.ImageLabelNoneDicomFileList.Any()).Count(),
|
||||
}).ToPagedListAsync(inQuery);
|
||||
//MarkDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).SelectMany(t => t.TaskStudyList).Count(),
|
||||
|
||||
//NoneDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).SelectMany(t => t.NoneDicomStudyList).Count(),
|
||||
|
||||
//MarkNoneDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.CheckState == CheckStateEnum.CVPassed).SelectMany(t => t.NoneDicomStudyList).Where(t => t.ImageLabelNoneDicomFileList.Any()).Count(),
|
||||
})
|
||||
.Where(t => t.VisitCount > 0)
|
||||
.WhereIf(inQuery.State == 0, t => t.LatestDownloadTime == null)//待处理
|
||||
.WhereIf(inQuery.State == 1, t => t.LatestDownloadTime != null && (2 * t.VisitCount) != (t.MarkIVUSVisitCount + t.MarkOCTVisitCount))//处理中
|
||||
.WhereIf(inQuery.State == 2, t => t.LatestDownloadTime != null && (2 * t.VisitCount) == (t.MarkIVUSVisitCount + t.MarkOCTVisitCount))//已完成
|
||||
.ToPagedListAsync(inQuery);
|
||||
|
||||
return ResponseOutput.Ok(list);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace IRaCIS.Core.Application.Services
|
||||
{
|
||||
[ApiExplorerSettings(GroupName = "Image")]
|
||||
[AllowAnonymous]
|
||||
public class InstanceService(IRepository<DicomInstance> _instanceRepository,
|
||||
public class InstanceService(IRepository<DicomInstance> _instanceRepository, IRepository<DicomSeries> _seriesRepository,
|
||||
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService, IInstanceService
|
||||
{
|
||||
|
||||
@@ -29,12 +29,15 @@ namespace IRaCIS.Core.Application.Services
|
||||
.OrderBy(s => s.InstanceNumber).ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
|
||||
.ProjectTo<DicomInstanceDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
var des = _seriesRepository.Where(t => t.Id == seriesId).Select(t => t.Description).FirstOrDefault();
|
||||
|
||||
// ⭐ DICOM 空间排序(带兜底)
|
||||
var sorted = DicomSortHelper.SortSlices(
|
||||
list,
|
||||
x => x.ImagePositionPatient,
|
||||
x => x.ImageOrientationPatient,
|
||||
x => x.InstanceNumber
|
||||
x => x.InstanceNumber,
|
||||
des
|
||||
);
|
||||
|
||||
var seriesInfo = await _instanceRepository.Where(s => s.SeriesId == seriesId).Select(t => new
|
||||
|
||||
@@ -59,7 +59,8 @@ namespace IRaCIS.Core.Application.Services
|
||||
instances,
|
||||
x => x.ImagePositionPatient,
|
||||
x => x.ImageOrientationPatient,
|
||||
x => x.InstanceNumber
|
||||
x => x.InstanceNumber,
|
||||
series.Description
|
||||
);
|
||||
|
||||
series.InstanceInfoList = sorted.Select(k =>
|
||||
@@ -104,13 +105,24 @@ namespace IRaCIS.Core.Application.Services
|
||||
.WhereIf(isReading == true, t => t.IsReading == true)
|
||||
.OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber)
|
||||
.ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
|
||||
.Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber, t.HtmlPath, t.IsReading, t.IsDeleted, t.FileSize ,t.IsMasked}).ToListAsync();//.GroupBy(u => u.SeriesId);
|
||||
.Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber, t.HtmlPath, t.IsReading, t.IsDeleted, t.FileSize ,t.IsMasked, t.ImagePositionPatient, t.ImageOrientationPatient }).ToListAsync();//.GroupBy(u => u.SeriesId);
|
||||
|
||||
|
||||
foreach (var series in seriesList)
|
||||
{
|
||||
|
||||
series.InstanceInfoList = instanceList.Where(t => t.SeriesId == series.Id).OrderBy(t => t.InstanceNumber).Select(k =>
|
||||
var instances = instanceList.Where(x => x.SeriesId == series.Id);
|
||||
|
||||
// ⭐ DICOM 空间排序(带兜底)
|
||||
var sorted = DicomSortHelper.SortSlices(
|
||||
instances,
|
||||
x => x.ImagePositionPatient,
|
||||
x => x.ImageOrientationPatient,
|
||||
x => x.InstanceNumber,
|
||||
series.Description
|
||||
);
|
||||
|
||||
series.InstanceInfoList = sorted.Select(k =>
|
||||
new InstanceBasicInfo()
|
||||
{
|
||||
Id = k.Id,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using DocumentFormat.OpenXml.InkML;
|
||||
using FellowOakDicom;
|
||||
using FellowOakDicom;
|
||||
using FellowOakDicom.Imaging;
|
||||
using FellowOakDicom.IO.Buffer;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
@@ -68,80 +67,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class DeleteImagePathCommand
|
||||
{
|
||||
public string Path { get; set; }
|
||||
}
|
||||
|
||||
public async Task<IResponseOutput> DeleteImageCache(DeleteImagePathCommand incommand)
|
||||
{
|
||||
await _oSSService.DeleteFromPrefix(incommand.Path, true);
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
public async Task<IResponseOutput> GetAnonymizeInfo(Guid visitTaskId, Guid? subjectVisitId)
|
||||
{
|
||||
|
||||
Guid svId = Guid.Empty;
|
||||
|
||||
if (subjectVisitId != null)
|
||||
{
|
||||
svId = subjectVisitId.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
svId = (Guid)_visitTaskRepository.Where(t => t.Id == visitTaskId).Select(t => t.SourceSubjectVisitId).FirstOrDefault();
|
||||
|
||||
}
|
||||
|
||||
// 写入dicom 固定的信息,以及组织路径的信息 以及匿名化的信息
|
||||
var otherData = GetSaveToDicomInfo(svId);
|
||||
|
||||
var anonymizeList = _fusionCache.GetOrSetAsync(CacheKeys.SystemAnonymization, _ => CacheHelper.GetSystemAnonymizationListAsync(_systemAnonymizationRepository), TimeSpan.FromDays(7)).Result;
|
||||
|
||||
return ResponseOutput.Ok(new
|
||||
{
|
||||
DicomStoreInfo = otherData,
|
||||
AnonymizeFixedList = anonymizeList.Where(t => t.IsFixed).ToList(),
|
||||
AnonymizeNotFixedList = anonymizeList.Where(t => t.IsFixed == false).ToList()
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<IResponseOutput> UpdateModality(Guid seriesId, string modality, bool isCRCReplace,
|
||||
[FromServices] IRepository<TaskSeries> _taskSeriesRepository,
|
||||
[FromServices] IRepository<TaskStudy> _taskStudyRepository
|
||||
)
|
||||
{
|
||||
if (isCRCReplace)
|
||||
{
|
||||
await _dicomSeriesRepository.BatchUpdateNoTrackingAsync(t => t.Id == seriesId, u => new DicomSeries() { Modality = modality });
|
||||
|
||||
var studyId = _dicomSeriesRepository.Where(t => t.Id == seriesId).Select(t => t.StudyId).FirstOrDefault();
|
||||
|
||||
//处理Modality
|
||||
var seriesModalityList = _dicomStudyRepository.Where(t => t.Id == studyId).SelectMany(u => u.SeriesList.Select(t => t.Modality)).Distinct();
|
||||
string ModaliyStr = string.Join('、', seriesModalityList.ToList());
|
||||
|
||||
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == studyId, u => new DicomStudy() { Modalities = ModaliyStr });
|
||||
}
|
||||
else
|
||||
{
|
||||
await _taskSeriesRepository.BatchUpdateNoTrackingAsync(t => t.Id == seriesId, u => new TaskSeries() { Modality = modality });
|
||||
|
||||
|
||||
var studyId = _taskSeriesRepository.Where(t => t.Id == seriesId).Select(t => t.StudyId).FirstOrDefault();
|
||||
|
||||
//处理Modality
|
||||
var seriesModalityList = _taskStudyRepository.Where(t => t.Id == studyId).SelectMany(u => u.SeriesList.Select(t => t.Modality)).Distinct();
|
||||
string ModaliyStr = string.Join('、', seriesModalityList.ToList());
|
||||
|
||||
await _taskStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == studyId, u => new TaskStudy() { Modalities = ModaliyStr });
|
||||
|
||||
}
|
||||
return ResponseOutput.Ok();
|
||||
|
||||
}
|
||||
|
||||
private static async Task<bool> TryWriteMergedDicomAsync(Func<Task<Stream>> sourceFactory, Stream output)
|
||||
{
|
||||
@@ -656,9 +581,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
};
|
||||
|
||||
|
||||
//var addEntity = await _studyMonitorRepository.AddAsync(studyMonitor, true);
|
||||
var addEntity = await _studyMonitorRepository.AddAsync(studyMonitor, true);
|
||||
|
||||
return ResponseOutput.Ok(Guid.NewGuid());
|
||||
return ResponseOutput.Ok(addEntity.Id);
|
||||
|
||||
}
|
||||
|
||||
@@ -719,20 +644,20 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
{
|
||||
var trialId = incommand.TrialId;
|
||||
|
||||
//var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId);
|
||||
//studyMonitor.UploadFinishedTime = DateTime.Now;
|
||||
//studyMonitor.ArchiveFinishedTime = DateTime.Now;
|
||||
//studyMonitor.FailedFileCount = incommand.FailedFileCount;
|
||||
//studyMonitor.IsSuccess = incommand.FailedFileCount == 0;
|
||||
//studyMonitor.RecordPath = incommand.RecordPath;
|
||||
//studyMonitor.FileSize = incommand.Study.SeriesList.SelectMany(t => t.InstanceList).Sum(t => t.FileSize);
|
||||
var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId);
|
||||
studyMonitor.UploadFinishedTime = DateTime.Now;
|
||||
studyMonitor.ArchiveFinishedTime = DateTime.Now;
|
||||
studyMonitor.FailedFileCount = incommand.FailedFileCount;
|
||||
studyMonitor.IsSuccess = incommand.FailedFileCount == 0;
|
||||
studyMonitor.RecordPath = incommand.RecordPath;
|
||||
studyMonitor.FileSize = incommand.Study.SeriesList.SelectMany(t => t.InstanceList).Sum(t => t.FileSize);
|
||||
|
||||
var studyId = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString());
|
||||
var findStudy = await _dicomStudyRepository.FirstOrDefaultAsync(t => t.Id == studyId);
|
||||
|
||||
//studyMonitor.StudyId = studyId;
|
||||
//studyMonitor.StudyCode = findStudy?.StudyCode ?? "";
|
||||
//studyMonitor.IsDicomReUpload = findStudy != null;
|
||||
studyMonitor.StudyId = studyId;
|
||||
studyMonitor.StudyCode = findStudy?.StudyCode ?? "";
|
||||
studyMonitor.IsDicomReUpload = findStudy != null;
|
||||
|
||||
|
||||
if (incommand.Study.SeriesList.SelectMany(t => t.InstanceList).Count() == 0)
|
||||
@@ -743,7 +668,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
}
|
||||
|
||||
//上传
|
||||
if ((findStudy != null) == false)
|
||||
if (studyMonitor.IsDicomReUpload == false)
|
||||
{
|
||||
var addStudy = _mapper.Map<DicomStudy>(incommand.Study);
|
||||
|
||||
@@ -788,7 +713,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
|
||||
|
||||
//studyMonitor.StudyCode = addStudy.StudyCode;
|
||||
studyMonitor.StudyCode = addStudy.StudyCode;
|
||||
|
||||
|
||||
foreach (var seriesItem in incommand.Study.SeriesList)
|
||||
@@ -847,14 +772,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
|
||||
DicomSeries dicomSeries = await _dicomSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
|
||||
|
||||
|
||||
var isNewSeries = false;
|
||||
|
||||
//判断重复
|
||||
if (dicomSeries == null)
|
||||
{
|
||||
isNewSeries = true;
|
||||
|
||||
var series = _mapper.Map<DicomSeries>(seriesItem);
|
||||
|
||||
series.Id = seriesId;
|
||||
@@ -870,53 +790,29 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||
//新的序列 那么 检查的序列数量+1
|
||||
findStudy.SeriesCount += 1;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// //该序列掉了instance
|
||||
// dicomSeries.InstanceCount += seriesItem.InstanceList.Count;
|
||||
//}
|
||||
|
||||
|
||||
//找到该序列已经存在的instanceId
|
||||
var existInstanceIdList = _dicomInstanceRepository.Where(t => t.SeriesId == dicomSeries.Id).Select(t => t.Id).ToList();
|
||||
else
|
||||
{
|
||||
//该序列掉了instance
|
||||
dicomSeries.InstanceCount += seriesItem.InstanceList.Count;
|
||||
}
|
||||
|
||||
foreach (var instanceItem in seriesItem.InstanceList)
|
||||
{
|
||||
var insntance = _mapper.Map<DicomInstance>(instanceItem);
|
||||
insntance.Id = IdentifierHelper.CreateGuid(insntance.StudyInstanceUid, insntance.SeriesInstanceUid, insntance.SopInstanceUid, trialId.ToString());
|
||||
insntance.StudyId = findStudy.Id;
|
||||
insntance.SeriesId = dicomSeries.Id;
|
||||
|
||||
if (!existInstanceIdList.Any(t => t == insntance.Id))
|
||||
{
|
||||
insntance.StudyId = findStudy.Id;
|
||||
insntance.SeriesId = dicomSeries.Id;
|
||||
|
||||
insntance.TrialId = incommand.TrialId;
|
||||
insntance.SubjectId = incommand.SubjectId;
|
||||
insntance.SubjectVisitId = incommand.SubjectVisitId;
|
||||
|
||||
await _dicomInstanceRepository.AddAsync(insntance);
|
||||
|
||||
if (isNewSeries == false)
|
||||
{
|
||||
dicomSeries.InstanceCount++;
|
||||
}
|
||||
|
||||
findStudy.InstanceCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
//更新,需要删除缓存,并更新路径
|
||||
|
||||
await _oSSService.DeleteFromPrefix(insntance.Path, true);
|
||||
|
||||
await _dicomInstanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == insntance.Id, u => new DicomInstance() { Path = insntance.Path });
|
||||
}
|
||||
insntance.TrialId = incommand.TrialId;
|
||||
insntance.SubjectId = incommand.SubjectId;
|
||||
insntance.SubjectVisitId = incommand.SubjectVisitId;
|
||||
|
||||
await _dicomInstanceRepository.AddAsync(insntance);
|
||||
}
|
||||
|
||||
|
||||
//// 不管是新的序列 还是 该序列 掉了Instance 重传的时候 检查的instance 数量都会增加
|
||||
//findStudy.InstanceCount += seriesItem.InstanceList.Count;
|
||||
// 不管是新的序列 还是 该序列 掉了Instance 重传的时候 检查的instance 数量都会增加
|
||||
findStudy.InstanceCount += seriesItem.InstanceList.Count;
|
||||
|
||||
|
||||
if (incommand.Study.RadionuclideTotalDose != string.Empty
|
||||
|
||||
@@ -168,19 +168,6 @@ namespace IRaCIS.Core.Application.Service
|
||||
.Where(t => t.UserTypeId == _userInfo.UserTypeId && (t.Menu.MenuType == "M" || t.Menu.MenuType == "C") && t.Menu.IsEnable)
|
||||
.ProjectTo<MenuTreeNode>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
|
||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA)
|
||||
{
|
||||
var otherGuid = new List<Guid>() { Guid.Parse("41d2bcbe-4ae2-4158-856e-08da0661d17d"), Guid.Parse("5acebe02-99de-4e39-f090-08da0c7fe82c") };
|
||||
|
||||
var otherlist = await _userTypeMenuRepository
|
||||
.Where(t => otherGuid.Contains(t.MenuId) && (t.Menu.MenuType == "M" || t.Menu.MenuType == "C") && t.Menu.IsEnable)
|
||||
.ProjectTo<MenuTreeNode>(_mapper.ConfigurationProvider).Distinct().ToListAsync();
|
||||
|
||||
menuFunctionlist.AddRange(otherlist);
|
||||
}
|
||||
|
||||
|
||||
var list = menuFunctionlist!.ToTree((root, child) => child!.ParentId == Guid.Empty,
|
||||
(root, child) => child!.ParentId == root!.MenuId,
|
||||
(child, datalist) =>
|
||||
|
||||
@@ -250,6 +250,37 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
public string TaskBlindName { get; set; }
|
||||
|
||||
public string SubjectID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 靶段
|
||||
/// </summary>
|
||||
public string TargetSegment { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 靶段备注
|
||||
/// </summary>
|
||||
public string TargetSegmentRemarks { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// ROI段落总长度
|
||||
/// </summary>
|
||||
public string ROIAllLength { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 回撤中的图像帧数
|
||||
/// </summary>
|
||||
public string PullbackFrameCount { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 斑块类型
|
||||
/// </summary>
|
||||
public string PlaqueType { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 访视点备注(如有)
|
||||
/// </summary>
|
||||
public string AdjustReason { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
|
||||
public class OCTFCTUploadData
|
||||
|
||||
@@ -2199,6 +2199,21 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
/// </summary>
|
||||
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
|
||||
@@ -2437,6 +2452,102 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
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>();
|
||||
/// <summary>
|
||||
/// 本次生成裁判的触发问题(包含自动计算题追溯到的源问题)
|
||||
/// </summary>
|
||||
public List<Guid> TriggerJudgeQuestionIds { get; set; } = new List<Guid>();
|
||||
public List<JudgeFormQuestionDto> QuestionList { get; set; } = new List<JudgeFormQuestionDto>();
|
||||
}
|
||||
|
||||
public class JudgeFormQuestionDto
|
||||
{
|
||||
public Guid ReadingQuestionId { get; set; }
|
||||
/// <summary>
|
||||
/// 是否为本次生成裁判的触发问题
|
||||
/// </summary>
|
||||
public bool IsTriggerJudge { get; set; }
|
||||
public string QuestionName { get; set; } = string.Empty;
|
||||
public string Type { get; set; } = string.Empty;
|
||||
|
||||
public ShowQuestion ShowQuestion { get; set; }
|
||||
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 DataSources DataSource { get; set; }
|
||||
public string? CustomUnit { get; set; }
|
||||
public ValueOfType? ValueType { get; set; }
|
||||
public string ClassifyAlgorithms { get; set; }
|
||||
|
||||
public ClassifyType? ClassifyType { get; set; }
|
||||
|
||||
public Guid? ClassifyQuestionId { 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 string VisitName { get; set; }
|
||||
@@ -2908,12 +3019,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
|
||||
{
|
||||
|
||||
@@ -6,6 +6,104 @@ using System.ComponentModel.DataAnnotations.Schema;
|
||||
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 CopyTrialQuestionVisitJudgeRuleInDto
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid TrialReadingCriterionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源访视
|
||||
/// </summary>
|
||||
public decimal SourceVisitNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标访视
|
||||
/// </summary>
|
||||
public decimal TargetVisitNum { get; set; }
|
||||
}
|
||||
|
||||
public class ApplyBaseLineTrialQuestionVisitJudgeRuleInDto
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid TrialReadingCriterionId { get; set; }
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
@@ -702,6 +800,16 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
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 Guid TrialId { get; set; }
|
||||
@@ -717,6 +825,24 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
/// 仲裁规则
|
||||
/// </summary>
|
||||
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
|
||||
@@ -1625,6 +1751,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
||||
|
||||
public bool IsGetAll { get; set; } = false;
|
||||
|
||||
public bool IsGetJudge { get; set; } = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
Task TriggerJudgeQuestion(Guid visitTaskId);
|
||||
Task<IResponseOutput> SubmitVisitTaskQuestions(SubmitVisitTaskQuestionsInDto inDto);
|
||||
|
||||
Task<IResponseOutput> SubmitJudgeForm(SetJudgeFormInDto inDto);
|
||||
Task<IResponseOutput> SubmitJudgeVisitTaskResult(SaveJudgeVisitTaskResult inDto);
|
||||
|
||||
Task<GetOncologyReadingInfoOutDto> GetOncologyReadingInfo(GetOncologyReadingInfoInDto inDto);
|
||||
|
||||
+51
-3
@@ -370,13 +370,62 @@ namespace IRaCIS.Core.Application.Service.RC
|
||||
TrialId = x.TrialId,
|
||||
IsReadingTaskViewInOrder = x.IsReadingTaskViewInOrder,
|
||||
ArbitrationRule = x.ArbitrationRule,
|
||||
IsArbitrationReading = x.IsArbitrationReading
|
||||
|
||||
IsArbitrationReading = x.IsArbitrationReading,
|
||||
JudgeModeEnum = x.JudgeModeEnum,
|
||||
JudgeRuleEnum = x.JudgeRuleEnum,
|
||||
JudgeGenerateEnum = x.JudgeGenerateEnum,
|
||||
IsSigned = x.IsSigned,
|
||||
}).FirstNotNullAsync();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑裁判规则配置
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> SetTrialJudgeRuleInfo(SetTrialJudgeRuleInfoInDto inDto)
|
||||
{
|
||||
if (inDto.JudgeRuleEnum == JudgeRule.Consistent)
|
||||
{
|
||||
if (await _readingQuestionTrialRepository.AnyAsync(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId&& x.IsJudgeQuestion && x.LimitShow != LimitShow.AllShow))
|
||||
{
|
||||
|
||||
|
||||
var questionList = await _readingQuestionTrialRepository
|
||||
.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion && x.LimitShow != LimitShow.AllShow)
|
||||
.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 questionName=string.Join(",", questionList.Select(x => x.QuestionName));
|
||||
|
||||
|
||||
//---当前标准裁判规则为一致性,但存在非全部显示的裁判问题,操作失败
|
||||
throw new BusinessValidationFailedException(_localizer["JudgeCanNotLimitShow", questionName]);
|
||||
}
|
||||
}
|
||||
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>
|
||||
@@ -482,7 +531,6 @@ namespace IRaCIS.Core.Application.Service.RC
|
||||
return ResponseOutput.Ok(result);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region 项目阅片标准问题分页
|
||||
|
||||
+271
-2
@@ -1,3 +1,4 @@
|
||||
using DocumentFormat.OpenXml.Office.SpreadSheetML.Y2023.MsForms;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
@@ -33,10 +34,225 @@ namespace IRaCIS.Core.Application.Service
|
||||
IRepository<OrganInfo> _organInfoRepository,
|
||||
IRepository<ReadingTableQuestionSystem> _readingTableQuestionSystemRepository,
|
||||
IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswer,
|
||||
IRepository<PreviousPDF> _previousPDFRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IReadingQuestionService
|
||||
IRepository<PreviousPDF> _previousPDFRepository,
|
||||
IRepository<ReadingQuestionVisitJudgeRule> _readingQuestionVisitJudgeRuleRepository,
|
||||
IRepository<VisitStage> _visitStageRepository,
|
||||
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.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion)
|
||||
.Where(x => x.LimitShow == LimitShow.AllShow
|
||||
|| (x.LimitShow == LimitShow.BaseLineShow && inDto.VisitNum == 0)
|
||||
|| (x.LimitShow == LimitShow.FollowShow && inDto.VisitNum != 0)
|
||||
|| (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(inDto.VisitNum)))
|
||||
.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 = inDto.QuestionList.Select(x => x.ReadingQuestionTrialId).ToList();
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制其他访视的项目阅片标准裁判规则配置。
|
||||
/// 目标访视不适用的问题保留其已有的不适用规则,不参与复制。
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> CopyTrialQuestionVisitJudgeRule(CopyTrialQuestionVisitJudgeRuleInDto inDto)
|
||||
{
|
||||
var targetQuestionIds = await _readingQuestionTrialRepository
|
||||
.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion)
|
||||
.Where(x => x.LimitShow == LimitShow.AllShow
|
||||
|| (x.LimitShow == LimitShow.BaseLineShow && inDto.TargetVisitNum == 0)
|
||||
|| (x.LimitShow == LimitShow.FollowShow && inDto.TargetVisitNum != 0)
|
||||
|| (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(inDto.TargetVisitNum)))
|
||||
.Select(x => x.Id)
|
||||
.ToListAsync();
|
||||
|
||||
if (targetQuestionIds.Count == 0)
|
||||
{
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
var sourceRules = await _readingQuestionVisitJudgeRuleRepository
|
||||
.Where(x => x.VisitNum == inDto.SourceVisitNum && targetQuestionIds.Contains(x.ReadingQuestionId))
|
||||
.ToListAsync();
|
||||
|
||||
await _readingQuestionVisitJudgeRuleRepository.BatchDeleteNoTrackingAsync(x =>
|
||||
x.VisitNum == inDto.TargetVisitNum && targetQuestionIds.Contains(x.ReadingQuestionId));
|
||||
|
||||
var targetRules = sourceRules.Select(rule => new ReadingQuestionVisitJudgeRule
|
||||
{
|
||||
Id = NewId.NextGuid(),
|
||||
ReadingQuestionId = rule.ReadingQuestionId,
|
||||
VisitNum = inDto.TargetVisitNum,
|
||||
AnswerGroup = rule.AnswerGroup,
|
||||
AnswerCombination = rule.AnswerCombination,
|
||||
JudgeType = rule.JudgeType,
|
||||
JudgeDifferenceValue = rule.JudgeDifferenceValue,
|
||||
JudgeDifferenceType = rule.JudgeDifferenceType,
|
||||
}).ToList();
|
||||
|
||||
if (targetRules.Count > 0)
|
||||
{
|
||||
await _readingQuestionVisitJudgeRuleRepository.AddRangeAsync(targetRules);
|
||||
}
|
||||
|
||||
return ResponseOutput.Result(await _readingQuestionVisitJudgeRuleRepository.SaveChangesAsync());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将基线访视(VisitNum = 0)的裁判规则配置应用到其他所有访视。
|
||||
/// 仅复制在基线和目标访视均适用的问题;目标访视不适用的问题保留其已有规则。
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> ApplyBaseLineTrialQuestionVisitJudgeRule(ApplyBaseLineTrialQuestionVisitJudgeRuleInDto inDto)
|
||||
{
|
||||
var trialCriterion = await _readingQuestionCriterionTrialRepository
|
||||
.Where(x => x.Id == inDto.TrialReadingCriterionId)
|
||||
.FirstNotNullAsync();
|
||||
|
||||
var targetVisitNums = await _visitStageRepository
|
||||
.Where(x => x.TrialId == trialCriterion.TrialId && x.VisitNum != 0)
|
||||
.Select(x => x.VisitNum)
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
|
||||
// 计划外访视不在 VisitStage 中,也应同步基线规则。
|
||||
targetVisitNums.Add(-1);
|
||||
targetVisitNums = targetVisitNums.Distinct().ToList();
|
||||
|
||||
var rulesToAdd = new List<ReadingQuestionVisitJudgeRule>();
|
||||
foreach (var targetVisitNum in targetVisitNums)
|
||||
{
|
||||
// 仅保留在基线和当前目标访视都显示的问题。
|
||||
var targetQuestionIds = await _readingQuestionTrialRepository
|
||||
.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion)
|
||||
.Where(x => x.LimitShow == LimitShow.AllShow
|
||||
|| (x.LimitShow == LimitShow.ExcludeSomeVisits
|
||||
&& !x.ExcludeShowVisitList.Contains(0)
|
||||
&& !x.ExcludeShowVisitList.Contains(targetVisitNum)))
|
||||
.Select(x => x.Id)
|
||||
.ToListAsync();
|
||||
|
||||
if (targetQuestionIds.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var baseLineRules = await _readingQuestionVisitJudgeRuleRepository
|
||||
.Where(x => x.VisitNum == 0 && targetQuestionIds.Contains(x.ReadingQuestionId))
|
||||
.ToListAsync();
|
||||
|
||||
await _readingQuestionVisitJudgeRuleRepository.BatchDeleteNoTrackingAsync(x =>
|
||||
x.VisitNum == targetVisitNum && targetQuestionIds.Contains(x.ReadingQuestionId));
|
||||
|
||||
rulesToAdd.AddRange(baseLineRules.Select(rule => new ReadingQuestionVisitJudgeRule
|
||||
{
|
||||
Id = NewId.NextGuid(),
|
||||
ReadingQuestionId = rule.ReadingQuestionId,
|
||||
VisitNum = targetVisitNum,
|
||||
AnswerGroup = rule.AnswerGroup,
|
||||
AnswerCombination = rule.AnswerCombination,
|
||||
JudgeType = rule.JudgeType,
|
||||
JudgeDifferenceValue = rule.JudgeDifferenceValue,
|
||||
JudgeDifferenceType = rule.JudgeDifferenceType,
|
||||
}));
|
||||
}
|
||||
|
||||
if (rulesToAdd.Count > 0)
|
||||
{
|
||||
await _readingQuestionVisitJudgeRuleRepository.AddRangeAsync(rulesToAdd);
|
||||
await _readingQuestionVisitJudgeRuleRepository.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return ResponseOutput.Result(true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 获取计算问题
|
||||
|
||||
@@ -570,7 +786,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
if (isArbitrationReading && (await _readingQuestionTrialRepository.AnyAsync(x => x.Id == indto.Id && x.IsJudgeQuestion && x.JudgeType != JudgeTypeEnum.None)))
|
||||
{
|
||||
//---当前问题已经设置了裁判标准了,修改失败
|
||||
throw new BusinessValidationFailedException(_localizer["ReadingQuestion_JudgmentSet"]);
|
||||
// throw new BusinessValidationFailedException(_localizer["ReadingQuestion_JudgmentSet"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -620,9 +836,61 @@ namespace IRaCIS.Core.Application.Service
|
||||
}
|
||||
|
||||
var entity = await _readingQuestionTrialRepository.InsertOrUpdateAsync(indto, true);
|
||||
await AddNAJudgeRule(entity);
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加问题的不适用规则
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task AddNAJudgeRule(ReadingQuestionTrial entity)
|
||||
{
|
||||
List<decimal> visitNums = new List<decimal>();
|
||||
if (entity.IsJudgeQuestion)
|
||||
{
|
||||
var visitStageNums = await _visitStageRepository
|
||||
.Where(x => x.TrialId == entity.TrialId)
|
||||
.Select(x => x.VisitNum)
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
|
||||
switch (entity.LimitShow)
|
||||
{
|
||||
case LimitShow.BaseLineShow:
|
||||
visitNums = visitStageNums.Where(x => x > 0).ToList();
|
||||
visitNums.Add(-1);
|
||||
break;
|
||||
case LimitShow.FollowShow:
|
||||
visitNums.Add(0);
|
||||
break;
|
||||
case LimitShow.ExcludeSomeVisits:
|
||||
visitNums = entity.ExcludeShowVisitList;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (visitNums.Count==0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
await _readingQuestionVisitJudgeRuleRepository.BatchDeleteNoTrackingAsync(x =>
|
||||
x.ReadingQuestionId == entity.Id && visitNums.Contains(x.VisitNum));
|
||||
|
||||
var rules = visitNums.Select(visitNum => new ReadingQuestionVisitJudgeRule
|
||||
{
|
||||
Id = NewId.NextGuid(),
|
||||
ReadingQuestionId = entity.Id,
|
||||
VisitNum = visitNum,
|
||||
JudgeType = JudgeTypeEnum.NotApplicable,
|
||||
}).ToList();
|
||||
|
||||
await _readingQuestionVisitJudgeRuleRepository.AddRangeAsync(rules);
|
||||
await _readingQuestionVisitJudgeRuleRepository.SaveChangesAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目问题(项目)
|
||||
/// </summary>
|
||||
@@ -687,6 +955,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
if (inDto.TrialReadingCriterionId != null)
|
||||
{
|
||||
return await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId)
|
||||
.WhereIf(inDto.IsGetJudge,x=>x.IsJudgeQuestion)
|
||||
.WhereIf(!inDto.IsGetAll, x => x.DataSource == DataSources.Automatic && x.Type == "number")
|
||||
.Select(x => new CalculateRelationDto()
|
||||
{
|
||||
|
||||
+26
-17
@@ -26,6 +26,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
public partial class ReadingImageTaskService(
|
||||
IRepository<NoneDicomStudy> _noneDicomStudyRepository,
|
||||
IRepository<VisitTask> _visitTaskRepository,
|
||||
IRepository<VisitStage> _visitStageRepository,
|
||||
IRepository<Trial> _trialRepository,
|
||||
IRepository<TaskInstance> _taskInstanceRepository,
|
||||
IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository,
|
||||
@@ -66,6 +67,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository,
|
||||
IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository,
|
||||
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
||||
IRepository<ReadingQuestionVisitJudgeRule> _readingQuestionVisitJudgeRuleRepository,
|
||||
IRepository<ReadingQuestionSystem> _readingQuestionSystem,
|
||||
IRepository<CriterionKeyFileRead> _criterionKeyFileReadRepository,
|
||||
IRepository<TrialCriterionKeyFile> _trialCriterionKeyFileRepository,
|
||||
@@ -1074,28 +1076,28 @@ namespace IRaCIS.Core.Application.Service
|
||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
private async Task VerifyTaskIsSign(Guid visitTaskid)
|
||||
{
|
||||
//var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskid).FirstNotNullAsync();
|
||||
var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskid).FirstNotNullAsync();
|
||||
|
||||
//if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskid && x.ReadingTaskState == ReadingTaskState.HaveSigned))
|
||||
//{
|
||||
// throw new BusinessValidationFailedException(_localizer["ReadingImage_BeSigned"]);
|
||||
//}
|
||||
if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskid && x.ReadingTaskState == ReadingTaskState.HaveSigned))
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ReadingImage_BeSigned"]);
|
||||
}
|
||||
|
||||
|
||||
//if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskid && x.TaskState != TaskState.Effect))
|
||||
//{
|
||||
// throw new BusinessValidationFailedException(_localizer["ReadingImage_Beinvalid"]);
|
||||
//}
|
||||
if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskid && x.TaskState != TaskState.Effect))
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ReadingImage_Beinvalid"]);
|
||||
}
|
||||
|
||||
//if (await _visitTaskRepository.AnyAsync(x => x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
|
||||
//&& x.IsAnalysisCreate && taskInfo.IsAnalysisCreate
|
||||
//&& x.SubjectId == taskInfo.SubjectId && x.TaskState == TaskState.Effect &&
|
||||
//((x.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && x.DoctorUserId == taskInfo.DoctorUserId) || x.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
|
||||
if (await _visitTaskRepository.AnyAsync(x => x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
|
||||
&& x.IsAnalysisCreate && taskInfo.IsAnalysisCreate
|
||||
&& x.SubjectId == taskInfo.SubjectId && x.TaskState == TaskState.Effect &&
|
||||
((x.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && x.DoctorUserId == taskInfo.DoctorUserId) || x.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
|
||||
|
||||
//))
|
||||
//{
|
||||
// throw new BusinessValidationFailedException(_localizer["ReadingImage_PresenceReview"]);
|
||||
//}
|
||||
))
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ReadingImage_PresenceReview"]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3920,6 +3922,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
x.ReadingToolList,
|
||||
x.CircleRadius,
|
||||
x.DefaultSegmentName,
|
||||
x.JudgeGenerateEnum,
|
||||
x.JudgeModeEnum,
|
||||
x.JudgeRuleEnum,
|
||||
x.ArbitrationRule,
|
||||
}).FirstNotNullAsync();
|
||||
|
||||
task.IsReadingShowPreviousResults = criterionInfo.IsReadingShowPreviousResults;
|
||||
@@ -3983,6 +3989,9 @@ namespace IRaCIS.Core.Application.Service
|
||||
task.IsViewStudyPart = visitTaskInfo.ReadingCategory == ReadingCategory.Judge || visitTaskInfo.IsViewStudyPart;
|
||||
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.JudgeModeEnum = criterionInfo.JudgeModeEnum;
|
||||
task.JudgeRuleEnum = criterionInfo.JudgeRuleEnum;
|
||||
task.ArbitrationRule = criterionInfo.ArbitrationRule;
|
||||
// 添加默认答案
|
||||
if (inDto.VisitTaskId == null && visitTaskInfo.ReadingTaskState != ReadingTaskState.HaveSigned)
|
||||
{
|
||||
|
||||
+535
-44
@@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MimeKit;
|
||||
using Newtonsoft.Json;
|
||||
using System.Linq.Dynamic.Core;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
@@ -23,6 +24,29 @@ namespace IRaCIS.Core.Application.Service
|
||||
/// </summary>
|
||||
public partial class ReadingImageTaskService : BaseService, IReadingImageTaskService
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 统一生成裁判任务
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task PhasedGenerationJudge(Guid trialReadingCriterionId)
|
||||
{
|
||||
var visitTaskList = await _visitTaskRepository.Where(x =>
|
||||
x.TrialReadingCriterionId == trialReadingCriterionId
|
||||
&& (x.ReadingCategory == ReadingCategory.Visit||x.ReadingCategory == ReadingCategory.Global)
|
||||
&&x.ReadingTaskState == ReadingTaskState.HaveSigned
|
||||
&&x.TaskState==TaskState.Effect
|
||||
&&!x.IsCalculatedJudge
|
||||
).ToListAsync();
|
||||
|
||||
foreach (var item in visitTaskList)
|
||||
{
|
||||
await TriggerJudgeQuestion(item.Id);
|
||||
}
|
||||
}
|
||||
|
||||
#region 配置裁判问题相关
|
||||
|
||||
/// <summary>
|
||||
@@ -91,6 +115,337 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
|
||||
#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, false);
|
||||
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 judgeDataInfo = await _readingJudgeInfoRepository
|
||||
.Where(x => x.JudgeTaskId == inDto.VisitTaskId)
|
||||
.FirstNotNullAsync();
|
||||
|
||||
var taskIds = new List<Guid> { judgeDataInfo.TaskIdOne, judgeDataInfo.TaskIdTwo };
|
||||
|
||||
var readingTask = await _visitTaskRepository
|
||||
.Where(x => taskIds.Contains(x.Id))
|
||||
.Select(x => new
|
||||
{
|
||||
x.Id,
|
||||
x.ArmEnum,
|
||||
x.TrialReadingCriterionId,
|
||||
x.VisitTaskNum,
|
||||
})
|
||||
.FirstNotNullAsync();
|
||||
|
||||
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, readingTask.VisitTaskNum, judgeRule, true);
|
||||
var questionIds = questionList.Select(x => x.Id).ToList();
|
||||
var answers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && questionIds.Contains(x.ReadingQuestionTrialId)).ToListAsync();
|
||||
var triggerJudgeQuestionIds = await GetTriggerJudgeQuestionIds(taskIds, questionList, readingTask.VisitTaskNum, judgeRule);
|
||||
|
||||
// 自动计算题本身触发裁判时,同时标记其所有源问题(包含多层计算依赖)。
|
||||
var calculateQuestions = await _readingQuestionTrialRepository
|
||||
.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId)
|
||||
.ToListAsync();
|
||||
var calculateQuestionMap = calculateQuestions.ToDictionary(x => x.Id);
|
||||
var pendingQuestionIds = new Queue<Guid>(triggerJudgeQuestionIds);
|
||||
while (pendingQuestionIds.Count > 0)
|
||||
{
|
||||
var questionId = pendingQuestionIds.Dequeue();
|
||||
if (!calculateQuestionMap.TryGetValue(questionId, out var question))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var calculateQuestionId in question.CalculateQuestionList
|
||||
.Where(x => !x.IsTable && x.QuestionId.HasValue)
|
||||
.Select(x => x.QuestionId!.Value))
|
||||
{
|
||||
if (triggerJudgeQuestionIds.Add(calculateQuestionId))
|
||||
{
|
||||
pendingQuestionIds.Enqueue(calculateQuestionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new GetJudgeFormOutDto
|
||||
{
|
||||
JudgeResultRemark = taskInfo.JudgeResultRemark,
|
||||
JudgeResultImagePathList = taskInfo.JudgeResultImagePathList,
|
||||
TriggerJudgeQuestionIds = triggerJudgeQuestionIds.ToList(),
|
||||
QuestionList = questionList.Select(x => new JudgeFormQuestionDto
|
||||
{
|
||||
ReadingQuestionId = x.Id,
|
||||
IsTriggerJudge = triggerJudgeQuestionIds.Contains(x.Id),
|
||||
QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
|
||||
Type = x.Type,
|
||||
ShowQuestion = x.ShowQuestion,
|
||||
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,
|
||||
DataSource = x.DataSource,
|
||||
CustomUnit = x.CustomUnit,
|
||||
ValueType = x.ValueType,
|
||||
|
||||
|
||||
ClassifyQuestionId = x.ClassifyQuestionId,
|
||||
ClassifyAlgorithms = x.ClassifyAlgorithms,
|
||||
ClassifyType = x.ClassifyType
|
||||
}).ToList(),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新按当前访视的裁判规则计算实际触发裁判的问题。
|
||||
/// </summary>
|
||||
private async Task<HashSet<Guid>> GetTriggerJudgeQuestionIds(List<Guid> taskIds, List<ReadingQuestionTrial> questionList, decimal visitTaskNum, JudgeRule judgeRule)
|
||||
{
|
||||
var questionIds = questionList.Select(x => x.Id).ToList();
|
||||
var questionAnswers = await (from answer in _readingTaskQuestionAnswerRepository.Where(x => taskIds.Contains(x.VisitTaskId) && questionIds.Contains(x.ReadingQuestionTrialId))
|
||||
join question in _readingQuestionTrialRepository.Where(x => questionIds.Contains(x.Id)) on answer.ReadingQuestionTrialId equals question.Id
|
||||
select new TaskAnswerDto
|
||||
{
|
||||
Answer = answer.Answer,
|
||||
AnswerGroup = question.AnswerGroup,
|
||||
AnswerCombination = question.AnswerCombination,
|
||||
JudgeType = question.JudgeType,
|
||||
JudgeDifferenceValue = question.JudgeDifferenceValue,
|
||||
JudgeDifferenceType = question.JudgeDifferenceType,
|
||||
QuestionId = question.Id,
|
||||
VisitTaskId = answer.VisitTaskId,
|
||||
VisitTaskNum = visitTaskNum,
|
||||
}).ToListAsync();
|
||||
|
||||
await ApplyVisitJudgeRules(questionAnswers, judgeRule);
|
||||
var groupTasks = questionAnswers.GroupBy(x => new { x.JudgeDifferenceValue, x.JudgeDifferenceType, x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination })
|
||||
.Select(x => new GroupTaskAnswerDto
|
||||
{
|
||||
QuestionId = x.Key.QuestionId,
|
||||
AnswerGroup = x.Key.AnswerGroup,
|
||||
AnswerCombination = x.Key.AnswerCombination,
|
||||
JudgeType = x.Key.JudgeType,
|
||||
JudgeDifferenceValue = x.Key.JudgeDifferenceValue,
|
||||
JudgeDifferenceType = x.Key.JudgeDifferenceType,
|
||||
TaskAnswerList = x.Select(y => y.Answer).ToList(),
|
||||
}).ToList();
|
||||
|
||||
var triggerJudgeQuestionIds = new HashSet<Guid>();
|
||||
ComputeJudgeResult(groupTasks, Guid.Empty, triggerJudgeQuestionIds, false);
|
||||
return triggerJudgeQuestionIds;
|
||||
}
|
||||
|
||||
/// <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 judgeDataInfo = await _readingJudgeInfoRepository
|
||||
.Where(x => x.JudgeTaskId == inDto.VisitTaskId)
|
||||
.FirstNotNullAsync();
|
||||
|
||||
var taskIds = new List<Guid> { judgeDataInfo.TaskIdOne, judgeDataInfo.TaskIdTwo };
|
||||
|
||||
var readingTask = await _visitTaskRepository
|
||||
.Where(x => taskIds.Contains(x.Id))
|
||||
.Select(x => new
|
||||
{
|
||||
x.Id,
|
||||
x.ArmEnum,
|
||||
x.TrialReadingCriterionId,
|
||||
x.VisitTaskNum,
|
||||
})
|
||||
.FirstNotNullAsync();
|
||||
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, readingTask.VisitTaskNum, judgeRule, true)).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,bool isGetShowQuestion)
|
||||
{
|
||||
var questionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialReadingCriterionId && x.IsJudgeQuestion)
|
||||
.WhereIf(!isGetShowQuestion,x=>x.ShowQuestion!= ShowQuestion.Hide)
|
||||
.WhereIf(visitNum == 0, x => x.LimitShow != LimitShow.FollowShow)
|
||||
.WhereIf(visitNum != 0, x => x.LimitShow != LimitShow.BaseLineShow)
|
||||
.Where(x=>!(x.LimitShow==LimitShow.ExcludeSomeVisits&&x.ExcludeShowVisitList.Contains(visitNum)))
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == trialReadingCriterionId).FirstNotNullAsync();
|
||||
var questionIds = questionList.Select(x => x.Id).ToList();
|
||||
var visitJudgeRules=new List<ReadingQuestionVisitJudgeRule>();
|
||||
if (judgeRule == JudgeRule.Difference)
|
||||
{
|
||||
if (await _visitStageRepository.AnyAsync(x => x.TrialId == trialCriterion.TrialId && x.VisitNum == visitNum))
|
||||
{
|
||||
visitJudgeRules = await _readingQuestionVisitJudgeRuleRepository.Where(x => questionIds.Contains(x.ReadingQuestionId) && x.VisitNum == visitNum).ToListAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
visitJudgeRules = await _readingQuestionVisitJudgeRuleRepository.Where(x => questionIds.Contains(x.ReadingQuestionId) && x.VisitNum == -1).ToListAsync();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
visitJudgeRules = questionList.Select(x => new ReadingQuestionVisitJudgeRule()
|
||||
{
|
||||
ReadingQuestionId = x.Id,
|
||||
AnswerCombination = JsonConvert.DeserializeObject<List<AnswerCombinationDto>>(x.AnswerCombination.IsNullOrEmpty() ? "[]" : x.AnswerCombination),
|
||||
AnswerGroup = JsonConvert.DeserializeObject<List<string>>(x.AnswerGroup.IsNullOrEmpty() ? "[]" : x.AnswerGroup),
|
||||
JudgeDifferenceType = x.JudgeDifferenceType,
|
||||
JudgeType = x.JudgeType,
|
||||
JudgeDifferenceValue = x.JudgeDifferenceValue,
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
|
||||
return questionList
|
||||
.Where(x => visitJudgeRules.FirstOrDefault(rule => rule.ReadingQuestionId == x.Id && rule.VisitNum == -1)?.JudgeType != JudgeTypeEnum.NotApplicable)
|
||||
.OrderBy(x=>x.ShowOrder)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取裁判阅片任务信息
|
||||
/// </summary>
|
||||
@@ -476,8 +831,15 @@ namespace IRaCIS.Core.Application.Service
|
||||
});
|
||||
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)
|
||||
{
|
||||
@@ -514,11 +876,9 @@ namespace IRaCIS.Core.Application.Service
|
||||
|
||||
|
||||
// 创建任务关联关系
|
||||
await this.CreateTaskRelated(inDto.VisitTaskId);
|
||||
await this.CreateTaskRelated(visitTaskId);
|
||||
|
||||
await SafeMailHelper.Run(async () => await _trialEmailNoticeConfigService.BaseBusinessScenarioSendEmailAsync(inDto.VisitTaskId));
|
||||
|
||||
return ResponseOutput.Ok(result);
|
||||
await SafeMailHelper.Run(async () => await _trialEmailNoticeConfigService.BaseBusinessScenarioSendEmailAsync(visitTaskId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -560,6 +920,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
List<Guid> visitTaskids = new List<Guid>();
|
||||
|
||||
var visitTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).AsNoTracking().FirstNotNullAsync();
|
||||
// 计算过 就不计算了
|
||||
if(visitTask.IsCalculatedJudge)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 是否是组件一致性
|
||||
var isGroupAnalysis = false;
|
||||
@@ -624,12 +989,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
x.ArbitrationRule,
|
||||
x.IsGlobalReading,
|
||||
x.IsReadingPeriod,
|
||||
x.JudgeRuleEnum,
|
||||
}).FirstNotNullAsync();
|
||||
|
||||
var noteEqual = false;
|
||||
|
||||
// 判断项目是否设置了裁判
|
||||
if (criterionInfo.IsArbitrationReading)
|
||||
if (criterionInfo.IsArbitrationReading&& !visitTask.IsCalculatedJudge)
|
||||
{
|
||||
// 判断数量是否为2 是否仲裁
|
||||
if (visitTaskids.Count == 2)
|
||||
@@ -667,6 +1033,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
VisitTaskId = questionAnswer.VisitTaskId,
|
||||
};
|
||||
var globalVisitAnswerlist = await globalVisitQuestionQuery.ToListAsync();
|
||||
await ApplyVisitJudgeRules(globalVisitAnswerlist, criterionInfo.JudgeRuleEnum);
|
||||
|
||||
var taskNums = globalVisitAnswerlist.Select(x => x.VisitTaskNum).Distinct().OrderBy(x => x).ToList();
|
||||
|
||||
@@ -697,11 +1064,13 @@ namespace IRaCIS.Core.Application.Service
|
||||
AnswerCombination = question.AnswerCombination,
|
||||
JudgeType = question.JudgeType,
|
||||
QuestionId = question.Id,
|
||||
JudgeDifferenceValue = question.JudgeDifferenceValue,
|
||||
JudgeDifferenceType = question.JudgeDifferenceType,
|
||||
VisitTaskId = questionAnswet.VisitTaskId,
|
||||
};
|
||||
JudgeDifferenceValue = question.JudgeDifferenceValue,
|
||||
JudgeDifferenceType = question.JudgeDifferenceType,
|
||||
VisitTaskId = questionAnswet.VisitTaskId,
|
||||
VisitTaskNum = questionAnswet.VisitTask.VisitTaskNum,
|
||||
};
|
||||
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
|
||||
@@ -749,6 +1118,8 @@ namespace IRaCIS.Core.Application.Service
|
||||
}
|
||||
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(
|
||||
twoItem.AfterQuestionList.Where(x => x.QuestionId != null && x.IsJudgeQuestion).ToList()
|
||||
).ToList();
|
||||
@@ -772,6 +1143,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
break;
|
||||
}
|
||||
|
||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => visitTaskids.Contains(x.Id), x => new VisitTask()
|
||||
{
|
||||
IsCalculatedJudge = true
|
||||
});
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -811,6 +1187,8 @@ namespace IRaCIS.Core.Application.Service
|
||||
};
|
||||
|
||||
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(
|
||||
lastTask.AfterQuestionList.Where(x => x.QuestionId != null).ToList()
|
||||
@@ -831,6 +1209,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
}
|
||||
|
||||
|
||||
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x =>x.Id ==visitTask.Id, x => new VisitTask()
|
||||
{
|
||||
IsCalculatedJudge = true
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -929,6 +1312,105 @@ 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)&&x.LimitShow == LimitShow.ExcludeSomeVisits).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();
|
||||
#region 这里是排除访视 但这里其实不用去除 因为就不会有答案
|
||||
|
||||
//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));
|
||||
#endregion
|
||||
|
||||
|
||||
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>
|
||||
/// 发送微信通知
|
||||
@@ -1077,50 +1559,53 @@ namespace IRaCIS.Core.Application.Service
|
||||
/// </summary>
|
||||
/// <param name="groupTasks"></param>
|
||||
/// <returns></returns>
|
||||
private bool ComputeJudgeResult(List<GroupTaskAnswerDto> groupTasks,Guid visiTaskId)
|
||||
private bool ComputeJudgeResult(List<GroupTaskAnswerDto> groupTasks, Guid visiTaskId, HashSet<Guid>? triggerJudgeQuestionIds = null, bool notifyException = true)
|
||||
{
|
||||
var noteEqual = false;
|
||||
foreach (var item in groupTasks)
|
||||
{
|
||||
if (item.JudgeType == JudgeTypeEnum.NotApplicable || item.JudgeType == JudgeTypeEnum.None)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 裁判问题可以不必填
|
||||
if(item.TaskAnswerList.Count()==0)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
_ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案等于0");
|
||||
_ = SendAbnormalEmail(visiTaskId, EmailBusinessScenario.JudgeExceptio);
|
||||
}
|
||||
catch (Exception)
|
||||
if (notifyException)
|
||||
{
|
||||
try
|
||||
{
|
||||
_ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案等于0");
|
||||
_ = SendAbnormalEmail(visiTaskId, EmailBusinessScenario.JudgeExceptio);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (item.TaskAnswerList.Count() != 2)
|
||||
{
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// 发送微信通知
|
||||
_ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案不等于2");
|
||||
_ = SendAbnormalEmail(visiTaskId, EmailBusinessScenario.JudgeExceptio);
|
||||
}
|
||||
catch (Exception)
|
||||
if (notifyException)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 发送微信通知
|
||||
_ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案不等于2");
|
||||
_ = SendAbnormalEmail(visiTaskId, EmailBusinessScenario.JudgeExceptio);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (noteEqual)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
var isTriggerJudge = false;
|
||||
var taskAnswer1 = item.TaskAnswerList[0];
|
||||
var taskAnswer2 = item.TaskAnswerList[1];
|
||||
if (taskAnswer1 != taskAnswer2)
|
||||
@@ -1129,7 +1614,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
switch (item.JudgeType)
|
||||
{
|
||||
case JudgeTypeEnum.AnswerDisaffinity:
|
||||
noteEqual = true;
|
||||
isTriggerJudge = true;
|
||||
break;
|
||||
case JudgeTypeEnum.AnswerGroup:
|
||||
var answerGroupList = JsonConvert.DeserializeObject<List<string>>(item.AnswerGroup).Select(x => new AnswerGroup()
|
||||
@@ -1142,7 +1627,7 @@ namespace IRaCIS.Core.Application.Service
|
||||
var unionList = itemAnswerGroupsitem1.Intersect(itemAnswerGroupsitem2).ToList();
|
||||
if (unionList.Count < 1)
|
||||
{
|
||||
noteEqual = true;
|
||||
isTriggerJudge = true;
|
||||
}
|
||||
break;
|
||||
case JudgeTypeEnum.AnswerCombination:
|
||||
@@ -1151,11 +1636,11 @@ namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
if (x.AnswerGroupA.Contains(taskAnswer1) && x.AnswerGroupB.Contains(taskAnswer2))
|
||||
{
|
||||
noteEqual = true;
|
||||
isTriggerJudge = true;
|
||||
}
|
||||
if (x.AnswerGroupB.Contains(taskAnswer1) && x.AnswerGroupA.Contains(taskAnswer2))
|
||||
{
|
||||
noteEqual = true;
|
||||
isTriggerJudge = true;
|
||||
}
|
||||
});
|
||||
break;
|
||||
@@ -1165,21 +1650,21 @@ namespace IRaCIS.Core.Application.Service
|
||||
// 已经判断不相等了 所以只可能有一个为Null
|
||||
if (answer1 == null || answer2 == null)
|
||||
{
|
||||
noteEqual = true;
|
||||
isTriggerJudge = true;
|
||||
}
|
||||
var deffaultValue = Math.Abs(taskAnswer1.IsNullOrEmptyReturn0() - taskAnswer2.IsNullOrEmptyReturn0());
|
||||
if (item.JudgeDifferenceType == JudgeDifferenceType.Greater)
|
||||
{
|
||||
if (deffaultValue > item.JudgeDifferenceValue)
|
||||
{
|
||||
noteEqual = true;
|
||||
isTriggerJudge = true;
|
||||
}
|
||||
}
|
||||
else if (item.JudgeDifferenceType == JudgeDifferenceType.AboveOrEqual)
|
||||
{
|
||||
if (deffaultValue >= item.JudgeDifferenceValue)
|
||||
{
|
||||
noteEqual = true;
|
||||
isTriggerJudge = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1189,24 +1674,24 @@ namespace IRaCIS.Core.Application.Service
|
||||
// 已经判断不相等了 所以只可能有一个为Null
|
||||
if (answer1P == null || answer2P == null)
|
||||
{
|
||||
noteEqual = true;
|
||||
isTriggerJudge = true;
|
||||
}
|
||||
var value1 = taskAnswer1.IsNullOrEmptyReturn0();
|
||||
var value2 = taskAnswer2.IsNullOrEmptyReturn0();
|
||||
if (value1 == 0 || value2 == 0)
|
||||
{
|
||||
noteEqual = true;
|
||||
isTriggerJudge = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var absoluteValue = (Math.Abs(value1 - value2) * 100) / (value1 < value2 ? value1 : value2);
|
||||
if (item.JudgeDifferenceType == JudgeDifferenceType.Greater)
|
||||
{
|
||||
noteEqual = absoluteValue > item.JudgeDifferenceValue;
|
||||
isTriggerJudge = absoluteValue > item.JudgeDifferenceValue;
|
||||
}
|
||||
else if (item.JudgeDifferenceType == JudgeDifferenceType.AboveOrEqual)
|
||||
{
|
||||
noteEqual = absoluteValue >= item.JudgeDifferenceValue;
|
||||
isTriggerJudge = absoluteValue >= item.JudgeDifferenceValue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1214,6 +1699,12 @@ namespace IRaCIS.Core.Application.Service
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isTriggerJudge)
|
||||
{
|
||||
noteEqual = true;
|
||||
triggerJudgeQuestionIds?.Add(item.QuestionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using IRaCIS.Core.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Infra.EFCore.Common;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
@@ -6,6 +8,8 @@ using MassTransit;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
{
|
||||
@@ -18,12 +22,15 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository,
|
||||
IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
|
||||
IRepository<OrganInfo> _organInfoRepository,
|
||||
ISubjectVisitService iSubjectVisitService,
|
||||
IRepository<Dictionary> _dictionaryRepository,
|
||||
IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository,
|
||||
IRepository<SubjectVisit> _subjectVisitRepository,
|
||||
IRepository<TumorAssessment_IRECIST1Point1> _tumorAssessmentRepository,
|
||||
IGeneralCalculateService _generalCalculateService,
|
||||
IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository,
|
||||
IVisitTaskHelpeService _visitTaskHelpeService,
|
||||
IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository,
|
||||
IHttpContextAccessor httpContext,
|
||||
ILogger<IRECIST1Point1CalculateService> _logger, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ICriterionCalculateService
|
||||
{
|
||||
@@ -411,13 +418,117 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
[HttpPost]
|
||||
public async Task<FileResult> GetIVUSTemplate(GetExportTemplateInDto inDto)
|
||||
{
|
||||
return await CreateIVUSTemplate(inDto.VisitTaskId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前分组、受试者、标准下所有有效任务的IVUS模板压缩包
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<FileResult> GetIVUSTemplatesZip(GetExportTemplateInDto inDto)
|
||||
{
|
||||
var currentTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x=>x.Subject).FirstNotNullAsync();
|
||||
var taskList = await _visitTaskRepository.Where(x => x.ArmEnum == currentTask.ArmEnum
|
||||
&& x.SubjectId == currentTask.SubjectId
|
||||
&& x.TrialReadingCriterionId == currentTask.TrialReadingCriterionId
|
||||
&& x.TaskState == TaskState.Effect)
|
||||
.Include(x => x.Subject)
|
||||
.ToListAsync();
|
||||
|
||||
var zipStream = new MemoryStream();
|
||||
using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Create, leaveOpen: true))
|
||||
{
|
||||
foreach (var task in taskList)
|
||||
{
|
||||
var template = await CreateIVUSTemplate(task.Id) as FileStreamResult;
|
||||
await using (template.FileStream)
|
||||
await using (var entryStream = archive.CreateEntry($"{GetTemplateFileName(task)}.xlsx", CompressionLevel.Optimal).Open())
|
||||
{
|
||||
await template.FileStream.CopyToAsync(entryStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zipStream.Position = 0;
|
||||
var subjectCode = (currentTask.BlindSubjectCode.IsNullOrEmpty() ? currentTask.Subject.Code : currentTask.BlindSubjectCode);
|
||||
var code = string.Concat(subjectCode.Select(c => Path.GetInvalidFileNameChars().Contains(c) ? '_' : c));
|
||||
return new FileStreamResult(zipStream, "application/zip")
|
||||
{
|
||||
FileDownloadName = code+"_IVUS_Templates.zip"
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<FileResult> CreateIVUSTemplate(Guid visitTaskId)
|
||||
{
|
||||
|
||||
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x=>x.Subject).FirstNotNullAsync();
|
||||
|
||||
//靶段
|
||||
var targetSegmentdic = await _dictionaryRepository.Where(x => x.Parent.Code == "TargetSegment").ToListAsync();
|
||||
|
||||
//斑块类型
|
||||
var plaqueTypedic = await _dictionaryRepository.Where(x => x.Parent.Code == "PlaqueType").ToListAsync();
|
||||
|
||||
|
||||
|
||||
|
||||
var awswerList=await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Include(x=>x.ReadingQuestionTrial).ToListAsync();
|
||||
|
||||
|
||||
|
||||
var targetSegmentAnswer = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.TargetSegment).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
|
||||
if (targetSegmentAnswer.IsNotNullOrEmpty())
|
||||
{
|
||||
var data= JsonConvert.DeserializeObject<List<string>>(targetSegmentAnswer);
|
||||
targetSegmentAnswer = string.Join(",", targetSegmentdic
|
||||
.Where(x => data.Contains(x.Code))
|
||||
.Select(x => x.ValueCN));
|
||||
}
|
||||
else
|
||||
{
|
||||
var targetSegmentData = await iSubjectVisitService.GetReadingVisitStudyList(new Contracts.GetReadingVisitStudyListIndto()
|
||||
{
|
||||
SujectVisitId = taskinfo.SourceSubjectVisitId ?? default(Guid),
|
||||
TrialId = taskinfo.TrialId,
|
||||
VisitTaskId = visitTaskId
|
||||
});
|
||||
targetSegmentAnswer = string.Join(",", targetSegmentData
|
||||
.Where(x => x.BodyPartForEdit.IsNotNullOrEmpty())
|
||||
.SelectMany(x => x.BodyPartForEdit.Split('|'))
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s))
|
||||
.Distinct());
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
var plaqueTypeAnswer = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.PlaqueType).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
|
||||
if (plaqueTypeAnswer.IsNotNullOrEmpty())
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<List<string>>(plaqueTypeAnswer);
|
||||
plaqueTypeAnswer = string.Join(",", plaqueTypedic
|
||||
.Where(x => data.Contains(x.Code))
|
||||
.Select(x => x.ValueCN));
|
||||
}
|
||||
|
||||
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x=>x.Subject).FirstNotNullAsync();
|
||||
|
||||
var values = new TemplateData()
|
||||
{
|
||||
SubjectID = (taskinfo.BlindSubjectCode.IsNullOrEmpty() ? taskinfo.Subject.Code : taskinfo.BlindSubjectCode),
|
||||
TaskBlindName = taskinfo.TaskBlindName,
|
||||
TargetSegment= targetSegmentAnswer,
|
||||
TargetSegmentRemarks = awswerList.Where(x=>x.ReadingQuestionTrial.QuestionType == QuestionType.TargetSegmentRemarks).Select(x=>x.Answer).FirstOrDefault()??string.Empty,
|
||||
//ROIAllLength = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.ROIAllLength).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
|
||||
//PullbackFrameCount = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.PullbackFrameCount).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
|
||||
//AdjustReason = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.AdjustReason).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
|
||||
//PlaqueType = plaqueTypeAnswer,
|
||||
|
||||
|
||||
|
||||
};
|
||||
return await _visitTaskHelpeService.ExportTemplateAsync(new IRaCIS.Application.Contracts.ExportTemplateAsyncDto()
|
||||
{
|
||||
@@ -427,6 +538,13 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
});
|
||||
}
|
||||
|
||||
private static string GetTemplateFileName(VisitTask task)
|
||||
{
|
||||
var subjectCode = (task.BlindSubjectCode.IsNullOrEmpty() ? task.Subject.Code : task.BlindSubjectCode);
|
||||
var fileName = $"{subjectCode}_{task.TaskBlindName}";
|
||||
return string.Concat(fileName.Select(c => Path.GetInvalidFileNameChars().Contains(c) ? '_' : c));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导入IVUS数据
|
||||
/// </summary>
|
||||
@@ -442,7 +560,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
|
||||
List<string> sheetNames = new List<string>()
|
||||
{
|
||||
"各匹配片段测量值","MeasuredValue"
|
||||
"ROI测量值","ROI 测量值"
|
||||
};
|
||||
|
||||
if (sheetNames.Intersect(uploadInfo.SheetNames).Count() == 0)
|
||||
@@ -510,6 +628,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
|
||||
Dictionary<string, string> isPresent = new Dictionary<string, string>()
|
||||
{
|
||||
{ "1","1"},
|
||||
{ "0","0"},
|
||||
{ "有","1"},
|
||||
{ "无","0"},
|
||||
{ "Existence","1"},
|
||||
@@ -520,6 +640,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
|
||||
Dictionary<string, string> yesOrNo = new Dictionary<string, string>()
|
||||
{
|
||||
{ "1","1"},
|
||||
{ "0","0"},
|
||||
{ "是","1"},
|
||||
{ "否","0"},
|
||||
{ "Yes","1"},
|
||||
@@ -529,7 +651,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
List<IVUSMeasuredValue> measuredValueList = new List<IVUSMeasuredValue>();
|
||||
var errorRow = new List<int> { };
|
||||
|
||||
for (int i = 3; i < dataTable.Rows.Count; i++)
|
||||
for (int i = 9; i < dataTable.Rows.Count; i++)
|
||||
{
|
||||
IVUSMeasuredValue iVUSMeasuredValue = new IVUSMeasuredValue() { };
|
||||
try
|
||||
@@ -691,7 +813,100 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
}
|
||||
}
|
||||
|
||||
#region 构造外层问题答案
|
||||
List<ReadingTaskQuestionAnswer> questionAnswers = new List<ReadingTaskQuestionAnswer>();
|
||||
|
||||
var readingQuestionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId).ToListAsync();
|
||||
var targetSegmentAnswer = dataTable.Rows[2]["B"].ToString();
|
||||
|
||||
if (targetSegmentAnswer.IsNotNullOrEmpty())
|
||||
{
|
||||
var targetSegmentValues = targetSegmentAnswer.Replace(" ", "").Replace(",", ",").Split(",").ToList();
|
||||
var targetSegmentdic = await _dictionaryRepository.Where(x => x.Parent.Code == "TargetSegment").ToListAsync();
|
||||
targetSegmentAnswer = JsonConvert.SerializeObject(targetSegmentdic.Where(x => targetSegmentValues.Contains(x.ValueCN.Replace(" ", ""))).Select(x => x.Code).ToList());
|
||||
}
|
||||
|
||||
questionAnswers.Add(new ReadingTaskQuestionAnswer()
|
||||
{
|
||||
Answer= targetSegmentAnswer??string.Empty,
|
||||
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
|
||||
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.TargetSegment).Select(x => x.Id).FirstOrDefault(),
|
||||
TrialId = taskinfo.TrialId,
|
||||
SubjectId= taskinfo.SubjectId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
});
|
||||
|
||||
questionAnswers.Add(new ReadingTaskQuestionAnswer()
|
||||
{
|
||||
Answer = dataTable.Rows[3]["B"].ToString()??string.Empty,
|
||||
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
|
||||
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.TargetSegmentRemarks).Select(x => x.Id).FirstOrDefault(),
|
||||
TrialId = taskinfo.TrialId,
|
||||
SubjectId = taskinfo.SubjectId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
});
|
||||
|
||||
|
||||
questionAnswers.Add(new ReadingTaskQuestionAnswer()
|
||||
{
|
||||
Answer = dataTable.Rows[4]["B"].ToString() ?? string.Empty,
|
||||
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
|
||||
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.ROIAllLength).Select(x => x.Id).FirstOrDefault(),
|
||||
TrialId = taskinfo.TrialId,
|
||||
SubjectId = taskinfo.SubjectId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
});
|
||||
|
||||
|
||||
questionAnswers.Add(new ReadingTaskQuestionAnswer()
|
||||
{
|
||||
Answer = dataTable.Rows[5]["B"].ToString() ?? string.Empty,
|
||||
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
|
||||
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.PullbackFrameCount).Select(x => x.Id).FirstOrDefault(),
|
||||
TrialId = taskinfo.TrialId,
|
||||
SubjectId = taskinfo.SubjectId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
});
|
||||
|
||||
|
||||
var plaqueTypeAnswer = dataTable.Rows[6]["B"].ToString();
|
||||
|
||||
if (plaqueTypeAnswer.IsNotNullOrEmpty())
|
||||
{
|
||||
var plaqueTypeAnswerValues = plaqueTypeAnswer.Replace(" ", "").Replace(",", ",").Split(",").ToList();
|
||||
var plaqueTypeAnswerdic = await _dictionaryRepository.Where(x => x.Parent.Code == "PlaqueType").ToListAsync();
|
||||
plaqueTypeAnswer = JsonConvert.SerializeObject(plaqueTypeAnswerdic
|
||||
.Where(x => plaqueTypeAnswerValues.Any(val => x.ValueCN.Replace(" ", "").Contains(val)))
|
||||
.Select(x => x.Code)
|
||||
.ToList());
|
||||
}
|
||||
|
||||
questionAnswers.Add(new ReadingTaskQuestionAnswer()
|
||||
{
|
||||
Answer = plaqueTypeAnswer ?? string.Empty,
|
||||
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
|
||||
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.PlaqueType).Select(x => x.Id).FirstOrDefault(),
|
||||
TrialId = taskinfo.TrialId,
|
||||
SubjectId = taskinfo.SubjectId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
});
|
||||
|
||||
questionAnswers.Add(new ReadingTaskQuestionAnswer()
|
||||
{
|
||||
Answer = dataTable.Rows[7]["B"].ToString() ?? string.Empty,
|
||||
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
|
||||
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.AdjustReason).Select(x => x.Id).FirstOrDefault(),
|
||||
TrialId = taskinfo.TrialId,
|
||||
SubjectId = taskinfo.SubjectId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
});
|
||||
|
||||
var questionids = questionAnswers.Select(x => x.ReadingQuestionTrialId).ToList();
|
||||
await _readingTaskQuestionAnswerRepository.DeleteFromQueryAsync(x => x.VisitTaskId == taskinfo.Id && questionids.Contains(x.ReadingQuestionTrialId));
|
||||
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
|
||||
await _readingTaskQuestionAnswerRepository.AddRangeAsync(questionAnswers);
|
||||
await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
|
||||
#endregion
|
||||
await _readingTableAnswerRowInfoRepository.DeleteFromQueryAsync(x => x.QuestionId == questionInfo.Id && x.VisitTaskId == taskinfo.Id);
|
||||
await _readingTableQuestionAnswerRepository.DeleteFromQueryAsync(x => x.QuestionId == questionInfo.Id && x.VisitTaskId == taskinfo.Id);
|
||||
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
|
||||
@@ -921,6 +1136,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 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(".jpeg", 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();
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using DocumentFormat.OpenXml.Drawing.Spreadsheet;
|
||||
using DocumentFormat.OpenXml.Office.SpreadSheetML.Y2023.MsForms;
|
||||
using DocumentFormat.OpenXml.Office2010.Excel;
|
||||
using IRaCIS.Core.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
@@ -12,6 +13,8 @@ using MassTransit;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
{
|
||||
@@ -24,6 +27,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository,
|
||||
IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
|
||||
IRepository<OrganInfo> _organInfoRepository,
|
||||
ISubjectVisitService iSubjectVisitService,
|
||||
IRepository<Dictionary> _dictionaryRepository,
|
||||
IHttpContextAccessor httpContext,
|
||||
IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository,
|
||||
IRepository<SubjectVisit> _subjectVisitRepository,
|
||||
@@ -31,6 +36,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
IGeneralCalculateService _generalCalculateService,
|
||||
IVisitTaskHelpeService _visitTaskHelpeService,
|
||||
IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository,
|
||||
IRepository<TaskStudy> _taskStudyRepository,
|
||||
IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository,
|
||||
ILogger<IRECIST1Point1CalculateService> _logger, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ICriterionCalculateService
|
||||
{
|
||||
/// <summary>
|
||||
@@ -270,11 +277,113 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
[HttpPost]
|
||||
public async Task<FileResult> GetOCTFCTTemplate(GetExportTemplateInDto inDto)
|
||||
{
|
||||
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.Subject).FirstNotNullAsync();
|
||||
return await CreateOCTFCTTemplate(inDto.VisitTaskId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前分组、受试者、标准下所有有效任务的OCT-FCT模板压缩包
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<FileResult> GetOCTFCTTemplatesZip(GetExportTemplateInDto inDto)
|
||||
{
|
||||
var currentTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.Subject).FirstNotNullAsync();
|
||||
var taskList = await _visitTaskRepository.Where(x => x.ArmEnum == currentTask.ArmEnum
|
||||
&& x.SubjectId == currentTask.SubjectId
|
||||
&& x.TrialReadingCriterionId == currentTask.TrialReadingCriterionId
|
||||
&& x.TaskState == TaskState.Effect)
|
||||
.Include(x => x.Subject)
|
||||
.ToListAsync();
|
||||
|
||||
var zipStream = new MemoryStream();
|
||||
using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Create, leaveOpen: true))
|
||||
{
|
||||
foreach (var task in taskList)
|
||||
{
|
||||
var template = await CreateOCTFCTTemplate(task.Id) as FileStreamResult;
|
||||
await using (template.FileStream)
|
||||
await using (var entryStream = archive.CreateEntry($"{GetTemplateFileName(task)}.xlsx", CompressionLevel.Optimal).Open())
|
||||
{
|
||||
await template.FileStream.CopyToAsync(entryStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zipStream.Position = 0;
|
||||
var subjectCode = (currentTask.BlindSubjectCode.IsNullOrEmpty() ? currentTask.Subject.Code : currentTask.BlindSubjectCode);
|
||||
var code = string.Concat(subjectCode.Select(c => Path.GetInvalidFileNameChars().Contains(c) ? '_' : c));
|
||||
return new FileStreamResult(zipStream, "application/zip")
|
||||
{
|
||||
FileDownloadName = $"{code}_OCT_FCT_Templates.zip"
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<FileResult> CreateOCTFCTTemplate(Guid visitTaskId)
|
||||
{
|
||||
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.Subject).FirstNotNullAsync();
|
||||
|
||||
//靶段
|
||||
var targetSegmentdic = await _dictionaryRepository.Where(x => x.Parent.Code == "TargetSegment").ToListAsync();
|
||||
|
||||
//斑块类型
|
||||
var plaqueTypedic = await _dictionaryRepository.Where(x => x.Parent.Code == "PlaqueType").ToListAsync();
|
||||
|
||||
|
||||
|
||||
|
||||
var awswerList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Include(x => x.ReadingQuestionTrial).ToListAsync();
|
||||
|
||||
|
||||
|
||||
var targetSegmentAnswer = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.TargetSegment).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
|
||||
if (targetSegmentAnswer.IsNotNullOrEmpty())
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<List<string>>(targetSegmentAnswer);
|
||||
targetSegmentAnswer = string.Join(",", targetSegmentdic
|
||||
.Where(x => data.Contains(x.Code))
|
||||
.Select(x => x.ValueCN));
|
||||
}
|
||||
else
|
||||
{
|
||||
var targetSegmentData = await iSubjectVisitService.GetReadingVisitStudyList(new Contracts.GetReadingVisitStudyListIndto()
|
||||
{
|
||||
SujectVisitId = taskinfo.SourceSubjectVisitId ?? default(Guid),
|
||||
TrialId = taskinfo.TrialId,
|
||||
VisitTaskId = visitTaskId
|
||||
});
|
||||
targetSegmentAnswer = string.Join(",", targetSegmentData
|
||||
.Where(x => x.BodyPartForEdit.IsNotNullOrEmpty())
|
||||
.SelectMany(x => x.BodyPartForEdit.Split('|'))
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s))
|
||||
.Distinct());
|
||||
}
|
||||
|
||||
|
||||
var plaqueTypeAnswer = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.PlaqueType).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
|
||||
if (plaqueTypeAnswer.IsNotNullOrEmpty())
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<List<string>>(plaqueTypeAnswer);
|
||||
plaqueTypeAnswer = string.Join(",", plaqueTypedic
|
||||
.Where(x => data.Contains(x.Code))
|
||||
.Select(x => x.ValueCN));
|
||||
}
|
||||
|
||||
|
||||
var values = new TemplateData()
|
||||
{
|
||||
SubjectID = (taskinfo.BlindSubjectCode.IsNullOrEmpty() ? taskinfo.Subject.Code : taskinfo.BlindSubjectCode),
|
||||
TaskBlindName = taskinfo.TaskBlindName,
|
||||
TargetSegment = targetSegmentAnswer,
|
||||
TargetSegmentRemarks = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.TargetSegmentRemarks).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
|
||||
//ROIAllLength = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.ROIAllLength).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
|
||||
////PullbackFrameCount = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.PullbackFrameCount).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
|
||||
//PlaqueType = plaqueTypeAnswer,
|
||||
//AdjustReason = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.AdjustReason).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
return await _visitTaskHelpeService.ExportTemplateAsync(new IRaCIS.Application.Contracts.ExportTemplateAsyncDto()
|
||||
{
|
||||
@@ -284,6 +393,13 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
});
|
||||
}
|
||||
|
||||
private static string GetTemplateFileName(VisitTask task)
|
||||
{
|
||||
var subjectCode = (task.BlindSubjectCode.IsNullOrEmpty() ? task.Subject.Code : task.BlindSubjectCode);
|
||||
var fileName = $"{subjectCode}_{task.TaskBlindName}";
|
||||
return string.Concat(fileName.Select(c => Path.GetInvalidFileNameChars().Contains(c) ? '_' : c));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导入OCT-FCT数据
|
||||
/// </summary>
|
||||
@@ -299,7 +415,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
|
||||
List<string> sheetNames = new List<string>()
|
||||
{
|
||||
"FCT导入","FCT"
|
||||
"ROI测量值","ROI 测量值"
|
||||
};
|
||||
|
||||
if (sheetNames.Intersect(uploadInfo.SheetNames).Count() == 0)
|
||||
@@ -338,6 +454,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
|
||||
Dictionary<string, string> yesOrNo = new Dictionary<string, string>()
|
||||
{
|
||||
{ "1","1"},
|
||||
{ "0","0"},
|
||||
{ "是","1"},
|
||||
{ "否","0"},
|
||||
{ "Yes","1"},
|
||||
@@ -356,11 +474,12 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
return value;
|
||||
}
|
||||
}
|
||||
for (int i = 3; i < dataTable.Rows.Count; i++)
|
||||
for (int i = 8; i < dataTable.Rows.Count; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
// 手动抛出异常进入catch
|
||||
if (!yesOrNo.ContainsKey(dataTable.Rows[i]["K"].ToString())|| !yesOrNo.ContainsKey(dataTable.Rows[i]["L"].ToString()))
|
||||
{
|
||||
@@ -404,6 +523,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
|
||||
Dictionary<string, string> isPresent = new Dictionary<string, string>()
|
||||
{
|
||||
{ "1","1"},
|
||||
{ "0","0"},
|
||||
{ "有","1"},
|
||||
{ "无","0"},
|
||||
{ "Existence","1"},
|
||||
@@ -411,7 +532,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
{ string.Empty,string.Empty},
|
||||
};
|
||||
|
||||
int row = 3;
|
||||
int row = 8;
|
||||
foreach (var item in measuredValueList)
|
||||
{
|
||||
row++;
|
||||
@@ -664,6 +785,91 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#region 构造外层问题答案
|
||||
List<ReadingTaskQuestionAnswer> questionAnswers = new List<ReadingTaskQuestionAnswer>();
|
||||
|
||||
var readingQuestionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId).ToListAsync();
|
||||
var targetSegmentAnswer = dataTable.Rows[2]["B"].ToString();
|
||||
|
||||
if (targetSegmentAnswer.IsNotNullOrEmpty())
|
||||
{
|
||||
var targetSegmentValues = targetSegmentAnswer.Replace(" ", "").Replace(",", ",").Split(",").ToList();
|
||||
var targetSegmentdic = await _dictionaryRepository.Where(x => x.Parent.Code == "TargetSegment").ToListAsync();
|
||||
targetSegmentAnswer = JsonConvert.SerializeObject(targetSegmentdic.Where(x => targetSegmentValues.Contains(x.ValueCN.Replace(" ", ""))).Select(x => x.Code).ToList());
|
||||
}
|
||||
|
||||
questionAnswers.Add(new ReadingTaskQuestionAnswer()
|
||||
{
|
||||
Answer = targetSegmentAnswer ?? string.Empty,
|
||||
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
|
||||
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.TargetSegment).Select(x => x.Id).FirstOrDefault(),
|
||||
TrialId = taskinfo.TrialId,
|
||||
SubjectId = taskinfo.SubjectId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
});
|
||||
|
||||
questionAnswers.Add(new ReadingTaskQuestionAnswer()
|
||||
{
|
||||
Answer = dataTable.Rows[3]["B"].ToString() ?? string.Empty,
|
||||
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
|
||||
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.TargetSegmentRemarks).Select(x => x.Id).FirstOrDefault(),
|
||||
TrialId = taskinfo.TrialId,
|
||||
SubjectId = taskinfo.SubjectId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
});
|
||||
|
||||
|
||||
questionAnswers.Add(new ReadingTaskQuestionAnswer()
|
||||
{
|
||||
Answer = dataTable.Rows[4]["B"].ToString() ?? string.Empty,
|
||||
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
|
||||
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.ROIAllLength).Select(x => x.Id).FirstOrDefault(),
|
||||
TrialId = taskinfo.TrialId,
|
||||
SubjectId = taskinfo.SubjectId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
});
|
||||
|
||||
|
||||
var plaqueTypeAnswer = dataTable.Rows[5]["B"].ToString();
|
||||
|
||||
if (plaqueTypeAnswer.IsNotNullOrEmpty())
|
||||
{
|
||||
var plaqueTypeAnswerValues = plaqueTypeAnswer.Replace(" ", "").Replace(",", ",").Split(",").ToList();
|
||||
var plaqueTypeAnswerdic = await _dictionaryRepository.Where(x => x.Parent.Code == "PlaqueType").ToListAsync();
|
||||
plaqueTypeAnswer = JsonConvert.SerializeObject(plaqueTypeAnswerdic
|
||||
.Where(x => plaqueTypeAnswerValues.Any(val => x.ValueCN.Replace(" ", "").Contains(val)))
|
||||
.Select(x => x.Code)
|
||||
.ToList());
|
||||
}
|
||||
|
||||
questionAnswers.Add(new ReadingTaskQuestionAnswer()
|
||||
{
|
||||
Answer = plaqueTypeAnswer ?? string.Empty,
|
||||
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
|
||||
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.PlaqueType).Select(x => x.Id).FirstOrDefault(),
|
||||
TrialId = taskinfo.TrialId,
|
||||
SubjectId = taskinfo.SubjectId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
});
|
||||
|
||||
questionAnswers.Add(new ReadingTaskQuestionAnswer()
|
||||
{
|
||||
Answer = dataTable.Rows[6]["B"].ToString() ?? string.Empty,
|
||||
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
|
||||
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.AdjustReason).Select(x => x.Id).FirstOrDefault(),
|
||||
TrialId = taskinfo.TrialId,
|
||||
SubjectId = taskinfo.SubjectId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
});
|
||||
|
||||
var questionids = questionAnswers.Select(x => x.ReadingQuestionTrialId).ToList();
|
||||
await _readingTaskQuestionAnswerRepository.DeleteFromQueryAsync(x => x.VisitTaskId == taskinfo.Id && questionids.Contains(x.ReadingQuestionTrialId));
|
||||
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
|
||||
await _readingTaskQuestionAnswerRepository.AddRangeAsync(questionAnswers);
|
||||
await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
|
||||
#endregion
|
||||
|
||||
await _readingTableAnswerRowInfoRepository.DeleteFromQueryAsync(x => x.QuestionId == questionInfo.Id && x.VisitTaskId == taskinfo.Id);
|
||||
await _readingTableQuestionAnswerRepository.DeleteFromQueryAsync(x => x.QuestionId == questionInfo.Id && x.VisitTaskId == taskinfo.Id);
|
||||
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
|
||||
@@ -1445,6 +1651,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 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();
|
||||
|
||||
|
||||
|
||||
+14
-1
@@ -3,6 +3,8 @@
|
||||
// 生成时间 2021-12-23 13:21:04
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
/// <summary> TrialSiteEquipmentSurveyView 列表视图模型 </summary>
|
||||
@@ -49,33 +51,44 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public string ScannerType { get; set; } = string.Empty;
|
||||
public string Note { get; set; } = string.Empty;
|
||||
|
||||
|
||||
[DictionaryTranslate("SiteSurvey_ScanEquipmentType")]
|
||||
[Comment("扫描设备-New")]
|
||||
public int? EquipmentTypeEnum { get; set; }
|
||||
|
||||
public string OtherEquipmentType { get; set; }
|
||||
|
||||
[Comment("扫描设备厂商")]
|
||||
[DictionaryTranslate("ManufacturerType")]
|
||||
public int? ManufacturerType { get; set; }
|
||||
|
||||
[Comment("磁场强度 (1.5T / 3.0T)")]
|
||||
[DictionaryTranslate("MagneticFieldStrengthType")]
|
||||
public int? MagneticFieldStrengthType { get; set; }
|
||||
|
||||
|
||||
[DictionaryTranslate("BodyCoilChannelCount")]
|
||||
[Comment("体部线圈通道数 (≥16 或 <16)")]
|
||||
public int? BodyCoilChannelCount { get; set; }
|
||||
|
||||
[DictionaryTranslate("YesOrNo")]
|
||||
[Comment("是否具备专用的PDFF脂肪定量序列(CSE-MRI序列)")]
|
||||
public bool? HasDedicatedPdfFatQuantificationSequence { get; set; }
|
||||
|
||||
[DictionaryTranslate("PdfFatQuantificationSequenceType")]
|
||||
|
||||
[Comment("专用的PDFF脂肪定量序列类型 (当 HasDedicatedPdfFatQuantificationSequence = true 时有效)")]
|
||||
public int? PdfFatQuantificationSequenceType { get; set; }
|
||||
|
||||
[Comment("其他序列详细说明 (当 PdfFatQuantificationSequenceType = Other 时建议填写)")]
|
||||
public string OtherSequenceSpecification { get; set; }
|
||||
|
||||
[DictionaryTranslate("YesOrNo")]
|
||||
[Comment("是否包含 T2/R2 校正(用于铁沉积校正)")]
|
||||
public bool? HasT2R2Correction { get; set; }
|
||||
|
||||
|
||||
|
||||
[DictionaryTranslate("YesOrNo")]
|
||||
[Comment("是否可完整导出 PDFF 参数图及全部原始 DICOM 数据")]
|
||||
public bool? CanFullyExportPdfParameterMapsAndRawDicom { get; set; }
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
@@ -131,13 +132,15 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
|
||||
/// <summary> TrialSiteSurveyView 列表视图模型 </summary>
|
||||
public class TrialSiteSurveyView: TrialSiteSurveyAddOrEdit
|
||||
public class TrialSiteSurveyView : TrialSiteSurveyAddOrEdit
|
||||
{
|
||||
|
||||
public string TrialSiteCode { get; set; } = String.Empty;
|
||||
public string TrialSiteAliasName { get; set; } = String.Empty;
|
||||
|
||||
public string SiteName { get; set; } = string.Empty;
|
||||
|
||||
[DictionaryTranslate("YesOrNo")]
|
||||
public bool IsDeleted { get; set; }
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
@@ -145,7 +148,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
public DateTime UpdateTime { get; set; }
|
||||
public Guid UpdateUserId { get; set; }
|
||||
|
||||
|
||||
[DictionaryTranslate("ResearchRecord")]
|
||||
public TrialSiteSurveyEnum State { get; set; }
|
||||
|
||||
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 Phone { get; set; } = string.Empty;
|
||||
public string Email { get; set; } = string.Empty;
|
||||
|
||||
public int AverageEngravingCycle { get; set; }
|
||||
|
||||
[DictionaryTranslate("YesOrNo")]
|
||||
public bool IsConfirmImagingTechnologist { get; set; }
|
||||
public string NotConfirmReson { get; set; } = string.Empty;
|
||||
|
||||
[DictionaryTranslate("EfficacyEvaluatorType")]
|
||||
public int EfficacyEvaluatorType { get; set; }
|
||||
|
||||
[DictionaryTranslate("YesOrNo")]
|
||||
public bool IsFollowStudyParameters { get; set; }
|
||||
public string NotFollowReson { get; set; } = string.Empty;
|
||||
|
||||
|
||||
[DictionaryTranslate("YesOrNo")]
|
||||
[Comment("MRI-PDEE 是否为本中心该适应症的常规诊疗检查项目")]
|
||||
public bool? IsRoutineMRIPDEE { get; set; }
|
||||
|
||||
@@ -346,14 +356,17 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
[Comment("MRI-PDEE 其他")]
|
||||
public string MRIPDFFOther { get; set; }
|
||||
|
||||
[DictionaryTranslate("YesOrNo")]
|
||||
|
||||
[Comment("是否授权影像科老师参与")]
|
||||
|
||||
public bool? IsAuthorizeRadiologistsParticipate { get; set; }
|
||||
|
||||
[DictionaryTranslate("YesOrNo")]
|
||||
[Comment("保持 1-2 名固定技师")]
|
||||
public bool? AssignFixedTechnologists { get; set; }
|
||||
|
||||
[DictionaryTranslate("YesOrNo")]
|
||||
|
||||
[Comment("是否严格按照影像手册参数完成刻盘")]
|
||||
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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
// 生成时间 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.Core.Application.Auth;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
@@ -22,6 +25,8 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "Trial")]
|
||||
public class TrialSiteSurveyService(IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
|
||||
IRepository<SiteSurveyLog> _siteSurveyLogRepository,
|
||||
IRepository<TrialSiteEquipmentSurvey> _trialSiteEquipmentSurveyRepository,
|
||||
IRepository<TrialSiteUserSurvey> _trialSiteUserSurveyRepository,
|
||||
IRepository<UserRole> _userRoleRepository,
|
||||
IRepository<IdentityUser> _identityUserRepository,
|
||||
@@ -474,6 +479,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
public async Task<IResponseOutput> SubmissionRejection(TrialSiteSubmitBackCommand trialSiteSubmitBackCommand, [FromServices] IMailVerificationService _IMailVerificationService)
|
||||
{
|
||||
var trialId = trialSiteSubmitBackCommand.TrialId;
|
||||
var trialSiteSurveyId = trialSiteSubmitBackCommand.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)
|
||||
{
|
||||
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 =>
|
||||
t.UserRole.IdentityUser.Status == UserStateEnum.Enable
|
||||
&& t.UserRole.IsUserRoleDisabled == false
|
||||
&& (t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM))
|
||||
);
|
||||
// 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.IsUserRoleDisabled == false
|
||||
//&& (t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM))
|
||||
//);
|
||||
|
||||
var isSPMjoin = isTrialSPMJoin && hasSPMOrCPM;
|
||||
// var isSPMjoin = isTrialSPMJoin && hasSPMOrCPM;
|
||||
|
||||
if (isSPMjoin)
|
||||
{
|
||||
survey.State = TrialSiteSurveyEnum.CRCSubmitted;
|
||||
// if (isSPMjoin)
|
||||
// {
|
||||
// survey.State = TrialSiteSurveyEnum.CRCSubmitted;
|
||||
|
||||
survey.ReviewerUserId = null;
|
||||
survey.ReviewerTime = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
survey.State = TrialSiteSurveyEnum.ToSubmit;
|
||||
// survey.ReviewerUserId = null;
|
||||
// survey.ReviewerTime = null;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// survey.State = TrialSiteSurveyEnum.ToSubmit;
|
||||
|
||||
survey.PreliminaryUserId = null;
|
||||
survey.ReviewerUserId = null;
|
||||
survey.PreliminaryTime = null;
|
||||
survey.ReviewerTime = null;
|
||||
// survey.PreliminaryUserId = null;
|
||||
// survey.ReviewerUserId = null;
|
||||
// survey.PreliminaryTime = 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();
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
@@ -547,6 +565,10 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
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();
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
@@ -612,6 +634,9 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
//从项目site 中找到已存在的 加到历史人员中
|
||||
addSurvey.TrialSiteUserSurveyList = userList;
|
||||
|
||||
//添加创建日志
|
||||
addSurvey.SiteSurveyLogList.Add(new SiteSurveyLog() { Name = userInfo.EmailOrPhone, OptType = SiteSurveyOptTyp.Create });
|
||||
|
||||
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)
|
||||
.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)
|
||||
{
|
||||
@@ -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();
|
||||
|
||||
copy.State = TrialSiteSurveyEnum.ToSubmit;
|
||||
@@ -685,10 +715,21 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
copy.Id = Guid.Empty;
|
||||
copy.CreateTime = DateTime.Now;
|
||||
|
||||
copy.PreliminaryUserId = null;
|
||||
copy.ReviewerUserId = null;
|
||||
copy.PreliminaryTime = null;
|
||||
copy.ReviewerTime = null;
|
||||
|
||||
if (userInfo.ReplaceUserEmailOrPhone != userInfo.EmailOrPhone)
|
||||
{
|
||||
copy.UserName = 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)
|
||||
{
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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 });
|
||||
|
||||
|
||||
//审批调研表日志
|
||||
|
||||
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();
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
@@ -1149,12 +1212,19 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
var queitUserTypeIdList = needQuitUserList.Select(t => t.UserTypeId).ToList();
|
||||
|
||||
|
||||
await _trialSiteUserRoleRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId && queitUserTypeIdList.Contains(t.UserRole.UserTypeId), c => new TrialSiteUserRole()
|
||||
foreach (var item in needQuitUserList)
|
||||
{
|
||||
IsDeleted = true,
|
||||
DeletedTime = DateTime.Now,
|
||||
});
|
||||
await _trialSiteUserRoleRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId
|
||||
&& 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 });
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,12 @@ namespace IRaCIS.Core.Application.Contracts
|
||||
|
||||
var item = addOrEditTrialSiteUserSurvey;
|
||||
|
||||
if (item.UserTypeId == null)
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["SystemCommon_WebErrorArgument"]);
|
||||
}
|
||||
|
||||
|
||||
//找下系统中是否存在该用户类型的 并且邮箱 或者手机的账户
|
||||
var sysUserInfo = await _identityUserRepository.Where(t => t.EMail == item.Email,true).Include(t => t.UserRoleList).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
@@ -98,6 +98,21 @@ namespace IRaCIS.Core.Application.AutoMapper
|
||||
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));
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,15 +27,16 @@ namespace IRaCIS.Core.Application
|
||||
IRepository<TrialQCQuestion> _trialQCQuestionRepository,
|
||||
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
||||
IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
|
||||
IRepository<ReadingQuestionVisitJudgeRule> _readingQuestionVisitJudgeRuleRepository,
|
||||
IRepository<TrialCriterionDictionaryCode> _trialCriterionDictionaryCode,
|
||||
IRepository<SystemCriterionDictionaryCode> _systemCriterionDictionaryCode,
|
||||
IRepository<ReadingQuestionCriterionSystem> _readingQuestionCriterionSystemRepository,
|
||||
IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository,
|
||||
IRepository<ReadingCriterionPage> _readingCriterionPageRepository,
|
||||
IRepository<SystemCriterionKeyFile> _systemCriterionKeyFileRepository,
|
||||
IOSSService _oSSService,
|
||||
|
||||
IRepository<TrialCriterionKeyFile> _trialCriterionKeyFileRepository,
|
||||
IRepository<SystemCriterionKeyFile> _systemCriterionKeyFileRepository,
|
||||
IOSSService _oSSService,
|
||||
IRepository<VisitStage> _visitStageRepository,
|
||||
IRepository<TrialCriterionKeyFile> _trialCriterionKeyFileRepository,
|
||||
IOrganInfoService _iOrganInfoService,
|
||||
IRepository<TrialBodyPart> _trialBodyPartRepository,
|
||||
IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository,
|
||||
@@ -48,7 +49,7 @@ namespace IRaCIS.Core.Application
|
||||
IRepository<SystemBasicData> _systemBasicDataRepository,
|
||||
IRepository<SubjectVisit> _subjectVisitRepository,
|
||||
IRepository<Enroll> _enrollRepository,
|
||||
IRepository<TrialQCQuestionAnswer> _qcQuestionAnswerRepository,
|
||||
IRepository<TrialQCQuestionAnswer> _qcQuestionAnswerRepository,
|
||||
IRepository<TrialStateChange> _trialStateChangeRepository,
|
||||
IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository, IRepository<TrialDicomAE> _dicomAERepository,
|
||||
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, ITrialConfigService
|
||||
@@ -105,6 +106,40 @@ namespace IRaCIS.Core.Application
|
||||
throw new BusinessValidationFailedException(_localizer["TrialConfig_JudgeTaskFail"]);
|
||||
}
|
||||
|
||||
if (trialCriterion.JudgeRuleEnum == JudgeRule.Difference)
|
||||
{
|
||||
var visitStageList = await _visitStageRepository.Where(x => x.TrialId == trialCriterion.TrialId).ToListAsync();
|
||||
|
||||
visitStageList.Add(new VisitStage()
|
||||
{
|
||||
VisitName = "Out of Plan",
|
||||
VisitNum=-1,
|
||||
});
|
||||
|
||||
|
||||
|
||||
var judgeCount = await _readingQuestionTrialRepository.CountAsync(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion);
|
||||
|
||||
var ruleList = await _readingQuestionVisitJudgeRuleRepository.Where(x => x.ReadingQuestionTrial.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId).ToListAsync();
|
||||
|
||||
var errorList = new List<string>();
|
||||
|
||||
visitStageList.ForEach(x =>
|
||||
{
|
||||
if (judgeCount != ruleList.Count(y => y.VisitNum == x.VisitNum))
|
||||
{
|
||||
errorList.Add(x.VisitName);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (errorList.Count() > 0)
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["TrialConfig_VisitjudgeDeficiency", string.Join(",", errorList)]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return ResponseOutput.Ok(true);
|
||||
}
|
||||
|
||||
@@ -734,9 +769,16 @@ namespace IRaCIS.Core.Application
|
||||
arbitration = inDto.IsReadingPeriod ? ArbitrationRule.Reading : ArbitrationRule.Visit;
|
||||
}
|
||||
|
||||
JudgeMode judgeMode =await _readingQuestionCriterionTrialRepository.Where(x=>x.Id==inDto.TrialReadingCriterionId).Select(x=>x.JudgeModeEnum).FirstOrDefaultAsync();
|
||||
if (arbitration== ArbitrationRule.Reading)
|
||||
{
|
||||
judgeMode = JudgeMode.SelectOne;
|
||||
}
|
||||
|
||||
await _readingQuestionCriterionTrialRepository.UpdatePartialFromQueryAsync(inDto.TrialReadingCriterionId, x => new ReadingQuestionCriterionTrial()
|
||||
{
|
||||
CircleRadius = inDto.CircleRadius,
|
||||
JudgeModeEnum = judgeMode,
|
||||
ReadingToolList = inDto.ReadingToolList,
|
||||
SegmentToolList = inDto.SegmentToolList,
|
||||
IsImageFilter = inDto.IsImageFilter,
|
||||
|
||||
@@ -292,7 +292,8 @@ namespace IRaCIS.Core.Application.Services
|
||||
instances,
|
||||
x => x.ImagePositionPatient,
|
||||
x => x.ImageOrientationPatient,
|
||||
x => x.InstanceNumber
|
||||
x => x.InstanceNumber,
|
||||
series.Description
|
||||
);
|
||||
|
||||
series.InstanceInfoList = sorted.Select(k =>
|
||||
@@ -629,7 +630,8 @@ namespace IRaCIS.Core.Application.Services
|
||||
instances,
|
||||
x => x.ImagePositionPatient,
|
||||
x => x.ImageOrientationPatient,
|
||||
x => x.InstanceNumber
|
||||
x => x.InstanceNumber,
|
||||
series.Description
|
||||
);
|
||||
|
||||
series.InstanceInfoList = sorted.Select(k =>
|
||||
@@ -682,7 +684,8 @@ namespace IRaCIS.Core.Application.Services
|
||||
series.InstanceInfoList,
|
||||
x => x.ImagePositionPatient,
|
||||
x => x.ImageOrientationPatient,
|
||||
x => x.InstanceNumber
|
||||
x => x.InstanceNumber,
|
||||
series.Description
|
||||
);
|
||||
|
||||
series.InstanceInfoList = sorted;
|
||||
|
||||
@@ -295,6 +295,21 @@ namespace IRaCIS.Core.Application.Service
|
||||
}
|
||||
|
||||
|
||||
public class SubjectTaskExcel
|
||||
{
|
||||
|
||||
public string SubjectCode { get; set; }
|
||||
|
||||
public string TaskName { get; set; }
|
||||
|
||||
public string TaskBlindName { get; set; }
|
||||
|
||||
public string UserName { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 访视数据模型
|
||||
/// </summary>
|
||||
@@ -1728,10 +1743,10 @@ namespace IRaCIS.Core.Application.Service
|
||||
//var d = _dicRepository.UpdateFromDTOAsync(new AddOrEditBasicDic() { Id = Guid.Parse("60d86683-c33b-4349-b672-08da1e91b622"), ParentId = null, ChildGroup = null, Code = null }, true, true).Result;
|
||||
//var a = 123;
|
||||
|
||||
throw new BusinessValidationFailedException(_localizer["TrialIsDoubleCheck{0}", "测试"]);
|
||||
//throw new BusinessValidationFailedException(_localizer["TrialIsDoubleCheck{0}", "测试"]);
|
||||
|
||||
var b = _localizer["test{0}", "测试"];
|
||||
return _localizer["test{0}", "测试"];
|
||||
//var b = _localizer["test{0}", "测试"];
|
||||
//return _localizer["test{0}", "测试"];
|
||||
|
||||
|
||||
//var list = _subjectVisitRepository.Where(t => t.Id == Guid.NewGuid()).SelectMany(t => t.VisitTaskList).ToList();
|
||||
@@ -1741,6 +1756,8 @@ namespace IRaCIS.Core.Application.Service
|
||||
//var list3 = _visitTaskRepository.Where(t => t.Id == Guid.NewGuid()).SelectMany(t => t.SourceSubjectVisit.VisitTaskList).ToList();
|
||||
//var list2 = _subjectRepository.Where(t => t.Id == Guid.NewGuid()).SelectMany(t => t.SubjectVisitTaskList).ToList();
|
||||
//return _userInfo.LocalIp;
|
||||
|
||||
return _userInfo.ClientInfo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3060,6 +3060,11 @@ namespace IRaCIS.Core.Domain.Share
|
||||
/// </summary>
|
||||
ROIAllLength = 1015,
|
||||
|
||||
/// <summary>
|
||||
/// 斑块类型
|
||||
/// </summary>
|
||||
PlaqueType=1018,
|
||||
|
||||
/// <summary>
|
||||
/// PAV(冠状动脉粥样硬化体积百分比)
|
||||
/// </summary>
|
||||
@@ -3376,6 +3381,11 @@ namespace IRaCIS.Core.Domain.Share
|
||||
/// </summary>
|
||||
PercentageDifference = 5,
|
||||
|
||||
/// <summary>
|
||||
/// 不适用
|
||||
/// </summary>
|
||||
NotApplicable = 6,
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -316,6 +316,11 @@ public class VisitTask : BaseFullAuditEntity
|
||||
/// </summary>
|
||||
public bool IsCopyLesionAnswer { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否计算过裁判
|
||||
/// </summary>
|
||||
public bool IsCalculatedJudge { get; set; } = false;
|
||||
|
||||
#region 完全随机增加字段
|
||||
|
||||
[Comment("完全随机阅片号")]
|
||||
|
||||
@@ -196,6 +196,73 @@ public class ReadingQuestionCriterionTrial : BaseAddAuditEntity
|
||||
/// 定圆工具默认半径
|
||||
/// </summary>
|
||||
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,
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 (计划外是-1)
|
||||
/// </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; }
|
||||
}
|
||||
@@ -23,6 +23,10 @@ public class TrialSiteSurvey : BaseFullDeleteAuditEntity
|
||||
|
||||
[JsonIgnore]
|
||||
public CommonUploadRecord SiteSurveyFile { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
|
||||
public List<SiteSurveyLog> SiteSurveyLogList { get; set; }=new List<SiteSurveyLog>();
|
||||
#endregion
|
||||
|
||||
public Guid TrialSiteId { get; set; }
|
||||
@@ -64,7 +68,7 @@ public class TrialSiteSurvey : BaseFullDeleteAuditEntity
|
||||
public bool? IsRoutineMRIPDEE { get; set; }
|
||||
|
||||
[Comment("MRI-PDFF 单次检查时长")]
|
||||
public string MRIPDFFScanTime { get; set; }
|
||||
public string MRIPDFFScanTime { get; set; }
|
||||
|
||||
[Comment("MRI-PDFF 预约等待时长")]
|
||||
public string MRIPDFFLeadTime { get; set; }
|
||||
@@ -88,3 +92,43 @@ public class TrialSiteSurvey : BaseFullDeleteAuditEntity
|
||||
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,
|
||||
}
|
||||
@@ -7,6 +7,9 @@ namespace IRaCIS.Core.Domain.Models;
|
||||
public class Subject : BaseFullDeleteAuditEntity
|
||||
{
|
||||
#region 导航属性
|
||||
[JsonIgnore]
|
||||
public List<TrialImageDownload> TrialImageDownloadList { get; set; } = new List<TrialImageDownload>();
|
||||
|
||||
[JsonIgnore]
|
||||
public List<TaskStudy> TaskStudyList { get; set; } = new List<TaskStudy>();
|
||||
|
||||
|
||||
@@ -63,5 +63,17 @@ namespace IRaCIS.Core.Domain.Share
|
||||
string BrowserFingerprint { get; }
|
||||
|
||||
UserWorkLanguage UserWorkLanguage { get; }
|
||||
|
||||
|
||||
ClientInfo ClientInfo { get; }
|
||||
}
|
||||
|
||||
public class ClientInfo
|
||||
{
|
||||
public string Browser { get; set; }
|
||||
public string OS { get; set; }
|
||||
public string DeviceType { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using UAParser;
|
||||
|
||||
namespace IRaCIS.Core.Domain.Share
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户信息
|
||||
/// </summary>
|
||||
public class UserInfo : IUserInfo
|
||||
public class UserInfo(IHttpContextAccessor _accessor, Parser parser) : IUserInfo
|
||||
{
|
||||
private readonly IHttpContextAccessor _accessor;
|
||||
|
||||
public UserInfo(IHttpContextAccessor accessor)
|
||||
{
|
||||
_accessor = accessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户角色Id
|
||||
@@ -348,6 +344,55 @@ namespace IRaCIS.Core.Domain.Share
|
||||
|
||||
}
|
||||
|
||||
public ClientInfo ClientInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var userAgent = _accessor?.HttpContext.Request.Headers["User-Agent"].ToString();
|
||||
|
||||
if (!string.IsNullOrEmpty(userAgent))
|
||||
{
|
||||
var clientInfo = parser.Parse(userAgent);
|
||||
|
||||
return new ClientInfo()
|
||||
{
|
||||
OS = clientInfo.OS.ToString(),
|
||||
Browser = clientInfo.UA.ToString(),
|
||||
DeviceType = userAgent.Contains("Mobile") ? "Mobile" : "Desktop"
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
return new ClientInfo()
|
||||
{
|
||||
OS = "Unknown",
|
||||
Browser = "Unknown",
|
||||
DeviceType = "Unknown"
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
return new ClientInfo()
|
||||
{
|
||||
OS = "ParseError",
|
||||
Browser = "ParseError",
|
||||
DeviceType = "ParseError"
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Guid? SignId
|
||||
{
|
||||
@@ -417,7 +462,7 @@ namespace IRaCIS.Core.Domain.Share
|
||||
|
||||
public const string PermissionStr = "permissionStr";
|
||||
|
||||
public const string UserWorkLanguage = "userWorkLanguage";
|
||||
public const string UserWorkLanguage = "userWorkLanguage";
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3886,6 +3886,8 @@ namespace IRaCIS.Core.Infra.EFCore.Common
|
||||
// 保存影像质量 、 修改整体肿瘤评估结果 、 非dicom 保存访视阅片结果 、附加评估
|
||||
if (_userInfo.RequestUrl == "ReadingImageTask/changeDicomReadingQuestionAnswer"
|
||||
|| _userInfo.RequestUrl == "ReadingImageTask/saveImageQuality"
|
||||
|| _userInfo.RequestUrl == "ReadingImageTask/setJudgeForm"
|
||||
|| _userInfo.RequestUrl == "ReadingImageTask/SubmitJudgeForm"
|
||||
|| _userInfo.RequestUrl.Contains("SaveTaskQuestion")
|
||||
|| _userInfo.RequestUrl == "ReadingImageTask/saveVisitTaskQuestions"
|
||||
|| _userInfo.RequestUrl == "ReadingImageTask/changeCalculationAnswer"
|
||||
|
||||
@@ -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 配置 暂时屏蔽
|
||||
//if (base.Database.IsNpgsql())
|
||||
//{
|
||||
@@ -421,6 +429,8 @@ public class IRaCISDBContext : DbContext
|
||||
|
||||
public virtual DbSet<ReadingQuestionTrial> ReadingQuestionTrial { get; set; }
|
||||
|
||||
public virtual DbSet<ReadingQuestionVisitJudgeRule> ReadingQuestionVisitJudgeRule { get; set; }
|
||||
|
||||
|
||||
public virtual DbSet<ReadingClinicalDataPDF> ReadingClinicalDataPDF { get; set; }
|
||||
public virtual DbSet<ReadingConsistentClinicalData> ReadingConsistentClinicalData { get; set; }
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
<PackageReference Include="EFCore.BulkExtensions" Version="10.0.1" />
|
||||
<PackageReference Include="EntityFrameworkCore.Triggered" Version="3.2.2" />
|
||||
<PackageReference Include="EntityFrameworkCore.Projectables" Version="6.0.5" />
|
||||
|
||||
@@ -48,7 +48,7 @@ public class AuditEntityInterceptor(IUserInfo _userInfo,
|
||||
AuditEntities(eventData.Context);
|
||||
|
||||
//IRC稽查 放在savechange 之前 不影响之前的逻辑
|
||||
//IRCDataInspection(eventData.Context);
|
||||
IRCDataInspection(eventData.Context);
|
||||
|
||||
//return result;
|
||||
|
||||
@@ -64,7 +64,7 @@ public class AuditEntityInterceptor(IUserInfo _userInfo,
|
||||
AuditEntities(eventData.Context);
|
||||
|
||||
//IRC稽查 放在savechange 之前 不影响之前的逻辑
|
||||
//IRCDataInspection(eventData.Context);
|
||||
IRCDataInspection(eventData.Context);
|
||||
|
||||
//return result;
|
||||
|
||||
|
||||
+22496
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6834,6 +6834,15 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||
.HasColumnType("bit")
|
||||
.HasComment("eCRF报告是否显示在图像页面");
|
||||
|
||||
b.Property<int>("JudgeGenerateEnum")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("JudgeModeEnum")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("JudgeRuleEnum")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime?>("ReadingInfoSignTime")
|
||||
.HasColumnType("datetime2")
|
||||
.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 =>
|
||||
{
|
||||
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 =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -16633,6 +16747,9 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||
.HasColumnType("bit")
|
||||
.HasComment("阅片结果是否和原数据有差异");
|
||||
|
||||
b.Property<bool>("IsCalculatedJudge")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsCanEditUrgentState")
|
||||
.HasColumnType("bit")
|
||||
.HasComment("是否和编辑加急状态");
|
||||
@@ -18978,6 +19095,25 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||
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 =>
|
||||
{
|
||||
b.HasOne("IRaCIS.Core.Domain.Models.UserRole", "CreateUserRole")
|
||||
@@ -19563,6 +19699,25 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||
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 =>
|
||||
{
|
||||
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 =>
|
||||
{
|
||||
b.Navigation("SiteSurveyLogList");
|
||||
|
||||
b.Navigation("TrialSiteEquipmentSurveyList");
|
||||
|
||||
b.Navigation("TrialSiteUserSurveyList");
|
||||
|
||||
@@ -325,7 +325,11 @@ public static class StaticData
|
||||
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";
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,37 @@
|
||||
kind: pipeline
|
||||
type: ssh
|
||||
name: ssh-linux-uat-irc-build-image
|
||||
|
||||
platform:
|
||||
os: Linux
|
||||
arch: 386
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
server:
|
||||
host: 101.132.253.119
|
||||
user: root
|
||||
password:
|
||||
from_secret: test_ssh_pwd
|
||||
|
||||
steps:
|
||||
- name: publish-test-irc
|
||||
commands:
|
||||
- bash /opt/1panel/xc-deploy-new/Uat_IRC/devops-publish/uat-branch-publish.sh
|
||||
- name: notify-wecom
|
||||
commands:
|
||||
- bash /opt/1panel/xc-deploy-new/devops-center/drone-notify-wecom.sh "$DRONE_BUILD_STATUS" "$DRONE_REPO_NAME" "$DRONE_BRANCH" "$DRONE_BUILD_NUMBER" "4355b98e-1e72-4678-8dfb-2fc6ad0bf449" "$DRONE_COMMIT_MESSAGE" "$DRONE_COMMIT_AUTHOR" "Uat_IRC_API Uat_IRC_SCP_API" "irc.uat.extimaging.com"
|
||||
when:
|
||||
status:
|
||||
- success
|
||||
- failure
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- Uat_IRC_Net10
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: ssh
|
||||
name: ssh-linux-test-irc-publish
|
||||
|
||||
Reference in New Issue
Block a user