Compare commits

...

116 Commits

Author SHA1 Message Date
hang b0ef2dc8ab 修改审核时间修改
continuous-integration/drone/push Build is passing
2024-08-02 15:41:29 +08:00
hang ccf4bbdff9 CRC 上传导表
continuous-integration/drone/push Build is passing
2024-08-02 11:48:09 +08:00
hang c3e36991b8 质控增加字段
continuous-integration/drone/push Build is passing
2024-08-02 11:29:41 +08:00
hang 81f6c10f23 QCAgreeUpload 才允许修改
continuous-integration/drone/push Build is passing
2024-08-01 17:22:10 +08:00
hang 719ca071e1 crc 重传允许修改部位编辑
continuous-integration/drone/push Build is passing
2024-08-01 17:06:17 +08:00
hang dad420a7e8 Merge branch 'Uat_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2024-07-31 14:34:30 +08:00
hang d84aedf135 邮件昵称修改 2024-07-31 14:34:29 +08:00
hang 34f3b1607e 修改隐藏邮箱的算法
continuous-integration/drone/push Build is passing
2024-07-31 10:04:58 +08:00
hang 7fa73e0054 修改us配置文件
continuous-integration/drone/push Build is passing
2024-07-29 11:47:02 +08:00
hang c146c2bfd2 修改uat 美国配置文件
continuous-integration/drone/push Build is passing
2024-07-29 11:27:02 +08:00
hang 2a1220899e 重阅自动失效,错误消息位置改变
continuous-integration/drone/push Build is passing
2024-07-25 14:22:19 +08:00
hang 874d36de28 同意重阅,成功,但是给出自动失效的提示
continuous-integration/drone/push Build is passing
2024-07-25 13:54:57 +08:00
hang 0283052555 修改,无序重阅 和审批
continuous-integration/drone/push Build is passing
2024-07-25 10:13:26 +08:00
hang effef5ad65 修改IR 无序阅片申请bug
continuous-integration/drone/push Build is passing
2024-07-24 16:25:53 +08:00
hang 43d260e036 修改美国环境配置,使用AWS
continuous-integration/drone/push Build is passing
2024-07-19 17:17:53 +08:00
hang 19708240b2 oss 下载走内网地址
continuous-integration/drone/push Build is passing
2024-07-19 16:13:33 +08:00
hang 0999bae749 修改非dicom 监控上传
continuous-integration/drone/push Build is passing
2024-07-19 09:04:55 +08:00
hang e6bd35ae04 url 解码下载修改
continuous-integration/drone/push Build is passing
2024-07-17 18:00:17 +08:00
he 102e193ae8 修改
continuous-integration/drone/push Build is passing
2024-07-17 10:19:51 +08:00
he 20d557e795 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2024-07-17 10:10:29 +08:00
he 593ab42882 修改 2024-07-17 10:10:28 +08:00
hang b56d256e10 去掉权限,方便前端测试
continuous-integration/drone/push Build is passing
2024-07-16 10:59:46 +08:00
he 614a3bd70e 返回值修改
continuous-integration/drone/push Build is passing
2024-07-16 10:10:12 +08:00
he 2eb3b04365 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2024-07-16 09:57:34 +08:00
he 1fa3a5a181 加返回参数 2024-07-16 09:57:33 +08:00
hang cd2007c4fd 减少压缩包访视层级,同时处理单个非dicom 特殊情况压缩包处理
continuous-integration/drone/push Build is passing
2024-07-15 16:55:21 +08:00
hang 67e710eac0 增加打包下载验证
continuous-integration/drone/push Build is passing
2024-07-15 16:28:29 +08:00
hang ef451d82ec 修改ivus影像下载功能
continuous-integration/drone/push Build is passing
2024-07-15 15:46:31 +08:00
he 899ebf2a30 跳过阅片修改
continuous-integration/drone/push Build is passing
2024-07-15 14:43:49 +08:00
he f233d27f96 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2024-07-15 14:13:14 +08:00
he 9e8ab8acca 跳过阅片修改 2024-07-15 14:13:14 +08:00
hang 2265387f47 Uat 自动打包发布
continuous-integration/drone/push Build is passing
2024-07-15 13:12:43 +08:00
he baf8f39bc6 提示语修改
continuous-integration/drone/push Build is passing
2024-07-12 10:30:44 +08:00
he 3fa14d92ae 配置文件修改
continuous-integration/drone/push Build is passing
2024-07-11 17:29:38 +08:00
he e6c577e68b 阅片时间修改到配置文件
continuous-integration/drone/push Build is passing
2024-07-11 17:28:18 +08:00
hang bb111dbbeb 修改发布文件
continuous-integration/drone/push Build is passing
2024-07-11 15:26:22 +08:00
hang 0df0b10a72 增加用户机构默认值修改
continuous-integration/drone/push Build is failing
2024-07-11 10:14:46 +08:00
hang 0a7ba9f0f5 修改字段名
continuous-integration/drone/push Build is failing
2024-07-11 09:42:15 +08:00
hang cd88990c32 spm cpm 返回增加字段 2024-07-11 09:42:03 +08:00
hang d53a1300fc 增加uat irc 自动打包成镜像
continuous-integration/drone/push Build is passing
2024-07-10 16:49:59 +08:00
hang 07332ff3e1 修改发送邮件配置 2024-07-09 13:12:59 +08:00
hang 8195a1cf3e 修改发件箱 2024-07-09 09:50:30 +08:00
hang f5e5a47624 修改美国irc uat 数据库名称 2024-07-09 09:40:32 +08:00
hang 28608f3ecb 美国验证增加配置文件 2024-07-08 11:39:30 +08:00
hang bb2da7ca81 修改配置文件 2024-07-05 09:07:57 +08:00
hang 713518a68c 增加美国生产环境配置文件 2024-07-04 14:31:50 +08:00
he bc448da297 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8 2024-07-03 15:15:48 +08:00
he 8447878cb2 代码修改 2024-07-03 15:15:46 +08:00
hang 1b5a9673f6 修改一致性核查颜色 2024-07-02 17:16:46 +08:00
he 27711f4184 关键序列修改 2024-07-02 09:33:42 +08:00
he bb9bac1edf 修改医学审核排序 2024-07-01 16:45:07 +08:00
hang 41ae2febc7 改为阿里云 2024-06-26 15:12:06 +08:00
hang c072c526e2 修改uat 配置文件 2024-06-26 14:36:56 +08:00
hang d6bb98b84f 中心调研修改 2024-06-25 10:57:42 +08:00
hang 42587ee59f 删掉邮件日志组件 2024-06-25 09:17:28 +08:00
hang 62a964a3ea 发送邮件的包降级 2024-06-25 09:01:58 +08:00
hang 72447eb82f 修改 界面控制bug 2024-06-24 16:53:53 +08:00
hang 2f83c27fde 修改筛选条件 2024-06-24 16:39:43 +08:00
hang b219593f61 医生入组,没有spm修改逻辑 2024-06-24 16:39:40 +08:00
hang 8521b0c28c 增加清理跟踪的方法
continuous-integration/drone/push Build is passing
2024-06-20 17:50:17 +08:00
hang 26a62426f0 修改发布方式
continuous-integration/drone/push Build is passing
2024-06-20 15:08:47 +08:00
hang 1246413e30 修改nonedicom过滤
continuous-integration/drone/push Build is passing
2024-06-19 19:38:16 +08:00
hang f50b5819c0 修改过滤规则
continuous-integration/drone/push Build is passing
2024-06-19 18:40:32 +08:00
hang 6db8d61b7c 修改 非dicom 检查过滤
continuous-integration/drone/push Build is passing
2024-06-19 17:57:40 +08:00
hang 58250fe993 非dicom zip过滤
continuous-integration/drone/push Build is passing
2024-06-19 16:57:08 +08:00
hang 6cae7a1ae4 修改非dicom 文件上传 增加文件类型
continuous-integration/drone/push Build is passing
2024-06-19 15:17:55 +08:00
hang 73541efbf4 uat 截图修改配置文件
continuous-integration/drone/push Build is passing
2024-06-19 14:17:35 +08:00
hang f4bd891deb 记录最新登录时间
continuous-integration/drone/push Build is passing
2024-06-19 13:48:59 +08:00
hang a9831657cc 修改Uat IRC 配置
continuous-integration/drone/push Build is passing
2024-06-19 13:11:20 +08:00
hang 500a9fbaca 修改配置文件
continuous-integration/drone/push Build is passing
2024-06-19 09:08:17 +08:00
hang 5f11c3a602 修改site 启用时间逻辑
continuous-integration/drone/push Build is passing
2024-06-18 19:36:57 +08:00
hang 7680e90d65 修改添加trialSite逻辑
continuous-integration/drone/push Build is passing
2024-06-18 19:28:26 +08:00
hang 06a57cd056 修改中心调样cpm bug
continuous-integration/drone/push Build is passing
2024-06-18 15:09:52 +08:00
hang 7626d17540 记录邮件异常
continuous-integration/drone/push Build is passing
2024-06-18 13:28:40 +08:00
hang 344b92c427 修改配置文件
continuous-integration/drone/push Build is passing
2024-06-18 13:16:26 +08:00
hang 4719177009 时间环境配置修改
continuous-integration/drone/push Build is passing
2024-06-18 11:53:17 +08:00
hang c1461633ce 修改中心调研国际化
continuous-integration/drone/push Build is passing
2024-06-18 11:10:18 +08:00
hang 6be7aa1ad9 修改默认值
continuous-integration/drone/push Build is passing
2024-06-18 10:28:10 +08:00
hang 4da7c2f960 irc minio 修改配置文件
continuous-integration/drone/push Build is passing
2024-06-17 11:48:09 +08:00
hang 47a45df610 修改mfa 配置
continuous-integration/drone/push Build is passing
2024-06-17 10:38:42 +08:00
hang 1a44e48b2d 删除备注
continuous-integration/drone/push Build is passing
2024-06-17 08:59:53 +08:00
hang c566a703eb 修改trialSitte Id 问题
continuous-integration/drone/push Build is passing
2024-06-14 16:04:12 +08:00
hang 001c248cb8 中心调研返回项目modality
continuous-integration/drone/push Build is passing
2024-06-14 15:35:08 +08:00
hang 654462fe6b 插入字符串efbug
continuous-integration/drone/push Build is passing
2024-06-14 14:34:18 +08:00
hang ab6642ce33 过滤检查
continuous-integration/drone/push Build is passing
2024-06-14 14:29:55 +08:00
hang 946386ad43 检查技术修改
continuous-integration/drone/push Build is passing
2024-06-14 13:46:30 +08:00
hang cf9c79a928 过滤失效的任务
continuous-integration/drone/push Build is passing
2024-06-14 13:28:42 +08:00
hang 493e4e8dca 枚举不能识别
continuous-integration/drone/push Build is passing
2024-06-14 11:05:07 +08:00
hang ecbe8434f3 修改编译问题
continuous-integration/drone/push Build is passing
2024-06-14 10:55:52 +08:00
he 644fe1bd3c Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is failing
2024-06-14 10:52:02 +08:00
he 870fca2e93 修改 2024-06-14 10:52:01 +08:00
hang 6207fb5006 修改MFA 接口
continuous-integration/drone/push Build is failing
2024-06-14 10:38:58 +08:00
hang ae913d8213 修改中心调研国际化
continuous-integration/drone/push Build is passing
2024-06-14 09:18:06 +08:00
hang ce969822a0 字段名错误
continuous-integration/drone/push Build is passing
2024-06-13 17:42:49 +08:00
hang 4fc311d4a5 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2024-06-13 17:42:05 +08:00
hang 2b424ff45c site 调研增加配置字段 2024-06-13 17:42:04 +08:00
he e5d9cfc50e Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-13 17:35:19 +08:00
he ac3552818b 修改 2024-06-13 17:35:18 +08:00
hang c004741f95 上传下载 改为不为空
continuous-integration/drone/push Build is passing
2024-06-13 17:08:09 +08:00
hang 2bdc0c7704 修改siteName 国际化
continuous-integration/drone/push Build is passing
2024-06-13 14:57:38 +08:00
hang 35d90d56dd 修改过滤
continuous-integration/drone/push Build is passing
2024-06-13 09:25:26 +08:00
hang f14525ea95 减少赋值字段
continuous-integration/drone/push Build is failing
2024-06-12 17:24:51 +08:00
hang c2350f1418 影像筛选逻辑增加
continuous-integration/drone/push Build is passing
2024-06-12 17:10:22 +08:00
hang 4b8b02fa55 重构检查列表
continuous-integration/drone/push Build is passing
2024-06-12 16:14:14 +08:00
hang 62102b8b03 重构检查列表
continuous-integration/drone/push Build is failing
2024-06-12 16:10:49 +08:00
hang 0655318d2d Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-12 15:44:00 +08:00
hang 0bd2a10091 修改受试者无序阅片 2024-06-12 15:44:00 +08:00
he ce11788878 修改
continuous-integration/drone/push Build is passing
2024-06-12 15:32:17 +08:00
he 0cb74296c3 修改
continuous-integration/drone/push Build is passing
2024-06-12 15:01:23 +08:00
hang def08b72ca 修改返回列表
continuous-integration/drone/push Build is passing
2024-06-12 14:22:01 +08:00
hang 1ef8d2913b Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is failing
2024-06-12 14:11:12 +08:00
hang 7e18b1287e 优化代码 2024-06-12 14:11:11 +08:00
he fdcb6ad12f 修改
continuous-integration/drone/push Build is failing
2024-06-12 14:08:18 +08:00
hang 988bf0e92c 修改任务查询
continuous-integration/drone/push Build is passing
2024-06-12 14:03:38 +08:00
he f6612286d9 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-12 13:45:18 +08:00
he c21845c60d 修改 2024-06-12 13:45:17 +08:00
74 changed files with 2107 additions and 1401 deletions
+3 -18
View File
@@ -32,6 +32,7 @@ using IRaCIS.Core.Application.Contracts;
using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO; using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO;
using DocumentFormat.OpenXml.Spreadsheet; using DocumentFormat.OpenXml.Spreadsheet;
using AutoMapper.QueryableExtensions; using AutoMapper.QueryableExtensions;
using NetTopologySuite.Algorithm;
namespace IRaCIS.Api.Controllers namespace IRaCIS.Api.Controllers
{ {
@@ -218,7 +219,7 @@ namespace IRaCIS.Api.Controllers
{ {
//发版屏蔽 //发版屏蔽
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo)); //returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
//MFA 发送邮件 //MFA 发送邮件
@@ -226,23 +227,7 @@ namespace IRaCIS.Api.Controllers
var email = returnModel.Data.BasicInfo.EMail; var email = returnModel.Data.BasicInfo.EMail;
#region Email var hiddenEmail = EmailMaskHelper.MaskEmail(email);
// 找到 "@" 符号的位置
int atIndex = email.IndexOf('@');
// 替换 "@" 符号前的中间两位为星号
string visiblePart = email.Substring(0, atIndex);
int startIndex = (visiblePart.Length - 2) / 2;
// 替换中间两位字符为星号
string hiddenPartBeforeAt = visiblePart.Substring(0, startIndex) + "**" + visiblePart.Substring(startIndex + 2);
string afterAt = email.Substring(atIndex + 1);
// 组合隐藏和可见部分
string hiddenEmail = hiddenPartBeforeAt + "@" + afterAt;
#endregion
returnModel.Data.BasicInfo.EMail = hiddenEmail; returnModel.Data.BasicInfo.EMail = hiddenEmail;
@@ -479,6 +479,8 @@ namespace IRaCIS.Core.API.Controllers
public string FilePath { get; set; } public string FilePath { get; set; }
public string FileName { get; set; } public string FileName { get; set; }
public int FileFize { get; set; } public int FileFize { get; set; }
public string FileType { get; set; }
} }
} }
@@ -511,7 +513,7 @@ namespace IRaCIS.Core.API.Controllers
foreach (var item in incommand.UploadedFileList) foreach (var item in incommand.UploadedFileList)
{ {
await _repository.AddAsync(new NoneDicomStudyFile() { FileName = item.FileName, Path = item.FilePath, NoneDicomStudyId = noneDicomStudyId }); await _repository.AddAsync(new NoneDicomStudyFile() { FileName = item.FileName, Path = item.FilePath, NoneDicomStudyId = noneDicomStudyId,FileType=item.FileType });
} }
var uploadFinishedTime = DateTime.Now; var uploadFinishedTime = DateTime.Now;
@@ -528,6 +530,7 @@ namespace IRaCIS.Core.API.Controllers
studyMonitor.StudyCode = noneDicomStudy.StudyCode; studyMonitor.StudyCode = noneDicomStudy.StudyCode;
studyMonitor.ArchiveFinishedTime = DateTime.Now; studyMonitor.ArchiveFinishedTime = DateTime.Now;
studyMonitor.IP = _userInfo.IP; studyMonitor.IP = _userInfo.IP;
studyMonitor.IsSuccess = true;
await _repository.SaveChangesAsync(); await _repository.SaveChangesAsync();
-1
View File
@@ -79,7 +79,6 @@
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" /> <PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.0.3" /> <PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.0.3" />
<PackageReference Include="Serilog.Sinks.Email" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.6.2" /> <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.6.2" />
</ItemGroup> </ItemGroup>
@@ -30,7 +30,7 @@
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Event_IRC" "ASPNETCORE_ENVIRONMENT": "Event_IRC"
}, },
"applicationUrl": "http://localhost:6101" "applicationUrl": "http://localhost:6100"
}, },
"Docker": { "Docker": {
"commandName": "Docker", "commandName": "Docker",
@@ -54,11 +54,11 @@
}, },
"applicationUrl": "http://localhost:6100" "applicationUrl": "http://localhost:6100"
}, },
"IRaCIS.US_IRC": { "IRaCIS.US_Uat_IRC": {
"commandName": "Project", "commandName": "Project",
"launchBrowser": true, "launchBrowser": true,
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "US_IRC" "ASPNETCORE_ENVIRONMENT": "US_Uat_IRC"
}, },
"applicationUrl": "http://localhost:6100" "applicationUrl": "http://localhost:6100"
} }
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Serilog; using Serilog;
using Serilog.Events; using Serilog.Events;
using Serilog.Sinks.Email; //using Serilog.Sinks.Email;
using System; using System;
using System.Net; using System.Net;
+10 -2
View File
@@ -14,6 +14,7 @@
"ObjectStoreUse": "AliyunOSS", "ObjectStoreUse": "AliyunOSS",
"AliyunOSS": { "AliyunOSS": {
"regionId": "cn-shanghai", "regionId": "cn-shanghai",
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"endpoint": "https://oss-cn-shanghai.aliyuncs.com", "endpoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
@@ -42,8 +43,11 @@
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30, "LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60 "AutoLoginOutMinutes": 60,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10
}, },
"SystemEmailSendConfig": { "SystemEmailSendConfig": {
"Port": 465, "Port": 465,
@@ -51,7 +55,11 @@
"FromEmail": "uat@extimaging.com", "FromEmail": "uat@extimaging.com",
"FromName": "UAT_IRC", "FromName": "UAT_IRC",
"AuthorizationCode": "SHzyyl2021", "AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.event.extimaging.com/login" "SiteUrl": "http://irc.event.extimaging.com/login",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗"
} }
+14 -5
View File
@@ -7,8 +7,8 @@
} }
}, },
"ConnectionStrings": { "ConnectionStrings": {
// "RemoteNew": "Server=47.117.165.18,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true", //"RemoteNew": "Server=101.132.193.237,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
// "Hangfire": "Server=47.117.165.18,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true" //"Hangfire": "Server=101.132.193.237,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true", "RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true" "Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
}, },
@@ -16,6 +16,7 @@
"ObjectStoreUse": "AliyunOSS", "ObjectStoreUse": "AliyunOSS",
"AliyunOSS": { "AliyunOSS": {
"regionId": "cn-shanghai", "regionId": "cn-shanghai",
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"endpoint": "https://oss-cn-shanghai.aliyuncs.com", "endpoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
@@ -36,14 +37,20 @@
"BasicSystemConfig": { "BasicSystemConfig": {
"OpenUserComplexPassword": true, "OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true, "OpenSignDocumentBeforeWork": true,
"OpenLoginLimit": true, "OpenLoginLimit": true,
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30, "LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60
"AutoLoginOutMinutes": 360,
"OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10
}, },
"SystemEmailSendConfig": { "SystemEmailSendConfig": {
@@ -53,6 +60,8 @@
"FromName": "IRC", "FromName": "IRC",
"AuthorizationCode": "ExtImg@2022", "AuthorizationCode": "ExtImg@2022",
"SiteUrl": "http://irc.extimaging.com/login", "SiteUrl": "http://irc.extimaging.com/login",
"OrganizationName": "Extlmaging",
"OrganizationNameCN": "Extlmaging",
"CompanyName": "Extensive Imaging", "CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司", "CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging", "CompanyShortName": "Extensive Imaging",
+15 -9
View File
@@ -18,6 +18,7 @@
"AliyunOSS": { "AliyunOSS": {
"regionId": "cn-shanghai", "regionId": "cn-shanghai",
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"endPoint": "https://oss-cn-shanghai.aliyuncs.com", "endPoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
@@ -26,15 +27,14 @@
"viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", "viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai" "region": "oss-cn-shanghai"
}, },
"MinIO": { "MinIO": {
"endPoint": "192.168.3.68", "endPoint": "hir-oss.test.extimaging.com",
"port": "8001", "port": "443",
"useSSL": false, "useSSL": true,
"accessKey": "IDFkwEpWej0b4DtiuThL", "accessKey": "fbStsVYCIPKHQneeqMwD",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h", "secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"bucketName": "test", "bucketName": "irc-test",
"viewEndpoint": "http://192.168.3.68:8001/test/" "viewEndpoint": "https://hir-oss.test.extimaging.com/irc-test"
}, },
"AWS": { "AWS": {
@@ -63,7 +63,11 @@
"AutoLoginOutMinutes": 1, "AutoLoginOutMinutes": 1,
"OpenLoginMFA": false "OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10
}, },
"SystemEmailSendConfig": { "SystemEmailSendConfig": {
@@ -75,6 +79,8 @@
"SiteUrl": "http://irc.test.extimaging.com/login", "SiteUrl": "http://irc.test.extimaging.com/login",
"OrganizationName": "Extlmaging",
"OrganizationNameCN": "Extlmaging",
"CompanyName": "Extensive Imaging", "CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司", "CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging", "CompanyShortName": "Extensive Imaging",
@@ -0,0 +1,76 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=us-prod-mssql-service,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=us-prod-mssql-service,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
//"RemoteNew": "Server=44.210.231.169,1435;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
//"Hangfire": "Server=44.210.231.169,1435;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
},
"ObjectStoreService": {
"ObjectStoreUse": "AWS",
"MinIO": {
"endPoint": "44.210.231.169",
"port": "9001",
"useSSL": false,
"accessKey": "e9bT1isTOqSAUxb6wd4n",
"secretKey": "b5TaDzNdQCBtCvfm8eZ3dR6yY7tfZu2JYze2Po1i",
"bucketName": "prod-irc-us",
"viewEndpoint": "http://44.210.231.169:9001/prod-irc-us/"
},
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": true,
"accessKey": "AKIAW3MEAFJX5P32P6NA",
"secretKey": "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",
"bucketName": "ei-med-s3-lili-store",
"viewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com/"
}
},
"BasicSystemConfig": {
"OpenUserComplexPassword": false,
"OpenSignDocumentBeforeWork": false,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"OpenLoginMFA": false
},
"SystemEmailSendConfig": {
"Port": 587,
"Host": "smtp-mail.outlook.com",
"FromEmail": "donotreply@elevateimaging.ai",
"FromName": "LiLi",
"AuthorizationCode": "Q#669869497420ul",
"OrganizationName": "Elevate Imaging",
"OrganizationNameCN": "Elevate Imaging",
"CompanyName": "Elevate Imaging Inc.",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Elevate Imaging",
"CompanyShortNameCN": "展影医疗",
"SiteUrl": "https://lili.elevateimaging.ai/login"
}
}
@@ -7,19 +7,16 @@
} }
}, },
"ConnectionStrings": { "ConnectionStrings": {
"RemoteNew": "Server=us-mssql-service,1433;Database=Prod_US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", "RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=us-mssql-service,1433;Database=Prod_US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" "Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
//"RemoteNew": "Server=44.218.11.19,1435;Database=Prod_US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
//"Hangfire": "Server=44.218.11.19,1435;Database=Prod_US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
}, },
"ObjectStoreService": { "ObjectStoreService": {
"ObjectStoreUse": "AWS", "ObjectStoreUse": "MinIO",
"AliyunOSS": { "AliyunOSS": {
"regionId": "cn-shanghai", "regionId": "cn-shanghai",
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"endPoint": "https://oss-cn-shanghai.aliyuncs.com", "endPoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
@@ -30,13 +27,20 @@
}, },
"MinIO": { "MinIO": {
"endPoint": "192.168.3.68", //"endPoint": "hir-oss.uat.extimaging.com",
"port": "8001", //"port": "443",
//"useSSL": true,
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/hir-uat",
"endPoint": "47.117.164.182",
"port": "9001",
"useSSL": false, "useSSL": false,
"accessKey": "IDFkwEpWej0b4DtiuThL", "viewEndpoint": "http://47.117.164.182:9001/test-irc-us",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
"bucketName": "test", "accessKey": "b9Ul0e98xPzt6PwRXA1Q",
"viewEndpoint": "http://192.168.3.68:8001/test/" "secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
"bucketName": "test-irc-us"
}, },
"AWS": { "AWS": {
@@ -61,19 +65,27 @@
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30, "LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60 "AutoLoginOutMinutes": 60,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10
}, },
"SystemEmailSendConfig": { "SystemEmailSendConfig": {
"Port": 465, "Port": 587,
"Host": "smtp.qiye.aliyun.com", "Host": "smtp-mail.outlook.com",
"FromEmail": "test@extimaging.com", "FromEmail": "donotreply@elevateimaging.ai",
"FromName": "Test_IRC", "FromName": "LiLi",
"AuthorizationCode": "SHzyyl2021", "AuthorizationCode": "Q#669869497420ul",
"CompanyName": "Elevate Imaging",
"OrganizationName": "Elevate Imaging",
"OrganizationNameCN": "Elevate Imaging",
"CompanyName": "Elevate Imaging Inc.",
"CompanyNameCN": "上海展影医疗科技有限公司", "CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Elevate Imaging", "CompanyShortName": "Elevate Imaging",
"CompanyShortNameCN": "展影医疗" "CompanyShortNameCN": "展影医疗",
"SiteUrl": "https://lili.test.elevateimaging.ai/login"
} }
} }
@@ -0,0 +1,85 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
//"RemoteNew": "Server=3.226.182.187,1435;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
//"Hangfire": "Server=3.226.182.187,1435;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"ObjectStoreService": {
"ObjectStoreUse": "AWS",
"MinIO": {
//"endPoint": "hir-minio.uat.elevateimaging.ai",
//"port": "443",
//"useSSL": true,
//"viewEndpoint": "https://hir-minio.uat.elevateimaging.ai/uat-irc-us",
"endPoint": "3.226.182.187",
"port": "9001",
"useSSL": false,
"viewEndpoint": "http://44.218.11.19:9001/uat-irc-us",
"accessKey": "lH8DkKskLuDqPaiubuSQ",
"secretKey": "pdPdicvvLeH7xAC5yFUrI7odMyBfOXxvVWMvKYV4",
"bucketName": "uat-irc-us"
},
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": true,
"accessKey": "AKIAW3MEAFJXUO6XYFYN",
"secretKey": "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",
"bucketName": "ei-med-s3-lili-uat-store",
"viewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/"
}
},
"BasicSystemConfig": {
"OpenUserComplexPassword": false,
"OpenSignDocumentBeforeWork": false,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"OpenLoginMFA": true
},
"SystemEmailSendConfig": {
"Port": 587,
"Host": "smtp-mail.outlook.com",
"FromEmail": "donotreply@elevateimaging.ai",
"FromName": "LiLi",
"AuthorizationCode": "Q#669869497420ul",
"OrganizationName": "Elevate Imaging",
"OrganizationNameCN": "Elevate Imaging",
"CompanyName": "Elevate Imaging Inc.",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Elevate Imaging",
"CompanyShortNameCN": "展影医疗",
"SiteUrl": "https://lili.test.elevateimaging.ai/login"
}
}
+20 -7
View File
@@ -16,6 +16,7 @@
"AliyunOSS": { "AliyunOSS": {
"regionId": "cn-shanghai", "regionId": "cn-shanghai",
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"endpoint": "https://oss-cn-shanghai.aliyuncs.com", "endpoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
@@ -26,12 +27,17 @@
}, },
"MinIO": { "MinIO": {
"endpoint": "http://192.168.3.68", "endPoint": "hir-oss.uat.extimaging.com",
"port": "8001", //"port": "80",
"useSSL": false, //"useSSL": false,
"accessKey": "IDFkwEpWej0b4DtiuThL", //"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h", "port": "443",
"bucketName": "test" "useSSL": true,
"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
"bucketName": "irc-uat"
} }
}, },
@@ -45,7 +51,12 @@
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30, "LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60 "AutoLoginOutMinutes": 60,
"OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10
}, },
"SystemEmailSendConfig": { "SystemEmailSendConfig": {
@@ -55,6 +66,8 @@
"FromName": "UAT_IRC", "FromName": "UAT_IRC",
"AuthorizationCode": "SHzyyl2021", "AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.uat.extimaging.com/login", "SiteUrl": "http://irc.uat.extimaging.com/login",
"OrganizationName": "Extlmaging",
"OrganizationNameCN": "Extlmaging",
"CompanyName": "Extensive Imaging", "CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司", "CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging", "CompanyShortName": "Extensive Imaging",
@@ -0,0 +1,44 @@
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Helper
{
public static class EmailMaskHelper
{
//显示位数:3分之2的位数,向上取整
//取哪几个个值:最后一位和前面几位
//其他:3个***。
//比如:hlj23@126.com
//为:hlj***3@126.com
//he@126.com
//为:h*** e@126.com
public static string MaskEmail(string email)
{
// 找到 "@" 符号的位置
int atIndex = email.IndexOf('@');
string visiblePartBefore = email.Substring(0, atIndex);
string afterAt = email.Substring(atIndex + 1);
int visibleLength = (int)Math.Ceiling((double)visiblePartBefore.Length * 2 / 3);
// 替换中间两位字符为星号
string hiddenPartBeforeAt = visiblePartBefore.Substring(0, visibleLength - 1) + "***" + visiblePartBefore.Last();
// 组合隐藏和可见部分
string hiddenEmail = hiddenPartBeforeAt + "@" + afterAt;
return hiddenEmail;
}
}
}
+7 -4
View File
@@ -39,6 +39,9 @@ namespace IRaCIS.Core.Application.Helper
public string regionId { get; set; } public string regionId { get; set; }
public string accessKeyId { get; set; } public string accessKeyId { get; set; }
public string accessKeySecret { get; set; } public string accessKeySecret { get; set; }
public string internalEndpoint { get; set; }
public string endPoint { get; set; } public string endPoint { get; set; }
public string bucketName { get; set; } public string bucketName { get; set; }
@@ -144,7 +147,7 @@ namespace IRaCIS.Core.Application.Helper
{ {
var aliConfig = ObjectStoreServiceOptions.AliyunOSS; var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); var _ossClient = new OssClient(aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
@@ -220,7 +223,7 @@ namespace IRaCIS.Core.Application.Helper
{ {
var aliConfig = ObjectStoreServiceOptions.AliyunOSS; var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); var _ossClient = new OssClient(aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
// 上传文件 // 上传文件
var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, localFilePath); var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, localFilePath);
@@ -279,7 +282,7 @@ namespace IRaCIS.Core.Application.Helper
{ {
var aliConfig = ObjectStoreServiceOptions.AliyunOSS; var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); var _ossClient = new OssClient(aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
// 上传文件 // 上传文件
var result = _ossClient.GetObject(aliConfig.bucketName, ossRelativePath); var result = _ossClient.GetObject(aliConfig.bucketName, ossRelativePath);
@@ -351,7 +354,7 @@ namespace IRaCIS.Core.Application.Helper
{ {
var aliConfig = ObjectStoreServiceOptions.AliyunOSS; var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); var _ossClient = new OssClient(aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
// 生成签名URL。 // 生成签名URL。
var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get) var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get)
@@ -29,7 +29,7 @@ public static class SendEmailHelper
//await smtp.AuthenticateAsync("zhou941003@qq.com", "sqfhlpfdvnexbcab"); //await smtp.AuthenticateAsync("zhou941003@qq.com", "sqfhlpfdvnexbcab");
await smtp.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.SslOnConnect); await smtp.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto);
await smtp.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode); await smtp.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode);
@@ -40,11 +40,11 @@ public static class SendEmailHelper
} }
} }
catch (Exception ) catch (Exception ex)
{ {
//---邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员 //---邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员
throw new Exception(StaticData.International("SendEmail_SendFail")); throw new Exception(StaticData.International("SendEmail_SendFail"),new Exception(ex.Message));
} }
@@ -55,7 +55,7 @@ public static class SendEmailHelper
using (var client = new MailKit.Net.Smtp.SmtpClient()) using (var client = new MailKit.Net.Smtp.SmtpClient())
{ {
await client.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.SslOnConnect); await client.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto);
await client.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode); await client.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode);
@@ -133,7 +133,7 @@ public static class SendEmailHelper
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true; smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
await smtp.ConnectAsync(sMTPEmailConfig.Host, sMTPEmailConfig.Port, SecureSocketOptions.SslOnConnect); await smtp.ConnectAsync(sMTPEmailConfig.Host, sMTPEmailConfig.Port, SecureSocketOptions.Auto);
await smtp.AuthenticateAsync(sMTPEmailConfig.UserName, sMTPEmailConfig.AuthorizationCode); await smtp.AuthenticateAsync(sMTPEmailConfig.UserName, sMTPEmailConfig.AuthorizationCode);
@@ -78,9 +78,9 @@
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.2" /> <PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.2" />
<PackageReference Include="fo-dicom.Codecs" Version="5.12.0" /> <PackageReference Include="fo-dicom.Codecs" Version="5.12.0" />
<PackageReference Include="IP2Region.Net" Version="2.0.2" /> <PackageReference Include="IP2Region.Net" Version="2.0.2" />
<PackageReference Include="MailKit" Version="4.5.0" /> <PackageReference Include="MailKit" Version="4.2.0" />
<PackageReference Include="MediatR" Version="12.2.0" /> <PackageReference Include="MediatR" Version="12.2.0" />
<PackageReference Include="MimeKit" Version="4.5.0" /> <PackageReference Include="MimeKit" Version="4.2.0" />
<PackageReference Include="MiniExcel" Version="1.32.0" /> <PackageReference Include="MiniExcel" Version="1.32.0" />
<PackageReference Include="Minio" Version="6.0.2" /> <PackageReference Include="Minio" Version="6.0.2" />
<PackageReference Include="MiniWord" Version="0.8.0" /> <PackageReference Include="MiniWord" Version="0.8.0" />
@@ -424,11 +424,11 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.Allocation.VisitTaskService.GetOrderReadingIQueryable(IRaCIS.Core.Application.ViewModel.GetOrderReadingIQueryableInDto)"> <member name="M:IRaCIS.Core.Application.Service.Allocation.VisitTaskService.GetSubjectReadingIQueryable(IRaCIS.Core.Application.ViewModel.GetReadingIQueryableInDto)">
<summary> <summary>
获取序阅片IQuery对象 获取subject有序 或者无序阅片IQuery对象
</summary> </summary>
<param name="inDto"></param> <param name="inQuery"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.Allocation.VisitTaskService.GetIRHaveReadTaskList(IRaCIS.Core.Application.ViewModel.VisitTaskQuery)"> <member name="M:IRaCIS.Core.Application.Service.Allocation.VisitTaskService.GetIRHaveReadTaskList(IRaCIS.Core.Application.ViewModel.VisitTaskQuery)">
@@ -13265,11 +13265,12 @@
<param name="state"></param> <param name="state"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Application.Services.UserService.SendMFAEmail(System.Guid)"> <member name="M:IRaCIS.Application.Services.UserService.SendMFAEmail(System.Guid,System.Int32)">
<summary> <summary>
发送MFA 验证邮件 发送MFA 验证邮件
</summary> </summary>
<param name="userId"></param> <param name="userId"></param>
<param name="mfaType"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Application.Services.UserService.VerifyMFACodeAsync(System.Guid,System.String)"> <member name="M:IRaCIS.Application.Services.UserService.VerifyMFACodeAsync(System.Guid,System.String)">
@@ -13970,6 +13971,13 @@
<param name="inDto"></param> <param name="inDto"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Application.Services.ReadingImageTaskService.ResetReadingTask(IRaCIS.Core.Application.Service.Reading.Dto.ResetReadingTaskInDto)">
<summary>
重置阅片任务
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Application.Services.ReadingImageTaskService.VerifyReadingRestTime"> <member name="M:IRaCIS.Application.Services.ReadingImageTaskService.VerifyReadingRestTime">
<summary> <summary>
验证阅片休息时间 验证阅片休息时间
@@ -370,16 +370,16 @@ namespace IRaCIS.Core.Application.ViewModel
} }
public class GetOrderReadingIQueryableInDto public class GetReadingIQueryableInDto:PageInput
{ {
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid? SubjectId { get; set; }
public Guid TrialReadingCriterionId { get; set; } public Guid TrialReadingCriterionId { get; set; }
public string? SubjectCode { get; set; } = null; public string? SubjectCode { get; set; } = null;
public PageInput? Page { get; set; } = null;
} }
public class VisitTaskQuery : PageInput public class VisitTaskQuery : PageInput
@@ -16,6 +16,6 @@ namespace IRaCIS.Core.Application.Service
Task<IResponseOutput> ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService); Task<IResponseOutput> ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService);
Task<(int, List<IRUnReadSubjectView>)> GetOrderReadingIQueryable(GetOrderReadingIQueryableInDto inDto); Task<PageOutput<IRUnReadSubjectView>> GetSubjectReadingIQueryable(GetReadingIQueryableInDto inDto);
} }
} }
@@ -117,7 +117,7 @@ namespace IRaCIS.Core.Application.Service
var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);
var trialTaskConfig = _repository.Where<Trial>(t => t.Id == queryVisitTask.TrialId).Select(t => new { IsHaveDoubleReadCriterion=t.ReadingQuestionCriterionTrialList.Any(t=>t.IsSigned && t.IsConfirm && t.ReadingType==ReadingMethod.Double), t.VitrualSiteCode }).FirstOrDefault(); var trialTaskConfig = _repository.Where<Trial>(t => t.Id == queryVisitTask.TrialId).Select(t => new { IsHaveDoubleReadCriterion=t.TrialReadingCriterionList.Any(t=>t.IsSigned && t.IsConfirm && t.ReadingType==ReadingMethod.Double), t.VitrualSiteCode }).FirstOrDefault();
return ResponseOutput.Ok(pageList, trialTaskConfig); return ResponseOutput.Ok(pageList, trialTaskConfig);
} }
@@ -259,7 +259,7 @@ namespace IRaCIS.Core.Application.Service
.ProjectTo<TaskMedicalReviewView>(_mapper.ConfigurationProvider); .ProjectTo<TaskMedicalReviewView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.AuditState), nameof(TaskMedicalReviewView.SubjectId), nameof(TaskMedicalReviewView.ArmEnum), nameof(TaskMedicalReviewView.VisitTaskNum) }; var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.SubjectId), nameof(TaskMedicalReviewView.ArmEnum), nameof(TaskMedicalReviewView.VisitTaskNum) };
var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
return ResponseOutput.Ok(pageList, new return ResponseOutput.Ok(pageList, new
@@ -22,6 +22,8 @@ using DocumentFormat.OpenXml.Bibliography;
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto;
using IRaCIS.Core.Domain.Share.Reading; using IRaCIS.Core.Domain.Share.Reading;
using MassTransit; using MassTransit;
using System.Reactive.Subjects;
using Subject = IRaCIS.Core.Domain.Models.Subject;
namespace IRaCIS.Core.Application.Service.Allocation namespace IRaCIS.Core.Application.Service.Allocation
{ {
@@ -957,132 +959,6 @@ namespace IRaCIS.Core.Application.Service.Allocation
var readingTool = criterionConfig.ReadingTool; var readingTool = criterionConfig.ReadingTool;
var isReadingTaskViewInOrder = criterionConfig.IsReadingTaskViewInOrder; var isReadingTaskViewInOrder = criterionConfig.IsReadingTaskViewInOrder;
#region Subject
if (isReadingTaskViewInOrder == ReadingOrder.InOrder)
{
var visitTaskListInfo = await GetOrderReadingIQueryable(new GetOrderReadingIQueryableInDto()
{
TrialId = trialId,
TrialReadingCriterionId = trialReadingCriterionId,
SubjectCode = inQuery.SubjectCode,
Page = new PageInput()
{
PageIndex = inQuery.PageIndex,
PageSize = inQuery.PageSize,
Asc = inQuery.Asc,
SortField = inQuery.SortField,
}
});
var totalCount = visitTaskListInfo.Item1;
var currentPageData = visitTaskListInfo.Item2;
var result = new PageOutput<IRUnReadSubjectView>()
{
PageSize = inQuery.PageSize,
PageIndex = inQuery.PageIndex,
TotalCount = totalCount,
CurrentPageData = currentPageData,
};
// 封装的方法有问题
//var result = await visitQuery.ToPagedListAsync(iRUnReadSubjectQuery.PageIndex, iRUnReadSubjectQuery.PageSize, String.IsNullOrEmpty(iRUnReadSubjectQuery.SortField) ? nameof(IRUnReadSubjectView.SubjectId) : iRUnReadSubjectQuery.SortField, iRUnReadSubjectQuery.Asc);
return ResponseOutput.Ok(result, new
{
RandomReadInfo = new IRUnReadOutDto(),
IsReadingTaskViewInOrder = isReadingTaskViewInOrder,
ReadingTool = readingTool,
IseCRFShowInDicomReading = criterionConfig.IseCRFShowInDicomReading,
IsReadingShowSubjectInfo = criterionConfig.IsReadingShowSubjectInfo,
IsReadingShowPreviousResults = criterionConfig.IsReadingShowPreviousResults,
DigitPlaces = criterionConfig.DigitPlaces,
CriterionType = criterionConfig.CriterionType,
});
}
else if(isReadingTaskViewInOrder == ReadingOrder.SubjectRandom)
{
var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId);
var visitQuery = _visitTaskRepository.Where(x => x.TrialId == trialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect)
.WhereIf(!string.IsNullOrEmpty(subjectCode), t => (t.Subject.Code.Contains(subjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(subjectCode!) && t.IsAnalysisCreate));
var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode });
var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView()
{
SubjectId = x.Key.SubjectId,
SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode,
SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime),
//未读任务量
UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(),
UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Where(x => x.IsUrgent).Count(),
//已读任务量
HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(),
ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed),
UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned)
.OrderBy(x => x.VisitTaskNum)
.Select(u => new IRUnreadTaskView()
{
Id = u.Id,
IsUrgent = u.IsUrgent,
VisitNum = u.VisitTaskNum,
TaskBlindName = u.TaskBlindName,
VisistId = u.SourceSubjectVisitId,
SuggesteFinishedTime = u.SuggesteFinishedTime,
ReadingCategory = u.ReadingCategory,
IsAnalysisCreate = u.IsAnalysisCreate,
ArmEnum = u.ArmEnum,
TrialReadingCriterionId = u.TrialReadingCriterionId,
IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
IsClinicalDataSign = u.IsClinicalDataSign,
IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign
})
.ToList()
}).Where(x => x.UnReadCanReadTaskCount > 0);
var pageList = await visitTaskQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField)? nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) : inQuery.SortField, inQuery.Asc );
return ResponseOutput.Ok(pageList, new
{
RandomReadInfo = new IRUnReadOutDto(),
IsReadingTaskViewInOrder = isReadingTaskViewInOrder,
ReadingTool = readingTool,
IseCRFShowInDicomReading = criterionConfig.IseCRFShowInDicomReading,
IsReadingShowSubjectInfo = criterionConfig.IsReadingShowSubjectInfo,
IsReadingShowPreviousResults = criterionConfig.IsReadingShowPreviousResults,
DigitPlaces = criterionConfig.DigitPlaces,
CriterionType = criterionConfig.CriterionType,
});
}
else
{
var taskQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == trialReadingCriterionId)
// .Where(x=>x.Subject.ClinicalDataList.Any(c => c.IsSign && (c.ReadingId == x.SouceReadModuleId || c.ReadingId == x.SourceSubjectVisitId)))
.Where(x => !x.Subject.IsDeleted).Where(x => (x.IsNeedClinicalDataSign && x.IsClinicalDataSign) || !x.IsNeedClinicalDataSign);
IRUnReadOutDto iRUnReadOut = new IRUnReadOutDto()
{
FinishJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(),
FinishTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(),
SuggesteFinishedTime = await taskQuery.Where(x => x.ReadingTaskState != ReadingTaskState.HaveSigned).MaxAsync(x => x.SuggesteFinishedTime),
UnReadJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(),
UnReadTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(),
};
var result = new PageOutput<IRUnReadSubjectView>() var result = new PageOutput<IRUnReadSubjectView>()
{ {
@@ -1092,6 +968,41 @@ namespace IRaCIS.Core.Application.Service.Allocation
CurrentPageData = null, CurrentPageData = null,
}; };
IRUnReadOutDto iRUnReadOut = new IRUnReadOutDto();
//subject 级别 有序 无序查询
if (isReadingTaskViewInOrder == ReadingOrder.InOrder || isReadingTaskViewInOrder == ReadingOrder.SubjectRandom)
{
result = await GetSubjectReadingIQueryable(new GetReadingIQueryableInDto()
{
TrialId = trialId,
TrialReadingCriterionId = trialReadingCriterionId,
SubjectCode = inQuery.SubjectCode,
PageIndex = inQuery.PageIndex,
PageSize = inQuery.PageSize,
Asc = inQuery.Asc,
SortField = inQuery.SortField,
});
}
//随机阅片
else
{
var taskQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == trialReadingCriterionId)
// .Where(x=>x.Subject.ClinicalDataList.Any(c => c.IsSign && (c.ReadingId == x.SouceReadModuleId || c.ReadingId == x.SourceSubjectVisitId)))
.Where(x => !x.Subject.IsDeleted).Where(x => (x.IsNeedClinicalDataSign && x.IsClinicalDataSign) || !x.IsNeedClinicalDataSign);
iRUnReadOut = new IRUnReadOutDto()
{
FinishJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(),
FinishTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(),
SuggesteFinishedTime = await taskQuery.Where(x => x.ReadingTaskState != ReadingTaskState.HaveSigned).MaxAsync(x => x.SuggesteFinishedTime),
UnReadJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(),
UnReadTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(),
};
}
return ResponseOutput.Ok(result, new return ResponseOutput.Ok(result, new
{ {
IsReadingTaskViewInOrder = isReadingTaskViewInOrder, IsReadingTaskViewInOrder = isReadingTaskViewInOrder,
@@ -1104,30 +1015,28 @@ namespace IRaCIS.Core.Application.Service.Allocation
CriterionType = criterionConfig.CriterionType, CriterionType = criterionConfig.CriterionType,
}); });
}
#endregion
} }
/// <summary> /// <summary>
/// 获取序阅片IQuery对象 /// 获取subject有序 或者无序阅片IQuery对象
/// </summary> /// </summary>
/// <param name="inDto"></param> /// <param name="inQuery"></param>
/// <returns></returns> /// <returns></returns>
public async Task<(int, List<IRUnReadSubjectView>)> GetOrderReadingIQueryable(GetOrderReadingIQueryableInDto inDto) public async Task<PageOutput<IRUnReadSubjectView>> GetSubjectReadingIQueryable(GetReadingIQueryableInDto inQuery)
{ {
var trialReadingCriterionId = inDto.TrialReadingCriterionId; var trialReadingCriterionId = inQuery.TrialReadingCriterionId;
var subjectCode = inQuery.SubjectCode;
var trialId = inQuery.TrialId;
var subjectId = inQuery.SubjectId;
var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId); var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId);
if (critrion.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{
var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect)
var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect) .WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId)
//前序 不存在 未生成任务的访视 //前序 不存在 未生成任务的访视
.WhereIf(critrion.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum)) .WhereIf(critrion.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum))
@@ -1139,7 +1048,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
//满足前序访视不存在 需要签署但是未签署 sql 相当复杂 同时想查询所有未读的统计数字 就无法统计 byzhouhang //满足前序访视不存在 需要签署但是未签署 sql 相当复杂 同时想查询所有未读的统计数字 就无法统计 byzhouhang
//但是加字段 IsFrontTaskNeedSignButNotSign 那么签名临床数据的时候,要对该subject 该标准的有效的任务 这个字段需要在签名的时候维护 采取这种方式 统计数字灵活 //但是加字段 IsFrontTaskNeedSignButNotSign 那么签名临床数据的时候,要对该subject 该标准的有效的任务 这个字段需要在签名的时候维护 采取这种方式 统计数字灵活
//.Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)) //.Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum))
.WhereIf(!string.IsNullOrEmpty(inDto.SubjectCode), t => (t.Subject.Code.Contains(inDto.SubjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inDto.SubjectCode!) && t.IsAnalysisCreate)); .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate));
var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }); var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode });
@@ -1221,22 +1130,112 @@ namespace IRaCIS.Core.Application.Service.Allocation
var result = new List<IRUnReadSubjectView>(); var result = new List<IRUnReadSubjectView>();
var propName = string.IsNullOrWhiteSpace(inDto.Page!.SortField) ? nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) : inDto.Page.SortField; var propName = string.IsNullOrWhiteSpace(inQuery!.SortField) ? nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) : inQuery.SortField;
var visitTaskOrderQuery = inQuery.Asc ? visitTaskQuery.OrderBy(propName) : visitTaskQuery.OrderBy(propName + " desc");
var visitTaskOrderQuery = inDto.Page.Asc ? visitTaskQuery.OrderBy(propName) : visitTaskQuery.OrderBy(propName + " desc");
if (inDto.Page != null)
{
result = await visitTaskOrderQuery result = await visitTaskOrderQuery
.Skip((inDto.Page.PageIndex - 1) * inDto.Page.PageSize) .Skip((inQuery.PageIndex - 1) * inQuery.PageSize)
.Take(inDto.Page.PageSize).ToListAsync(); .Take(inQuery.PageSize).ToListAsync();
return new PageOutput<IRUnReadSubjectView>()
{
PageSize = inQuery.PageSize,
PageIndex = inQuery.PageIndex,
TotalCount = count,
CurrentPageData = result,
};
} }
else else
{ {
result = await visitTaskOrderQuery.ToListAsync();
if (subjectId != null)
{
//找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务
var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
&& t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskBlindName == "Timepoint" && t.ReadingCategory == ReadingCategory.Visit
&& (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze), true).ToListAsync();
if (needDealTaskList.Count > 0)
{
//已完成的访视任务数量(包含重阅的)
var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
&& t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit);
//已经处理过的任务名称的数量
var haveDealedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
&& t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint");
//随机赋值编号 比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个
List<int> availableNumbers = Enumerable.Range(haveDealedTaskCount + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList();
Random rng = new Random();
foreach (var visitTask in needDealTaskList)
{
int randomIndex = rng.Next(availableNumbers.Count);
visitTask.TaskBlindName = $"Timepoint Ran {availableNumbers[randomIndex]}";
availableNumbers.RemoveAt(randomIndex);
}
await _visitTaskRepository.SaveChangesAsync();
}
} }
var visitQuery = _visitTaskRepository.Where(x => x.TrialId == trialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect)
.WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId)
.WhereIf(!string.IsNullOrEmpty(subjectCode), t => (t.Subject.Code.Contains(subjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(subjectCode!) && t.IsAnalysisCreate));
var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode });
var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView()
{
SubjectId = x.Key.SubjectId,
SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode,
SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime),
//未读任务量
UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(),
UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Where(x => x.IsUrgent).Count(),
//已读任务量
HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(),
ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed),
UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned)
.OrderBy(x => x.VisitTaskNum)
.Select(u => new IRUnreadTaskView()
{
Id = u.Id,
IsUrgent = u.IsUrgent,
VisitNum = u.VisitTaskNum,
TaskBlindName = u.TaskBlindName,
VisistId = u.SourceSubjectVisitId,
SuggesteFinishedTime = u.SuggesteFinishedTime,
ReadingCategory = u.ReadingCategory,
IsAnalysisCreate = u.IsAnalysisCreate,
ArmEnum = u.ArmEnum,
TrialReadingCriterionId = u.TrialReadingCriterionId,
IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
IsClinicalDataSign = u.IsClinicalDataSign,
IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign
})
.ToList()
}).Where(x => x.UnReadCanReadTaskCount > 0);
var pageList = await visitTaskQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) : inQuery.SortField, inQuery.Asc);
return pageList;
}
return (count, result);
} }
@@ -1417,6 +1416,13 @@ namespace IRaCIS.Core.Application.Service.Allocation
{ {
task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed;
//在PM 的申请重阅的影响列表里也不能申请重阅
var pmApply = await _visitTaskReReadingRepository.Where(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect && t.OriginalReReadingTask.ReadingCategory == ReadingCategory.Visit
&& t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default).Include(t => t.OriginalReReadingTask).FirstOrDefaultAsync();
// 有序 // 有序
if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
@@ -1430,10 +1436,6 @@ namespace IRaCIS.Core.Application.Service.Allocation
} }
//在PM 的申请重阅的影响列表里也不能申请重阅
var pmApply = await _visitTaskReReadingRepository.Where(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect && t.OriginalReReadingTask.ReadingCategory == ReadingCategory.Visit
&& t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default).Include(t => t.OriginalReReadingTask).FirstOrDefaultAsync();
if (pmApply != null) if (pmApply != null)
{ {
@@ -1462,13 +1464,13 @@ namespace IRaCIS.Core.Application.Service.Allocation
throw new BusinessValidationFailedException(_localizer["VisitTask_LastReading"]); throw new BusinessValidationFailedException(_localizer["VisitTask_LastReading"]);
} }
if (task.ReadingCategory == ReadingCategory.Oncology && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Oncology))) if (task.ReadingCategory == ReadingCategory.Oncology && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Oncology && t.ReadingTaskState==ReadingTaskState.HaveSigned)))
{ {
//---有序阅片,只允许申请该受试者阅片人最后一次完成肿瘤学任务重阅 //---有序阅片,只允许申请该受试者阅片人最后一次完成肿瘤学任务重阅
throw new BusinessValidationFailedException(_localizer["VisitTask_LastOncologistRecheck"]); throw new BusinessValidationFailedException(_localizer["VisitTask_LastOncologistRecheck"]);
} }
if (task.ReadingCategory == ReadingCategory.Judge && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Judge))) if (task.ReadingCategory == ReadingCategory.Judge && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned)))
{ {
//---有序阅片,只允许申请该受试者阅片人最后一次完成裁判的任务重阅 //---有序阅片,只允许申请该受试者阅片人最后一次完成裁判的任务重阅
throw new BusinessValidationFailedException(_localizer["VisitTask_LastAdjudicatorRecheck"]); throw new BusinessValidationFailedException(_localizer["VisitTask_LastAdjudicatorRecheck"]);
@@ -1477,9 +1479,27 @@ namespace IRaCIS.Core.Application.Service.Allocation
} }
else else
{ {
if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Global)
if (pmApply != null)
{ {
//---无序阅片,仅仅允许IR 申请 全局和访视类型类别的任务进行重阅 var originalTask = pmApply.OriginalReReadingTask;
//PM 无序影响列表
if (await _visitTaskRepository.Where(t => t.TrialId == originalTask.TrialId && t.SubjectId == originalTask.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.TrialReadingCriterionId == originalTask.TrialReadingCriterionId )
.Where(t=>t.Id==originalTask.Id||t.Id==originalTask.JudgeVisitTaskId)
.AnyAsync(t => t.VisitTaskNum == task.VisitTaskNum))
{
//---当前为无序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅
throw new BusinessValidationFailedException(_localizer["VisitTask_RandomInvalidRereading"]);
}
}
//也要支持裁判重阅240701
if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Judge)
{
//---无序阅片,仅仅允许IR 申请 访视、裁判类型类别的任务进行重阅
throw new BusinessValidationFailedException(_localizer["VisitTask_IRGlobalRecheck"]); throw new BusinessValidationFailedException(_localizer["VisitTask_IRGlobalRecheck"]);
} }
} }
@@ -1607,8 +1627,10 @@ namespace IRaCIS.Core.Application.Service.Allocation
if ((origenalTask.TaskState != TaskState.Effect && origenalTask.TaskState != TaskState.Freeze)) if ((origenalTask.TaskState != TaskState.Effect && origenalTask.TaskState != TaskState.Freeze))
{ {
await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new VisitTaskReReading() { RequestReReadingConfirmUserId = _userInfo.Id, RequestReReadingResultEnum = RequestReReadingResult.Invalid });
//---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作 //---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作
return ResponseOutput.NotOk(_localizer["VisitTask_ReapplyStatusConflict"]); return ResponseOutput.Ok(string.Empty, msg:_localizer["VisitTask_ReapplyStatusConflict"]);
} }
@@ -74,7 +74,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<TaskAllocationRule, TaskAllocationRuleDTO>() CreateMap<TaskAllocationRule, TaskAllocationRuleDTO>()
.ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.Enroll.DoctorUser)) .ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.Enroll.DoctorUser))
.ForMember(o => o.CriterionReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Select(t => new TrialCriterionReadingCategory() { EnrollId = t.EnrollId, ReadingCategory = t.ReadingCategory, TrialReadingCriterionId = t.TrialReadingCriterionId }))) .ForMember(o => o.CriterionReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Select(t => new TrialCriterionReadingCategory() { EnrollId = t.EnrollId, ReadingCategory = t.ReadingCategory, TrialReadingCriterionId = t.TrialReadingCriterionId })))
.ForMember(o => o.TrialReadingCriterionList, t => t.MapFrom(u => u.Trial.ReadingQuestionCriterionTrialList.Where(t => t.IsConfirm))) .ForMember(o => o.TrialReadingCriterionList, t => t.MapFrom(u => u.Trial.TrialReadingCriterionList.Where(t => t.IsConfirm)))
.ForMember(o => o.ReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Where(t=>t.TrialReadingCriterionId== trialReadingCriterionId).OrderBy(t => t.ReadingCategory).Select(t => t.ReadingCategory).ToList())) .ForMember(o => o.ReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Where(t=>t.TrialReadingCriterionId== trialReadingCriterionId).OrderBy(t => t.ReadingCategory).Select(t => t.ReadingCategory).ToList()))
; ;
@@ -21,7 +21,7 @@ namespace IRaCIS.Application.Services
Task SiteSurveyRejectEmail(MimeMessage messageToSend); Task SiteSurveyRejectEmail(MimeMessage messageToSend);
Task SenMFAVerifyEmail(Guid userId, string userName, string emailAddress, int verificationCode); Task SenMFAVerifyEmail(Guid userId, string userName, string emailAddress, int verificationCode, UserMFAType mfaType = UserMFAType.Login);
Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode); Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode);
@@ -94,7 +94,7 @@ namespace IRaCIS.Application.Services
} }
//MFA //MFA
public async Task SenMFAVerifyEmail(Guid userId, string userName, string emailAddress, int verificationCode) public async Task SenMFAVerifyEmail(Guid userId, string userName, string emailAddress, int verificationCode, UserMFAType mfaType = UserMFAType.Login)
{ {
var messageToSend = new MimeMessage(); var messageToSend = new MimeMessage();
//发件地址 //发件地址
@@ -103,7 +103,7 @@ namespace IRaCIS.Application.Services
messageToSend.To.Add(new MailboxAddress(userName, emailAddress)); messageToSend.To.Add(new MailboxAddress(userName, emailAddress));
//主题 //主题
//---[来自{0}] 关于MFA邮箱验证的提醒 //---[来自{0}] 关于MFA邮箱验证的提醒
messageToSend.Subject = _localizer["Mail_EmailMFATopic", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN]; messageToSend.Subject = _localizer[mfaType == UserMFAType.Login? "Mail_EmailMFALoginTopic":"Mail_EmailMFAUnlockTopic", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN];
var builder = new BodyBuilder(); var builder = new BodyBuilder();
@@ -123,7 +123,7 @@ namespace IRaCIS.Application.Services
builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
userName, userName,
_localizer["Mail_MFAEmail"], _localizer[mfaType == UserMFAType.Login ? "Mail_EmailMFALoginEmail": "Mail_EmailMFAUnlockEmail"],
verificationCode verificationCode
); );
} }
@@ -252,7 +252,7 @@ namespace IRaCIS.Application.Services
builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
"", "Sir/Madam",
//---您正在进行邮箱重置密码操作 //---您正在进行邮箱重置密码操作
_localizer["Mail_ResettingPassword"], _localizer["Mail_ResettingPassword"],
verificationCode verificationCode
@@ -320,7 +320,7 @@ namespace IRaCIS.Application.Services
builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
"Sir or Madam", "Sir/Madam",
//---您正在参与展影医疗IRC项目 //---您正在参与展影医疗IRC项目
_localizer["Mail_IRCProject", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN], _localizer["Mail_IRCProject", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN],
verificationCode verificationCode
@@ -387,7 +387,7 @@ namespace IRaCIS.Application.Services
builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
"Sir or Madam", "Sir/Madam",
//---您正在参与展影医疗IRC项目中心调研工作 //---您正在参与展影医疗IRC项目中心调研工作
_localizer["Mail_CenterResearchReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN], _localizer["Mail_CenterResearchReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN],
verificationCode verificationCode
@@ -46,12 +46,25 @@ namespace IRaCIS.Core.Application.Contracts.Dicom.DTO
//存放在instance 上面 //存放在instance 上面
public string WindowCenter { get; set; } = string.Empty; public string? WindowCenter => InstanceInfoList.FirstOrDefault()?.WindowCenter;
public string WindowWidth { get; set; } = string.Empty; public string? WindowWidth => InstanceInfoList.FirstOrDefault()?.WindowWidth;
public string ImageResizePath { get; set; } public string ImageResizePath { get; set; }
} }
public class StudyInstanceInfo
{
public int ShowOrder { get; set; }
public decimal RowIndex { get; set; }
public Guid? SeriesId { get; set; }
public Guid? StudyId { get; set; }
public Guid? InstanceId { get; set; }
}
public class InstanceBasicInfo public class InstanceBasicInfo
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
@@ -68,6 +81,10 @@ namespace IRaCIS.Core.Application.Contracts.Dicom.DTO
public int ShowOrder { get; set; } public int ShowOrder { get; set; }
[JsonIgnore] [JsonIgnore]
public decimal RowIndex { get; set; } public decimal RowIndex { get; set; }
[JsonIgnore]
public string WindowCenter { get; set; }
[JsonIgnore]
public string WindowWidth { get; set; }
} }
public class DicomSeriesWithLabelDTO : DicomSeriesDTO public class DicomSeriesWithLabelDTO : DicomSeriesDTO
@@ -6,10 +6,12 @@ using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO; using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit; using MassTransit;
using MathNet.Numerics; using MathNet.Numerics;
using Medallion.Threading; using Medallion.Threading;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
@@ -17,12 +19,13 @@ using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web;
namespace IRaCIS.Core.Application.Service.ImageAndDoc namespace IRaCIS.Core.Application.Service.ImageAndDoc
{ {
public interface IDownloadAndUploadService public interface IDownloadAndUploadService
{ {
Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isAnonymize = true); Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isDicom, bool isAnonymize = true);
} }
[ApiExplorerSettings(GroupName = "Trial")] [ApiExplorerSettings(GroupName = "Trial")]
public class DownloadAndUploadService : BaseService, IDownloadAndUploadService public class DownloadAndUploadService : BaseService, IDownloadAndUploadService
@@ -69,12 +72,18 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
if (needDealTaskList.Count > 0) if (needDealTaskList.Count > 0)
{ {
//已完成的访视任务数量(包含重阅的) //已完成的访视任务数量(包含重阅的)
var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
&& t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit); && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit);
//随机赋值编号 比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个 //已经处理过的任务名称的数量
List<int> availableNumbers = Enumerable.Range(haveFinishedTaskCount + 1, needDealTaskList.Count).ToList(); var haveDealedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
&& t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint");
//随机赋值编号 比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个
List<int> availableNumbers = Enumerable.Range(haveDealedTaskCount + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList();
Random rng = new Random(); Random rng = new Random();
foreach (var visitTask in needDealTaskList) foreach (var visitTask in needDealTaskList)
{ {
@@ -100,15 +109,14 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{ {
await SubejctRandomReadingTaskNameDeal(subjectId, trialReadingCriterionId); await SubejctRandomReadingTaskNameDeal(subjectId, trialReadingCriterionId);
var query = _repository.Where<VisitTask>(t => t.SubjectId == subjectId &&t.TrialReadingCriterionId== trialReadingCriterionId && t.SourceSubjectVisitId != null && t.DoctorUserId == _userInfo.Id) var query = _repository.Where<VisitTask>(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.SourceSubjectVisitId != null
&& t.DoctorUserId == _userInfo.Id && t.TaskState == TaskState.Effect)
.Select(u => new SubjectImageUploadDTO() .Select(u => new SubjectImageUploadDTO()
{ {
VisitTaskId = u.Id, VisitTaskId = u.Id,
SubejctId = u.SubjectId, SubejctId = u.SubjectId,
TrialSiteId = u.Subject.TrialSiteId, TrialSiteId = u.Subject.TrialSiteId,
IsImageFilter = u.TrialReadingCriterion.IsImageFilter, IsImageFilter = u.TrialReadingCriterion.IsImageFilter,
@@ -122,7 +130,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
SourceSubjectVisitId = u.SourceSubjectVisitId, SourceSubjectVisitId = u.SourceSubjectVisitId,
PackState = u.SourceSubjectVisit.PackState, PackState = u.SourceSubjectVisit.PackState,
OrginalStudyList = u.SourceSubjectVisit.StudyList.Select(t => new StudyBasicInfo() OrginalStudyList = u.SourceSubjectVisit.StudyList
.Where(t => u.TrialReadingCriterion.IsImageFilter ? ("|" + u.TrialReadingCriterion.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
.Select(t => new StudyBasicInfo()
{ {
Id = t.Id, Id = t.Id,
StudyInstanceUid = t.StudyInstanceUid, StudyInstanceUid = t.StudyInstanceUid,
@@ -476,24 +486,51 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
/// </summary> /// </summary>
/// <param name="trialId"></param> /// <param name="trialId"></param>
/// <param name="subjectVisitId"></param> /// <param name="subjectVisitId"></param>
/// <param name="isDicom"></param>
/// <param name="isAnonymize"></param> /// <param name="isAnonymize"></param>
/// <returns></returns> /// <returns></returns>
public async Task<IResponseOutput> RequestPackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isAnonymize = true) public async Task<IResponseOutput> RequestPackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isDicom, bool isAnonymize = true)
{ {
var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId);
if (subjectVisit.PackState == PackState.WaitPack)
var extralConfig = _repository.Where<Trial>(t => t.Id == trialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty;
var config = JsonConvert.DeserializeObject<TrialExtraConfig>(extralConfig) ?? new TrialExtraConfig();
if (config.IsSupportQCDownloadImage == false)
{ {
HangfireJobHelper.NotImmediatelyOnceOnlyJob<IDownloadAndUploadService>(t => t.PackageAndAnonymizImage(trialId, subjectVisitId, isAnonymize), TimeSpan.FromSeconds(1)); throw new BusinessValidationFailedException("该项目不支持QC下载影像");
subjectVisit.PackState = PackState.Packing;
await _subjectVisitRepository.SaveChangesAsync();
} }
return ResponseOutput.Ok(subjectVisit.VisitImageZipPath); var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId);
var sujectCode = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => t.Subject.Code).FirstOrDefaultAsync();
var packState = isDicom ? subjectVisit.PackState : subjectVisit.NoDicomPackState;
if (packState == PackState.WaitPack)
{
if (isDicom)
{
subjectVisit.PackState = PackState.Packing;
HangfireJobHelper.NotImmediatelyOnceOnlyJob<IDownloadAndUploadService>(t => t.PackageAndAnonymizImage(trialId, subjectVisitId, true, isAnonymize), TimeSpan.FromSeconds(1));
}
else
{
subjectVisit.NoDicomPackState = PackState.Packing;
HangfireJobHelper.NotImmediatelyOnceOnlyJob<IDownloadAndUploadService>(t => t.PackageAndAnonymizImage(trialId, subjectVisitId, false, isAnonymize), TimeSpan.FromSeconds(1));
}
await _subjectVisitRepository.SaveChangesAsync();
}
return ResponseOutput.Ok(isDicom ? subjectVisit.VisitImageZipPath : subjectVisit.VisitNoDicomImageZipPath,
new { FileName = $"{sujectCode}_{subjectVisit.VisitName}_ImageStudy_{(isDicom ? "Dicom" : "NoneDicom")}.zip" });
} }
@@ -503,9 +540,10 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
/// </summary> /// </summary>
/// <param name="trialId"></param> /// <param name="trialId"></param>
/// <param name="subjectVisitId"></param> /// <param name="subjectVisitId"></param>
/// <param name="isDicom"></param>
/// <param name="isAnonymize"></param> /// <param name="isAnonymize"></param>
/// <returns></returns> /// <returns></returns>
public async Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isAnonymize = true) public async Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isDicom, bool isAnonymize = true)
{ {
var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId); var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId);
@@ -549,6 +587,20 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}) })
}) })
}),
NoneDicomStudyList = sv.NoneDicomStudyList.Select(nd => new
{
nd.Modality,
nd.StudyCode,
nd.ImageDate,
FileList = nd.NoneDicomFileList.Select(file => new
{
file.FileName,
file.Path,
file.FileType
})
}) })
}; };
@@ -560,22 +612,26 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
string tempFolderPath = Path.Combine(Directory.GetCurrentDirectory(), $"DownloadTemp_{NewId.NextGuid()}"); string tempFolderPath = Path.Combine(Directory.GetCurrentDirectory(), $"DownloadTemp_{NewId.NextGuid()}");
Directory.CreateDirectory(tempFolderPath); Directory.CreateDirectory(tempFolderPath);
//dicom 处理
if (isDicom)
{
// 遍历查询结果 // 遍历查询结果
foreach (var studyInfo in info.StudyList) foreach (var studyInfo in info.StudyList)
{ {
// 遍历 Series // 遍历 Series
foreach (var seriesInfo in studyInfo.SeriesList) foreach (var seriesInfo in studyInfo.SeriesList)
{ {
string studyFolderPath = Path.Combine(tempFolderPath, $"{info.SubjectCode}_{info.VisitName}", $"{studyInfo.StudyCode}_{studyInfo.StudyTime?.ToString("yyyy-MM-dd")}_{seriesInfo.Modality}"); string studyDicomFolderPath = Path.Combine(tempFolderPath, "Dicom",/* $"{info.SubjectCode}_{info.VisitName}",*/ $"{studyInfo.StudyCode}_{studyInfo.StudyTime?.ToString("yyyy-MM-dd")}_{seriesInfo.Modality}");
// 创建 影像 文件夹 // 创建 影像 文件夹
Directory.CreateDirectory(studyFolderPath); Directory.CreateDirectory(studyDicomFolderPath);
// 遍历 InstancePathList // 遍历 InstancePathList
foreach (var instanceInfo in seriesInfo.InstancePathList) foreach (var instanceInfo in seriesInfo.InstancePathList)
{ {
// 复制文件到相应的文件夹 // 复制文件到相应的文件夹
string destinationPath = Path.Combine(studyFolderPath, Path.GetFileName(instanceInfo.Path)); string destinationPath = Path.Combine(studyDicomFolderPath, Path.GetFileName(instanceInfo.Path));
//下载到当前目录 //下载到当前目录
await _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath); await _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath);
@@ -644,23 +700,58 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
} }
} }
var zipPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy.zip");
ZipFile.CreateFromDirectory(tempFolderPath, zipPath);
var zipDicomPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy_Dicom.zip");
ZipFile.CreateFromDirectory(Path.Combine(tempFolderPath, "Dicom"), zipDicomPath);
//上传到Oss //上传到Oss
var relativePath = await _oSSService.UploadToOSSAsync(zipPath, $"download_zip", false); var relativeDicomPath = await _oSSService.UploadToOSSAsync(zipDicomPath, $"download_zip", false);
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitImageZipPath = relativeDicomPath });
//subjectVisit.PackState = PackState.Packed; File.Delete(zipDicomPath);
//subjectVisit.VisitImageZipPath = relativePath; }
//await _subjectVisitRepository.SaveChangesAsync(); else
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitImageZipPath = relativePath }); {
var relativeNoneDicomPath = string.Empty;
if (info.NoneDicomStudyList.Count() == 1 && info.NoneDicomStudyList.SelectMany(t => t.FileList).Count() == 1)
{
relativeNoneDicomPath = info.NoneDicomStudyList.First().FileList.First().Path;
}
else
{
//非dicom 处理
foreach (var noneDicomStudy in info.NoneDicomStudyList)
{
string studyNoneDicomFolderPath = Path.Combine(tempFolderPath, "NoneDicom", /*$"{info.SubjectCode}_{info.VisitName}",*/ $"{noneDicomStudy.StudyCode}_{noneDicomStudy.ImageDate.ToString("yyyy-MM-dd")}_{noneDicomStudy.Modality}");
Directory.CreateDirectory(studyNoneDicomFolderPath);
foreach (var file in noneDicomStudy.FileList)
{
string destinationPath = Path.Combine(studyNoneDicomFolderPath, Path.GetFileName(file.FileName));
//下载到当前目录
await _oSSService.DownLoadFromOSSAsync(HttpUtility.UrlDecode(file.Path) , destinationPath);
}
}
var zipNoneDicomPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy_NoneDicom.zip");
ZipFile.CreateFromDirectory(Path.Combine(tempFolderPath, "NoneDicom"), zipNoneDicomPath);
relativeNoneDicomPath = await _oSSService.UploadToOSSAsync(zipNoneDicomPath, $"download_zip", false);
File.Delete(zipNoneDicomPath);
}
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitNoDicomImageZipPath = relativeNoneDicomPath });
}
//清理文件夹 //清理文件夹
Directory.Delete(tempFolderPath, true); Directory.Delete(tempFolderPath, true);
File.Delete(zipPath);
} }
} }
@@ -12,7 +12,7 @@ namespace IRaCIS.Application.Services
Task<IResponseOutput<LoginReturnDTO>> Login(string userName, string password); Task<IResponseOutput<LoginReturnDTO>> Login(string userName, string password);
Task<IResponseOutput> VerifyMFACodeAsync(Guid userId, string Code); Task<IResponseOutput> VerifyMFACodeAsync(Guid userId, string Code);
Task<IResponseOutput> SendMFAEmail(Guid userId); Task<IResponseOutput> SendMFAEmail(Guid userId, int mfaType=0);
Task<UserBasicInfo> GetUserBasicInfo(Guid userId,string pwd); Task<UserBasicInfo> GetUserBasicInfo(Guid userId,string pwd);
Task<IResponseOutput> ModifyPassword(EditPasswordCommand editPwModel); Task<IResponseOutput> ModifyPassword(EditPasswordCommand editPwModel);
Task<IResponseOutput> ResetPassword(Guid userId); Task<IResponseOutput> ResetPassword(Guid userId);
@@ -18,6 +18,7 @@ using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO;
using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Application.Auth;
using BeetleX.Redis.Commands; using BeetleX.Redis.Commands;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Application.Helper;
namespace IRaCIS.Application.Services namespace IRaCIS.Application.Services
{ {
@@ -36,7 +37,7 @@ namespace IRaCIS.Application.Services
private readonly IEasyCachingProvider _cache; private readonly IEasyCachingProvider _cache;
private readonly IReadingImageTaskService _readingImageTaskService; private readonly IReadingImageTaskService _readingImageTaskService;
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig; private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
private readonly SystemEmailSendConfig _systemEmailConfig;
public UserService(IRepository<User> userRepository, public UserService(IRepository<User> userRepository,
@@ -47,6 +48,7 @@ namespace IRaCIS.Application.Services
IReadingImageTaskService readingImageTaskService, IReadingImageTaskService readingImageTaskService,
IRepository<TrialUser> userTrialRepository, IRepository<TrialUser> userTrialRepository,
IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig, IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig,
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig,
IRepository<UserLog> userLogRepository, IRepository<UserLog> userLogRepository,
IRepository<UserPassWordLog> userPassWordLogRepository IRepository<UserPassWordLog> userPassWordLogRepository
, ,
@@ -64,6 +66,8 @@ namespace IRaCIS.Application.Services
_userTrialRepository = userTrialRepository; _userTrialRepository = userTrialRepository;
_userLogRepository = userLogRepository; _userLogRepository = userLogRepository;
_distributedLockProvider = distributedLockProvider; _distributedLockProvider = distributedLockProvider;
_systemEmailConfig = systemEmailConfig.CurrentValue;
} }
@@ -589,7 +593,7 @@ namespace IRaCIS.Application.Services
if (user.IsZhiZhun) if (user.IsZhiZhun)
{ {
user.OrganizationName = AppSettings.DefaultInternalOrganizationName; user.OrganizationName = _userInfo.IsEn_Us? _systemEmailConfig.OrganizationName: _systemEmailConfig.OrganizationNameCN ;
} }
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = model.Id, OptType = UserOptType.UpdateUser }, true); await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = model.Id, OptType = UserOptType.UpdateUser }, true);
@@ -653,17 +657,19 @@ namespace IRaCIS.Application.Services
/// 发送MFA 验证邮件 /// 发送MFA 验证邮件
/// </summary> /// </summary>
/// <param name="userId"></param> /// <param name="userId"></param>
/// <param name="mfaType"></param>
/// <returns></returns> /// <returns></returns>
[AllowAnonymous] [AllowAnonymous]
public async Task<IResponseOutput> SendMFAEmail(Guid userId) public async Task<IResponseOutput> SendMFAEmail(Guid userId, int mfaType )
{ {
var userInfo = await _userRepository.Where(u => u.Id == userId).Select(t => new { t.FullName, t.EMail }).FirstOrDefaultAsync(); var userInfo = await _userRepository.Where(u => u.Id == userId).Select(t => new { t.FullName, t.EMail }).FirstOrDefaultAsync();
int verificationCode = new Random().Next(100000, 1000000); int verificationCode = new Random().Next(100000, 1000000);
await _mailVerificationService.SenMFAVerifyEmail(userId, userInfo.FullName, userInfo.EMail, verificationCode); await _mailVerificationService.SenMFAVerifyEmail(userId, userInfo.FullName, userInfo.EMail, verificationCode, (UserMFAType)mfaType );
return ResponseOutput.Ok(); var hiddenEmail = EmailMaskHelper.MaskEmail(userInfo.EMail);
return ResponseOutput.Ok(hiddenEmail);
} }
/// <summary> /// <summary>
@@ -811,7 +817,8 @@ namespace IRaCIS.Application.Services
await _userRepository.BatchUpdateNoTrackingAsync(x => x.Id == loginUser.Id, x => new User() await _userRepository.BatchUpdateNoTrackingAsync(x => x.Id == loginUser.Id, x => new User()
{ {
LastLoginIP = _userInfo.IP LastLoginIP = _userInfo.IP,
LastLoginTime= DateTime.Now
}); });
@@ -20,7 +20,9 @@ namespace IRaCIS.Core.Application.Contracts
public string FullFilePath => Path; public string FullFilePath => Path;
public string PreviewPath => "/Common/LocalFilePreview?relativePath=" + Path; public string FileType { get; set; }
//public string PreviewPath => "/Common/LocalFilePreview?relativePath=" + Path;
} }
@@ -17,7 +17,7 @@ namespace IRaCIS.Core.Application.Contracts
public List<NoneDicomStudyFileView> NoneDicomStudyFileList { get; set; } = new List<NoneDicomStudyFileView>(); public List<NoneDicomStudyFileView> NoneDicomStudyFileList { get; set; } = new List<NoneDicomStudyFileView>();
public List<string> NoneDicomStudyFilePreviewList => NoneDicomStudyFileList.Select(t=> t.PreviewPath).ToList(); //public List<string> NoneDicomStudyFilePreviewList => NoneDicomStudyFileList.Select(t=> t.PreviewPath).ToList();
} }
@@ -62,6 +62,10 @@ namespace IRaCIS.Core.Application.Contracts
//public string VisitPlanInfo { get; set; } = String.Empty; //public string VisitPlanInfo { get; set; } = String.Empty;
public Guid? HandleUserId { get; set; } public Guid? HandleUserId { get; set; }
public DateTime? BeginAuditTime { get; set; }
public DateTime? EndAuditTime { get; set; }
} }
public class GetNextIQCQualityInDto public class GetNextIQCQualityInDto
@@ -187,6 +191,13 @@ namespace IRaCIS.Core.Application.Contracts
public string SubmitUserName { get; set; } public string SubmitUserName { get; set; }
public TrialQCProcess QCProcessEnum { get; set; }
public DateTime? ReviewAuditTime { get; set; }
public DateTime? PreliminaryAuditTime { get; set; }
public DateTime? AuditTime => QCProcessEnum == TrialQCProcess.SingleAudit ? PreliminaryAuditTime : (QCProcessEnum == TrialQCProcess.DoubleAudit ? ReviewAuditTime : null);
} }
@@ -1105,6 +1116,9 @@ namespace IRaCIS.Core.Application.Contracts
public bool IsHaveUploadFailed { get; set; } public bool IsHaveUploadFailed { get; set; }
} }
@@ -1399,8 +1413,7 @@ namespace IRaCIS.Core.Application.Contracts
public string ReviewAuditUserName { get; set; } = String.Empty; public string ReviewAuditUserName { get; set; } = String.Empty;
public DateTime? ReviewAuditTime { get; set; }
public DateTime? PreliminaryAuditTime { get; set; }
public bool IsEnrollmentConfirm { get; set; } = false; public bool IsEnrollmentConfirm { get; set; } = false;
public DateTime? SubjectFirstGiveMedicineTime { get; set; } public DateTime? SubjectFirstGiveMedicineTime { get; set; }
@@ -1475,6 +1488,12 @@ namespace IRaCIS.Core.Application.Contracts
public PackState PackState { get; set; } public PackState PackState { get; set; }
//public Guid? ClinicalDataSignUserId { get; set; } //public Guid? ClinicalDataSignUserId { get; set; }
public DateTime? ReviewAuditTime { get; set; }
public DateTime? PreliminaryAuditTime { get; set; }
public DateTime? AuditTime => QCProcessEnum == TrialQCProcess.SingleAudit ? PreliminaryAuditTime : (QCProcessEnum == TrialQCProcess.DoubleAudit ? ReviewAuditTime : null);
} }
@@ -16,7 +16,7 @@ namespace IRaCIS.Core.Application.Contracts
Task<IResponseOutput> DeleteNoneDicomStudy(Guid noneDicomStudyId, Guid subjectVisitId); Task<IResponseOutput> DeleteNoneDicomStudy(Guid noneDicomStudyId, Guid subjectVisitId);
Task<IResponseOutput> DeleteNoneDicomStudyFile(Guid noneDicomStudyFileId, Guid subjectVisitId); Task<IResponseOutput> DeleteNoneDicomStudyFile(Guid noneDicomStudyFileId, Guid subjectVisitId);
Task<List<NoneDicomStudyFileView>> GetNoneDicomStudyFileList(Guid noneDicomStudyId); Task<List<NoneDicomStudyFileView>> GetNoneDicomStudyFileList(Guid noneDicomStudyId);
Task<List<NoneDicomStudyView>> GetNoneDicomStudyList(Guid subjectVisitId, Guid? sujectVisitId = null); Task<List<NoneDicomStudyView>> GetNoneDicomStudyList(Guid subjectVisitId, Guid? sujectVisitId = null, bool isFilterZip=false);
Task<List<NoneDicomStudyFileView>> GetVisitNoneDicomStudyFileList(Guid subjectVisitId); Task<List<NoneDicomStudyFileView>> GetVisitNoneDicomStudyFileList(Guid subjectVisitId);
//Task<IResponseOutput> UploadNoneDicomFile(IFormCollection formCollection, Guid subjectVisitId, Guid noneDicomStudyId); //Task<IResponseOutput> UploadNoneDicomFile(IFormCollection formCollection, Guid subjectVisitId, Guid noneDicomStudyId);
@@ -37,12 +37,12 @@ namespace IRaCIS.Core.Application.Contracts
[HttpGet] [HttpGet]
public async Task<List<NoneDicomStudyView>> GetNoneDicomStudyList([FromQuery, NotDefault] Guid subjectVisitId, Guid? nonedicomStudyId) public async Task<List<NoneDicomStudyView>> GetNoneDicomStudyList([FromQuery, NotDefault] Guid subjectVisitId, [FromQuery] Guid? nonedicomStudyId, [FromQuery] bool isFilterZip)
{ {
var noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId).WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) var noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId).WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId)
.ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken }); .ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip });
return await noneDicomStudyQueryable.ToListAsync(); return await noneDicomStudyQueryable.ToListAsync();
} }
@@ -179,7 +179,7 @@ namespace IRaCIS.Core.Application.Image.QA
PageSize = 1, PageSize = 1,
}); });
return result.Item1.CurrentPageData.Count > 0 ? result.Item1.CurrentPageData[0] : null; return result.Data.CurrentPageData.Count > 0 ? result.Data.CurrentPageData[0] : null;
} }
/// <summary> /// <summary>
@@ -188,7 +188,7 @@ namespace IRaCIS.Core.Application.Image.QA
/// <param name="visitSearchDTO"></param> /// <param name="visitSearchDTO"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<(PageOutput<QCVisitViewModel>, TrialSubjectAndSVConfig)> GetQCVisitList(QCVisitSearchDTO visitSearchDTO) public async Task<IResponseOutput<PageOutput<QCVisitViewModel>>> GetQCVisitList(QCVisitSearchDTO visitSearchDTO)
{ {
var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray); var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray);
@@ -210,6 +210,12 @@ namespace IRaCIS.Core.Application.Image.QA
|| t.QCChallengeDialogList.Any(t => t.CreateUserId == visitSearchDTO.HandleUserId)) || t.QCChallengeDialogList.Any(t => t.CreateUserId == visitSearchDTO.HandleUserId))
.WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent) .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent)
.Where(t => t.SubmitState != SubmitStateEnum.None) .Where(t => t.SubmitState != SubmitStateEnum.None)
.WhereIf(visitSearchDTO.BeginAuditTime != null, t => t.Trial.QCProcessEnum==TrialQCProcess.SingleAudit? t.PreliminaryAuditTime>= visitSearchDTO.BeginAuditTime:
(t.Trial.QCProcessEnum == TrialQCProcess.DoubleAudit?t.ReviewAuditTime>= visitSearchDTO.BeginAuditTime:true))
.WhereIf(visitSearchDTO.EndAuditTime != null, t => t.Trial.QCProcessEnum == TrialQCProcess.SingleAudit ? t.PreliminaryAuditTime <= visitSearchDTO.EndAuditTime :
(t.Trial.QCProcessEnum == TrialQCProcess.DoubleAudit ? t.ReviewAuditTime <= visitSearchDTO.EndAuditTime : true))
//.WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState) //.WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState)
//.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) //.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState)
.ProjectTo<QCVisitViewModel>(_mapper.ConfigurationProvider); .ProjectTo<QCVisitViewModel>(_mapper.ConfigurationProvider);
@@ -223,7 +229,7 @@ namespace IRaCIS.Core.Application.Image.QA
var config = await _repository.Where<Trial>(t => t.Id == visitSearchDTO.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); var config = await _repository.Where<Trial>(t => t.Id == visitSearchDTO.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
return (pageList, config); return ResponseOutput.Ok (pageList, config);
} }
@@ -706,7 +706,7 @@ namespace IRaCIS.Core.Application.Image.QA
} }
else else
{ {
if (await _subjectVisitRepository.AnyAsync(t => t.Id == updateModalityCommand.SubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted)) if (await _subjectVisitRepository.AnyAsync(t => t.Id == updateModalityCommand.SubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted && !t.QCChallengeList.Any(c=>c.ReuploadEnum==QCChanllengeReuploadEnum.QCAgreeUpload)) )
{ {
//---提交之后,不允许修改! //---提交之后,不允许修改!
throw new BusinessValidationFailedException(_localizer["QCOperation_NoModifyAfterSubmit"]); throw new BusinessValidationFailedException(_localizer["QCOperation_NoModifyAfterSubmit"]);
@@ -942,7 +942,8 @@ namespace IRaCIS.Core.Application.Image.QA
.OrderBy(x => x.VisitNum).FirstOrDefault(); .OrderBy(x => x.VisitNum).FirstOrDefault();
if (subjectVisit != null) if (subjectVisit != null)
{ {
return new GetNextIQCQualityOutDto() { return new GetNextIQCQualityOutDto()
{
SubjectId = subjectVisit.SubjectId, SubjectId = subjectVisit.SubjectId,
VisitId = subjectVisit.Id VisitId = subjectVisit.Id
}; };
@@ -1315,38 +1316,13 @@ namespace IRaCIS.Core.Application.Image.QA
return ResponseOutput.NotOk(_localizer["QCOperation_MissingBaselineDate"]); return ResponseOutput.NotOk(_localizer["QCOperation_MissingBaselineDate"]);
} }
//基线 且配置了临床数据 if (_subjectVisitRepository.Where(t => t.Id == dbSubjectVisit.Id).Any(t => (t.StudyList.Count(t => t.ModalityForEdit == "") > 0 ||t.NoneDicomStudyList.Count(t => t.Modality == "")>0) && t.Trial.TrialReadingCriterionList.Count(t => t.IsImageFilter == true) > 0))
//if (trialConfig.ClinicalInformationTransmissionEnum != 0 /*&& dbSubjectVisit.IsBaseLine*//*&&dbSubjectVisit.ClinicalDataSignUserId==null*/) {
//{ //有标准配置了影像筛选,该受试者有检查未设置检查类型,不允许提交
return ResponseOutput.NotOk(_localizer["QCOperation_MissingModality"]);
}
////找到需要确认的PDF 临床数据 如果没有CRC 没有上传 那么就添加一条没有文件的记录
//var crcNeedConfirmClinicalDataSetList = clinicalDataConfirmList.Where(t => t.UploadRole == UploadRole.CRC && t.ClinicalUploadType == ClinicalUploadType.PDF).ToList();
//// 找到CRC 已经自己添加的临床PDF数据文件
//var crcAddClinicalDataIdList = _readingClinicalDataRepository.Where(t => t.ReadingId == dbSubjectVisit.Id && t.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF)
// .Select(t => new { t.ClinicalDataTrialSetId }).ToList();
//foreach (var crcNeedConfirmClinicalDataSet in crcNeedConfirmClinicalDataSetList)
//{
// if (!crcAddClinicalDataIdList.Any(t => t.ClinicalDataTrialSetId == crcNeedConfirmClinicalDataSet.Id))
// {
// await _repository.AddAsync(new ReadingClinicalData()
// {
// TrialId = dbSubjectVisit.TrialId,
// SubjectId = dbSubjectVisit.SubjectId,
// ReadingId = dbSubjectVisit.Id,
// ClinicalDataTrialSetId = crcNeedConfirmClinicalDataSet.Id,
// IsVisit = true,
// IsSign = true,
// ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned
// });
// }
//}
//已确认临床数据完整性 //已确认临床数据完整性
dbSubjectVisit.IsConfirmedClinicalData = true; dbSubjectVisit.IsConfirmedClinicalData = true;
@@ -1368,27 +1344,6 @@ namespace IRaCIS.Core.Application.Image.QA
}); });
//var signSuccess = await _repository.UpdateFromQueryAsync<TrialSign>(t => t.Id == cRCRequestToQCCommand.SignId, u => new TrialSign() { IsCompleted = true });
////现在修改为 提交时 设置签名信息
//dbSubjectVisit.ClinicalDataSignUserId = _userInfo.Id;
//dbSubjectVisit.ClinicalDataSignTime = DateTime.Now;
//那么没有录入 不允许提交
//if (!await _repository.AnyAsync<SubjectVisit>(t => t.PreviousHistoryList.Any() || t.PreviousOtherList.Any() || t.PreviousSurgeryList.Any()))
//{
// return ResponseOutput.NotOk("没有临床数据,不允许提交");
//}
//return ResponseOutput.NotOk("没有签名临床数据,不允许提交");
//}
var maxVisit = await _subjectVisitRepository.Where(t => t.SubjectId == dbSubjectVisit.SubjectId && t.SubmitState == SubmitStateEnum.Submitted) var maxVisit = await _subjectVisitRepository.Where(t => t.SubjectId == dbSubjectVisit.SubjectId && t.SubmitState == SubmitStateEnum.Submitted)
.OrderByDescending(t => t.VisitNum).Select(t => new { t.Id, t.VisitNum }).FirstOrDefaultAsync(); .OrderByDescending(t => t.VisitNum).Select(t => new { t.Id, t.VisitNum }).FirstOrDefaultAsync();
@@ -1464,14 +1419,7 @@ namespace IRaCIS.Core.Application.Image.QA
dbSubjectVisit.IsUrgent = true; dbSubjectVisit.IsUrgent = true;
////PD确认的紧急会把前面所有未QC完成的访视均标记为紧急
//var previosSVlist = await _subjectVisitRepository.Where(t => t.SubjectId == dbSubjectVisit.SubjectId && t.VisitNum < dbSubjectVisit.VisitNum && t.IsUrgent == false && t.SubmitState == SubmitStateEnum.Submitted, true).ToListAsync();
//previosSVlist.ForEach(t =>
//{
// t.IsUrgent = true;
//});
} }
@@ -22,6 +22,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<Trial, ExcelExportInfo>(); CreateMap<Trial, ExcelExportInfo>();
CreateMap<SubjectVisit, CRCVisitExportDTO>() CreateMap<SubjectVisit, CRCVisitExportDTO>()
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode)) .ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode))
.ForMember(d => d.QCProcessEnum, u => u.MapFrom(s => s.Trial.QCProcessEnum))
.ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.Subject.Code)) .ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.Subject.Code))
.ForMember(d => d.SubmitUserName, u => u.MapFrom(s => s.SubmitUser.FullName)) .ForMember(d => d.SubmitUserName, u => u.MapFrom(s => s.SubmitUser.FullName))
@@ -254,6 +255,7 @@ namespace IRaCIS.Core.Application.Service
bool isFilterZip = false;
string token = string.Empty; string token = string.Empty;
//一致性核查 //一致性核查
@@ -560,7 +562,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<NoneDicomStudy, NoneDicomStudyView>() CreateMap<NoneDicomStudy, NoneDicomStudyView>()
//.ForMember(d => d.FileCount, u => u.MapFrom(s => s.NoneDicomFileList.Count)) //.ForMember(d => d.FileCount, u => u.MapFrom(s => s.NoneDicomFileList.Count))
.ForMember(d => d.NoneDicomStudyFileList, u => u.MapFrom(s => s.NoneDicomFileList)) .ForMember(d => d.NoneDicomStudyFileList, u => u.MapFrom(s => isFilterZip? s.NoneDicomFileList.Where(t=>!t.FileType.Contains(StaticData.FileType.Zip)): s.NoneDicomFileList))
.ForMember(d => d.CodeView, u => u.MapFrom(s => s.StudyCode)); .ForMember(d => d.CodeView, u => u.MapFrom(s => s.StudyCode));
@@ -299,6 +299,13 @@ namespace IRaCIS.Application.Services
}; };
} }
if (inDto.FilterNoneForm)
{
cRCClinicalDataList = cRCClinicalDataList.Where(x => !(x.ClinicalFromList.Count() == 0 && x.ClinicalUploadType == ClinicalUploadType.Structuring)).ToList();
}
return cRCClinicalDataList; return cRCClinicalDataList;
} }
@@ -158,6 +158,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public Guid? StudyId { get; set; } public Guid? StudyId { get; set; }
public bool FilterNoneForm { get; set; } = false;
} }
@@ -1696,6 +1696,20 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
} }
public class ResetReadingTaskOutDto
{
}
public class ResetReadingTaskInDto
{
public Guid VisitTaskId { get; set; }
}
public class SetSkipReadingCacheInDto
{
public Guid VisitTaskId { get; set; }
}
public class GetNextTaskInDto public class GetNextTaskInDto
{ {
@@ -37,7 +37,7 @@ namespace IRaCIS.Core.Application.Contracts
Task<List<GetManualListOutDto>> GetManualList(GetManualListInDto inDto); Task<List<GetManualListOutDto>> GetManualList(GetManualListInDto inDto);
Task ResetReadingRestTime(Guid? userId); Task<bool> ResetReadingRestTime(Guid? userId);
Task<List<GetReadingPastResultListOutDto>> GetReadingPastResultList(GetReadingPastResultListInDto inDto); Task<List<GetReadingPastResultListOutDto>> GetReadingPastResultList(GetReadingPastResultListInDto inDto);
@@ -7,6 +7,7 @@ using Panda.DynamicWebApi.Attributes;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using Newtonsoft.Json; using Newtonsoft.Json;
using IRaCIS.Core.Domain.Models;
namespace IRaCIS.Application.Services namespace IRaCIS.Application.Services
{ {
@@ -1093,7 +1094,7 @@ namespace IRaCIS.Application.Services
await _readingTableQuestionTrialRepository.BatchDeleteNoTrackingAsync(x => x.TrialCriterionId == trialCriterion.Id); await _readingTableQuestionTrialRepository.BatchDeleteNoTrackingAsync(x => x.TrialCriterionId == trialCriterion.Id);
await _readingTableQuestionTrialRepository.AddRangeAsync(needAddTableDatas); await _readingTableQuestionTrialRepository.AddRangeAsync(_mapper.Map<List<ReadingTableQuestionTrial>>(needAddTableDatas));
#endregion #endregion
} }
@@ -21,6 +21,9 @@ using IRaCIS.Core.Application.Service.ReadingCalculate.Interface;
using AutoMapper.QueryableExtensions; using AutoMapper.QueryableExtensions;
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using Microsoft.Extensions.Options;
using System.Linq;
using NPOI.SS.Formula.Functions;
namespace IRaCIS.Application.Services namespace IRaCIS.Application.Services
{ {
@@ -42,6 +45,7 @@ namespace IRaCIS.Application.Services
private readonly IReadingCalculateService _readingCalculateService; private readonly IReadingCalculateService _readingCalculateService;
private readonly IRepository<SubjectVisit> _subjectVisitRepository; private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IRepository<Subject> _subjectRepository; private readonly IRepository<Subject> _subjectRepository;
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
private readonly IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository; private readonly IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository;
private readonly IRepository<ReadingCriterionPage> _readingCriterionPageRepository; private readonly IRepository<ReadingCriterionPage> _readingCriterionPageRepository;
private readonly IRepository<ReadingTaskRelation> _readingTaskRelationRepository; private readonly IRepository<ReadingTaskRelation> _readingTaskRelationRepository;
@@ -84,6 +88,7 @@ namespace IRaCIS.Application.Services
IReadingCalculateService readingCalculateService, IReadingCalculateService readingCalculateService,
IRepository<SubjectVisit> subjectVisitRepository, IRepository<SubjectVisit> subjectVisitRepository,
IRepository<Subject> subjectRepository, IRepository<Subject> subjectRepository,
IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig,
IRepository<ReadingGlobalTaskInfo> readingGlobalTaskInfoRepository, IRepository<ReadingGlobalTaskInfo> readingGlobalTaskInfoRepository,
IRepository<ReadingCriterionPage> readingCriterionPageRepository, IRepository<ReadingCriterionPage> readingCriterionPageRepository,
IRepository<ReadingTaskRelation> readingTaskRelationRepository, IRepository<ReadingTaskRelation> readingTaskRelationRepository,
@@ -125,6 +130,7 @@ namespace IRaCIS.Application.Services
this._readingCalculateService = readingCalculateService; this._readingCalculateService = readingCalculateService;
this._subjectVisitRepository = subjectVisitRepository; this._subjectVisitRepository = subjectVisitRepository;
this._subjectRepository = subjectRepository; this._subjectRepository = subjectRepository;
this._verifyConfig = verifyConfig;
this._readingGlobalTaskInfoRepository = readingGlobalTaskInfoRepository; this._readingGlobalTaskInfoRepository = readingGlobalTaskInfoRepository;
this._readingCriterionPageRepository = readingCriterionPageRepository; this._readingCriterionPageRepository = readingCriterionPageRepository;
this._readingTaskRelationRepository = readingTaskRelationRepository; this._readingTaskRelationRepository = readingTaskRelationRepository;
@@ -990,7 +996,8 @@ namespace IRaCIS.Application.Services
var questionMark = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<GetTableAnswerRowInfoOutDto>(_mapper.ConfigurationProvider).ToListAsync(); var questionMark = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<GetTableAnswerRowInfoOutDto>(_mapper.ConfigurationProvider).ToListAsync();
questionMark.ForEach(x => { questionMark.ForEach(x =>
{
x.IsFirstChangeTask = x.VisitTaskId == inDto.VisitTaskId; x.IsFirstChangeTask = x.VisitTaskId == inDto.VisitTaskId;
}); });
@@ -1824,7 +1831,8 @@ namespace IRaCIS.Application.Services
if (tumorAnswer != null) if (tumorAnswer != null)
{ {
var isConvertedTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.IsConvertedTask).FirstOrDefaultAsync(); var isConvertedTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.IsConvertedTask).FirstOrDefaultAsync();
var reportVerify = await _readingCalculateService.GetReportVerify(new GetReportVerifyInDto() { var reportVerify = await _readingCalculateService.GetReportVerify(new GetReportVerifyInDto()
{
BeforeConvertedTaskId = taskInfo.BeforeConvertedTaskId, BeforeConvertedTaskId = taskInfo.BeforeConvertedTaskId,
IsConvertTask = isConvertedTask, IsConvertTask = isConvertedTask,
VisitTaskId = inDto.VisitTaskId VisitTaskId = inDto.VisitTaskId
@@ -1899,7 +1907,8 @@ namespace IRaCIS.Application.Services
var datetime = DateTime.Now; var datetime = DateTime.Now;
var markList = _mapper.Map<List<QuestionMarkInfo>, List<ReadingTaskQuestionMark>>(inDto.QuestionMarkInfoList); var markList = _mapper.Map<List<QuestionMarkInfo>, List<ReadingTaskQuestionMark>>(inDto.QuestionMarkInfoList);
markList.ForEach(x => { markList.ForEach(x =>
{
x.Id = NewId.NextGuid(); x.Id = NewId.NextGuid();
x.VisitTaskId = inDto.VisitTaskId; x.VisitTaskId = inDto.VisitTaskId;
x.CreateTime = datetime; x.CreateTime = datetime;
@@ -2693,7 +2702,43 @@ namespace IRaCIS.Application.Services
return ResponseOutput.Ok(true); return ResponseOutput.Ok(true);
} }
/// <summary>
/// 清除跳过阅片的缓存
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<bool> ClearSkipReadingCache()
{
var clearSkipReadingCacheKey = _userInfo.Id.ToString() + "SkipReadingCache";
_provider.Remove(clearSkipReadingCacheKey);
return true;
}
/// <summary>
/// 设置跳过阅片的缓存
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<bool> SetSkipReadingCache(SetSkipReadingCacheInDto inDto )
{
var clearSkipReadingCacheKey = _userInfo.Id.ToString() + "SkipReadingCache";
var clearSkipReadingCache = _provider.Get<string>(clearSkipReadingCacheKey).Value;
if (clearSkipReadingCache == null|| clearSkipReadingCache==string.Empty)
{
List<Guid> cacheIds = new List<Guid>();
cacheIds.Add(inDto.VisitTaskId);
_provider.Set(clearSkipReadingCacheKey, JsonConvert.SerializeObject(cacheIds), TimeSpan.FromHours(24));
}
else
{
List<Guid>? cacheIds=JsonConvert.DeserializeObject<List<Guid>>(clearSkipReadingCache);
cacheIds.Add(inDto.VisitTaskId);
_provider.Set(clearSkipReadingCacheKey, JsonConvert.SerializeObject(cacheIds), TimeSpan.FromHours(24));
}
return true;
}
/// <summary> /// <summary>
@@ -2721,6 +2766,19 @@ namespace IRaCIS.Application.Services
var trialReadingCriterion = await _readingQuestionCriterionTrialRepository.FindAsync(trialReadingCriterionId ?? Guid.Empty); var trialReadingCriterion = await _readingQuestionCriterionTrialRepository.FindAsync(trialReadingCriterionId ?? Guid.Empty);
#region
var clearSkipReadingCacheKey = _userInfo.Id.ToString() + "SkipReadingCache";
var clearSkipReadingCache = _provider.Get<string>(clearSkipReadingCacheKey).Value;
List<Guid> cacheSkipIds = new List<Guid>();
if (clearSkipReadingCache != null && clearSkipReadingCache != string.Empty)
{
cacheSkipIds = JsonConvert.DeserializeObject<List<Guid>>(clearSkipReadingCache);
}
#endregion
if (inDto.VisitTaskId != null) if (inDto.VisitTaskId != null)
{ {
task = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => new GetReadingTaskDto() task = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => new GetReadingTaskDto()
@@ -2739,18 +2797,17 @@ namespace IRaCIS.Application.Services
trialReadingCriterionId = task.TrialReadingCriterionId; trialReadingCriterionId = task.TrialReadingCriterionId;
} }
// 有序
else if (inDto.SubjectId != null && trialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.InOrder) else if (inDto.SubjectId != null && trialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
var subjectTaskList = (await _visitTaskService.GetOrderReadingIQueryable(new GetOrderReadingIQueryableInDto() var subjectTaskList = (await _visitTaskService.GetSubjectReadingIQueryable(new GetReadingIQueryableInDto()
{ {
TrialId = inDto.TrialId, TrialId = inDto.TrialId,
TrialReadingCriterionId = trialReadingCriterionId!.Value, TrialReadingCriterionId = trialReadingCriterionId!.Value,
Page = new PageInput()
{
PageIndex = 1, PageIndex = 1,
PageSize = 99999, PageSize = 99999,
}
})).Item2; })).CurrentPageData;
var index = 0; var index = 0;
subjectTaskList.ForEach(x => subjectTaskList.ForEach(x =>
@@ -2761,14 +2818,20 @@ namespace IRaCIS.Application.Services
var subjectIndex = subjectTaskList.Where(x => x.SubjectId == inDto.SubjectId && x.SubjectCode == inDto.SubjectCode).Select(x => x.Index).FirstOrDefault(); var subjectIndex = subjectTaskList.Where(x => x.SubjectId == inDto.SubjectId && x.SubjectCode == inDto.SubjectCode).Select(x => x.Index).FirstOrDefault();
var currentSubject = subjectTaskList.Where(x => x.Index >= subjectIndex && !x.ExistReadingApply).OrderBy(x => x.Index).FirstOrDefault();
var currentSubject = subjectTaskList.Where(x => x.Index >= subjectIndex && !x.ExistReadingApply)
// 排除跳过的
.Where(x=> x.UnReadCanReadTaskList.Select(y => y.Id).Intersect(cacheSkipIds).Count()==0)
.OrderBy(x => x.Index).FirstOrDefault();
if (currentSubject == null) if (currentSubject == null)
{ {
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows); throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
} }
task = currentSubject.UnReadCanReadTaskList.Select(x => new GetReadingTaskDto() task = currentSubject.UnReadCanReadTaskList
.Select(x => new GetReadingTaskDto()
{ {
ReadingCategory = x.ReadingCategory, ReadingCategory = x.ReadingCategory,
SubjectCode = currentSubject.SubjectCode, SubjectCode = currentSubject.SubjectCode,
@@ -2784,11 +2847,71 @@ namespace IRaCIS.Application.Services
} }
// 受试者无序
else if (inDto.SubjectId != null && trialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom)
{
var subjectTaskList = (await _visitTaskService.GetSubjectReadingIQueryable(new GetReadingIQueryableInDto()
{
TrialId = inDto.TrialId,
SubjectId = inDto.SubjectId,
TrialReadingCriterionId = trialReadingCriterionId!.Value,
PageIndex = 1,
PageSize = 99999,
})).CurrentPageData;
if (subjectTaskList.Count() == 0)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
}
var taskList = subjectTaskList.FirstOrDefault()!.UnReadCanReadTaskList;
// 排除跳过的
List<Guid> remainingItems = taskList.Select(x => x.Id).Except(cacheSkipIds).ToList();
taskList = taskList.Where(x => remainingItems.Contains(x.Id)).ToList();
if (taskList.Count() == 0)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
}
Random random = new Random();
//返回的范围是 0- taskList.Count-1
int randomIndex = random.Next(taskList.Count);
var visitTaskId = taskList[randomIndex].Id;
task = await _visitTaskRepository.Where(x=>x.Id== visitTaskId).Select(x => new GetReadingTaskDto()
{
VisitTaskId = x.Id,
ArmEnum = x.ArmEnum,
TaskBlindName = x.TaskBlindName,
ReadingCategory = x.ReadingCategory,
VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : x.ReadModule == null ? default(Guid) : x.ReadModule.SubjectVisitId,
VisitNum = x.VisitTaskNum,
SubjectId = x.SubjectId,
SubjectCode = x.Subject.Code,
TrialReadingCriterionId = x.TrialReadingCriterionId,
}).FirstOrDefaultAsync();
}
// 完全随机
else else
{ {
var query = _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterionId == trialReadingCriterionId && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.DoctorUserId == _userInfo.Id var query = _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterionId == trialReadingCriterionId && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.DoctorUserId == _userInfo.Id
&& x.TrialReadingCriterionId == trialReadingCriterionId && x.TrialReadingCriterionId == trialReadingCriterionId
&& x.TaskState == TaskState.Effect); && x.TaskState == TaskState.Effect)
// 排除跳过的
.Where(x => !cacheSkipIds.Contains(x.Id));
var count = await query.CountAsync(); var count = await query.CountAsync();
if (count == 0) if (count == 0)
{ {
@@ -2906,23 +3029,42 @@ namespace IRaCIS.Application.Services
return task; return task;
} }
/// <summary>
/// 重置阅片任务
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<ResetReadingTaskOutDto> ResetReadingTask(ResetReadingTaskInDto inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
if (taskinfo.ReadingCategory != ReadingCategory.Visit)
{
}
return new ResetReadingTaskOutDto() { };
}
/// <summary> /// <summary>
/// 验证阅片休息时间 /// 验证阅片休息时间
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task VerifyReadingRestTime() public async Task<bool> VerifyReadingRestTime()
{ {
var userTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt; var userTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt;
if (userTypeEnum != UserTypeEnum.IndependentReviewer) if (userTypeEnum != UserTypeEnum.IndependentReviewer)
{ {
return; return true;
} }
var startReadingTimeKey = _userInfo.Id.ToString() + "StartReadingTime"; var startReadingTimeKey = _userInfo.Id.ToString() + "StartReadingTime";
var startRestTimeKey = _userInfo.Id.ToString() + "StartRestTime"; var startRestTimeKey = _userInfo.Id.ToString() + "StartRestTime";
int readingMinute = 120; // 为60整数 int readingMinute = _verifyConfig.CurrentValue.ContinuousReadingTimeMin; // 为60整数
int restMinute = 10; // int restMinute = _verifyConfig.CurrentValue.ReadingRestTimeMin; //
var startReadingTime = _provider.Get<string>(startReadingTimeKey).Value; var startReadingTime = _provider.Get<string>(startReadingTimeKey).Value;
var startRestTime = _provider.Get<string>(startRestTimeKey).Value; var startRestTime = _provider.Get<string>(startRestTimeKey).Value;
if (startReadingTime == null && startRestTime == null) if (startReadingTime == null && startRestTime == null)
@@ -2935,7 +3077,7 @@ namespace IRaCIS.Application.Services
int timespanMin = (DateTime.Now - cacheStartRestTime).Minutes; int timespanMin = (DateTime.Now - cacheStartRestTime).Minutes;
if (timespanMin <= restMinute) if (timespanMin <= restMinute)
{ {
throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", readingMinute/60m, restMinute]); throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", 2, 10]);
} }
else else
{ {
@@ -2961,6 +3103,8 @@ namespace IRaCIS.Application.Services
#endregion #endregion
} }
return true;
} }
/// <summary> /// <summary>
@@ -2968,7 +3112,7 @@ namespace IRaCIS.Application.Services
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task ResetReadingRestTime(Guid? userID) public async Task<bool> ResetReadingRestTime(Guid? userID)
{ {
if (userID == null) if (userID == null)
{ {
@@ -2995,6 +3139,7 @@ namespace IRaCIS.Application.Services
{ {
_provider.Set(startReadingTimeKey, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48)); _provider.Set(startReadingTimeKey, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48));
} }
return true;
} }
/// <summary> /// <summary>
@@ -66,7 +66,7 @@ namespace IRaCIS.Application.Services
/// <param name="inDto"></param> /// <param name="inDto"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<(List<NoneDicomStudyView>, object)> GetReadingImageFile(GetReadingImgInDto inDto) public async Task<IResponseOutput<List<NoneDicomStudyView>> > GetReadingImageFile(GetReadingImgInDto inDto)
{ {
var task = await GetNextTask(new GetNextTaskInDto() var task = await GetNextTask(new GetNextTaskInDto()
{ {
@@ -84,8 +84,8 @@ namespace IRaCIS.Application.Services
// 阅片期取前面所有的图像 // 阅片期取前面所有的图像
visitIds.AddRange(await _subjectVisitRepository.Where(x => x.VisitNum <= task.VisitNum && x.SubjectId == task.SubjectId).Select(x => x.Id).ToListAsync()); visitIds.AddRange(await _subjectVisitRepository.Where(x => x.VisitNum <= task.VisitNum && x.SubjectId == task.SubjectId).Select(x => x.Id).ToListAsync());
} }
List<NoneDicomStudyView> result = await _noneDicomStudyRepository.Where(t => visitIds.Contains(t.SubjectVisitId)) List<NoneDicomStudyView> result = await _noneDicomStudyRepository.Where(t => visitIds.Contains(t.SubjectVisitId) && t.NoneDicomFileList.Any(t=>!t.FileType.Contains(StaticData.FileType.Zip)))
.ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken }).ToListAsync(); .ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = true }).ToListAsync();
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisistTaskId).FirstNotNullAsync(); var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisistTaskId).FirstNotNullAsync();
@@ -121,7 +121,7 @@ namespace IRaCIS.Application.Services
var taskInfo = await _visitTaskRepository.Where(x => x.Id == task.VisitTaskId).FirstNotNullAsync(); var taskInfo = await _visitTaskRepository.Where(x => x.Id == task.VisitTaskId).FirstNotNullAsync();
return (result, new return ResponseOutput.Ok (result, new
{ {
VisitTaskId = task.VisitTaskId, VisitTaskId = task.VisitTaskId,
SubjectId = task.SubjectId, SubjectId = task.SubjectId,
@@ -500,7 +500,7 @@ namespace IRaCIS.Application.Services
var existsBubjectVisitsQuery = _readModuleRepository.Where(y => y.ReadingSetType == inDto.ReadingSetType && y.TrialId == inDto.TrialId && y.TrialReadingCriterionId == inDto.TrialReadingCriterionId).Select(x => x.SubjectVisitId); var existsBubjectVisitsQuery = _readModuleRepository.Where(y => y.ReadingSetType == inDto.ReadingSetType && y.TrialId == inDto.TrialId && y.TrialReadingCriterionId == inDto.TrialReadingCriterionId).Select(x => x.SubjectVisitId);
visitQuery = visitQuery.Where(x => !existsBubjectVisitsQuery.Contains(x.Id)) visitQuery = visitQuery.Where(x => !existsBubjectVisitsQuery.Contains(x.Id))
.WhereIf(inDto.ExpirationDate != null, x => x.LatestScanDate <= inDto.ExpirationDate.Value) .WhereIf(inDto.ExpirationDate != null, x => x.LatestScanDate < inDto.ExpirationDate.Value.AddDays(1))
.WhereIf(inDto.ExpirationVisitNum != null, x => x.VisitNum == inDto.ExpirationVisitNum) .WhereIf(inDto.ExpirationVisitNum != null, x => x.VisitNum == inDto.ExpirationVisitNum)
.WhereIf(inDto.ReadingSetType == ReadingSetType.TumorReading, x => readModulequery.Where(y => y.SubjectVisitId == x.Id && y.ReadingSetType == ReadingSetType.ImageReading).Count() > 0); .WhereIf(inDto.ReadingSetType == ReadingSetType.TumorReading, x => readModulequery.Where(y => y.SubjectVisitId == x.Id && y.ReadingSetType == ReadingSetType.ImageReading).Count() > 0);
@@ -232,6 +232,9 @@ namespace IRaCIS.Core.Application.Service
CreateMap<ReadingTableQuestionTrial, ReadingTrialTableQuestionData>() CreateMap<ReadingTableQuestionTrial, ReadingTrialTableQuestionData>()
.ForMember(d => d.OriginalId, u => u.MapFrom(s => s.Id)); .ForMember(d => d.OriginalId, u => u.MapFrom(s => s.Id));
CreateMap<ReadingTrialTableQuestionData, ReadingTableQuestionTrial>();
CreateMap<ReadingQuestionCriterionSystem, ReadingQuestionCriterionTrial>() CreateMap<ReadingQuestionCriterionSystem, ReadingQuestionCriterionTrial>()
.ForMember(dest => dest.ReadingQuestionTrialList, opt => opt.Ignore()) .ForMember(dest => dest.ReadingQuestionTrialList, opt => opt.Ignore())
.ForMember(d => d.ReadingQuestionCriterionSystemId, u => u.MapFrom(s => s.Id)); ; .ForMember(d => d.ReadingQuestionCriterionSystemId, u => u.MapFrom(s => s.Id)); ;
@@ -5,6 +5,7 @@
//-------------------------------------------------------------------- //--------------------------------------------------------------------
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.Application.Contracts namespace IRaCIS.Core.Application.Contracts
{ {
@@ -30,6 +31,8 @@ namespace IRaCIS.Core.Application.Contracts
public string TrialSiteSurveyEquipmentType { get; set; } = string.Empty; public string TrialSiteSurveyEquipmentType { get; set; } = string.Empty;
public string Modalitys { get; set; }
public List<TrialSiteForSelect> TrialSiteSelectList { get; set; } = new List<TrialSiteForSelect>(); public List<TrialSiteForSelect> TrialSiteSelectList { get; set; } = new List<TrialSiteForSelect>();
} }
@@ -67,6 +70,9 @@ namespace IRaCIS.Core.Application.Contracts
public List<TrialSiteEquipmentSurveyView> TrialSiteEquipmentSurveyList { get; set; } = new List<TrialSiteEquipmentSurveyView>(); public List<TrialSiteEquipmentSurveyView> TrialSiteEquipmentSurveyList { get; set; } = new List<TrialSiteEquipmentSurveyView>();
public List<TrialSiteUserSurveyView> TrialSiteUserSurveyList { get; set; } = new List<TrialSiteUserSurveyView>(); public List<TrialSiteUserSurveyView> TrialSiteUserSurveyList { get; set; } = new List<TrialSiteUserSurveyView>();
public TrialExtraConfig SiteSurveyFiledConfig { get; set; }
} }
public class TrialSiteUserSurveyAllDTO : TrialSiteUserSurveyView public class TrialSiteUserSurveyAllDTO : TrialSiteUserSurveyView
@@ -22,6 +22,8 @@ using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using Medallion.Threading; using Medallion.Threading;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using NPOI.SS.Formula.Functions;
using Newtonsoft.Json;
namespace IRaCIS.Core.Application.Contracts namespace IRaCIS.Core.Application.Contracts
{ {
@@ -386,10 +388,12 @@ namespace IRaCIS.Core.Application.Contracts
} }
var result = await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId && t.TrialId == trialId).IgnoreQueryFilters() var result = await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId && t.TrialId == trialId).IgnoreQueryFilters()
.ProjectTo<LoginReturnDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); .ProjectTo<LoginReturnDTO>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync().IfNullThrowException();
var siteSurveryConfig = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).Select(t => t.Trial.TrialExtraConfigJsonStr).FirstOrDefault()??string.Empty;
result.SiteSurveyFiledConfig = JsonConvert.DeserializeObject<TrialExtraConfig>(siteSurveryConfig) ?? new TrialExtraConfig();
return result; return result;
} }
@@ -722,15 +726,15 @@ namespace IRaCIS.Core.Application.Contracts
t.Email, t.Email,
}).ToListAsync(); }).ToListAsync();
var currentUserList = siteUserList.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId).ToList(); //var currentUserList = siteUserList.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId).ToList();
if (!currentUserList.Any(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator) ) if (!siteUserList.Any(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.CRA))
{ {
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_MissingAccount"]); throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_MissingAccount"]);
} }
if (currentUserList.Where(t=>t.IsGenerateAccount && t.UserTypeId!=null).GroupBy(t => new { t.UserTypeId, t.Email }) if (siteUserList.Where(t => t.IsGenerateAccount && t.UserTypeId != null).GroupBy(t => new { t.UserTypeId, t.Email })
.Any(g => g.Count() > 1)) .Any(g => g.Count() > 1))
{ {
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_DuplicateEmail"]); throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_DuplicateEmail"]);
@@ -39,10 +39,9 @@ namespace IRaCIS.Core.Application.AutoMapper
.ForMember(d => d.IsJoin, u => u.MapFrom(c => !c.IsDeleted)); .ForMember(d => d.IsJoin, u => u.MapFrom(c => !c.IsDeleted));
//列表 //列表
CreateMap<TrialSiteEquipmentSurvey, TrialSiteEquipmentSurveyView>() CreateMap<TrialSiteEquipmentSurvey, TrialSiteEquipmentSurveyView>()
.ForMember(t => t.EquipmentType, u => u.MapFrom(d => d.EquipmentType.Value)); .ForMember(t => t.EquipmentType, u => u.MapFrom(d => isEn_Us? d.EquipmentType.Value: d.EquipmentType.ValueCN));
@@ -504,7 +504,7 @@ namespace IRaCIS.Core.Application.Contracts
public string CriterionModalitys { get; set; } public string CriterionModalitys { get; set; }
public ReadingImageDownload? ImageDownloadEnum { get; set; } public ReadingImageDownload ImageDownloadEnum { get; set; }
public ReadingImageUpload? ImageUploadEnum { get; set; } public ReadingImageUpload? ImageUploadEnum { get; set; }
@@ -870,9 +870,9 @@ namespace IRaCIS.Core.Application.Contracts
public bool IsImageFilter { get; set; } public bool IsImageFilter { get; set; }
public string CriterionModalitys { get; set; } public string CriterionModalitys { get; set; }
public ReadingImageDownload? ImageDownloadEnum { get; set; } public ReadingImageDownload ImageDownloadEnum { get; set; }
public ReadingImageUpload? ImageUploadEnum { get; set; } public ReadingImageUpload ImageUploadEnum { get; set; }
//是否附加评估 //是否附加评估
@@ -1465,7 +1465,7 @@ namespace IRaCIS.Core.Application
.WhereIf(!string.IsNullOrEmpty(inQuery.ResearchProgramNo), o => o.ResearchProgramNo.Contains(inQuery.ResearchProgramNo)) .WhereIf(!string.IsNullOrEmpty(inQuery.ResearchProgramNo), o => o.ResearchProgramNo.Contains(inQuery.ResearchProgramNo))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.ExperimentName), o => o.ExperimentName.Contains(inQuery.ExperimentName)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.ExperimentName), o => o.ExperimentName.Contains(inQuery.ExperimentName))
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.Admin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.OP, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id && t.IsDeleted == false) && t.IsDeleted == false) .WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.Admin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.OP, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id && t.IsDeleted == false) && t.IsDeleted == false)
.WhereIf(inQuery.CriterionType != null, o => o.ReadingQuestionCriterionTrialList.Any(t=>t.CriterionType==inQuery.CriterionType && t.IsSigned && t.IsConfirm)) .WhereIf(inQuery.CriterionType != null, o => o.TrialReadingCriterionList.Any(t=>t.CriterionType==inQuery.CriterionType && t.IsSigned && t.IsConfirm))
.WhereIf(!string.IsNullOrEmpty(inQuery.PM_EMail), o => o.TrialUserList.Any(t => t.User.EMail.Contains(inQuery.PM_EMail) && (t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM))) .WhereIf(!string.IsNullOrEmpty(inQuery.PM_EMail), o => o.TrialUserList.Any(t => t.User.EMail.Contains(inQuery.PM_EMail) && (t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM)))
.Select(t => new TrialToBeDoneDto() .Select(t => new TrialToBeDoneDto()
{ {
@@ -1525,7 +1525,7 @@ namespace IRaCIS.Core.Application
.Where(u => u.CurrentActionUserId == null && (u.PreliminaryAuditUserId == null || (u.PreliminaryAuditUserId != _userInfo.Id && u.ReviewAuditUserId == null))).Count() : 0, .Where(u => u.CurrentActionUserId == null && (u.PreliminaryAuditUserId == null || (u.PreliminaryAuditUserId != _userInfo.Id && u.ReviewAuditUserId == null))).Count() : 0,
IR_ReadingCriterionList =isIR ? t.ReadingQuestionCriterionTrialList.Where(t=>t.IsConfirm && t.IsSigned).OrderBy(t => t.CriterionName).Select(t=>t.CriterionName).ToList():null, IR_ReadingCriterionList =isIR ? t.TrialReadingCriterionList.Where(t=>t.IsConfirm && t.IsSigned).OrderBy(t => t.CriterionName).Select(t=>t.CriterionName).ToList():null,
IR_PMEmailList= isIR ? t.TrialUserList.Where(t=>t.User.UserTypeEnum==UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM).OrderBy(t => t.User.EMail).Select(t => t.User.EMail).ToList() : null, IR_PMEmailList= isIR ? t.TrialUserList.Where(t=>t.User.UserTypeEnum==UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM).OrderBy(t => t.User.EMail).Select(t => t.User.EMail).ToList() : null,
@@ -21,6 +21,7 @@ using DocumentFormat.OpenXml.Office.CustomUI;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors; using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors;
using Newtonsoft.Json;
namespace IRaCIS.Core.Application namespace IRaCIS.Core.Application
{ {
@@ -1354,5 +1355,13 @@ namespace IRaCIS.Core.Application
return ResponseOutput.Ok(cro.Id.ToString(), ApiResponseCodeEnum.NeedTips); return ResponseOutput.Ok(cro.Id.ToString(), ApiResponseCodeEnum.NeedTips);
} }
[AllowAnonymous]
public async Task<TrialExtraConfig> GetTrialExtralConfig(Guid trialId)
{
var extralConfig = _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty;
return JsonConvert.DeserializeObject<TrialExtraConfig>(extralConfig) ?? new TrialExtraConfig();
}
} }
} }
@@ -115,7 +115,7 @@ namespace IRaCIS.Core.Application.Services
{ {
var list= _siteRepository var list= _siteRepository
.WhereIf(!string.IsNullOrWhiteSpace(siteName), t => t.SiteName.Contains(siteName) || t.SiteNameCN.Contains(siteName) || t.AliasName.Contains(siteName)) .WhereIf(!string.IsNullOrWhiteSpace(siteName), t => t.SiteName.Contains(siteName) || t.SiteNameCN.Contains(siteName) || t.AliasName.Contains(siteName))
.Select(t => new TrialSiteSelect() { SiteId = t.Id, SiteName = t.SiteName, AliasName = t.AliasName }).ToList(); .Select(t => new TrialSiteSelect() { SiteId = t.Id, SiteName = _userInfo.IsEn_Us? t.SiteName:t.SiteNameCN, AliasName = t.AliasName }).ToList();
return list; return list;
} }
@@ -131,6 +131,14 @@ namespace IRaCIS.Core.Application.Services
{ {
var addArray = _mapper.Map<List<TrialSite>>(trialSites); var addArray = _mapper.Map<List<TrialSite>>(trialSites);
foreach (var item in addArray)
{
if (item.IsDeleted==false)
{
item.EnabledTime = DateTime.Now;
}
}
await _repository.AddRangeAsync(addArray); await _repository.AddRangeAsync(addArray);
@@ -197,7 +205,7 @@ namespace IRaCIS.Core.Application.Services
dbEntity.EnabledTime = null; dbEntity.EnabledTime = null;
} }
else else if (editTrialSiteCommand.IsDeleted==false && dbEntity.EnabledTime==null)
{ {
dbEntity.EnabledTime = DateTime.Now; dbEntity.EnabledTime = DateTime.Now;
} }
@@ -66,7 +66,7 @@ namespace IRaCIS.Core.Application.Service
var userTypeEnumInt = 0; var userTypeEnumInt = 0;
var isEn_Us = false; var isEn_Us = false;
CreateMap<Trial, TrialDetailDTO>() CreateMap<Trial, TrialDetailDTO>()
.ForMember(x=>x.CriterionList,y=>y.MapFrom(z=>z.ReadingQuestionCriterionTrialList.Where(n=>n.IsConfirm).Select(m=>m.CriterionName))) .ForMember(x => x.CriterionList, y => y.MapFrom(z => z.TrialReadingCriterionList.Where(n => n.IsConfirm).Select(m => m.CriterionName)))
.ForMember(d => d.DictionaryList, u => u.MapFrom(s => s.TrialDicList.Select(t => t.Dictionary).OrderBy(t => t.ShowOrder))) .ForMember(d => d.DictionaryList, u => u.MapFrom(s => s.TrialDicList.Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)))
//.ForMember(d => d.Code, u => u.MapFrom(s => s.TrialCode)) //.ForMember(d => d.Code, u => u.MapFrom(s => s.TrialCode))
.ForMember(d => d.Sponsor, u => u.MapFrom(s => s.Sponsor.SponsorName)) .ForMember(d => d.Sponsor, u => u.MapFrom(s => s.Sponsor.SponsorName))
@@ -120,20 +120,8 @@ namespace IRaCIS.Core.Application.Service
#region site country hospital #region site country hospital
CreateMap<TrialSite, SiteStatDTO>() CreateMap<TrialSite, SiteStatDTO>()
//.ForMember(d => d.SiteCode, u => u.MapFrom(s => s.Site.SiteCode))
//.ForMember(d => d.City, u => u.MapFrom(s => s.Site.City))
//.ForMember(d => d.Country, u => u.MapFrom(s => s.Site.Country))
//.ForMember(d => d.Hospital, u => u.MapFrom(s => s.Site.Hospital.HospitalName))
//.ForMember(d => d.DirectorName, u => u.MapFrom(s => s.Site.DirectorName))
//.ForMember(d => d.DirectorPhone, u => u.MapFrom(s => s.Site.DirectorPhone))
//.ForMember(d => d.ContactPhone, u => u.MapFrom(s => s.Site.ContactPhone))
//.ForMember(d => d.Address, u => u.MapFrom(s => s.Site.Address))
//.ForMember(d => d.Site, u => u.MapFrom(s => s.Site.SiteName))
.ForMember(d => d.TrialSiteId, u => u.MapFrom(s => s.Id))
.ForMember(d => d.VisitCount, u => u.MapFrom(s => s.SubjectVisitList.Count())) .ForMember(d => d.VisitCount, u => u.MapFrom(s => s.SubjectVisitList.Count()))
.ForMember(d => d.SubjectCount, u => u.MapFrom(s => s.SubjectList.Count())) .ForMember(d => d.SubjectCount, u => u.MapFrom(s => s.SubjectList.Count()))
.ForMember(d => d.UserCount, u => u.MapFrom(s => s.CRCUserList.Count())) .ForMember(d => d.UserCount, u => u.MapFrom(s => s.CRCUserList.Count()))
@@ -170,8 +158,8 @@ namespace IRaCIS.Core.Application.Service
CreateMap<Domain.Models.Trial, TrialConfigDTO>().ForMember(t => t.TrialId, u => u.MapFrom(c => c.Id)) CreateMap<Domain.Models.Trial, TrialConfigDTO>().ForMember(t => t.TrialId, u => u.MapFrom(c => c.Id))
.ForMember(t => t.TrialCriterionIds, u => u.MapFrom(c => c.ReadingQuestionCriterionTrialList.Where(v =>v.IsConfirm).OrderBy(x=>x.ShowOrder).Select(r => r.Id))) .ForMember(t => t.TrialCriterionIds, u => u.MapFrom(c => c.TrialReadingCriterionList.Where(v => v.IsConfirm).OrderBy(x => x.ShowOrder).Select(r => r.Id)))
.ForMember(t => t.TrialCriterionNames, u => u.MapFrom(c => c.ReadingQuestionCriterionTrialList.Where(v => v.IsConfirm).OrderBy(x => x.ShowOrder).Select(r => r.CriterionName))) .ForMember(t => t.TrialCriterionNames, u => u.MapFrom(c => c.TrialReadingCriterionList.Where(v => v.IsConfirm).OrderBy(x => x.ShowOrder).Select(r => r.CriterionName)))
.ForMember(t => t.ClinicalDataTrialSetIds, u => u.MapFrom(c => c.clinicalDataTrialSets.Where(v => v.IsConfirm).Select(r => r.Id))) .ForMember(t => t.ClinicalDataTrialSetIds, u => u.MapFrom(c => c.clinicalDataTrialSets.Where(v => v.IsConfirm).Select(r => r.Id)))
.ForMember(t => t.ClinicalDataSetNames, u => u.MapFrom(c => c.clinicalDataTrialSets.Where(v => v.IsConfirm).Select(r => isEn_Us ? r.ClinicalDataSetEnName : r.ClinicalDataSetName))) .ForMember(t => t.ClinicalDataSetNames, u => u.MapFrom(c => c.clinicalDataTrialSets.Where(v => v.IsConfirm).Select(r => isEn_Us ? r.ClinicalDataSetEnName : r.ClinicalDataSetName)))
//.ForMember(t => t.CriterionIds, u => u.MapFrom(c => c.TrialDicList.Where(v => v.KeyName == StaticData.Criterion).Select(r => r.DictionaryId))) //.ForMember(t => t.CriterionIds, u => u.MapFrom(c => c.TrialDicList.Where(v => v.KeyName == StaticData.Criterion).Select(r => r.DictionaryId)))
@@ -188,7 +188,7 @@ namespace IRaCIS.Core.Application.Contracts
{ {
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SujectVisitId { get; set; } public Guid SujectVisitId { get; set; }
public Guid? VisitTaskId { get; set; } public Guid VisitTaskId { get; set; }
} }
@@ -264,7 +264,7 @@ namespace IRaCIS.Core.Application.Contracts
public bool IsCriticalSequence { get; set; } = false; public bool IsCriticalSequence { get; set; } = false;
public int SeriesCount { get; set; } public int SeriesCount =>SeriesList.Count;
public int InstanceCount { get; set; } public int InstanceCount { get; set; }
public bool IsDicom { get; set; } = true; public bool IsDicom { get; set; } = true;
@@ -15,6 +15,7 @@ using IRaCIS.Application.Services;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using DocumentFormat.OpenXml.Drawing.Charts; using DocumentFormat.OpenXml.Drawing.Charts;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using NPOI.SS.Formula.Functions;
namespace IRaCIS.Core.Application.Services namespace IRaCIS.Core.Application.Services
{ {
@@ -31,6 +32,7 @@ namespace IRaCIS.Core.Application.Services
private readonly IRepository<DicomInstance> _dicomInstanceRepository; private readonly IRepository<DicomInstance> _dicomInstanceRepository;
private readonly IRepository<VisitTask> _visitTaskRepository; private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository; private readonly IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository;
private readonly IRepository<ReadingCustomTag> _readingCustomTagRepository;
private readonly IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository; private readonly IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository;
private readonly IRepository<ReadingPeriodPlan> _readingPeriodPlanRepository; private readonly IRepository<ReadingPeriodPlan> _readingPeriodPlanRepository;
private readonly IRepository<Subject> _subjectRepository; private readonly IRepository<Subject> _subjectRepository;
@@ -49,6 +51,7 @@ namespace IRaCIS.Core.Application.Services
IRepository<DicomInstance> dicomInstanceRepository, IRepository<DicomInstance> dicomInstanceRepository,
IRepository<VisitTask> visitTaskRepository, IRepository<VisitTask> visitTaskRepository,
IRepository<ReadingTableAnswerRowInfo> readingTableAnswerRowInfoRepository, IRepository<ReadingTableAnswerRowInfo> readingTableAnswerRowInfoRepository,
IRepository<ReadingCustomTag> readingCustomTagRepository,
IRepository<NoneDicomStudyFile> noneDicomStudyFileRepository, IRepository<NoneDicomStudyFile> noneDicomStudyFileRepository,
IRepository<ReadingPeriodPlan> readingPeriodPlanRepository, IRepository<ReadingPeriodPlan> readingPeriodPlanRepository,
IRepository<Subject> subjectRepository, IRepository<Subject> subjectRepository,
@@ -69,6 +72,7 @@ namespace IRaCIS.Core.Application.Services
this._dicomInstanceRepository = dicomInstanceRepository; this._dicomInstanceRepository = dicomInstanceRepository;
this._visitTaskRepository = visitTaskRepository; this._visitTaskRepository = visitTaskRepository;
this._readingTableAnswerRowInfoRepository = readingTableAnswerRowInfoRepository; this._readingTableAnswerRowInfoRepository = readingTableAnswerRowInfoRepository;
this._readingCustomTagRepository = readingCustomTagRepository;
this._noneDicomStudyFileRepository = noneDicomStudyFileRepository; this._noneDicomStudyFileRepository = noneDicomStudyFileRepository;
this._readingPeriodPlanRepository = readingPeriodPlanRepository; this._readingPeriodPlanRepository = readingPeriodPlanRepository;
_subjectRepository = subjectRepository; _subjectRepository = subjectRepository;
@@ -263,7 +267,7 @@ namespace IRaCIS.Core.Application.Services
{ {
InstanceCount = k.InstanceCount, InstanceCount = k.InstanceCount,
Modalities = k.Modalities, Modalities = k.Modalities,
SeriesCount = k.SeriesCount, //SeriesCount = k.SeriesCount,
StudyCode = k.StudyCode, StudyCode = k.StudyCode,
StudyId = k.Id StudyId = k.Id
}).ToListAsync(); }).ToListAsync();
@@ -297,7 +301,7 @@ namespace IRaCIS.Core.Application.Services
); );
//设置为阅片与否 不更改数据库检查 的instance数量 和 SeriesCount 所以这里要实时统计 //设置为阅片与否 不更改数据库检查 的instance数量 和 SeriesCount 所以这里要实时统计
t.SeriesCount = t.SeriesList.Count; //t.SeriesCount = t.SeriesList.Count;
t.InstanceCount = t.SeriesList.SelectMany(t => t.InstanceInfoList).Count(); t.InstanceCount = t.SeriesList.SelectMany(t => t.InstanceInfoList).Count();
} }
@@ -338,8 +342,8 @@ namespace IRaCIS.Core.Application.Services
series.WindowWidth = instanceList.FirstOrDefault()!.WindowWidth; //series.WindowWidth = instanceList.FirstOrDefault()!.WindowWidth;
series.WindowCenter = instanceList.FirstOrDefault()!.WindowCenter; //series.WindowCenter = instanceList.FirstOrDefault()!.WindowCenter;
return series; return series;
} }
@@ -445,8 +449,8 @@ namespace IRaCIS.Core.Application.Services
series.WindowWidth = instanceList.FirstOrDefault()!.WindowWidth; //series.WindowWidth = instanceList.FirstOrDefault()!.WindowWidth;
series.WindowCenter = instanceList.FirstOrDefault()!.WindowCenter; //series.WindowCenter = instanceList.FirstOrDefault()!.WindowCenter;
}); });
} }
@@ -480,22 +484,120 @@ namespace IRaCIS.Core.Application.Services
[HttpPost] [HttpPost]
public async Task<List<VisitStudyDTO>> GetReadingVisitStudyList(GetReadingVisitStudyListIndto indto) public async Task<List<VisitStudyDTO>> GetReadingVisitStudyList(GetReadingVisitStudyListIndto indto)
{ {
var result = new List<VisitStudyDTO>();
var rowInfoList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == indto.VisitTaskId && x.StudyId != null).OrderBy(x => x.ReadingQuestionTrial.ShowOrder).ThenBy(x => x.RowIndex).Select(x => new var studyList = new List<VisitStudyDTO>();
var taskInfo = await _visitTaskRepository.Where(x => x.Id == indto.VisitTaskId).Select(t => new { t.TrialReadingCriterionId, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys, t.ReadingTaskState, TaskStudyCount = t.TaskStudyList.Count }).FirstNotNullAsync();
//影像后处理 上传了新的影像
if (taskInfo.TaskStudyCount > 0)
{ {
x.ReadingQuestionTrial.ShowOrder,
x.RowIndex, var taskStudyList = await _repository.Where<TaskStudy>(t => t.TrialId == indto.TrialId && t.VisitTaskId == indto.VisitTaskId).ProjectTo<VisitStudyDTO>(_mapper.ConfigurationProvider).ToListAsync();
x.SeriesId,
x.StudyId, foreach (var study in taskStudyList)
x.InstanceId, {
study.SeriesList = study.SeriesList.OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).ToList();
//foreach (var series in study.SeriesList)
//{
// series.WindowCenter = series.InstanceInfoList.FirstOrDefault()!.WindowCenter;
// series.WindowWidth = series.InstanceInfoList.FirstOrDefault()!.WindowWidth;
//}
//study.SeriesCount = study.SeriesList.Count;
study.InstanceCount = study.SeriesList.SelectMany(t => t.InstanceInfoList).Count();
}
studyList.AddRange(taskStudyList);
}
else
{
#region dicom
//如果是手动生成的标准,需要过滤检查和序列数据
var isManualGenerate = await _trialReadingCriterionRepository.AnyAsync(t => t.Id == taskInfo.TrialReadingCriterionId && t.IsAutoCreate == false);
var dicomStudyList = await _repository.Where<DicomStudy>(t => t.TrialId == indto.TrialId && t.SubjectVisitId == indto.SujectVisitId)
.WhereIf(taskInfo.IsImageFilter == true, t => taskInfo.CriterionModalitys.Contains(t.ModalityForEdit))
.WhereIf(isManualGenerate, t => t.SubjectCriteriaEvaluationVisitStudyFilterList.Any(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsConfirmed && t.IsReading))
.Select(k => new VisitStudyDTO()
{
InstanceCount = k.InstanceCount,
Modalities = k.Modalities,
//SeriesCount = k.SeriesCount,
StudyCode = k.StudyCode,
StudyId = k.Id,
}).ToListAsync();
var studyIds = dicomStudyList.Select(t => t.StudyId).ToList();
var instanceList = await _repository.Where<DicomInstance>(t => studyIds.Contains(t.StudyId))
.Select(t => new { t.SeriesId, t.Id, t.InstanceNumber, t.Path, t.NumberOfFrames, t.WindowCenter, t.WindowWidth, t.HtmlPath }).ToListAsync();
List<DicomSeriesDTO> seriesLists = await _repository.Where<DicomSeries>(s => studyIds.Contains(s.StudyId))
.WhereIf(isManualGenerate == false, t => t.IsReading)
.WhereIf(isManualGenerate, t => t.SubjectCriteriaEvaluationVisitStudyFilterList.Any(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsConfirmed && t.IsReading))
.OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();
foreach (var t in dicomStudyList)
{
t.SeriesList = seriesLists.Where(s => s.StudyId == t.StudyId).OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).ToList();
t.SeriesList.ForEach(series =>
{
series.InstanceInfoList = instanceList.Where(t => t.SeriesId == series.Id).OrderBy(t => t.InstanceNumber).Select(k =>
new InstanceBasicInfo()
{
Id = k.Id,
NumberOfFrames = k.NumberOfFrames,
HtmlPath = k.HtmlPath,
Path = k.Path,
InstanceNumber = k.InstanceNumber,
}).ToList();
//series.WindowWidth = instanceList.FirstOrDefault()!.WindowWidth;
//series.WindowCenter = instanceList.FirstOrDefault()!.WindowCenter;
});
//设置为阅片与否 不更改数据库检查 的instance数量 和 SeriesCount 所以这里要实时统计
//t.SeriesCount = t.SeriesList.Count;
t.InstanceCount = t.SeriesList.SelectMany(t => t.InstanceInfoList).Count();
}
studyList.AddRange(dicomStudyList);
#endregion
#region dicom
//已经签名的任务,加关键序列
if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned)
{
var rowInfoList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == indto.VisitTaskId && x.StudyId != null).OrderBy(x => x.ReadingQuestionTrial.ShowOrder).ThenBy(x => x.RowIndex).Select(x => new StudyInstanceInfo()
{
ShowOrder = x.ReadingQuestionTrial.ShowOrder,
RowIndex = x.RowIndex,
SeriesId = x.SeriesId,
StudyId = x.StudyId,
InstanceId = x.InstanceId,
}).ToListAsync(); }).ToListAsync();
var taskInfo = await _visitTaskRepository.Where(x => x.Id == indto.VisitTaskId).FirstNotNullAsync();
if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned) var customoList = await _readingCustomTagRepository.Where(x => x.VisitTaskId == indto.VisitTaskId && x.StudyId != null).Select(x => new StudyInstanceInfo()
{ {
ShowOrder = 0,
RowIndex = 0m,
SeriesId = x.SeriesId,
StudyId = x.StudyId,
InstanceId = x.InstanceId,
}).ToListAsync();
rowInfoList.AddRange(customoList);
var thisStudyIds = rowInfoList.OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex).Select(x => x.StudyId).Distinct().ToList(); var thisStudyIds = rowInfoList.OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex).Select(x => x.StudyId).Distinct().ToList();
var thisSeriesIdIds = rowInfoList.Where(x => x.SeriesId != null).OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex).Select(x => x.SeriesId).Distinct().ToList(); var thisSeriesIdIds = rowInfoList.Where(x => x.SeriesId != null).OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex).Select(x => x.SeriesId).Distinct().ToList();
@@ -505,7 +607,7 @@ namespace IRaCIS.Core.Application.Services
{ {
InstanceCount = k.InstanceCount, InstanceCount = k.InstanceCount,
SeriesCount = k.SeriesCount, //SeriesCount = k.SeriesCount,
StudyId = k.Id, StudyId = k.Id,
IsCriticalSequence = true, IsCriticalSequence = true,
@@ -558,79 +660,38 @@ namespace IRaCIS.Core.Application.Services
var modalityList = await _repository.Where<DicomSeries>(s => thisSeriesIdIds.Contains(s.Id)).OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).Select(x => x.Modality).Distinct().ToListAsync(); ; var modalityList = await _repository.Where<DicomSeries>(s => thisSeriesIdIds.Contains(s.Id)).OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).Select(x => x.Modality).Distinct().ToListAsync(); ;
item.Modality = string.Join(",", modalityList); item.Modality = string.Join(",", modalityList);
thisVisitTaskStudy.SeriesList.Add(item); thisVisitTaskStudy.SeriesList.Add(item);
thisVisitTaskStudy.SeriesCount = thisVisitTaskStudy.SeriesList.Count; //thisVisitTaskStudy.SeriesCount = thisVisitTaskStudy.SeriesList.Count;
}
studyList.Insert(0,thisVisitTaskStudy);
} }
result.Add(thisVisitTaskStudy);
} }
} studyList.ForEach(x =>
}
//如果是手动生成的标准,需要过滤检查和序列数据
var isManualGenerate = await _trialReadingCriterionRepository.AnyAsync(t => t.Id == taskInfo.TrialReadingCriterionId && t.IsAutoCreate == false);
var studyList = await _repository.Where<DicomStudy>(t => t.TrialId == indto.TrialId && t.SubjectVisitId == indto.SujectVisitId)
.WhereIf(isManualGenerate, t => t.SubjectCriteriaEvaluationVisitStudyFilterList.Any(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsConfirmed && t.IsReading))
.Select(k => new VisitStudyDTO()
{ {
InstanceCount = k.InstanceCount, x.SeriesList.ForEach(y =>
Modalities = k.Modalities,
SeriesCount = k.SeriesCount,
StudyCode = k.StudyCode,
StudyId = k.Id,
}).ToListAsync();
var studyIds = studyList.Select(t => t.StudyId).ToList();
var instanceList = await _repository.Where<DicomInstance>(t => studyIds.Contains(t.StudyId))
.Select(t => new { t.SeriesId, t.Id, t.InstanceNumber, t.Path, t.NumberOfFrames, t.WindowCenter, t.WindowWidth, t.HtmlPath }).ToListAsync();
List<DicomSeriesDTO> seriesLists = await _repository.Where<DicomSeries>(s => studyIds.Contains(s.StudyId) /*&& s.IsReading*/)
.WhereIf(isManualGenerate == false, t => t.IsReading)
.WhereIf(isManualGenerate, t => t.SubjectCriteriaEvaluationVisitStudyFilterList.Any(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsConfirmed && t.IsReading))
.OrderBy(s => s.SeriesNumber). ThenBy(s => s.SeriesTime).ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();
foreach (var t in studyList)
{ {
t.SeriesList = seriesLists.Where(s => s.StudyId == t.StudyId).OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).ToList(); y.IsBeMark = rowInfoList.Any(z => z.SeriesId == y.Id);
t.SeriesList.ForEach(series =>
{
series.InstanceInfoList = instanceList.Where(t => t.SeriesId == series.Id).OrderBy(t => t.InstanceNumber).Select(k =>
new InstanceBasicInfo()
{
Id = k.Id,
NumberOfFrames = k.NumberOfFrames,
HtmlPath = k.HtmlPath,
Path = k.Path,
InstanceNumber = k.InstanceNumber,
}).ToList();
series.WindowWidth = instanceList.FirstOrDefault()!.WindowWidth;
series.WindowCenter = instanceList.FirstOrDefault()!.WindowCenter;
}); });
//设置为阅片与否 不更改数据库检查 的instance数量 和 SeriesCount 所以这里要实时统计 });
t.SeriesCount = t.SeriesList.Count;
t.InstanceCount = t.SeriesList.SelectMany(t => t.InstanceInfoList).Count();
} }
// 非Dicom #endregion
}
var noDicomList = await _noneDicomStudyRepository.Where(x => x.TrialId == indto.TrialId && x.SubjectVisitId == indto.SujectVisitId).ToListAsync();
#region Dicom
var noDicomList = await _noneDicomStudyRepository.Where(x => x.TrialId == indto.TrialId && x.SubjectVisitId == indto.SujectVisitId && x.NoneDicomFileList.Any(t => !t.FileType.Contains(StaticData.FileType.Zip)))
.WhereIf(taskInfo.IsImageFilter == true, t => taskInfo.CriterionModalitys.Contains(t.Modality) ).ToListAsync();
List<VisitStudyDTO> noDicomStudyList = noDicomList.Select(x => new VisitStudyDTO() List<VisitStudyDTO> noDicomStudyList = noDicomList.Select(x => new VisitStudyDTO()
@@ -638,7 +699,7 @@ namespace IRaCIS.Core.Application.Services
InstanceCount = x.FileCount, InstanceCount = x.FileCount,
StudyId = x.Id, StudyId = x.Id,
Modalities = x.Modality, Modalities = x.Modality,
SeriesCount = 1, //SeriesCount = 1,
StudyCode = x.StudyCode, StudyCode = x.StudyCode,
IsDicom = false, IsDicom = false,
@@ -653,7 +714,7 @@ namespace IRaCIS.Core.Application.Services
if (instanceCount == 0) if (instanceCount == 0)
{ {
item.SeriesList = new List<DicomSeriesDTO>(); item.SeriesList = new List<DicomSeriesDTO>();
item.SeriesCount = 0; //item.SeriesCount = 0;
} }
else else
{ {
@@ -669,7 +730,7 @@ namespace IRaCIS.Core.Application.Services
SubjectVisitId=nodicom.SubjectVisitId, SubjectVisitId=nodicom.SubjectVisitId,
SubjectId=nodicom.SubjectId, SubjectId=nodicom.SubjectId,
SeriesNumber=1, SeriesNumber=1,
NoneDicomFileFirstFile=await _noneDicomStudyFileRepository.Where(x=>x.NoneDicomStudyId==item.StudyId).Select(x=>x.Path).FirstOrDefaultAsync(), NoneDicomFileFirstFile=await _noneDicomStudyFileRepository.Where(x=>x.NoneDicomStudyId==item.StudyId && !x.FileType.Contains(StaticData.FileType.Zip)).Select(x=>x.Path).FirstOrDefaultAsync(),
} }
}; };
@@ -677,24 +738,14 @@ namespace IRaCIS.Core.Application.Services
} }
if (studyList == null || studyList.Count == 0)
{
studyList = new List<VisitStudyDTO>();
}
studyList.AddRange(noDicomStudyList); studyList.AddRange(noDicomStudyList);
studyList.ForEach(x => #endregion
{
x.SeriesList.ForEach(y =>
{
y.IsBeMark = rowInfoList.Any(z => z.SeriesId == y.Id); var result = studyList.Where(x => x.SeriesCount > 0).ToList();
});
});
result.AddRange(studyList);
result = result.Where(x => x.SeriesCount > 0).ToList();
return result; return result;
@@ -1,6 +1,7 @@
using AutoMapper; using AutoMapper;
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.MediatR.CommandAndQueries; using IRaCIS.Core.Application.MediatR.CommandAndQueries;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
@@ -101,6 +102,16 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.SubjectVisit.Subject.Code)) .ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.SubjectVisit.Subject.Code))
.ForMember(d => d.VisitName, u => u.MapFrom(s => s.SubjectVisit.VisitName)) .ForMember(d => d.VisitName, u => u.MapFrom(s => s.SubjectVisit.VisitName))
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.SubjectVisit.TrialSite.TrialSiteCode)); .ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.SubjectVisit.TrialSite.TrialSiteCode));
CreateMap<TaskStudy, VisitStudyDTO>()
.ForMember(d => d.StudyId, u => u.MapFrom(s => s.Id))
.ForMember(d => d.SeriesList, u => u.MapFrom(s => s.SeriesList));
CreateMap<TaskSeries, DicomSeriesDTO>()
.ForMember(d => d.InstanceInfoList, u => u.MapFrom(s => s.InstanceList));
CreateMap<TaskInstance, InstanceBasicInfo>();
} }
} }
@@ -377,9 +377,9 @@ namespace IRaCIS.Application.Contracts
public bool IsReadingPeriod { get; set; } public bool IsReadingPeriod { get; set; }
public ReadingImageDownload? ImageDownloadEnum { get; set; } public ReadingImageDownload ImageDownloadEnum { get; set; }
public ReadingImageUpload? ImageUploadEnum { get; set; } public ReadingImageUpload ImageUploadEnum { get; set; }
} }
public class TrialCriterionReadingCategory public class TrialCriterionReadingCategory
@@ -252,7 +252,7 @@ namespace IRaCIS.Application.Services
EnrollId = intoGroup.Id, EnrollId = intoGroup.Id,
IsEnable = allocateRule.IsEnable, IsEnable = allocateRule.IsEnable,
TrialReadingCriterionList = intoGroup.Trial.ReadingQuestionCriterionTrialList.Where(t => t.IsConfirm).Select(t => new TrialReadingCriterionDto() { TrialReadingCriterionId = t.Id, TrialReadingCriterionName = t.CriterionName, CriterionType = t.CriterionType, IsOncologyReading = t.IsOncologyReading, IsArbitrationReading = t.IsArbitrationReading, IsGlobalReading = t.IsGlobalReading, ReadingInfoSignTime = t.ReadingInfoSignTime, ReadingType = t.ReadingType }).ToList(), TrialReadingCriterionList = intoGroup.Trial.TrialReadingCriterionList.Where(t => t.IsConfirm).Select(t => new TrialReadingCriterionDto() { TrialReadingCriterionId = t.Id, TrialReadingCriterionName = t.CriterionName, CriterionType = t.CriterionType, IsOncologyReading = t.IsOncologyReading, IsArbitrationReading = t.IsArbitrationReading, IsGlobalReading = t.IsGlobalReading, ReadingInfoSignTime = t.ReadingInfoSignTime, ReadingType = t.ReadingType }).ToList(),
DoctorCriterionStatusList= intoGroup.EnrollReadingCriteriaList.Select(t=>new DoctorCriterionStatus() DoctorCriterionStatusList= intoGroup.EnrollReadingCriteriaList.Select(t=>new DoctorCriterionStatus()
{ {
@@ -194,13 +194,14 @@ namespace IRaCIS.Application.Services
var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId); var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
var hasSPMOrCPM = await _repository.Where<TrialUser>(t => t.TrialId == trialId).AnyAsync(t=> t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM);
if (trial != null) if (trial != null)
{ {
if (commitState == 1) //确认提交CRO if (commitState == 1) //确认提交CRO
{ {
//更新项目状态 //更新项目状态
trial.TrialEnrollStatus = (int)TrialEnrollStatus.HasCommitCRO; trial.TrialEnrollStatus = hasSPMOrCPM ? (int)TrialEnrollStatus.HasCommitCRO : (int)TrialEnrollStatus.HasConfirmedDoctorNames;
//添加项目详细记录 //添加项目详细记录
var trialDetail = new TrialStatusDetail() var trialDetail = new TrialStatusDetail()
@@ -217,9 +218,19 @@ namespace IRaCIS.Application.Services
{ {
if (doctorIdArray.Contains(intoGroupItem.DoctorId)) if (doctorIdArray.Contains(intoGroupItem.DoctorId))
{ {
intoGroupItem.EnrollStatus = EnrollStatus.HasCommittedToCRO; intoGroupItem.EnrollStatus = hasSPMOrCPM ? EnrollStatus.HasCommittedToCRO : EnrollStatus.InviteIntoGroup;
//_enrollRepository.Update(intoGroupItem);
await _enrollDetailRepository.AddAsync(new EnrollDetail()
{
TrialDetailId = trialDetail.Id,
DoctorId = intoGroupItem.DoctorId,
TrialId = trialId,
EnrollStatus = hasSPMOrCPM ? EnrollStatus.HasCommittedToCRO : EnrollStatus.InviteIntoGroup,
OptUserType = (int)SystemUserType.AdminUser, //后台用户
});
if (!hasSPMOrCPM)
{
await _enrollDetailRepository.AddAsync(new EnrollDetail() await _enrollDetailRepository.AddAsync(new EnrollDetail()
{ {
TrialDetailId = trialDetail.Id, TrialDetailId = trialDetail.Id,
@@ -229,6 +240,9 @@ namespace IRaCIS.Application.Services
OptUserType = (int)SystemUserType.AdminUser, //后台用户 OptUserType = (int)SystemUserType.AdminUser, //后台用户
}); });
} }
}
} }
@@ -257,7 +271,7 @@ namespace IRaCIS.Application.Services
} }
return ResponseOutput.Result(await _enrollRepository.SaveChangesAsync()); return ResponseOutput.Result(await _enrollRepository.SaveChangesAsync(), new {IsHaveSPMOrCPM=hasSPMOrCPM});
} }
//$"Cannot find trial {trialId}" //$"Cannot find trial {trialId}"
return ResponseOutput.NotOk(_localizer["Enroll_NotFound", trialId]); return ResponseOutput.NotOk(_localizer["Enroll_NotFound", trialId]);
+5 -2
View File
@@ -258,9 +258,12 @@ namespace IRaCIS.Application.Services
[AllowAnonymous] [AllowAnonymous]
public async Task testwwwww([FromServices] IWebHostEnvironment env) public async Task<string> testEmail([FromServices] IWebHostEnvironment env ,string email)
{ {
await Task.CompletedTask;
var hiddenEmail = EmailMaskHelper.MaskEmail(email);
return hiddenEmail;
} }
@@ -213,7 +213,7 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
else else
{ {
//"Problems are as follows: //"Problems are as follows:
dialogMsg.AppendLine($"<br/><div style='color: yellow'>{_localizer["ConsistencyVerification_Prob"]}</div>"); dialogMsg.AppendLine($"<br/><div style='color: red'>{_localizer["ConsistencyVerification_Prob"]}</div>");
num = 0; num = 0;
foreach (var item in dbExceptExcel) foreach (var item in dbExceptExcel)
@@ -368,7 +368,9 @@ namespace IRaCIS.Core.Domain.Share
Agree = 1, Agree = 1,
Reject = 2 Reject = 2,
Invalid = 3,
} }
public enum ReReadingApplyState public enum ReReadingApplyState
@@ -1,4 +1,6 @@
namespace IRaCIS.Core.Domain.Share using System.Collections.Generic;
namespace IRaCIS.Core.Domain.Share
{ {
public enum TrialExpedited public enum TrialExpedited
{ {
@@ -39,6 +41,38 @@
} }
public class TrialExtraConfig
{
#region MyRegion
//QC质控
public bool IsSupportQCDownloadImage { get; set; } = false;
#endregion
#region
public List<string> NotShowFieldList { get; set; } = new List<string>();
public List<SiteSurveyModifyFiled> ModifyFiledList { get; set; } = new List<SiteSurveyModifyFiled>();
#endregion
}
public class SiteSurveyModifyFiled
{
public string NeedModifyFiled { get; set; }
public string ReplaceContent { get; set; }
public string ReplaceContentCN { get; set; }
}
public enum DeclarationType public enum DeclarationType
{ {
Other = 3, Other = 3,
@@ -90,6 +90,13 @@
EnrollOrPD_EMailCopy=5, EnrollOrPD_EMailCopy=5,
} }
public enum UserMFAType
{
Login=0,
Unlock=1,
}
} }
@@ -36,7 +36,7 @@ namespace IRaCIS.Core.Domain.Models
[Required] [Required]
public Guid CreateUserId { get; set; } public Guid CreateUserId { get; set; }
public string FileType { get; set; }
} }
@@ -276,9 +276,9 @@ namespace IRaCIS.Core.Domain.Models
public List<VisitTask> VisitTaskList { get; set; } public List<VisitTask> VisitTaskList { get; set; }
public ReadingImageDownload? ImageDownloadEnum { get; set; } public ReadingImageDownload ImageDownloadEnum { get; set; }
public ReadingImageUpload? ImageUploadEnum { get; set; } public ReadingImageUpload ImageUploadEnum { get; set; }
public bool IsImageFilter { get; set; } public bool IsImageFilter { get; set; }
} }
@@ -294,7 +294,9 @@ namespace IRaCIS.Core.Domain.Models
{ {
None = 0, None = 0,
IRReadingEnable = 1 IRReadingSubejctEnable = 1,
IRReadingVisitEnable = 2,
} }
+4 -2
View File
@@ -46,7 +46,7 @@ namespace IRaCIS.Core.Domain.Models
[JsonIgnore] [JsonIgnore]
public List<TrialUser> TrialUserList { get; set; } = new List<TrialUser>(); public List<TrialUser> TrialUserList { get; set; } = new List<TrialUser>();
[JsonIgnore] [JsonIgnore]
public List<ReadingQuestionCriterionTrial> ReadingQuestionCriterionTrialList { get; set; } = new List<ReadingQuestionCriterionTrial>(); public List<ReadingQuestionCriterionTrial> TrialReadingCriterionList { get; set; } = new List<ReadingQuestionCriterionTrial>();
[JsonIgnore] [JsonIgnore]
public List<Subject> SubjectList { get; set; } = new List<Subject>(); public List<Subject> SubjectList { get; set; } = new List<Subject>();
[JsonIgnore] [JsonIgnore]
@@ -183,6 +183,8 @@ namespace IRaCIS.Core.Domain.Models
public string TrialExtraConfigJsonStr { get; set; } = string.Empty;
public bool VisitPlanConfirmed { get; set; } public bool VisitPlanConfirmed { get; set; }
/// <summary> /// <summary>
@@ -271,7 +273,7 @@ namespace IRaCIS.Core.Domain.Models
public string Modalitys { get; set; } = "CT|MRI|Bone Scan|Photograph|PET|X-ray|US"; public string Modalitys { get; set; } = string.Empty;
[NotMapped] [NotMapped]
public List<string> ModalityList => Modalitys.Split('|', StringSplitOptions.RemoveEmptyEntries).Where(t => !string.IsNullOrEmpty(t)).ToList(); public List<string> ModalityList => Modalitys.Split('|', StringSplitOptions.RemoveEmptyEntries).Where(t => !string.IsNullOrEmpty(t)).ToList();
+4
View File
@@ -248,6 +248,10 @@ namespace IRaCIS.Core.Domain.Models
public string VisitImageZipPath { get; set; } = string.Empty; public string VisitImageZipPath { get; set; } = string.Empty;
public PackState PackState { get; set; } public PackState PackState { get; set; }
public PackState NoDicomPackState { get; set; }
public string VisitNoDicomImageZipPath { get; set;} = string.Empty;
} }
/// <summary> /// <summary>
/// 影像下载打包状态 /// 影像下载打包状态
@@ -24,6 +24,17 @@ namespace IRaCIS.Core.Domain.Share
public int AutoLoginOutMinutes { get; set; } public int AutoLoginOutMinutes { get; set; }
public bool OpenLoginMFA { get; set; } public bool OpenLoginMFA { get; set; }
/// <summary>
/// 连续阅片时间 (min)
/// </summary>
public int ContinuousReadingTimeMin { get; set; }
/// <summary>
/// 休息时间 (min)
/// </summary>
public int ReadingRestTimeMin { get; set; }
} }
public class SystemEmailSendConfig public class SystemEmailSendConfig
@@ -41,6 +52,9 @@ namespace IRaCIS.Core.Domain.Share
public string SiteUrl { get; set; } public string SiteUrl { get; set; }
public string OrganizationName { get; set; }
public string OrganizationNameCN { get; set; }
public string CompanyName { get; set; } public string CompanyName { get; set; }
public string CompanyNameCN { get; set; } public string CompanyNameCN { get; set; }
+4 -1
View File
@@ -112,7 +112,10 @@ public static class StaticData
public static readonly string UploadFileFolder = "UploadFile"; public static readonly string UploadFileFolder = "UploadFile";
} }
public static class FileType
{
public static readonly string Zip = "zip";
}
public static class TrialOpt public static class TrialOpt
{ {
@@ -284,6 +284,31 @@ namespace IRaCIS.Core.Infra.EFCore.Common
.Select(t => new { t.AdditionalAssessmentType, t.IsSelected }).ToListAsync(); .Select(t => new { t.AdditionalAssessmentType, t.IsSelected }).ToListAsync();
var oncologyAssessIdsStr = string.Empty;
var allList = new List<ReadingTrialCriterionDictionary>();
if (entitys.Any(x => x.Entity.GetType() == typeof(ReadingTrialCriterionDictionary)))
{
allList = entitys.Where(x => x.Entity.GetType() == typeof(ReadingTrialCriterionDictionary))
.Select(t => t.Entity as ReadingTrialCriterionDictionary).ToList().Where(x=>
x.CriterionId== entity.Id &&
x.ParentCode == ReadingCommon.CriterionDictionary.OncologyAssess).ToList();
}
else
{
allList=await _dbContext.ReadingTrialCriterionDictionary.Where(x =>
x.CriterionId == entity.Id &&
x.ParentCode == ReadingCommon.CriterionDictionary.OncologyAssess).ToListAsync();
}
//查询出字典的Value ValueCN Des 保存
var diclistOncologyAssess = allList.Select(t => t.DictionaryId).ToList();
var selectList = await _dbContext.Dictionary.Where(x => diclistOncologyAssess.Contains(x.Id)).Select(t => t.ValueCN).ToListAsync();
oncologyAssessIdsStr = string.Join(",", selectList);
await InsertInspection<ReadingQuestionCriterionTrial>(entity, type, x => new InspectionConvertDTO() await InsertInspection<ReadingQuestionCriterionTrial>(entity, type, x => new InspectionConvertDTO()
{ {
IsDistinctionInterface = isDistinctionInterface, IsDistinctionInterface = isDistinctionInterface,
@@ -296,6 +321,8 @@ namespace IRaCIS.Core.Infra.EFCore.Common
}, new }, new
{ {
OncologyAssessIdsStr= oncologyAssessIdsStr,
EvaluationResultTypes = dicValueList.Count > 0 ? string.Join(",", dicValueList) : string.Empty, EvaluationResultTypes = dicValueList.Count > 0 ? string.Join(",", dicValueList) : string.Empty,
AdditionalAssessmentTypeList = addtionalAssesementList AdditionalAssessmentTypeList = addtionalAssesementList
}); });
@@ -133,6 +133,8 @@ namespace IRaCIS.Core.Infra.EFCore
Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities, bool autoSave = false); Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities, bool autoSave = false);
Task<bool> SaveChangesAsync(CancellationToken cancellationToken = default); Task<bool> SaveChangesAsync(CancellationToken cancellationToken = default);
Task<bool> SaveChangesAndClearAllTrackingAsync(CancellationToken cancellationToken = default);
Task<bool> DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default); Task<bool> DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);
@@ -449,7 +449,12 @@ namespace IRaCIS.Core.Infra.EFCore
return await _dbContext.SaveChangesAsync(cancellationToken) > 0; return await _dbContext.SaveChangesAsync(cancellationToken) > 0;
} }
public async Task<bool> SaveChangesAndClearAllTrackingAsync(CancellationToken cancellationToken = default)
{
var count = await _dbContext.SaveChangesAsync(cancellationToken);
_dbContext.ChangeTracker.Clear();
return count > 0;
}
#endregion #endregion
#region #region
+79 -105
View File
@@ -1,83 +1,31 @@
---
kind: pipeline kind: pipeline
type: docker type: ssh
name: irc-netcore-api name: ssh-linux-uat-irc-build-image
platform:
os: Linux
arch: 386
clone: clone:
disable: true disable: true
server:
host: 47.117.164.182
user: root
password:
from_secret: test_ssh_pwd
steps: steps:
- name: clone-repo - name: build-uat-irc
image: alpine/git
pull: if-not-exists
volumes:
- name: irc-test-work
path: /work
commands: commands:
- if [ ! -e /work/netcore-repo/.git ]; then - cd /opt/1panel/xc-deploy/Uat_IRC/devops-build-publish/Uat-To-Uat
git clone -b Test.IRC http://192.168.3.68:2000/XCKJ/irc-netcore-api.git /work/netcore-repo; - sh uat-branch-latest-build-image-publish.sh v${DRONE_BUILD_NUMBER}
else
cd /work/netcore-repo;
git pull;
fi
- |
if [ ! -e Dockerfile ]; then
echo 'FROM mcr.microsoft.com/dotnet/aspnet:6.0
EXPOSE 80
WORKDIR /app
COPY publish .
ENTRYPOINT ["dotnet", "IRaCIS.Core.API.dll"]' > /work/Dockerfile
fi
- name: restore-publish
image: mcr.microsoft.com/dotnet/sdk:6.0
pull: if-not-exists
depends_on:
- clone-repo
volumes:
- name: nuget-packages
path: /root/.nuget/packages
- name: irc-test-work
path: /work
commands:
- cd /work/netcore-repo/IRaCIS.Core.API
- dotnet restore ./IRaCIS.Core.API.csproj
- rm -rf /work/publish
- cd /work/netcore-repo/IRaCIS.Core.API
- dotnet publish ./IRaCIS.Core.API.csproj -c Release --no-restore -o /work/publish
- name: docker-build
image: docker
pull: if-not-exists
depends_on:
- restore-publish
commands:
- cd /work
- docker build -t test-irc:v${DRONE_BUILD_NUMBER} .
volumes:
- name: irc-test-work
path: /work
- name: dockersock
path: /var/run/docker.sock
volumes:
- name: nuget-packages
host:
path: /opt/cicd/nuget/packages
- name: irc-test-work
host:
path: /opt/cicd/irc-test
- name: dockersock
host:
path: /var/run/docker.sock
trigger: trigger:
branch: branch:
- master - Uat_IRC_Net8
--- ---
kind: pipeline kind: pipeline
type: ssh type: ssh
name: ssh-linux-test-irc-publish name: ssh-linux-test-irc-publish
@@ -98,45 +46,13 @@ server:
steps: steps:
- name: publish-test-irc - name: publish-test-irc
commands: commands:
- echo start publish test-irc-api - cd /opt/1panel/xc-deploy/Test_IRC/devops-build-publish;sh test-irc-update-or-create-stack.sh v${DRONE_BUILD_NUMBER}
- cd /opt/1panel/hang/devops/test-irc-net8
- sh test-irc.sh v${DRONE_BUILD_NUMBER}
trigger: trigger:
branch: branch:
- Test_IRC_Net8 - Test_IRC_Net8
--- ---
kind: pipeline
type: ssh
name: test-irc-publish-image-push-aliyun
platform:
os: Linux
arch: 386
clone:
disable: true
server:
host: 192.168.3.68
user: root
password:
from_secret: local_pwd
steps:
- name: build-and-push-image
commands:
- cd /opt/hang/netcore/irc-test
- sh test-irc.sh v${DRONE_BUILD_NUMBER}
trigger:
branch:
- master
---
kind: pipeline kind: pipeline
type: ssh type: ssh
name: ssh-linux-test-study-publish name: ssh-linux-test-study-publish
@@ -146,10 +62,10 @@ platform:
arch: 386 arch: 386
clone: clone:
disable: true disable: true #禁用默认克隆
server: server:
host: 123.56.94.154 host: 106.14.89.110
user: root user: root
password: password:
from_secret: test_ssh_pwd from_secret: test_ssh_pwd
@@ -157,10 +73,68 @@ server:
steps: steps:
- name: publish-test-study - name: publish-test-study
commands: commands:
- echo start publish test-study-api - cd /opt/1panel/xc-deploy/Test_Study/devops-build-publish
- cd /opt/1panel/hang/devops/test-study
- sh test-study.sh v${DRONE_BUILD_NUMBER} - sh test-study.sh v${DRONE_BUILD_NUMBER}
trigger: trigger:
branch: branch:
- Test.Study - Test.Study
---
kind: pipeline
type: ssh
name: ssh-linux-test-scp-publish
platform:
os: Linux
arch: 386
clone:
disable: true #禁用默认克隆
server:
host: 106.14.89.110
user: root
password:
from_secret: test_ssh_pwd
steps:
- name: publish-test-hir-scp
commands:
- cd /opt/1panel/xc-deploy/Test_HIR_SCP/devops-build-publish;sh pull-build-test-hir-scp-image.sh v${DRONE_BUILD_NUMBER}
- cd /opt/1panel/xc-deploy/Test_HIR_SCP ;sh update-image-if-need-then-pull-aliyun.sh v${DRONE_BUILD_NUMBER}
trigger:
branch:
- Test_HIR
---
kind: pipeline
type: ssh
name: ssh-linux-test-hir-publish
platform:
os: Linux
arch: 386
clone:
disable: true #禁用默认克隆
server:
host: 106.14.89.110
user: root
password:
from_secret: test_ssh_pwd
steps:
- name: publish-test-hir
commands:
- cd /opt/1panel/xc-deploy/Test_HIR/devops-build-publish;sh pull-build-test-hir-image.sh v${DRONE_BUILD_NUMBER}
- cd /opt/1panel/xc-deploy/Test_HIR ; sh update-image-if-need-then-pull-aliyun.sh v${DRONE_BUILD_NUMBER}
trigger:
branch:
- Test_HIR