Compare commits

...

137 Commits

Author SHA1 Message Date
hang 0a2513245c 升级net8 模型要求严格了 2024-01-05 17:09:25 +08:00
hang f10cc0adbf 修改稽查上传文件路径
continuous-integration/drone/push Build is passing
2024-01-05 12:56:26 +08:00
hang 58b2f9c7a9 修改配置文件
continuous-integration/drone/push Build is passing
2024-01-05 12:40:13 +08:00
hang 472e744b6c 修改生产数据库
continuous-integration/drone/push Build is passing
2024-01-05 12:27:11 +08:00
hang 699df338c1 修改待阅列表 临床数据未签名但是可以做后续访视,生成任务逻辑遗漏
continuous-integration/drone/push Build is passing
2024-01-04 15:20:00 +08:00
hang a64127537e Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-04 12:16:39 +08:00
hang 2287c8869d 修改导表错误 2024-01-04 12:16:31 +08:00
he 0d8319feaa 代码修改
continuous-integration/drone/push Build is passing
2024-01-03 17:28:15 +08:00
he 676c5b0e74 再次修改
continuous-integration/drone/push Build is passing
2024-01-03 17:17:33 +08:00
he a76654c210 修改状态
continuous-integration/drone/push Build is passing
2024-01-03 17:08:39 +08:00
he 0a29d431dc 修改状态
continuous-integration/drone/push Build is passing
2024-01-03 16:58:43 +08:00
he 86562b39e3 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-03 16:47:51 +08:00
he 86fe43aa93 代码修改 修改阅片状态 2024-01-03 16:47:49 +08:00
hang 082998da09 修改监控导出
continuous-integration/drone/push Build is passing
2024-01-03 15:39:43 +08:00
hang d209a8de4d 修改中心调研导表
continuous-integration/drone/push Build is passing
2024-01-03 15:26:40 +08:00
he b1608812ec Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-03 14:24:57 +08:00
he 20c18d957a 阅片状态修改 2024-01-03 14:24:55 +08:00
hang 7a7011e7ef 打开文件修改监控
continuous-integration/drone/push Build is passing
2024-01-03 13:43:31 +08:00
hang 24a395f8c8 增加真实名字
continuous-integration/drone/push Build is passing
2024-01-03 13:42:01 +08:00
hang df2f179917 xx
continuous-integration/drone/push Build is passing
2024-01-03 13:39:17 +08:00
hang 1bcc831937 不监测修改
continuous-integration/drone/push Build is passing
2024-01-03 13:32:03 +08:00
hang 75bf85997a 禁止热更新
continuous-integration/drone/push Build is passing
2024-01-03 13:20:27 +08:00
hang 074cba906c xx
continuous-integration/drone/push Build is passing
2024-01-03 13:18:11 +08:00
hang 86db676df8 必须在镜像里面修改
continuous-integration/drone/push Build is passing
2024-01-03 13:12:36 +08:00
hang bc67f16735 docker 部署方式解决
continuous-integration/drone/push Build is passing
2024-01-03 12:13:47 +08:00
hang 3e046e24e9 增加上传人
continuous-integration/drone/push Build is passing
2024-01-03 11:43:04 +08:00
hang c971161d31 修改utf-8
continuous-integration/drone/push Build is passing
2024-01-03 11:19:07 +08:00
hang a63904c0bb 暂时屏蔽
continuous-integration/drone/push Build is passing
2024-01-03 11:11:57 +08:00
hang 572d4ea4b8 修改docker-compose 文件打开文件修改跟踪
continuous-integration/drone/push Build is passing
2024-01-03 11:05:19 +08:00
hang ae4345cfcc x 监控文件错误 测试
continuous-integration/drone/push Build is passing
2024-01-03 10:06:30 +08:00
hang a536c33302 自动打包修改
continuous-integration/drone/push Build is passing
2024-01-03 09:29:07 +08:00
hang be5c9b636e 修改国际化邮件代码 2024-01-03 09:23:55 +08:00
hang c71bf65cd9 系统签名文档废除
continuous-integration/drone/push Build encountered an error
2023-12-29 17:36:08 +08:00
he 69c5ce9841 代码统计修改 查询数量 2023-12-29 17:36:00 +08:00
hang 2139193df4 清理裁判任务Id
continuous-integration/drone/push Build encountered an error
2023-12-29 17:35:11 +08:00
he 9aa2f23a67 修改代码 需要发study
continuous-integration/drone/push Build encountered an error
2023-12-28 13:25:02 +08:00
he 531e0fa228 计算小数位修改 需要同步study 2023-12-28 13:24:35 +08:00
hang 250c478687 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build encountered an error
2023-12-27 11:13:29 +08:00
hang 09ba37ec6d 修改测试环境数据库地址 2023-12-27 11:13:27 +08:00
hang 913b673b72 迁移修改
continuous-integration/drone/push Build is passing
2023-12-23 11:30:15 +08:00
hang 5ee8a3db21 迁移修改数据库连接地址
continuous-integration/drone/push Build is failing
2023-12-22 18:01:29 +08:00
hang 3c41789ba9 修改导表 5 2023-12-20 16:44:40 +08:00
hang d2268f0706 裁判任务失效的时候,清理裁判任务id 需要迁移 2023-12-20 16:44:36 +08:00
hang e8496df81a 修改模板文件位置 4 2023-12-20 16:43:49 +08:00
hang 3e24fe9461 修改路径bug 3 2023-12-20 16:43:45 +08:00
hang d771ab0f6f 修改文档删除2 2023-12-20 16:43:39 +08:00
hang 29dfa03d0f 修改导表时间格式2 2023-12-20 16:43:34 +08:00
hang 44e9b211c2 更新模板的时候,清理之前的文档,需要迁移 2023-12-20 16:43:29 +08:00
hang b1154ea594 修改导表时间格式 2023-12-20 16:43:25 +08:00
he 6dd12b419b 临床数据查询修改
continuous-integration/drone/push Build is passing
2023-12-13 09:57:18 +08:00
he bce7c1cc99 临床数据查询修改
continuous-integration/drone/push Build is failing
2023-12-13 09:51:24 +08:00
he a660eb4f37 临床数据修改 2023-12-13 09:51:17 +08:00
he 3ade13a922 临床数据修改
continuous-integration/drone/push Build is passing
2023-12-13 09:47:51 +08:00
he a5fed78c19 临床数据修改 2023-12-13 09:47:18 +08:00
he 5207fef130 医学审核加是否有临床数据 2023-12-13 09:47:07 +08:00
he b8ad8085cd Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-12-13 09:45:48 +08:00
hang dc8451f55c windows linux 环境路径修改 迁移
continuous-integration/drone/push Build is passing
2023-12-08 12:45:02 +08:00
hang dd9ec3d8fe 用户登录国际化
continuous-integration/drone/push Build is passing
2023-12-08 09:01:06 +08:00
hang 589cd83576 修改编码格式
continuous-integration/drone/push Build is passing
2023-12-07 10:27:59 +08:00
hang 6c2a1e0a4b 修改文件格式
continuous-integration/drone/push Build is passing
2023-12-07 10:02:32 +08:00
hang 7a927b3133 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-12-06 17:14:13 +08:00
hang 3dbf6dc897 修改为utf8 测试 2023-12-06 17:14:11 +08:00
he bb5401f78c 代码修改
continuous-integration/drone/push Build is passing
2023-12-06 16:55:49 +08:00
he 59e9d9df69 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-12-06 16:53:56 +08:00
hang 9a70193e7a hospital修改 需要迁移
continuous-integration/drone/push Build is passing
2023-12-06 16:12:59 +08:00
hang b44a9ecc63 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-12-06 11:48:25 +08:00
hang fb45173106 修改trigger 注入服务异常 2023-12-06 11:47:46 +08:00
hang bf2996bd1c 修改合并bug
continuous-integration/drone/push Build is passing
2023-12-05 17:33:28 +08:00
hang d840f14a2f x
continuous-integration/drone/push Build is passing
2023-12-05 16:11:24 +08:00
hang 4101c68d37 修改国际化
continuous-integration/drone/push Build is passing
2023-12-05 14:56:45 +08:00
hang 91503dc599 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study 2023-12-05 14:53:09 +08:00
hang debe22fdc3 清理无用的文件 2023-12-05 14:41:00 +08:00
hang 8f4f9a91c2 修改一致性核查国际化
continuous-integration/drone/push Build is passing
2023-12-05 13:59:21 +08:00
hang a53e306427 修改调研表 增加SR
continuous-integration/drone/push Build is passing
2023-12-05 11:03:58 +08:00
hang 02183affc3 修改study 生成用户类型
continuous-integration/drone/push Build is passing
2023-12-05 10:50:45 +08:00
hang e81c97037a 修改 验证 和生产配置文件
continuous-integration/drone/push Build is passing
2023-12-04 17:07:58 +08:00
hang 1fd02cbbc5 修改后端上传OSS 解析
continuous-integration/drone/push Build is passing
2023-12-04 15:32:25 +08:00
hang 55cbbffba6 oss 直接返回secret
continuous-integration/drone/push Build is passing
2023-12-04 11:35:34 +08:00
hang 4a1bf759cf OSS 大写改为小写 2023-12-04 11:31:22 +08:00
hang 703ab03b7f 阿里云临时token改为直接返回token和秘钥 2023-12-04 11:29:42 +08:00
he 0582390b2c 代码修改
continuous-integration/drone/push Build is passing
2023-12-04 09:27:43 +08:00
he cdf1119764 缓存时间修改 需要同步 2023-12-04 09:27:32 +08:00
hang 72cb407766 删除无用的服务
continuous-integration/drone/push Build is passing
2023-12-01 14:15:20 +08:00
hang 9f80386a19 修改警告4 2023-12-01 14:13:22 +08:00
hang 3a96710210 修改警告7 2023-12-01 14:12:45 +08:00
hang b8b63e33b8 修改警告6 2023-12-01 14:12:05 +08:00
hang 98d09886de 修改警告5 2023-12-01 14:11:10 +08:00
hang 91671c5003 修改警告4 2023-12-01 14:09:56 +08:00
hang 35ef014391 修改警告4 2023-12-01 14:07:43 +08:00
hang 82fc9bfc75 警告修改2 2023-12-01 14:05:31 +08:00
hang d6d47a6f85 修改警告 1 2023-12-01 14:03:22 +08:00
hang 32d6cce33e 服务循环依赖
continuous-integration/drone/push Build is passing
2023-12-01 13:59:28 +08:00
hang 06ca624886 x
continuous-integration/drone/push Build is passing
2023-11-30 15:29:59 +08:00
hang 88231fffb4 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-11-30 15:29:11 +08:00
hang 12ab0d3eb4 合并代码修改 2023-11-30 15:29:09 +08:00
hang 6faeecebb0 修改统计,需要迁移 2023-11-30 15:13:15 +08:00
hang 48b778c95a linux 下适配 转换pdf 2023-11-30 15:13:09 +08:00
hang dee286cc90 验证环境发布 2023-11-30 15:09:53 +08:00
hang 2e96f7a936 日志提示当前部署平台 2023-11-30 15:07:52 +08:00
he ebb33f45ba 临床数据修改
continuous-integration/drone/push Build is passing
2023-11-30 15:00:04 +08:00
he 9d32be658c Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-11-30 14:24:33 +08:00
he 27fd819c9c 临床数据维护 2023-11-30 14:24:12 +08:00
he 937f8a5b66 临床数据问题修改 2023-11-30 14:24:09 +08:00
hang 53544001a7 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-11-28 13:25:20 +08:00
hang f08cd1c818 1127 稽查修改 2023-11-28 13:24:34 +08:00
hang 2c377d02f9 中心调研修改 需要迁移 2023-11-28 13:23:03 +08:00
hang 29f8648287 修改OSS 配置
continuous-integration/drone/push Build is passing
2023-11-24 14:47:12 +08:00
hang f0725873e1 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-11-24 11:25:17 +08:00
hang dc12e57494 迁移提交 2023-11-24 11:25:15 +08:00
hang d4a731d544 OSS 稽查修改 ,新增健康检查
continuous-integration/drone/push Build is passing
2023-11-24 11:23:39 +08:00
hang 6e22515603 迁移修改
continuous-integration/drone/push Build is passing
2023-11-24 09:51:50 +08:00
hang abd5c8942d 上传文件到OSS 需要迁移 2023-11-24 09:37:12 +08:00
hang 3decef7693 修改统计bug,医学审核增加最新回复人 2023-11-24 09:29:30 +08:00
hang ae83c753cb 统计排序 03
continuous-integration/drone/push Build is failing
2023-11-24 09:20:29 +08:00
hang 53ae0527ff 修改稽查和界面统计 需要迁移02 2023-11-24 09:20:21 +08:00
hang a234e0746d 修改重阅稽查 2023-11-24 09:18:20 +08:00
hang c88d927c4b 稽查修改 2023-11-24 09:18:04 +08:00
hang 245898e22e 医学审核稽查修改 2023-11-24 09:16:41 +08:00
he 93d3024b0f 修改
continuous-integration/drone/push Build is passing
2023-11-21 13:12:31 +08:00
he 35be7f3144 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-11-21 13:11:57 +08:00
hang 62ac9418b5 修改统计bug,
continuous-integration/drone/push Build is passing
2023-11-21 11:13:56 +08:00
hang ea5de83364 修改统计03 -需迁移 2023-11-21 11:13:00 +08:00
hang cf5a8b20e4 CRC 影像质疑 2023-11-21 11:12:55 +08:00
hang ea95ece331 修改页面查询结果显示 2023-11-21 11:12:51 +08:00
hang 894b9eb67b Merge branch 'Test.Study' of http://192.168.3.69:2000/XCKJ/irc-netcore-api into Test.Study 2023-11-08 18:28:02 +08:00
hang d7e5b3f57c 没有建议完成时间 2023-11-08 18:27:58 +08:00
hang 29a47e7351 修改邮件 2023-11-08 16:43:52 +08:00
he 6d2cddfcfc 修改 2023-11-08 16:07:31 +08:00
he 60b2978deb Merge branch 'Test.Study' of http://192.168.3.69:2000/XCKJ/irc-netcore-api into Test.Study 2023-11-08 16:06:30 +08:00
hang 79187772a6 Merge branch 'Test.Study' of http://192.168.3.69:2000/XCKJ/irc-netcore-api into Test.Study 2023-11-07 11:59:56 +08:00
hang 105da818a8 修改删除 2023-11-07 11:59:19 +08:00
hang 584516f936 修改项目列表 2023-11-07 11:46:47 +08:00
hang a7429c1739 通用文档下载 2023-11-06 13:58:34 +08:00
hang 75f227e547 增加权限 2023-11-06 13:39:30 +08:00
hang 60c31b470c 导表bug 2023-11-06 13:32:06 +08:00
hang 731f049fc0 修改国际化,导表,增加查看角色类型 2023-11-06 13:10:13 +08:00
hang 201c24238c 权限增加 2023-11-06 11:14:41 +08:00
103 changed files with 2125 additions and 3793 deletions
+41
View File
@@ -126,6 +126,47 @@ csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent csharp_style_unused_value_expression_statement_preference = discard_variable:silent
# SA0001: XML comment analysis disabled
dotnet_diagnostic.SA0001.severity = suggestion
# SA1002: Semicolons should be spaced correctly
dotnet_diagnostic.SA1002.severity = suggestion
# SA1005: Single line comments should begin with single space
dotnet_diagnostic.SA1005.severity = none
dotnet_diagnostic.CS8618.severity = none
dotnet_diagnostic.CS8604.severity = none
dotnet_diagnostic.CS8600.severity = none
dotnet_diagnostic.CS1570.severity = none
dotnet_diagnostic.CS8601.severity = none
dotnet_diagnostic.CS8632.severity = none
dotnet_diagnostic.CS8625.severity = none
dotnet_diagnostic.CS8603.severity = none
dotnet_diagnostic.CS8602.severity = none
dotnet_diagnostic.CS1998.severity = none
dotnet_diagnostic.CS0168.severity = none
dotnet_diagnostic.CS0219.severity = none
dotnet_diagnostic.CS0108.severity = none
dotnet_diagnostic.CS0120.severity = none
dotnet_diagnostic.CS8620.severity = none
dotnet_diagnostic.CS8619.severity = none
dotnet_diagnostic.CS0162.severity = none
dotnet_diagnostic.CS0472.severity = none
dotnet_diagnostic.CS8629.severity = none
dotnet_diagnostic.CS8073.severity = none
dotnet_diagnostic.CS0414.severity = none
dotnet_diagnostic.CS1573.severity = none
dotnet_diagnostic.CS0109.severity = none
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_top_level_statements = true:silent
dotnet_diagnostic.SA1003.severity = silent
dotnet_diagnostic.SA1108.severity = silent
dotnet_diagnostic.SA1107.severity = silent
[*.vb] [*.vb]
#### 命名样式 #### #### 命名样式 ####
+71 -12
View File
@@ -26,6 +26,8 @@ using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Sts.Model.V20150401; using Aliyun.Acs.Sts.Model.V20150401;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using MassTransit; using MassTransit;
using IRaCIS.Core.Application.Helper;
using Microsoft.Extensions.Options;
namespace IRaCIS.Api.Controllers namespace IRaCIS.Api.Controllers
{ {
@@ -134,25 +136,82 @@ namespace IRaCIS.Api.Controllers
return returnModel; return returnModel;
} }
[AllowAnonymous] [HttpGet("user/GetObjectStoreToken")]
[HttpGet("user/GenerateSTS")] public IResponseOutput GetObjectStoreToken([FromServices] IOptionsMonitor<ObjectStoreServiceOptions> options)
public IResponseOutput GenerateSTS( [FromServices] IWebHostEnvironment webHostEnvironment)
{ {
var serviceOption = options.CurrentValue;
var configuration = new ConfigurationBuilder() if (Enum.TryParse<ObjectStoreUse>(serviceOption.ObjectStoreUse, out var parsedEnum) && parsedEnum == ObjectStoreUse.AliyunOSS)
.AddJsonFile($"appsettings.{webHostEnvironment.EnvironmentName}.json") {
.Build();
var ossOptions = serviceOption.AliyunOSS;
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO ,AliyunOSS= serviceOption.AliyunOSS });
#region token
//IClientProfile profile = DefaultProfile.GetProfile(ossOptions.RegionId, ossOptions.AccessKeyId, ossOptions.AccessKeySecret);
//DefaultAcsClient client = new DefaultAcsClient(profile);
IClientProfile profile = DefaultProfile.GetProfile("cn-shanghai", configuration["AliyunOSS:accessKeyId"], configuration["AliyunOSS:accessKeySecret"]); //// 创建一个STS请求
//AssumeRoleRequest request = new AssumeRoleRequest
//{
// RoleArn = ossOptions.RoleArn, // 角色ARN,需要替换为你的角色ARN
// RoleSessionName = $"session-name-{NewId.NextGuid()}", // 角色会话名称,可自定义
// DurationSeconds = 900, // 令牌有效期(单位:秒),这里设置为1小时
//};
//AssumeRoleResponse response = client.GetAcsResponse(request);
//// 返回STS令牌信息给前端
//var stsToken = new ObjectStoreDTO()
//{
// ObjectStoreUse = serviceOption.ObjectStoreUse,
// AliyunOSS = new AliyunOSSTempToken()
// {
// AccessKeyId = response.Credentials.AccessKeyId,
// AccessKeySecret = response.Credentials.AccessKeySecret,
// SecurityToken = response.Credentials.SecurityToken,
// Expiration = response.Credentials.Expiration,
// Region = ossOptions.Region,
// BucketName = ossOptions.BucketName,
// ViewEndpoint = ossOptions.ViewEndpoint,
// },
// MinIO = serviceOption.MinIO
//};
//return ResponseOutput.Ok(stsToken);
#endregion
}
else if (Enum.TryParse<ObjectStoreUse>(serviceOption.ObjectStoreUse, out var parsedValue) && parsedValue == ObjectStoreUse.MinIO)
{
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO });
}
else
{
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO });
}
}
[HttpGet("user/GenerateSTS")]
public IResponseOutput GenerateSTS([FromServices] IOptionsMonitor<AliyunOSSOptions> options)
{
var ossOptions = options.CurrentValue;
IClientProfile profile = DefaultProfile.GetProfile(ossOptions.regionId, ossOptions.accessKeyId, ossOptions.accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile); DefaultAcsClient client = new DefaultAcsClient(profile);
// 创建一个STS请求 // 创建一个STS请求
AssumeRoleRequest request = new AssumeRoleRequest AssumeRoleRequest request = new AssumeRoleRequest
{ {
RoleArn = "acs:ram::1899121822495495:role/oss-upload", // 角色ARN,需要替换为你的角色ARN RoleArn = ossOptions.roleArn, // 角色ARN,需要替换为你的角色ARN
RoleSessionName = $"session-name-{NewId.NextGuid()}", // 角色会话名称,可自定义 RoleSessionName = $"session-name-{NewId.NextGuid()}", // 角色会话名称,可自定义
DurationSeconds = 900, // 令牌有效期(单位:秒),这里设置为1小时 DurationSeconds = 900, // 令牌有效期(单位:秒),这里设置为1小时
}; };
@@ -168,9 +227,9 @@ namespace IRaCIS.Api.Controllers
SecurityToken = response.Credentials.SecurityToken, SecurityToken = response.Credentials.SecurityToken,
Expiration = response.Credentials.Expiration, Expiration = response.Credentials.Expiration,
Region= configuration["AliyunOSS:region"], Region = ossOptions.region ,
BucketName = configuration["AliyunOSS:bucketName"], BucketName = ossOptions.bucketName ,
ViewEndpoint = configuration["AliyunOSS:viewEndpoint"], ViewEndpoint = ossOptions.viewEndpoint ,
}; };
@@ -24,6 +24,7 @@ using Magicodes.ExporterAndImporter.Excel;
using MassTransit; using MassTransit;
using MediatR; using MediatR;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@@ -37,7 +38,7 @@ using Microsoft.Net.Http.Headers;
using MiniExcelLibs; using MiniExcelLibs;
using Newtonsoft.Json; using Newtonsoft.Json;
using SharpCompress.Archives; using SharpCompress.Archives;
using SharpCompress.Common; using SkiaSharp;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
@@ -134,6 +135,32 @@ namespace IRaCIS.Core.API.Controllers
} }
} }
[Route("base")]
public virtual async Task FileUploadToOSSAsync(Func<string, Stream, Task<string>> toMemoryStreamFunc)
{
var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary).Value;
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
var section = await reader.ReadNextSectionAsync();
while (section != null)
{
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
if (hasContentDispositionHeader)
{
var fileName = contentDisposition.FileName.Value;
await toMemoryStreamFunc(fileName, section.Body);
}
section = await reader.ReadNextSectionAsync();
}
}
/// <summary> 流式上传 Dicom上传 </summary> /// <summary> 流式上传 Dicom上传 </summary>
@@ -280,9 +307,6 @@ namespace IRaCIS.Core.API.Controllers
if (!HttpContext.Request.HasFormContentType || if (!HttpContext.Request.HasFormContentType ||
!MediaTypeHeaderValue.TryParse(HttpContext.Request.ContentType, out var mediaTypeHeader) || !MediaTypeHeaderValue.TryParse(HttpContext.Request.ContentType, out var mediaTypeHeader) ||
string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value)) string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
@@ -756,11 +780,13 @@ namespace IRaCIS.Core.API.Controllers
[HttpPost("QCOperation/UploadVisitCheckExcel/{trialId:guid}")] [HttpPost("QCOperation/UploadVisitCheckExcel/{trialId:guid}")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//[Authorize(Policy = IRaCISPolicy.PM_APM)] //[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> UploadVisitCheckExcel(Guid trialId) public async Task<IResponseOutput> UploadVisitCheckExcel(Guid trialId, [FromServices] IOSSService oSSService)
{ {
var (serverFilePath, relativePath, fileName) = (string.Empty, string.Empty, string.Empty); var fileName = string.Empty;
await FileUploadAsync(async (realFileName) => var templateFileStream = new MemoryStream();
await FileUploadToOSSAsync(async (realFileName, fileStream) =>
{ {
fileName = realFileName; fileName = realFileName;
@@ -770,19 +796,16 @@ namespace IRaCIS.Core.API.Controllers
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_SupportedFormats")); throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_SupportedFormats"));
} }
(serverFilePath, relativePath) = FileStoreHelper.GetTrialCheckFilePath(_hostEnvironment, fileName, trialId); fileStream.CopyTo(templateFileStream);
templateFileStream.Seek(0, SeekOrigin.Begin);
await _repository.AddAsync(new UserUploadFile()
{
TrialId = trialId,
CreateTime = DateTime.Now,
FileName = fileName,
FilePath = relativePath,
RelativePath = relativePath,
CreateUserId = _userInfo.Id
});
return serverFilePath; var ossRelativePath = oSSService.UploadToOSS(fileStream, "InspectionUpload/Check", $"{Guid.NewGuid()}_" + realFileName);
await _repository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId });
return ossRelativePath;
}); });
@@ -814,7 +837,7 @@ namespace IRaCIS.Core.API.Controllers
{ {
var Importer = new ExcelImporter(); var Importer = new ExcelImporter();
var import = await Importer.Import<CheckViewModel>(System.IO.File.OpenRead(serverFilePath)); var import = await Importer.Import<CheckViewModel>(templateFileStream);
if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString()); if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
@@ -829,7 +852,7 @@ namespace IRaCIS.Core.API.Controllers
#region MiniExcel读取 xlsx Magicodes验证数据 #region MiniExcel读取 xlsx Magicodes验证数据
//因为csv 需要加配置文件 不然都是null //因为csv 需要加配置文件 不然都是null
etcCheckList = MiniExcel.Query<CheckViewModel>(serverFilePath, null, configuration: new MiniExcelLibs.Csv.CsvConfiguration() etcCheckList = MiniExcel.Query<CheckViewModel>(templateFileStream, null, configuration: new MiniExcelLibs.Csv.CsvConfiguration()
{ {
StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312")) StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312"))
}).ToList(); }).ToList();
@@ -874,35 +897,35 @@ namespace IRaCIS.Core.API.Controllers
else else
{ {
//为了支持 xls 引入新的组件库 //为了支持 xls 引入新的组件库
using (var stream = System.IO.File.Open(serverFilePath, FileMode.Open, FileAccess.Read)) //using (var stream = System.IO.File.Open(templateFileStream, FileMode.Open, FileAccess.Read))
//{
// Auto-detect format, supports:
// - Binary Excel files (2.0-2003 format; *.xls)
// - OpenXml Excel files (2007 format; *.xlsx, *.xlsb)
using (var reader = ExcelReaderFactory.CreateReader(templateFileStream))
{ {
// Auto-detect format, supports:
// - Binary Excel files (2.0-2003 format; *.xls) // 2. Use the AsDataSet extension method
// - OpenXml Excel files (2007 format; *.xlsx, *.xlsb) var dateset = reader.AsDataSet();
using (var reader = ExcelReaderFactory.CreateReader(stream))
foreach (DataRow col in dateset.Tables[0].Rows)
{ {
// 2. Use the AsDataSet extension method etcCheckList.Add(new CheckViewModel()
var dateset = reader.AsDataSet();
foreach (DataRow col in dateset.Tables[0].Rows)
{ {
SiteCode = col[0].ToString(),
etcCheckList.Add(new CheckViewModel() SubjectCode = col[1].ToString(),
{ VisitName = col[2].ToString(),
SiteCode = col[0].ToString(), StudyDate = col[3].ToString(),
SubjectCode = col[1].ToString(), Modality = col[4].ToString(),
VisitName = col[2].ToString(), });
StudyDate = col[3].ToString(),
Modality = col[4].ToString(),
});
}
etcCheckList.Remove(etcCheckList[0]);
// The result of each spreadsheet is in result.Tables
} }
etcCheckList.Remove(etcCheckList[0]);
// The result of each spreadsheet is in result.Tables
} }
} }
if (etcCheckList == null || etcCheckList.Count == 0) if (etcCheckList == null || etcCheckList.Count == 0)
@@ -940,7 +963,6 @@ namespace IRaCIS.Core.API.Controllers
return ResponseOutput.Ok(); return ResponseOutput.Ok();
} }
} }
@@ -948,6 +970,8 @@ namespace IRaCIS.Core.API.Controllers
#region #region
[ApiExplorerSettings(GroupName = "Common")] [ApiExplorerSettings(GroupName = "Common")]
@@ -980,30 +1004,38 @@ namespace IRaCIS.Core.API.Controllers
[DisableFormValueModelBinding] [DisableFormValueModelBinding]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> UploadTrialSiteSurveyUser(Guid trialId, string baseUrl, string routeUrl, public async Task<IResponseOutput> UploadTrialSiteSurveyUser(Guid trialId, string baseUrl, string routeUrl,
[FromServices] IRepository<TrialSite> _trialSiteRepository, [FromServices] IRepository<TrialSite> _trialSiteRepository,
[FromServices] IRepository<UserType> _usertypeRepository, [FromServices] IRepository<UserType> _usertypeRepository,
[FromServices] ITrialSiteSurveyService _trialSiteSurveyService) [FromServices] ITrialSiteSurveyService _trialSiteSurveyService,
[FromServices] IOSSService oSSService,
[FromServices] IRepository<InspectionFile> _inspectionFileRepository)
{ {
var (serverFilePath, relativePath, fileName) = (string.Empty, string.Empty, string.Empty); var templateFileStream = new MemoryStream();
await FileUploadAsync(async (realFileName) =>
{
fileName = realFileName;
if (!fileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase))
await FileUploadToOSSAsync(async (realFileName, fileStream) =>
{
await fileStream.CopyToAsync(templateFileStream);
templateFileStream.Seek(0, SeekOrigin.Begin);
if (!realFileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase))
{ {
// 请用提供格式的模板excel上传需要处理的数据 // 请用提供格式的模板excel上传需要处理的数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_TemplateUploadData")); throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_TemplateUploadData"));
} }
(serverFilePath, relativePath) = FileStoreHelper.GetOtherFileUploadPath(_hostEnvironment, StaticData.Folder.TempFile, fileName); var ossRelativePath = oSSService.UploadToOSS(fileStream, "InspectionUpload/SiteSurvey", $"{Guid.NewGuid()}_"+ realFileName);
//FileStoreHelper.UploadOOS(serverFilePath, "testc/test", true); await _inspectionFileRepository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId });
return ossRelativePath;
return serverFilePath;
}); });
//去掉空白行 //去掉空白行
var excelList = MiniExcel.Query<SiteSurveyUserImportDto>(serverFilePath).ToList() var excelList = MiniExcel.Query<SiteSurveyUserImportDto>(templateFileStream,excelType:ExcelType.XLSX).ToList()
.Where(t => !(string.IsNullOrWhiteSpace(t.TrialSiteCode) && string.IsNullOrWhiteSpace(t.FirstName) && string.IsNullOrWhiteSpace(t.LastName) && string.IsNullOrWhiteSpace(t.Email) .Where(t => !(string.IsNullOrWhiteSpace(t.TrialSiteCode) && string.IsNullOrWhiteSpace(t.FirstName) && string.IsNullOrWhiteSpace(t.LastName) && string.IsNullOrWhiteSpace(t.Email)
&& string.IsNullOrWhiteSpace(t.Phone) && string.IsNullOrWhiteSpace(t.UserTypeStr) && string.IsNullOrWhiteSpace(t.OrganizationName))).ToList(); && string.IsNullOrWhiteSpace(t.Phone) && string.IsNullOrWhiteSpace(t.UserTypeStr) && string.IsNullOrWhiteSpace(t.OrganizationName))).ToList();
@@ -1033,7 +1065,7 @@ namespace IRaCIS.Core.API.Controllers
//有邮箱不符合邮箱格式,请核查Excel数据 //有邮箱不符合邮箱格式,请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidEmail")); throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidEmail"));
} }
var generateUserTypeList = new List<string>() { "CRC", "SR", "CRA" }; var generateUserTypeList = new List<string>() { "CRC", "CRA","SR" };
if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper()))) if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper())))
{ {
@@ -1083,122 +1115,18 @@ namespace IRaCIS.Core.API.Controllers
} }
#region /// <summary> 通用文件下载 </summary>
[AllowAnonymous]
[HttpGet("CommonDocument/DownloadCommonDoc")]
public async Task<IActionResult> DownloadCommonFile(string code, [FromServices] IRepository<CommonDocument> _commonDocumentRepository)
{
var (filePath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);
///// <summary> 缩略图 </summary> new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(filePath), out var contentType);
//[AllowAnonymous]
//[HttpGet("Common/LocalFilePreview")]
//public async Task<FileContentResult> LocalFilePreview(string relativePath)
//{
// var _fileStorePath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, relativePath);
// var storePreviewPath = _fileStorePath + ".preview.jpeg";
// if (!System.IO.File.Exists(storePreviewPath))
// {
// ImageHelper.ResizeSave(_fileStorePath, storePreviewPath);
// }
// return new FileContentResult(await System.IO.File.ReadAllBytesAsync(storePreviewPath), "image/jpeg");
//}
///// <summary> 通用文件下载 </summary>
//[AllowAnonymous]
//[HttpGet("CommonDocument/DownloadCommonDoc")]
//public async Task<IActionResult> DownloadCommonFile(string code, [FromServices] IRepository<CommonDocument> _commonDocumentRepository)
//{
// var (filePath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);
// new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(filePath), out var contentType);
// return File(System.IO.File.OpenRead(filePath), contentType ?? "application/octet-stream", fileName);
//}
///// <summary>
///// 下载项目临床数据文件
///// </summary>
///// <param name="clinicalDataTrialSetId"></param>
///// <param name="_clinicalDataTrialSetRepository"></param>
///// <returns></returns>
//[AllowAnonymous]
//[HttpGet("CommonDocument/DownloadTrialClinicalFile")]
//public async Task<IActionResult> DownloadTrialClinicalFile(Guid clinicalDataTrialSetId, [FromServices] IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository)
//{
// var (filePath, fileName) = await FileStoreHelper.GetTrialClinicalPathAsync(_hostEnvironment, _clinicalDataTrialSetRepository, clinicalDataTrialSetId);
// new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(filePath), out var contentType);
// return File(System.IO.File.OpenRead(filePath), contentType ?? "application/octet-stream", fileName);
//}
///// <summary>
///// 下载系统临床数据文件
///// </summary>
///// <param name="clinicalDataSystemSetId"></param>
///// <param name="_clinicalDataSystemSetRepository"></param>
///// <returns></returns>
//[AllowAnonymous]
//[HttpGet("CommonDocument/DownloadSystemClinicalFile")]
//public async Task<IActionResult> DownloadSystemClinicalFile(Guid clinicalDataSystemSetId, [FromServices] IRepository<ClinicalDataSystemSet> _clinicalDataSystemSetRepository)
//{
// var (filePath, fileName) = await FileStoreHelper.GetSystemClinicalPathAsync(_hostEnvironment, _clinicalDataSystemSetRepository, clinicalDataSystemSetId);
// new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(filePath), out var contentType);
// return File(System.IO.File.OpenRead(filePath), contentType ?? "application/octet-stream", fileName);
//}
///// <summary>
/////上传项目签名文档
///// </summary>
///// <param name="trialId"></param>
///// <returns></returns>
//[HttpPost("TrialDocument/UploadTrialDoc/{trialId:guid}")]
//[DisableRequestSizeLimit]
//[DisableFormValueModelBinding]
//public async Task<IResponseOutput> UploadTrialDoc(Guid trialId)
//{
// return await SingleFileUploadAsync((fileName) => FileStoreHelper.GetTrialSignDocPath(_hostEnvironment, trialId, fileName));
//}
///// <summary>
///// 上传系统签名文档
///// </summary>
///// <returns></returns>
//[HttpPost("TrialDocument/UploadSystemDoc")]
//[DisableRequestSizeLimit]
//[DisableFormValueModelBinding]
//public async Task<IResponseOutput> UploadSysTemDoc()
//{
// return await SingleFileUploadAsync((fileName) => FileStoreHelper.GetSystemSignDocPath(_hostEnvironment, fileName));
//}
///// <summary>
///// 上传系统通知文档
///// </summary>
///// <returns></returns>
//[HttpPost("SystemNotice/UploadSystemNoticeDoc")]
//[DisableRequestSizeLimit]
//[DisableFormValueModelBinding]
//public async Task<IResponseOutput> UploadSystemNoticeDoc()
//{
// return await SingleFileUploadAsync((fileName) => FileStoreHelper.GetSystemNoticePath(_hostEnvironment, fileName));
//}
#endregion
return File(System.IO.File.OpenRead(filePath), contentType ?? "application/octet-stream", fileName);
}
/// <summary> /// <summary>
/// 上传通用文档 比如一致性核查的 比如导出的excel 模板 /// 上传通用文档 比如一致性核查的 比如导出的excel 模板
-26
View File
@@ -1,26 +0,0 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["IRaCIS.Core.API/IRaCIS.Core.API.csproj", "IRaCIS.Core.API/"]
COPY ["IRaCIS.Core.Application/IRaCIS.Core.Application.csproj", "IRaCIS.Core.Application/"]
COPY ["IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj", "IRaCIS.Core.Infra.EFCore/"]
COPY ["IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj", "IRaCIS.Core.Domain/"]
COPY ["IRaCIS.Core.Domain.Share/IRaCIS.Core.Domain.Share.csproj", "IRaCIS.Core.Domain.Share/"]
COPY ["IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj", "IRaCIS.Core.Infrastructure/"]
RUN dotnet restore "IRaCIS.Core.API/IRaCIS.Core.API.csproj"
COPY . .
WORKDIR "/src/IRaCIS.Core.API"
RUN dotnet build "IRaCIS.Core.API.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "IRaCIS.Core.API.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "IRaCIS.Core.API.dll"]
+16 -16
View File
@@ -1,16 +1,16 @@
// 使用的是proto3版本 // 使用的是proto3版本
syntax = "proto3"; syntax = "proto3";
// 定义命名空间,后续生成代码时就会生成对应的命名空间 // 定义命名空间,后续生成代码时就会生成对应的命名空间
option csharp_namespace = "gRPC.ZHiZHUN.AuthServer.protos"; option csharp_namespace = "gRPC.ZHiZHUN.AuthServer.protos";
/* /*
每一句需要用分号结尾 每一句需要用分号结尾
message 用来定义请求和返回数据格式 message 用来定义请求和返回数据格式
tag message后面的值数字代表是字段的标识(tag),不是赋值, tag message后面的值数字代表是字段的标识(tag),不是赋值,
*/ */
// 新增用户时需要传递数据消息, 可理解为一个类 // 新增用户时需要传递数据消息, 可理解为一个类
message GetTokenReuqest{ message GetTokenReuqest{
string id=1; string id=1;
string userName=2; string userName=2;
@@ -22,48 +22,48 @@ message GetTokenReuqest{
} }
// 新增时返回的消息格式 // 新增时返回的消息格式
message GetTokenResponse { message GetTokenResponse {
int32 code=1; int32 code=1;
string token =2; string token =2;
} }
// service 用标识定义服务的,里面写对应的方法 // service 用标识定义服务的,里面写对应的方法
service TokenGrpcService{ service TokenGrpcService{
// 获取token // 获取token
rpc GetUserToken(GetTokenReuqest) returns (GetTokenResponse); rpc GetUserToken(GetTokenReuqest) returns (GetTokenResponse);
} }
/* /*
// 新增用户时需要传递数据消息, 可理解为一个类 // 新增用户时需要传递数据消息, 可理解为一个类
message AddUserReuqest{ message AddUserReuqest{
string name=1; string name=1;
int32 age=2; int32 age=2;
bool isBoy=3; bool isBoy=3;
} }
// 新增时返回的消息格式 // 新增时返回的消息格式
message ResultResponse { message ResultResponse {
int32 code=1; int32 code=1;
string msg =2; string msg =2;
} }
//传递的查询条件信息格式,可理解为平时传入的查询条件对象 //传递的查询条件信息格式,可理解为平时传入的查询条件对象
message QueryUserReuqest{ message QueryUserReuqest{
string name=1; string name=1;
} }
//查询返回的用户信息格式,可理解为返回的类 //查询返回的用户信息格式,可理解为返回的类
message UserInfoResponse { message UserInfoResponse {
string name=1; string name=1;
int32 age=2; int32 age=2;
string gender=3; string gender=3;
} }
// service 用标识定义服务的,里面写对应的方法 // service 用标识定义服务的,里面写对应的方法
service UserService{ service UserService{
// 新增用户 // 新增用户
rpc AddUser(AddUserReuqest) returns (ResultResponse); rpc AddUser(AddUserReuqest) returns (ResultResponse);
// 查询用户 // 查询用户
rpc GetAllUser(QueryUserReuqest) returns (UserInfoResponse); rpc GetAllUser(QueryUserReuqest) returns (UserInfoResponse);
} }
*/ */
+4 -1
View File
@@ -219,13 +219,16 @@
<param name="_noneDicomStudyRepository"></param> <param name="_noneDicomStudyRepository"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadVisitCheckExcel(System.Guid)"> <member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadVisitCheckExcel(System.Guid,IRaCIS.Core.Application.Helper.IOSSService)">
<summary> <summary>
一致性核查 excel上传 支持三种格式 一致性核查 excel上传 支持三种格式
</summary> </summary>
<param name="trialId"></param> <param name="trialId"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.DownloadCommonFile(System.String,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument})">
<summary> 通用文件下载 </summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.UploadCommonDoc"> <member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.UploadCommonDoc">
<summary> <summary>
上传通用文档 比如一致性核查的 比如导出的excel 模板 上传通用文档 比如一致性核查的 比如导出的excel 模板
+27 -15
View File
@@ -1,4 +1,4 @@
using System; using System;
using Autofac.Extensions.DependencyInjection; using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
@@ -13,8 +13,7 @@ using System.IO;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Application.Services.BackGroundJob; using System.Runtime.InteropServices;
using Hangfire;
namespace IRaCIS.Core.API namespace IRaCIS.Core.API
{ {
@@ -25,7 +24,7 @@ namespace IRaCIS.Core.API
{ {
try try
{ {
//以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数) //以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数)
var config = new ConfigurationBuilder() var config = new ConfigurationBuilder()
.AddEnvironmentVariables() .AddEnvironmentVariables()
.Build(); .Build();
@@ -41,11 +40,11 @@ namespace IRaCIS.Core.API
: "Development"; : "Development";
} }
//Dicom 浏览 //Dicom 浏览
//ImageManager.SetImplementation(WinFormsImageManager.Instance); //ImageManager.SetImplementation(WinFormsImageManager.Instance);
var host = CreateHostBuilder(args) var host = CreateHostBuilder(args)
.UseEnvironment(enviromentName) //命令行传入环境 .UseEnvironment(enviromentName) //命令行传入环境
.ConfigureAppConfiguration((hostContext, config) => .ConfigureAppConfiguration((hostContext, config) =>
{ {
@@ -58,17 +57,30 @@ namespace IRaCIS.Core.API
//// Serilog //// Serilog
SerilogExtension.AddSerilogSetup(enviromentName, host.Services); SerilogExtension.AddSerilogSetup(enviromentName, host.Services);
Log.Logger.Warning($"当前环境:{enviromentName}");
Log.Logger.Warning($"当前环境:{enviromentName}");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Log.Logger.Warning($"当前部署平台环境:windows");
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Log.Logger.Warning($"当前部署平台环境:linux");
}
else
{
Log.Logger.Warning($"当前部署平台环境:OSX or FreeBSD");
}
NewId.SetProcessIdProvider(new CurrentProcessIdProvider()); NewId.SetProcessIdProvider(new CurrentProcessIdProvider());
////缓存项目的状态 匿名化数据
//await InitCache(host);
host.Run(); host.Run();
} }
catch (Exception e) catch (Exception e)
{ {
@@ -85,13 +97,13 @@ namespace IRaCIS.Core.API
{ {
webBuilder.ConfigureKestrel((context, options) => webBuilder.ConfigureKestrel((context, options) =>
{ {
//设置应用服务器Kestrel请求体最大为1GB // if don't set default value is: 30 MB //设置应用服务器Kestrel请求体最大为1GB // if don't set default value is: 30 MB
options.Limits.MaxRequestBodySize = long.MaxValue; options.Limits.MaxRequestBodySize = long.MaxValue;
options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(30); options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(30);
options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(20); options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(20);
}); });
//webBuilder.UseSerilog();//在宿主机启动的时候配置serilog,与微软ILogger进行整合 //webBuilder.UseSerilog();//在宿主机启动的时候配置serilog,与微软ILogger进行整合
webBuilder.UseStartup<Startup>(); webBuilder.UseStartup<Startup>();
}).UseSerilog() }).UseSerilog()
.UseServiceProviderFactory(new AutofacServiceProviderFactory()); .UseServiceProviderFactory(new AutofacServiceProviderFactory());
@@ -101,14 +113,14 @@ namespace IRaCIS.Core.API
{ {
var _repository = host.Services.GetService(typeof(IRepository)) as IRepository; var _repository = host.Services.GetService(typeof(IRepository)) as IRepository;
//初始化 国际化数据,并且监测国际化文件变更 //初始化 国际化数据,并且监测国际化文件变更
//await InternationalizationHelper.InitInternationlizationDataAndWatchJsonFileAsync(_repository); //await InternationalizationHelper.InitInternationlizationDataAndWatchJsonFileAsync(_repository);
} }
} }
} }
+7 -13
View File
@@ -1,11 +1,13 @@
{ {
"$schema": "http://json.schemastore.org/launchsettings.json", "$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": { "profiles": {
"Docker": { "Test_Study": {
"commandName": "Docker", "commandName": "Project",
"launchBrowser": true, "launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", "environmentVariables": {
"publishAllPorts": true "ASPNETCORE_ENVIRONMENT": "Test_Study"
},
"applicationUrl": "http://localhost:6100"
}, },
"Uat_Study": { "Uat_Study": {
"commandName": "Project", "commandName": "Project",
@@ -14,14 +16,6 @@
"ASPNETCORE_ENVIRONMENT": "Uat_Study" "ASPNETCORE_ENVIRONMENT": "Uat_Study"
}, },
"applicationUrl": "http://localhost:6100" "applicationUrl": "http://localhost:6100"
},
"Test_Study": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Test_Study"
},
"applicationUrl": "http://localhost:6100"
} }
} }
} }
+16 -16
View File
@@ -1,16 +1,16 @@
// 使用的是proto3版本 // 使用的是proto3版本
syntax = "proto3"; syntax = "proto3";
// 定义命名空间,后续生成代码时就会生成对应的命名空间 // 定义命名空间,后续生成代码时就会生成对应的命名空间
option csharp_namespace = "gRPC.ZHiZHUN.AuthServer.protos"; option csharp_namespace = "gRPC.ZHiZHUN.AuthServer.protos";
/* /*
每一句需要用分号结尾 每一句需要用分号结尾
message 用来定义请求和返回数据格式 message 用来定义请求和返回数据格式
tag message后面的值数字代表是字段的标识(tag),不是赋值, tag message后面的值数字代表是字段的标识(tag),不是赋值,
*/ */
// 新增用户时需要传递数据消息, 可理解为一个类 // 新增用户时需要传递数据消息, 可理解为一个类
message GetTokenReuqest{ message GetTokenReuqest{
string id=1; string id=1;
string userName=2; string userName=2;
@@ -22,48 +22,48 @@ message GetTokenReuqest{
} }
// 新增时返回的消息格式 // 新增时返回的消息格式
message GetTokenResponse { message GetTokenResponse {
int32 code=1; int32 code=1;
string token =2; string token =2;
} }
// service 用标识定义服务的,里面写对应的方法 // service 用标识定义服务的,里面写对应的方法
service TokenGrpcService{ service TokenGrpcService{
// 获取token // 获取token
rpc GetUserToken(GetTokenReuqest) returns (GetTokenResponse); rpc GetUserToken(GetTokenReuqest) returns (GetTokenResponse);
} }
/* /*
// 新增用户时需要传递数据消息, 可理解为一个类 // 新增用户时需要传递数据消息, 可理解为一个类
message AddUserReuqest{ message AddUserReuqest{
string name=1; string name=1;
int32 age=2; int32 age=2;
bool isBoy=3; bool isBoy=3;
} }
// 新增时返回的消息格式 // 新增时返回的消息格式
message ResultResponse { message ResultResponse {
int32 code=1; int32 code=1;
string msg =2; string msg =2;
} }
//传递的查询条件信息格式,可理解为平时传入的查询条件对象 //传递的查询条件信息格式,可理解为平时传入的查询条件对象
message QueryUserReuqest{ message QueryUserReuqest{
string name=1; string name=1;
} }
//查询返回的用户信息格式,可理解为返回的类 //查询返回的用户信息格式,可理解为返回的类
message UserInfoResponse { message UserInfoResponse {
string name=1; string name=1;
int32 age=2; int32 age=2;
string gender=3; string gender=3;
} }
// service 用标识定义服务的,里面写对应的方法 // service 用标识定义服务的,里面写对应的方法
service UserService{ service UserService{
// 新增用户 // 新增用户
rpc AddUser(AddUserReuqest) returns (ResultResponse); rpc AddUser(AddUserReuqest) returns (ResultResponse);
// 查询用户 // 查询用户
rpc GetAllUser(QueryUserReuqest) returns (UserInfoResponse); rpc GetAllUser(QueryUserReuqest) returns (UserInfoResponse);
} }
*/ */
+38 -33
View File
@@ -1,4 +1,4 @@
using Autofac; using Autofac;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
@@ -53,7 +53,7 @@ namespace IRaCIS.Core.API
containerBuilder.RegisterModule<AutofacModuleSetup>(); containerBuilder.RegisterModule<AutofacModuleSetup>();
#region Test #region Test
//containerBuilder.RegisterType<ClinicalDataService>().PropertiesAutowired().InstancePerLifetimeScope();//注册仓储 //containerBuilder.RegisterType<ClinicalDataService>().PropertiesAutowired().InstancePerLifetimeScope();//注册仓储
//var container = containerBuilder.Build(); //var container = containerBuilder.Build();
@@ -75,10 +75,12 @@ namespace IRaCIS.Core.API
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
//本地化 //健康检查
services.AddHealthChecks();
//本地化
services.AddJsonLocalization(options => options.ResourcesPath = "Resources"); services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim() // 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
services.AddControllers(options => services.AddControllers(options =>
{ {
//options.Filters.Add<LogActionFilter>(); //options.Filters.Add<LogActionFilter>();
@@ -93,69 +95,70 @@ namespace IRaCIS.Core.API
}) })
.AddNewtonsoftJsonSetup(); // NewtonsoftJson 序列化 处理 .AddNewtonsoftJsonSetup(); // NewtonsoftJson 序列化 处理
services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig")); services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig"));
services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig")); services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
services.AddDynamicWebApiSetup(); services.AddDynamicWebApiSetup();
//AutoMapper //AutoMapper
services.AddAutoMapperSetup(); services.AddAutoMapperSetup();
//EF ORM QueryWithNoLock //EF ORM QueryWithNoLock
services.AddEFSetup(_configuration); services.AddEFSetup(_configuration);
//Http 响应压缩 //Http 响应压缩
services.AddResponseCompressionSetup(); services.AddResponseCompressionSetup();
//Swagger Api 文档 //Swagger Api 文档
services.AddSwaggerSetup(); services.AddSwaggerSetup();
//JWT Token 验证 //JWT Token 验证
services.AddJWTAuthSetup(_configuration); services.AddJWTAuthSetup(_configuration);
// MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系 // MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系
services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<ConsistencyVerificationHandler>()); services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<ConsistencyVerificationHandler>());
// EasyCaching 缓存 // EasyCaching 缓存
services.AddEasyCachingSetup(_configuration); services.AddEasyCachingSetup(_configuration);
//services.AddDistributedMemoryCache(); //services.AddDistributedMemoryCache();
// hangfire 定时任务框架 有界面,更友好~ // hangfire 定时任务框架 有界面,更友好~
services.AddhangfireSetup(_configuration); services.AddhangfireSetup(_configuration);
// QuartZ 定时任务框架 使用了hangfire 暂时不用,后续需要可以打开,已经配好 // QuartZ 定时任务框架 使用了hangfire 暂时不用,后续需要可以打开,已经配好
services.AddQuartZSetup(_configuration); services.AddQuartZSetup(_configuration);
// 保护上传文件 // 保护上传文件
//services.AddStaticFileAuthorizationSetup(); //services.AddStaticFileAuthorizationSetup();
////HttpReports 暂时废弃 ////HttpReports 暂时废弃
//services.AddHttpReports().AddHttpTransport(); //services.AddHttpReports().AddHttpTransport();
//Serilog 日志可视化 LogDashboard日志 //Serilog 日志可视化 LogDashboard日志
services.AddLogDashboardSetup(); services.AddLogDashboardSetup();
//上传限制 配置 //上传限制 配置
services.Configure<FormOptions>(options => services.Configure<FormOptions>(options =>
{ {
options.MultipartBodyLengthLimit = int.MaxValue; options.MultipartBodyLengthLimit = int.MaxValue;
options.ValueCountLimit = int.MaxValue; options.ValueCountLimit = int.MaxValue;
options.ValueLengthLimit = int.MaxValue; options.ValueLengthLimit = int.MaxValue;
}); });
//IP 限流 可设置白名单 或者黑名单 //IP 限流 可设置白名单 或者黑名单
//services.AddIpPolicyRateLimitSetup(_configuration); //services.AddIpPolicyRateLimitSetup(_configuration);
// 用户类型 策略授权 // 用户类型 策略授权
//services.AddAuthorizationPolicySetup(_configuration); //services.AddAuthorizationPolicySetup(_configuration);
services.AddJsonConfigSetup(_configuration); services.AddJsonConfigSetup(_configuration);
//转发头设置 获取真实IP //转发头设置 获取真实IP
services.Configure<ForwardedHeadersOptions>(options => services.Configure<ForwardedHeadersOptions>(options =>
{ {
options.ForwardedHeaders = options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
}); });
//Dicom影像渲染图片 跨平台 //Dicom影像渲染图片 跨平台
services.AddDicomSetup(); services.AddDicomSetup();
// 实时应用 // 实时应用
services.AddSignalR(); services.AddSignalR();
@@ -172,17 +175,17 @@ namespace IRaCIS.Core.API
{ {
//app.UsePathBase(PathString.FromUriComponent("/api")); //app.UsePathBase(PathString.FromUriComponent("/api"));
//本地化 //本地化
app.UseLocalization(); app.UseLocalization();
app.UseForwardedHeaders(); app.UseForwardedHeaders();
//响应压缩 //响应压缩
app.UseResponseCompression(); app.UseResponseCompression();
//app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()); //app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
//不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication. //不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles(); app.UseStaticFiles();
@@ -192,10 +195,10 @@ namespace IRaCIS.Core.API
//hangfire //hangfire
app.UseHangfireConfig(env); app.UseHangfireConfig(env);
////暂时废弃 ////暂时废弃
//app.UseHttpReports(); //app.UseHttpReports();
////限流 中间件 ////限流 中间件
//app.UseIpRateLimiting(); //app.UseIpRateLimiting();
@@ -208,18 +211,18 @@ namespace IRaCIS.Core.API
{ {
//app.UseHsts(); //app.UseHsts();
} }
Console.WriteLine("当前环境: " + env.EnvironmentName); Console.WriteLine("当前环境: " + env.EnvironmentName);
//app.UseMiddleware<AuthMiddleware>(); //app.UseMiddleware<AuthMiddleware>();
// 特殊异常处理 比如 404 // 特殊异常处理 比如 404
app.UseStatusCodePagesWithReExecute("/Error/{0}"); app.UseStatusCodePagesWithReExecute("/Error/{0}");
SwaggerSetup.Configure(app, env); SwaggerSetup.Configure(app, env);
////serilog 记录请求的用户信息 ////serilog 记录请求的用户信息
app.UseSerilogConfig(env); app.UseSerilogConfig(env);
app.UseRouting(); app.UseRouting();
@@ -234,7 +237,7 @@ namespace IRaCIS.Core.API
//app.UseJwtBearerQueryString(); //app.UseJwtBearerQueryString();
app.UseAuthorization(); app.UseAuthorization();
////文件伺服 必须带Token 访问 ////文件伺服 必须带Token 访问
////app.UseIRacisHostStaticFileStore(env); ////app.UseIRacisHostStaticFileStore(env);
app.UseEndpoints(endpoints => app.UseEndpoints(endpoints =>
@@ -242,13 +245,15 @@ namespace IRaCIS.Core.API
endpoints.MapControllers(); endpoints.MapControllers();
endpoints.MapHub<UploadHub>("/UploadHub"); endpoints.MapHub<UploadHub>("/UploadHub");
endpoints.MapHealthChecks("/health");
}); });
var hangfireJobService = app.ApplicationServices.GetRequiredService<IIRaCISHangfireJob>(); var hangfireJobService = app.ApplicationServices.GetRequiredService<IIRaCISHangfireJob>();
await hangfireJobService.InitHangfireJobTaskAsync(); await hangfireJobService.InitHangfireJobTaskAsync();
//有的时候每调用 //有的时候每调用
//HangfireJobHelper.NotImmediatelyOnceOnlyJob<IIRaCISHangfireJob>(t => t.InitHangfireJobTaskAsync(),TimeSpan.FromSeconds(1)); //HangfireJobHelper.NotImmediatelyOnceOnlyJob<IIRaCISHangfireJob>(t => t.InitHangfireJobTaskAsync(),TimeSpan.FromSeconds(1));
@@ -1,7 +1,6 @@
using Autofac; using Autofac;
using Autofac.Extras.DynamicProxy; using Autofac.Extras.DynamicProxy;
using IRaCIS.Core.Application; using IRaCIS.Core.Application;
using IRaCIS.Core.Application.AOP;
using IRaCIS.Core.Application.BackGroundJob; using IRaCIS.Core.Application.BackGroundJob;
using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Infra.EFCore;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
+23 -10
View File
@@ -6,19 +6,32 @@
"Microsoft.Hosting.Lifetime": "Information" "Microsoft.Hosting.Lifetime": "Information"
} }
}, },
"AliyunOSS": { "ObjectStoreService": {
"regionId": "cn-shanghai", "ObjectStoreUse": "AliyunOSS",
"region": "oss-cn-shanghai", "AliyunOSS": {
"endpoint": "https://oss-cn-shanghai.aliyuncs.com", "regionId": "cn-shanghai",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "endpoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"bucketName": "zy-sir-store", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
"viewEndpoint": "https://zy-sir-cache.oss-cn-shanghai.aliyuncs.com" "bucketName": "zy-sir-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-sir-cache.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
},
"MinIO": {
"endpoint": "http://192.168.3.68",
"port": "8001",
"useSSL": false,
"accessKey": "IDFkwEpWej0b4DtiuThL",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
"bucketName": "test"
}
}, },
"ConnectionStrings": { "ConnectionStrings": {
"RemoteNew": "Server=47.117.165.18,1434;Database=Prod_Study;User ID=sa;Password=WHxckj@2019;TrustServerCertificate=true", "RemoteNew": "Server=101.132.193.237,1434;Database=Prod_Study;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=47.117.165.18,1434;Database=Prod_Study.hangfire;User ID=sa;Password=WHxckj@2019;TrustServerCertificate=true" "Hangfire": "Server=101.132.193.237,1434;Database=Prod_Study_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
}, },
"BasicSystemConfig": { "BasicSystemConfig": {
+24 -10
View File
@@ -6,18 +6,32 @@
"Microsoft.Hosting.Lifetime": "Information" "Microsoft.Hosting.Lifetime": "Information"
} }
}, },
"AliyunOSS": { "ObjectStoreService": {
"regionId": "cn-shanghai", "ObjectStoreUse": "AliyunOSS",
"region": "oss-cn-shanghai", "AliyunOSS": {
"endpoint": "https://oss-cn-shanghai.aliyuncs.com", "regionId": "cn-shanghai",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "endpoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"bucketName": "zy-sir-test-store", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
"viewEndpoint": "https://zy-sir-test-store.oss-cn-shanghai.aliyuncs.com" "bucketName": "zy-sir-test-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-sir-test-store.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
},
"MinIO": {
"endpoint": "http://192.168.3.68",
"port": "8001",
"useSSL": false,
"accessKey": "IDFkwEpWej0b4DtiuThL",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
"bucketName": "test"
}
}, },
"ConnectionStrings": { "ConnectionStrings": {
"RemoteNew": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=Test.Study;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true", "RemoteNew": "Server=123.56.94.154,1435;Database=Test_Study;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=Test.Study.hangfire;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true" "Hangfire": "Server=123.56.94.154,1435;Database=Test_Study_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
}, },
"BasicSystemConfig": { "BasicSystemConfig": {
+21 -8
View File
@@ -6,14 +6,27 @@
"Microsoft.Hosting.Lifetime": "Information" "Microsoft.Hosting.Lifetime": "Information"
} }
}, },
"AliyunOSS": { "ObjectStoreService": {
"regionId": "cn-shanghai", "ObjectStoreUse": "AliyunOSS",
"region": "oss-cn-shanghai", "AliyunOSS": {
"endpoint": "https://oss-cn-shanghai.aliyuncs.com", "regionId": "cn-shanghai",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "endpoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"bucketName": "zy-sir-uat-store", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
"viewEndpoint": "https://zy-sir-uat-store.oss-cn-shanghai.aliyuncs.com" "bucketName": "zy-sir-uat-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-sir-uat-store.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
},
"MinIO": {
"endpoint": "http://192.168.3.68",
"port": "8001",
"useSSL": false,
"accessKey": "IDFkwEpWej0b4DtiuThL",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
"bucketName": "test"
}
}, },
"ConnectionStrings": { "ConnectionStrings": {
"RemoteNew": "Server=47.117.164.182,1434;Database=Uat.Study;User ID=sa;Password=xc@123456;TrustServerCertificate=true", "RemoteNew": "Server=47.117.164.182,1434;Database=Uat.Study;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
Binary file not shown.
@@ -34,7 +34,10 @@
角色: {5} 角色: {5}
</div> </div>
<div> <div>
系统登录地址:{6} 系统登录地址:
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
点击跳转
</a>
</div> </div>
</div> </div>
@@ -34,7 +34,10 @@
Role: {5} Role: {5}
</div> </div>
<div> <div>
Login URL: {6} Login URL:
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
click redirect
</a>
</div> </div>
</div> </div>
@@ -34,7 +34,10 @@
角色: {5} 角色: {5}
</div> </div>
<div> <div>
系统登录地址:{6} 系统登录地址:
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
点击跳转
</a>
</div> </div>
</div> </div>
@@ -34,7 +34,10 @@
Role: {5} Role: {5}
</div> </div>
<div> <div>
Login URL: {6} Login URL:
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
click redirect
</a>
</div> </div>
</div> </div>
@@ -1,97 +0,0 @@
using Castle.DynamicProxy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.AOP
{
public abstract class AsyncInterceptorBase : IInterceptor
{
public AsyncInterceptorBase()
{
}
public void Intercept(IInvocation invocation)
{
BeforeProceed(invocation);
invocation.Proceed();
if (IsAsyncMethod(invocation.MethodInvocationTarget))
{
invocation.ReturnValue = InterceptAsync((dynamic)invocation.ReturnValue, invocation);
}
else
{
AfterProceedSync(invocation);
}
}
private bool CheckMethodReturnTypeIsTaskType(MethodInfo method)
{
var methodReturnType = method.ReturnType;
if (methodReturnType.IsGenericType)
{
if (methodReturnType.GetGenericTypeDefinition() == typeof(Task<>) ||
methodReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>))
return true;
}
else
{
if (methodReturnType == typeof(Task) ||
methodReturnType == typeof(ValueTask))
return true;
}
return false;
}
private bool IsAsyncMethod(MethodInfo method)
{
bool isDefAsync = Attribute.IsDefined(method, typeof(AsyncStateMachineAttribute), false);
bool isTaskType = CheckMethodReturnTypeIsTaskType(method);
bool isAsync = isDefAsync && isTaskType;
return isAsync;
}
protected object ProceedAsyncResult { get; set; }
private async Task InterceptAsync(Task task, IInvocation invocation)
{
await task.ConfigureAwait(false);
await AfterProceedAsync(invocation, false);
}
private async Task<TResult> InterceptAsync<TResult>(Task<TResult> task, IInvocation invocation)
{
ProceedAsyncResult = await task.ConfigureAwait(false);
await AfterProceedAsync(invocation, true);
return (TResult)ProceedAsyncResult;
}
private async ValueTask InterceptAsync(ValueTask task, IInvocation invocation)
{
await task.ConfigureAwait(false);
await AfterProceedAsync(invocation, false);
}
private async ValueTask<TResult> InterceptAsync<TResult>(ValueTask<TResult> task, IInvocation invocation)
{
ProceedAsyncResult = await task.ConfigureAwait(false);
await AfterProceedAsync(invocation, true);
return (TResult)ProceedAsyncResult;
}
protected virtual void BeforeProceed(IInvocation invocation) { }
protected virtual void AfterProceedSync(IInvocation invocation) { }
protected virtual Task AfterProceedAsync(IInvocation invocation, bool hasAsynResult)
{
return Task.CompletedTask;
}
}
}
-499
View File
@@ -1,499 +0,0 @@
//using System;
//using Castle.DynamicProxy;
//using IRaCIS.Core.Application.Contracts.Dicom.DTO;
//using IRaCIS.Core.Infra.EFCore;
//using System.Linq;
//using IRaCIS.Core.Domain.Models;
//using IRaCIS.Core.Domain.Share;
//namespace IRaCIS.Core.API.Utility.AOP
//{
//#pragma warning disable
// public class QANoticeAOP : IInterceptor
// {
// private readonly IRepository<QANotice> _qaNoticeRepository;
// private readonly IRepository<DicomStudy> _studyRepository;
// private readonly IRepository<TrialUser> _userTrialRepository;
// private readonly IRepository<TrialSiteUser> _userTrialSiteRepository;
// private readonly IUserInfo _userInfo;
// public QANoticeAOP(IRepository<QANotice> qaNoticeRepository,
// IUserInfo userInfo, IRepository<DicomStudy> studyRepository, IRepository<TrialUser> userTrialRepository, IRepository<TrialSiteUser> userTrialSiteRepository)
// {
// _qaNoticeRepository = qaNoticeRepository;
// _studyRepository = studyRepository;
// _userTrialRepository = userTrialRepository;
// _userTrialSiteRepository = userTrialSiteRepository;
// _userInfo = userInfo;
// }
// public void Intercept(IInvocation invocation)
// {
// //处理拦截的方法
// invocation.Proceed();
// if (invocation.Method.Name == "UpdateStudyStatus")
// {
// var studyStatus = invocation.Arguments[0] as StudyStatusDetailCommand;
// var study = _studyRepository.FirstOrDefault(t=>t.Id==studyStatus.StudyId);
// if (study.Status == (int)StudyStatus.Uploaded)
// {
// _qaNoticeRepository.Add(new QANotice()
// {
// TrialId = study.TrialId,
// SubjectVisitId = study.Id,
// FromUser = _userInfo.RealName,
// FromUserId = _userInfo.Id,
// FromUserType = _userInfo.UserTypeShortName,
// NoticeTypeEnum = NoticeType.NotNeedNotice,
// NeedDeal = false,
// StudyStatusStr = "Uploaded",
// Message = $"CRC : {_userInfo.RealName} has uploaded {study.StudyCode} ",
// SendTime = DateTime.Now,
// });
// }
// #region 处理QA通知模块
// //查询项目的参与者 和 负责site下CRC用户
// var trialUserList = _userTrialRepository.Where(t => t.TrialId == study.TrialId).ToList();
// // 找到该study 关联Site 下的CRC
// var crcList = _userTrialSiteRepository.Where(t =>
// t.SiteId == study.SiteId && t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator && t.TrialId == study.TrialId).ToList();
// var qaList = trialUserList.Where(t => t.User.UserTypeEnum == UserTypeEnum.IQC).ToList();
// var pm = trialUserList.FirstOrDefault(t => t.User.UserTypeEnum == UserTypeEnum.ProjectManager);
// // CRC =>QA
// if (studyStatus.Status == (int)StudyStatus.QARequested)
// {
// //找出当前操作的CRC
// //PM 或者admin可以代替CRC角色 不能从CRC列表中查询用户
// //var currentCRC = trialUserList.First(t => t.UserId == _userInfo.Id);
// var notice = new QANotice()
// {
// TrialId = study.TrialId,
// SubjectVisitId = study.Id,
// FromUser = _userInfo.RealName,
// FromUserId = _userInfo.Id,
// FromUserType = _userInfo.UserTypeShortName,
// //FromUser = currentCRC.UserRealName,
// //FromUserId = _userInfo.Id,
// //FromUserType = currentCRC.UserType,
// NoticeTypeEnum = NoticeType.CRC_RequestToQA_NoticeQA,
// NeedDeal = true,
// StudyStatusStr = "QA Requested",
// Message =
// $"CRC -> QA : {_userInfo.RealName} request QA {study.StudyCode} , Inquiry can be performed! ",
// SendTime = DateTime.Now,
// };
// qaList.ForEach(t => notice.QANoticeUserList.Add(new QANoticeUser()
// {
// QANoticeId = notice.Id,
// SubjectVisitId = study.Id,
// ToUser = t.User.LastName + " / " + t.User.FirstName,
// ToUserId = t.UserId,
// ToUserType = t.User.UserTypeRole.UserTypeShortName
// }));
// _qaNoticeRepository.Add(notice);
// //DealRequestToQA(study.Id);
// var needDealNoticeList = _qaNoticeRepository.AsQueryable()
// .Where(t => t.SubjectVisitId == study.Id && t.NeedDeal && t.NoticeTypeEnum == NoticeType.CRC_RequestToQA_NoticeQA).ToList();
// needDealNoticeList.ForEach(t =>
// {
// t.NeedDeal = false;
// t.DealTime = DateTime.Now;
// _qaNoticeRepository.Update(t);
// });
// }
// // QA =>CRC 向CRC推送消息影像有问题 同时作为 requestToQA 的边界
// else if (studyStatus.Status == (int)StudyStatus.QAing)
// {
// //找出当前操作的QA 如果是pm 或者admin 代替操作 此时会有问题 所以 谁代替,就以谁的名义执行
// //var currentQA = qaList.First(t => t.UserId == _userInfo.Id);
// //var currentQA = trialUserList.First(t => t.UserId == _userInfo.Id);
// //在项目CRC列表中筛选出 负责该study关联 site的CRC
// var siteCRCList = _userTrialSiteRepository.Where(t =>
// t.SiteId == study.SiteId && t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator && t.TrialId == study.TrialId).ToList();
// //查询项目的参与者 和 负责site下CRC用户
// var notice = new QANotice()
// {
// TrialId = study.TrialId,
// SubjectVisitId = study.Id,
// //FromUser = currentQA.UserRealName,
// //FromUserId = _userInfo.Id,
// //FromUserType = currentQA.UserType,
// FromUser = _userInfo.RealName,
// FromUserId = _userInfo.Id,
// FromUserType = _userInfo.UserTypeShortName,
// NoticeTypeEnum = NoticeType.QA_InQA_NoticeCRC,
// NeedDeal = true,
// StudyStatusStr = "In QA",
// Message = $"QA -> CRC : {_userInfo.RealName} inquiry {study.StudyCode} ",
// SendTime = DateTime.Now,
// };
// siteCRCList.ForEach(t => notice.QANoticeUserList.Add(new QANoticeUser()
// {
// QANoticeId = notice.Id,
// SubjectVisitId = study.Id,
// ToUser = t.User.LastName + " / " + t.User.FirstName,
// ToUserId = t.UserId,
// ToUserType = t.UserTypeRole.UserTypeShortName
// }));
// //添加 发送给CRC的消息 消息和CRC是 一对多
// _qaNoticeRepository.Add(notice);
// //处理 消息 标记已处理
// var needDealNoticeList = _qaNoticeRepository.AsQueryable()
// .Where(t => t.SubjectVisitId == study.Id && t.NeedDeal &&
// (t.NoticeTypeEnum == NoticeType.CRC_RequestToQA_NoticeQA ||
// t.NoticeTypeEnum == NoticeType.CRC_ReUpload_NoticeQA ||
// t.NoticeTypeEnum == NoticeType.CRC_QARecordDialogPost_NoticeQA)).ToList();
// needDealNoticeList.ForEach(t =>
// {
// t.NeedDeal = false;
// t.DealTime = DateTime.Now;
// _qaNoticeRepository.Update(t);
// });
// }
// // QA =>QA 给自己的消息 通知需要匿名化 同时作为 requestToQA 的边界
// else if (studyStatus.Status == (int)StudyStatus.QAFinish)
// {
// //找出当前操作的QA 如果是pm 或者admin 代替操作 此时会有问题 所以 谁代替,就以谁的名义执行
// //var currentQA = qaList.First(t => t.UserId == _userInfo.Id);
// //var currentQA = trialUserList.First(t => t.UserId == _userInfo.Id);
// //发送给当前项目QA列表
// var notice = new QANotice()
// {
// TrialId = study.TrialId,
// SubjectVisitId = study.Id,
// //FromUser = currentQA.UserRealName,
// //FromUserId = _userInfo.Id,
// //FromUserType = currentQA.UserType,
// FromUser = _userInfo.RealName,
// FromUserId = _userInfo.Id,
// FromUserType = _userInfo.UserTypeShortName,
// NoticeTypeEnum = NoticeType.QA_QAPass_NoticeQA,
// NeedDeal = true,
// StudyStatusStr = "QA-Passed",
// Message =
// $"QA -> QA : {_userInfo.RealName} inquiry {study.StudyCode} finishedAnonymization can be performed",
// SendTime = DateTime.Now,
// };
// qaList.ForEach(t => notice.QANoticeUserList.Add(new QANoticeUser()
// {
// QANoticeId = notice.Id,
// SubjectVisitId = study.Id,
// ToUser = t.User.LastName+" / "+t.User.FirstName,
// ToUserId = t.UserId,
// ToUserType = t.User.UserTypeRole.UserTypeShortName
// }));
// _qaNoticeRepository.Add(notice);
// //处理 消息 标记已处理 存在意外情况 qa发给CRC的 但是qa里面设置了 通过或者不通过 此时qa发送的消息也设置为已处理
// var needDealNoticeList = _qaNoticeRepository.AsQueryable()
// .Where(t => t.SubjectVisitId == study.Id && t.NeedDeal &&
// (t.NoticeTypeEnum == NoticeType.CRC_RequestToQA_NoticeQA ||
// t.NoticeTypeEnum == NoticeType.CRC_ReUpload_NoticeQA ||
// t.NoticeTypeEnum == NoticeType.CRC_QARecordDialogPost_NoticeQA ||
// t.NoticeTypeEnum == NoticeType.QA_QARecordDialogPost_NoticeCRC ||
// t.NoticeTypeEnum == NoticeType.QA_InQA_NoticeCRC ||
// t.NoticeTypeEnum == NoticeType.QA_AddQARecord_NoticeCRC)).ToList();
// needDealNoticeList.ForEach(t =>
// {
// t.NeedDeal = false;
// t.DealTime = DateTime.Now;
// _qaNoticeRepository.Update(t);
// });
// }
// // QA =>CRC 暂时不用发送消息给CRC 因为CRC 暂时没有入口回复 同时作为 requestToQA 的边界
// else if (studyStatus.Status == (int)StudyStatus.QAFInishNotPass)
// {
// _qaNoticeRepository.Add(new QANotice()
// {
// TrialId = study.TrialId,
// SubjectVisitId = study.Id,
// FromUser = _userInfo.RealName,
// FromUserId = _userInfo.Id,
// FromUserType = _userInfo.UserTypeShortName,
// NoticeTypeEnum = NoticeType.NotNeedNotice,
// NeedDeal = false,
// StudyStatusStr = "QA-Failed",
// Message = $"QA : {_userInfo.RealName} set {study.StudyCode} QA-Failed ",
// SendTime = DateTime.Now,
// });
// //处理 消息 标记已处理
// var needDealNoticeList = _qaNoticeRepository.AsQueryable()
// .Where(t => t.SubjectVisitId == study.Id && t.NeedDeal &&
// (t.NoticeTypeEnum == NoticeType.CRC_RequestToQA_NoticeQA ||
// t.NoticeTypeEnum == NoticeType.CRC_ReUpload_NoticeQA ||
// t.NoticeTypeEnum == NoticeType.CRC_QARecordDialogPost_NoticeQA ||
// t.NoticeTypeEnum == NoticeType.QA_QARecordDialogPost_NoticeCRC ||
// t.NoticeTypeEnum == NoticeType.QA_InQA_NoticeCRC ||
// t.NoticeTypeEnum == NoticeType.QA_AddQARecord_NoticeCRC)).ToList();
// needDealNoticeList.ForEach(t =>
// {
// t.NeedDeal = false;
// t.DealTime = DateTime.Now;
// _qaNoticeRepository.Update(t);
// });
// }
// #endregion
// }
// else if (invocation.Method.Name == "ReUploadSameStudy")
// {
// var studyId = Guid.Parse(invocation.Arguments[0].ToString());
// var study = _studyRepository.FirstOrDefault(t => t.Id == studyId);
// var status = study.Status;
// //处理CRC 重传时 QA消息
// if (status == (int)StudyStatus.QAing)
// {
// //查询项目的参与者 和 负责site下CRC用户
// var trialUserList = _userTrialRepository.Where(t => t.TrialId == study.TrialId).ToList();
// // 找到该study 关联Site 下的CRC
// var crcList = _userTrialSiteRepository.Where(t =>
// t.SiteId == study.SiteId && t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator && t.TrialId == study.TrialId).ToList();
// var qaList = trialUserList.Where(t => t.User.UserTypeEnum == UserTypeEnum.IQC).ToList();
// //CRC =>QA CRC的职能被PM 或者admin代替
// //if (_userInfo.UserTypeEnumInt == (int)UserType.ClinicalResearchCoordinator)
// {
// //PM 或者admin可以代替CRC角色 不能从CRC列表中查询用户
// //var currentCRC = trialUserList.First(t => t.UserId == _userInfo.Id);
// var notice = new QANotice()
// {
// TrialId = study.TrialId,
// SubjectVisitId = study.Id,
// //FromUser = currentCRC.UserRealName,
// //FromUserId = _userInfo.Id,
// //FromUserType = currentCRC.UserType,
// FromUser = _userInfo.RealName,
// FromUserId = _userInfo.Id,
// FromUserType = _userInfo.UserTypeShortName,
// NoticeTypeEnum = NoticeType.CRC_ReUpload_NoticeQA,
// NeedDeal = true,
// Message = $"CRC -> QA :{_userInfo.RealName} has reuploaded {study.StudyCode} , Need to be inquiry again",
// SendTime = DateTime.Now
// };
// qaList.ForEach(t => notice.QANoticeUserList.Add(new QANoticeUser()
// {
// QANoticeId = notice.Id,
// SubjectVisitId = study.Id,
// ToUser = t.User.LastName+" / "+t.User.FirstName,
// ToUserId = t.UserId,
// ToUserType = t.User.UserTypeRole.UserTypeShortName
// }));
// _qaNoticeRepository.Add(notice);
// //这里作为 QA 设置 Inqa 状态的回复 或者QA和CRC对话的
// var needDealNoticeList = _qaNoticeRepository.Where(t => t.SubjectVisitId == study.Id && t.NeedDeal
// && (t.NoticeTypeEnum == NoticeType.QA_InQA_NoticeCRC || t.NoticeTypeEnum == NoticeType.QA_QARecordDialogPost_NoticeCRC))
// .ToList();
// needDealNoticeList.ForEach(t =>
// {
// t.NeedDeal = false;
// t.DealTime = DateTime.Now;
// _qaNoticeRepository.Update(t);
// });
// }
// }
// else
// {
// //不是QAing 的重传 不发送qa消息
// return;
// }
// }
// else if (invocation.Method.Name == "DicomAnonymize")
// {
// var studyId = Guid.Parse(invocation.Arguments[0].ToString());
// var study = _studyRepository.FirstOrDefault(t => t.Id == studyId);
// #region 处理QA通知 匿名化完毕 通知PM
// //查询项目的参与者 和 负责site下CRC用户
// var trialUserList = _userTrialRepository.Where(t => t.TrialId == study.TrialId).ToList();
// // 找到该study 关联Site 下的CRC
// var crcList = _userTrialSiteRepository.Where(t =>
// t.SiteId == study.SiteId && t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator && t.TrialId == study.TrialId).ToList();
// var qaList = trialUserList.Where(t => t.User.UserTypeEnum == UserTypeEnum.IQC).ToList();
// //
// var pm = trialUserList.FirstOrDefault(t => t.User.UserTypeEnum == UserTypeEnum.ProjectManager);
// //找出当前操作的QA 如果是pm 或者admin 代替操作 此时会有问题 所以 谁代替,就以谁的名义执行
// //var currentQA = trialUserList.First(t =>
// // t.UserTypeEnum == UserType.IQC && t.UserId == _userInfo.Id);
// //var currentQA = trialUserList.First(t => t.UserId == _userInfo.Id);
// var notice = new QANotice()
// {
// TrialId = study.TrialId,
// SubjectVisitId = study.Id,
// //FromUser = currentQA.UserRealName,
// //FromUserId = _userInfo.Id,
// //FromUserType = currentQA.UserType,
// FromUser = _userInfo.RealName,
// FromUserId = _userInfo.Id,
// FromUserType = _userInfo.UserTypeShortName,
// NoticeTypeEnum = NoticeType.QA_Anonymized_NoticeQA,
// NeedDeal = true,
// StudyStatusStr = "Anonymized",
// //Message = $"QA -> PM :{_userInfo.RealName} has anonymized {study.StudyCode} Forward can be performed!!",
// Message = $"QA -> QA :{_userInfo.RealName} has anonymized {study.StudyCode} Forward can be performed!!",
// SendTime = DateTime.Now,
// };
// //notice.QANoticeUserList.Add(new QANoticeUser()
// //{
// // QANoticeId = notice.Id,
// // StudyId = study.Id,
// // ToUser = pm.UserRealName,
// // ToUserId = pm.UserId,
// // ToUserType = pm.UserType
// //});
// qaList.ForEach(t => notice.QANoticeUserList.Add(new QANoticeUser()
// {
// QANoticeId = notice.Id,
// SubjectVisitId = study.Id,
// ToUser = t.User.LastName+" / "+t.User.FirstName,
// ToUserId = t.UserId,
// ToUserType = t.User.UserTypeRole.UserTypeShortName
// }));
// _qaNoticeRepository.Add(notice);
// var needDealNoticeList = _qaNoticeRepository.AsQueryable()
// .Where(t => t.SubjectVisitId == study.Id && t.NeedDeal && (t.NoticeTypeEnum == NoticeType.QA_QAPass_NoticeQA)).ToList();
// needDealNoticeList.ForEach(t =>
// {
// t.NeedDeal = false;
// t.DealTime = DateTime.Now;
// _qaNoticeRepository.Update(t);
// });
// #endregion
// }
// else if (invocation.Method.Name == "ForwardStudy")
// {
// var studyId = Guid.Parse(invocation.Arguments[0].ToString());
// var study = _studyRepository.FirstOrDefault(t => t.Id == studyId);
// //匿名化操作产生的消息 设置为已经处理
// _qaNoticeRepository.Add(new QANotice()
// {
// TrialId = study.TrialId,
// SubjectVisitId = study.Id,
// //FromUser = currentQA.UserRealName,
// //FromUserId = _userInfo.Id,
// //FromUserType = currentQA.UserType,
// FromUser = _userInfo.RealName,
// FromUserId = _userInfo.Id,
// FromUserType = _userInfo.UserTypeShortName,
// NoticeTypeEnum = NoticeType.NotNeedNotice,
// NeedDeal = false,
// StudyStatusStr = "Forwarded",
// //Message = $"PM :{_userInfo.RealName} has forwarded {study.StudyCode} ",
// Message = $"QA :{_userInfo.RealName} has forwarded {study.StudyCode} ",
// SendTime = DateTime.Now,
// });
// var needDealList = _qaNoticeRepository.Where(t =>
// t.SubjectVisitId == study.Id && t.NeedDeal && t.NoticeTypeEnum == NoticeType.QA_Anonymized_NoticeQA).ToList();
// needDealList.ForEach(t =>
// {
// t.NeedDeal = false;
// t.DealTime = DateTime.Now;
// _qaNoticeRepository.Update(t);
// });
// }
// var success = _qaNoticeRepository.SaveChanges();
// if (!success)
// {
// throw new Exception("Send QA message failed");
// }
// }
// }
//}
@@ -1,89 +0,0 @@
using Castle.DynamicProxy;
using EasyCaching.Core;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.Application.AOP
{
public class TrialStatusAutofacAOP : IAsyncInterceptor
{
private readonly IEasyCachingProvider _provider;
public TrialStatusAutofacAOP(IEasyCachingProvider provider)
{
_provider = provider;
}
public void InterceptAsynchronous(IInvocation invocation)
{
invocation.Proceed();
}
//这里AOP 处理两个方法 分别是 项目的添加和更新、项目状态的变更
public void InterceptAsynchronous<TResult>(IInvocation invocation)
{
//处理拦截的方法
invocation.Proceed();
dynamic result = invocation.ReturnValue;
//接口成功了,才修改缓存
if (!result.IsSuccess)
{
return;
}
#region ,
//if (invocation.Method.Name == "GetTrialList")
//{
// //在此 将当前查询的项目Id 和对应的项目状态进行缓存
// dynamic result = invocation.ReturnValue;
// foreach (var item in result.CurrentPageData)
// {
// _provider.Remove(item.Id.ToString());
// _provider.Set(item.Id.ToString(), item.TrialStatusStr.ToString(), TimeSpan.FromDays(1));
// }
//}
#endregion
if (invocation.Method.Name == "AddOrUpdateTrial")
{
//如果是添加 那么将对应的初始状态加进去 更新状态是单独操作的
var trialModel = (invocation.Arguments[0] as TrialCommand).IfNullThrowConvertException();
if (trialModel.Id == null || trialModel.Id == Guid.Empty)
{
_provider.Set(result.Data.Id.ToString(), StaticData.TrialState.TrialOngoing, TimeSpan.FromDays(1));
}
}
// 更新缓存
else if (invocation.Method.Name == "UpdateTrialStatus")
{
//项目状态更新,也需要及时更新
_provider.Set(invocation.Arguments[0].ToString(), invocation.Arguments[1].ToString(), TimeSpan.FromDays(1));
////Test参数是否符合要求
//var tt = invocation.Arguments[0].ToString();
//var cc = _provider.Get<string>(invocation.Arguments[0].ToString());
}
}
public void InterceptSynchronous(IInvocation invocation)
{
invocation.Proceed();
}
}
}
@@ -1,81 +0,0 @@
//using System.Diagnostics;
//using IRaCIS.Application.Interfaces;
//using IRaCIS.Application.Contracts;
//using IRaCIS.Core.Infra.EFCore;
//using IRaCIS.Core.Infrastructure.Extention;
//using Microsoft.AspNetCore.Mvc;
//using Microsoft.AspNetCore.Mvc.Filters;
//using Microsoft.Extensions.Logging;
//using Newtonsoft.Json;
//namespace IRaCIS.Core.Application.Filter
//{
// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
// public class LogFilter : Attribute
// {
// }
// public class LogActionFilter : IAsyncActionFilter
// {
// private readonly ILogService _logService;
// private readonly IUserInfo _userInfo;
// private readonly ILogger<LogActionFilter> _logger;
// public LogActionFilter(ILogService logService, IUserInfo userInfo , ILogger<LogActionFilter> logger)
// {
// _logService = logService;
// _userInfo = userInfo;
// _logger = logger;
// }
// public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
// {
// if (context.ActionDescriptor.EndpointMetadata!=null&& context.ActionDescriptor.EndpointMetadata.Any(m => m.GetType() == typeof(LogFilter)))
// {
// return LogAsync(context, next);
// }
// return next();
// }
// public async Task LogAsync(ActionExecutingContext context, ActionExecutionDelegate next)
// {
// var sw = new Stopwatch();
// sw.Start();
// dynamic actionResult = (await next()).Result;
// sw.Stop();
// var args = JsonConvert.SerializeObject(context.ActionArguments);
// var result = JsonConvert.SerializeObject(actionResult?.Value);
// var attr = (ApiExplorerSettingsAttribute)context.ActionDescriptor.EndpointMetadata.FirstOrDefault(m => m.GetType() == typeof(ApiExplorerSettingsAttribute));
// var groupName = attr?.GroupName;
// var res = actionResult?.Value as IResponseOutput;
// var input = new SystemLogDTO
// {
// ClientIP = string.Empty,
// OptUserId = _userInfo.Id,
// OptUserName = _userInfo.UserName,
// ApiPath = context.ActionDescriptor.AttributeRouteInfo.Template.ToLower(),
// Params = args,
// Result = result,
// RequestTime = DateTime.Now,
// ElapsedMilliseconds = sw.ElapsedMilliseconds,
// Status =res?.IsSuccess?? false,
// Message = res?.ErrorMessage,
// LogCategory = groupName
// };
// try
// {
// _logService.SaveLog2Db(input);
// }
// catch (Exception ex)
// {
// _logger.LogError(ex.Message);
// }
// }
// }
//}
File diff suppressed because it is too large Load Diff
@@ -12,9 +12,11 @@ using MiniExcelLibs;
using MiniExcelLibs.OpenXml; using MiniExcelLibs.OpenXml;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NPOI.HPSF;
using NPOI.HSSF.UserModel; using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel; using NPOI.XSSF.UserModel;
using SkiaSharp; using SkiaSharp;
using System.Collections;
using System.IO; using System.IO;
namespace IRaCIS.Core.Application.Service; namespace IRaCIS.Core.Application.Service;
@@ -51,20 +53,24 @@ public static class ExcelExportHelper
var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray()); var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());
var dic = JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull()); var dic = data.ConvertToDictionary();
foreach (var key in dic.Keys) foreach (var key in dic.Keys)
{ {
//是数组 那么找到对应的属性 进行翻译 //是数组 那么找到对应的属性 进行翻译
if (dic[key].GetType().IsAssignableFrom(typeof(JArray))) if (dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)))
{ {
var newObjList = new List<object>(); var newObjList = new List<object>();
var no = 1; var no = 1;
foreach (var item in dic[key] as JArray) foreach (var item in dic[key] as IList )
{ {
var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull()); //var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull());
var itemDic = item.ConvertToDictionary();
foreach (var needTranslateProperty in needTranslatePropertyList) foreach (var needTranslateProperty in needTranslatePropertyList)
@@ -72,7 +78,7 @@ public static class ExcelExportHelper
//翻译的属性依赖其他属性 //翻译的属性依赖其他属性
if (needTranslateProperty.IsTranslateDenpendOtherProperty) if (needTranslateProperty.IsTranslateDenpendOtherProperty)
{ {
if (item[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower()) if (itemDic[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower())
{ {
var beforeValue = itemDic[needTranslateProperty.Name]?.ToString(); var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
@@ -145,8 +151,12 @@ public static class ExcelExportHelper
workbook.RemoveSheetAt(1); workbook.RemoveSheetAt(1);
} }
FileStream fileOut = new FileStream("resultTemplate", FileMode.Create, FileAccess.ReadWrite);
workbook.Write(fileOut);
var memoryStream2 = new MemoryStream(); var memoryStream2 = new MemoryStream();
workbook.Write(memoryStream2); workbook.Write(memoryStream2,true);
memoryStream2.Seek(0, SeekOrigin.Begin); memoryStream2.Seek(0, SeekOrigin.Begin);
@@ -226,29 +236,30 @@ public static class ExcelExportHelper
var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray()); var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());
var dic = data.ConvertToDictionary();
var dic = JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull()); //var dic = (JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull())).IfNullThrowException();
foreach (var key in dic.Keys) foreach (var key in dic.Keys)
{ {
//是数组 那么找到对应的属性 进行翻译 //是数组 那么找到对应的属性 进行翻译
if (dic[key].GetType().IsAssignableFrom(typeof(JArray))) if (dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)))
//if (dic[key].GetType().IsAssignableFrom(typeof(JArray)))
{ {
var newObjList = new List<object>(); var newObjList = new List<object>();
var no = 1; var no = 1;
foreach (var item in dic[key] as IList)
foreach (var item in dic[key] as JArray) //foreach (var item in dic[key] as JArray)
{ {
var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull()); //var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull());
var itemDic = item.ConvertToDictionary();
foreach (var needTranslateProperty in needTranslatePropertyList) foreach (var needTranslateProperty in needTranslatePropertyList)
{ {
//翻译的属性依赖其他属性 //翻译的属性依赖其他属性
if (needTranslateProperty.IsTranslateDenpendOtherProperty) if (needTranslateProperty.IsTranslateDenpendOtherProperty)
{ {
if (item[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower()) if (itemDic[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower())
{ {
var beforeValue = itemDic[needTranslateProperty.Name]?.ToString(); var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
@@ -316,7 +327,7 @@ public static class ExcelExportHelper
} }
var memoryStream2 = new MemoryStream(); var memoryStream2 = new MemoryStream();
workbook.Write(memoryStream2); workbook.Write(memoryStream2,true);
memoryStream2.Seek(0, SeekOrigin.Begin); memoryStream2.Seek(0, SeekOrigin.Begin);
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Helper
{
public class FileConvertHelper
{
static public void ConvertWordToPdf(string inputWordFilePath, string outputPdfDir)
{
// 设置 libreoffice 命令行参数
string arguments = $"--headless --invisible --convert-to pdf \"{inputWordFilePath}\" --outdir \"{outputPdfDir}\"";
// 启动 libreoffice 进程
using (Process process = new Process())
{
process.StartInfo.FileName = "libreoffice";
process.StartInfo.Arguments = arguments;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.Start();
// 等待进程结束
process.WaitForExit();
}
}
}
}
@@ -142,8 +142,9 @@ public static class FileStoreHelper
//API vue 部署目录 //API vue 部署目录
public static string GetIRaCISRootPath(IWebHostEnvironment _hostEnvironment) public static string GetIRaCISRootPath(IWebHostEnvironment _hostEnvironment)
{ {
var rootPath = (Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\'))).IfNullThrowException().FullName; string parentDirectory = Path.GetFullPath(Path.Combine(_hostEnvironment.ContentRootPath, ".."));
return rootPath;
return parentDirectory;
} }
@@ -163,7 +164,7 @@ public static class FileStoreHelper
{ {
var rootPath = GetIRaCISRootPath(_hostEnvironment); var rootPath = GetIRaCISRootPath(_hostEnvironment);
var physicalFilePath = Path.Combine(rootPath, relativePath.Trim('/')); var physicalFilePath = Path.Combine(rootPath, relativePath.TrimStart('/'));
return physicalFilePath; return physicalFilePath;
} }
@@ -539,7 +540,6 @@ public static class FileStoreHelper
/// <param name="trialId"></param> /// <param name="trialId"></param>
/// <param name="siteid"></param> /// <param name="siteid"></param>
/// <param name="subjectId"></param> /// <param name="subjectId"></param>
/// <param name="type"></param>
/// <returns></returns> /// <returns></returns>
public static (string PhysicalPath, string RelativePath, string FileRealName) GetUploadPrintscreenFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteid, Guid subjectId) public static (string PhysicalPath, string RelativePath, string FileRealName) GetUploadPrintscreenFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteid, Guid subjectId)
{ {
@@ -686,7 +686,7 @@ public static class FileStoreHelper
var json = File.ReadAllText( Path.Combine(_hostEnvironment.ContentRootPath, "appsettings.json")); var json = File.ReadAllText( Path.Combine(_hostEnvironment.ContentRootPath, "appsettings.json"));
JObject jsonObject = JObject.Parse(json, new JsonLoadSettings() { CommentHandling = CommentHandling.Load }); JObject jsonObject = (JObject.Parse(json, new JsonLoadSettings() { CommentHandling = CommentHandling.Load })).IfNullThrowException();
int switchingRatio = 80; int switchingRatio = 80;
@@ -0,0 +1,210 @@
using Aliyun.OSS;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Infrastructure;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using NPOI.HPSF;
using SharpCompress.Common;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Helper
{
public class MinIOOptions
{
public string endpoint { get; set; }
public string port { get; set; }
public bool useSSL { get; set; }
public string accessKey { get; set; }
public string secretKey { get; set; }
public string bucketName { get; set; }
}
public class AliyunOSSOptions
{
public string regionId { get; set; }
public string accessKeyId { get; set; }
public string accessKeySecret { get; set; }
public string endPoint { get; set; }
public string bucketName { get; set; }
public string roleArn { get; set; }
public string region { get; set; }
public string viewEndpoint { get; set; }
}
public class ObjectStoreServiceOptions
{
public string ObjectStoreUse { get; set; }
public AliyunOSSOptions AliyunOSS { get; set; }
public MinIOOptions MinIO { get; set; }
}
public class ObjectStoreDTO
{
public string ObjectStoreUse { get; set; }
public AliyunOSSOptions AliyunOSS { get; set; }
public MinIOOptions MinIO { get; set; }
}
public class AliyunOSSTempToken
{
public string AccessKeyId { get; set; }
public string AccessKeySecret { get; set; }
public string SecurityToken { get; set; }
public string Expiration { get; set; }
public string Region { get; set; }
public string BucketName { get; set; }
public string ViewEndpoint { get; set; }
}
public enum ObjectStoreUse
{
AliyunOSS = 0,
MinIO = 1,
AWS = 2,
}
public interface IOSSService
{
public string UploadToOSS(Stream fileStream, string oosFolderPath, string fileRealName);
public string UploadToOSS(string localFilePath, string oosFolderPath);
public void DownLoadFromOSS(string ossRelativePath, string localFilePath);
}
public class OSSService : IOSSService
{
public AliyunOSSOptions _OSSConfig { get; set; }
public OssClient _ossClient { get; set; }
public OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options)
{
var ossOptions = options.CurrentValue;
_OSSConfig = ossOptions.AliyunOSS;
_ossClient = new OssClient(_OSSConfig.endPoint, _OSSConfig.accessKeyId, _OSSConfig.accessKeySecret);
}
/// <summary>
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
/// </summary>
/// <param name="fileStream"></param>
/// <param name="oosFolderPath"></param>
/// <param name="fileRealName"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public string UploadToOSS(Stream fileStream, string oosFolderPath,string fileRealName)
{
var ossRelativePath = oosFolderPath + "/" + fileRealName;
try
{
using (var memoryStream = new MemoryStream())
{
fileStream.Seek(0, SeekOrigin.Begin);
fileStream.CopyTo(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
// 上传文件
var result = _ossClient.PutObject(_OSSConfig.bucketName, ossRelativePath, memoryStream);
}
return "/" + ossRelativePath;
}
catch (Exception ex)
{
throw new BusinessValidationFailedException("oss上传失败" + ex.Message);
}
}
/// <summary>
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
/// </summary>
/// <param name="localFilePath"></param>
/// <param name="oosFolderPath"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public string UploadToOSS(string localFilePath, string oosFolderPath)
{
var localFileName = Path.GetFileName(localFilePath);
var ossRelativePath = oosFolderPath + "/" + localFileName;
try
{
// 上传文件
var result = _ossClient.PutObject(_OSSConfig.bucketName, ossRelativePath, localFilePath);
return ossRelativePath;
}
catch (Exception ex)
{
throw new BusinessValidationFailedException("oss上传失败" + ex.Message);
}
}
public void DownLoadFromOSS(string ossRelativePath, string localFilePath)
{
try
{
var result = _ossClient.GetObject(_OSSConfig.bucketName, ossRelativePath);
// 将下载的文件流保存到本地文件
using (var fs = File.OpenWrite(localFilePath))
{
result.Content.CopyTo(fs);
fs.Close();
}
}
catch (Exception ex)
{
throw new BusinessValidationFailedException("oss下载失败!" + ex.Message);
}
}
}
}
@@ -40,7 +40,7 @@ public static class SendEmailHelper
} }
} }
catch (Exception ex) catch (Exception )
{ {
//---邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员 //---邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员
@@ -81,7 +81,6 @@
<param name="trialId"></param> <param name="trialId"></param>
<param name="siteid"></param> <param name="siteid"></param>
<param name="subjectId"></param> <param name="subjectId"></param>
<param name="type"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Helper.FileStoreHelper.GetFilePath(Microsoft.AspNetCore.Hosting.IWebHostEnvironment,System.String,System.Guid,System.Guid,System.String)"> <member name="M:IRaCIS.Core.Application.Helper.FileStoreHelper.GetFilePath(Microsoft.AspNetCore.Hosting.IWebHostEnvironment,System.String,System.Guid,System.Guid,System.String)">
@@ -95,17 +94,30 @@
<param name="type"></param> <param name="type"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Helper.OSSService.UploadToOSS(System.IO.Stream,System.String,System.String)">
<summary>
oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
</summary>
<param name="fileStream"></param>
<param name="oosFolderPath"></param>
<param name="fileRealName"></param>
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>
<member name="M:IRaCIS.Core.Application.Helper.OSSService.UploadToOSS(System.String,System.String)">
<summary>
oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
</summary>
<param name="localFilePath"></param>
<param name="oosFolderPath"></param>
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>
<member name="T:IRaCIS.Core.Application.Service.TaskMedicalReviewRuleService"> <member name="T:IRaCIS.Core.Application.Service.TaskMedicalReviewRuleService">
<summary> <summary>
医学审核生成规则 废弃 医学审核生成规则 废弃
</summary> </summary>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.TaskMedicalReviewRuleService.GenerateMedicalReviewTask(IRaCIS.Core.Application.ViewModel.GenerateMedicalReviewTaskCommand)">
<summary>
产生医学审核
</summary>
<returns></returns>
</member>
<member name="T:IRaCIS.Core.Application.Service.TaskMedicalReviewService"> <member name="T:IRaCIS.Core.Application.Service.TaskMedicalReviewService">
<summary> <summary>
任务医学审核 任务医学审核
@@ -281,6 +293,7 @@
</summary> </summary>
<param name="origenalTask"></param> <param name="origenalTask"></param>
<param name="agreeReReadingCommand"></param> <param name="agreeReReadingCommand"></param>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.Allocation.VisitTaskService.SetReReadingOrBackInfluenceAnalysisAsync(System.Guid)"> <member name="M:IRaCIS.Core.Application.Service.Allocation.VisitTaskService.SetReReadingOrBackInfluenceAnalysisAsync(System.Guid)">
<summary> <summary>
@@ -490,7 +503,6 @@
<param name="_commonDocumentRepository"></param> <param name="_commonDocumentRepository"></param>
<param name="_dictionaryService"></param> <param name="_dictionaryService"></param>
<param name="_trialRepository"></param> <param name="_trialRepository"></param>
<param name="inQuery"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.GetTrialReadingCriterionCanExportDocumentList(System.Guid)"> <member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.GetTrialReadingCriterionCanExportDocumentList(System.Guid)">
@@ -937,7 +949,8 @@
<summary> <summary>
翻译稽查数据 翻译稽查数据
</summary> </summary>
<param name="dto">传入Dto</param> <param name="dto"></param>
<param name="currentInspectionId"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.SetDataInspectionDateType(System.Collections.Generic.List{System.String},System.String)"> <member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.SetDataInspectionDateType(System.Collections.Generic.List{System.String},System.String)">
@@ -1131,7 +1144,6 @@
<summary> <summary>
获取阅片报告 获取阅片报告
</summary> </summary>
<param name="indto"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.ReadingCalculate.ReadingCalculateService.GetDeleteLesionStatrIndex(IRaCIS.Core.Application.Service.Reading.Dto.DeleteReadingRowAnswerInDto)"> <member name="M:IRaCIS.Core.Application.Service.ReadingCalculate.ReadingCalculateService.GetDeleteLesionStatrIndex(IRaCIS.Core.Application.Service.Reading.Dto.DeleteReadingRowAnswerInDto)">
@@ -2468,6 +2480,8 @@
<param name="item"></param> <param name="item"></param>
<param name="questions"></param> <param name="questions"></param>
<param name="tableQuestions"></param> <param name="tableQuestions"></param>
<param name="answers"></param>
<param name="tableAnswers"></param>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.ClinicalQuestionService.GetTrialClinicalQuestionList(IRaCIS.Core.Application.Service.Reading.Dto.TrialClinicalQuestionQuery)"> <member name="M:IRaCIS.Core.Application.Service.ClinicalQuestionService.GetTrialClinicalQuestionList(IRaCIS.Core.Application.Service.Reading.Dto.TrialClinicalQuestionQuery)">
<summary> <summary>
@@ -10689,6 +10703,7 @@
</summary> </summary>
<param name="inQuery"></param> <param name="inQuery"></param>
<param name="_subjectVisitRepository"></param> <param name="_subjectVisitRepository"></param>
<param name="_trialRepository"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetImageClinicalDataToBeConfirmList(IRaCIS.Core.Application.Contracts.ImageClinicalDataToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})"> <member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetImageClinicalDataToBeConfirmList(IRaCIS.Core.Application.Contracts.ImageClinicalDataToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
@@ -10697,6 +10712,7 @@
</summary> </summary>
<param name="inQuery"></param> <param name="inQuery"></param>
<param name="_subjectVisitRepository"></param> <param name="_subjectVisitRepository"></param>
<param name="_trialRepository"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetCRCImageQuestionToBeDoneList(IRaCIS.Core.Application.Contracts.ImageQuestionToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})"> <member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetCRCImageQuestionToBeDoneList(IRaCIS.Core.Application.Contracts.ImageQuestionToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
@@ -10714,6 +10730,7 @@
</summary> </summary>
<param name="inQuery"></param> <param name="inQuery"></param>
<param name="_subjectVisitRepository"></param> <param name="_subjectVisitRepository"></param>
<param name="_trialRepository"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetImageReUploadToBeDoneList(IRaCIS.Core.Application.Contracts.ImageReUploadToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})"> <member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetImageReUploadToBeDoneList(IRaCIS.Core.Application.Contracts.ImageReUploadToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
@@ -10722,14 +10739,16 @@
</summary> </summary>
<param name="inQuery"></param> <param name="inQuery"></param>
<param name="_subjectVisitRepository"></param> <param name="_subjectVisitRepository"></param>
<param name="_trialRepository"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetImageSubmittedToBeDoneList(IRaCIS.Core.Application.Contracts.ImageSubmittedToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})"> <member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetImageSubmittedToBeDoneList(IRaCIS.Core.Application.Contracts.ImageSubmittedToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
<summary> <summary>
加急影像提交 --CRC 待办 加急影像提交 --CRC 待办
</summary> </summary>
<param name="inQuery"></param> <param name="inQuery"></param>
<param name="_subjectVisitRepository"></param> <param name="_subjectVisitRepository"></param>
<param name="_trialRepository"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetImageQualityToBeDoneList(IRaCIS.Core.Application.Contracts.ImageQualityToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})"> <member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetImageQualityToBeDoneList(IRaCIS.Core.Application.Contracts.ImageQualityToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
@@ -10738,14 +10757,16 @@
</summary> </summary>
<param name="inQuery"></param> <param name="inQuery"></param>
<param name="_subjectVisitRepository"></param> <param name="_subjectVisitRepository"></param>
<param name="_trialRepository"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetQCImageQuestionToBeDoneList(IRaCIS.Core.Application.Contracts.ImageQuestionToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})"> <member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetQCImageQuestionToBeDoneList(IRaCIS.Core.Application.Contracts.ImageQuestionToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
<summary> <summary>
QC 质疑 QC 质疑
</summary> </summary>
<param name="inQuery"></param> <param name="inQuery"></param>
<param name="_subjectVisitRepository"></param> <param name="_subjectVisitRepository"></param>
<param name="_trialRepository"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetIRImageReadingToBeDoneList(IRaCIS.Core.Application.Contracts.IRImageReadingToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})"> <member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetIRImageReadingToBeDoneList(IRaCIS.Core.Application.Contracts.IRImageReadingToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
@@ -10763,6 +10784,7 @@
IR医学反馈 IR医学反馈
</summary> </summary>
<param name="inQuery"></param> <param name="inQuery"></param>
<param name="_taskMedicalReviewRepository"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetMIMMedicalCommentsToBeDoneList(IRaCIS.Core.Application.Contracts.MedicalCommentsToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskMedicalReview})"> <member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetMIMMedicalCommentsToBeDoneList(IRaCIS.Core.Application.Contracts.MedicalCommentsToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskMedicalReview})">
@@ -10771,6 +10793,7 @@
</summary> </summary>
<param name="inQuery"></param> <param name="inQuery"></param>
<param name="_taskMedicalReviewRepository"></param> <param name="_taskMedicalReviewRepository"></param>
<param name="_trialReadingCriterionRepository"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetMedicalCommentsFirstToBeDone(IRaCIS.Core.Application.Contracts.MedicalCommentsFirstToBeDoneQuery,IRaCIS.Core.Application.Interfaces.ITaskMedicalReviewService)"> <member name="M:IRaCIS.Core.Application.PersonalWorkstation.GetMedicalCommentsFirstToBeDone(IRaCIS.Core.Application.Contracts.MedicalCommentsFirstToBeDoneQuery,IRaCIS.Core.Application.Interfaces.ITaskMedicalReviewService)">
@@ -11019,7 +11042,7 @@
构造函数注入 构造函数注入
</summary> </summary>
</member> </member>
<member name="M:IRaCIS.Core.Application.MediatR.Handlers.ConsistencyVerificationHandler.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomStudy},IRaCIS.Core.Domain.Share.IUserInfo,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSite},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},AutoMapper.IMapper)"> <member name="M:IRaCIS.Core.Application.MediatR.Handlers.ConsistencyVerificationHandler.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomStudy},IRaCIS.Core.Domain.Share.IUserInfo,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSite},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},AutoMapper.IMapper,Microsoft.Extensions.Localization.IStringLocalizer)">
<summary> <summary>
构造函数注入 构造函数注入
</summary> </summary>
@@ -11556,7 +11579,6 @@
<summary> <summary>
新增修改系统表格问题 新增修改系统表格问题
</summary> </summary>
<param name="addOrEditReadingTableQuestionSystem"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Application.Services.ReadingQuestionService.DeleteReadingTableQuestionSystem(System.Guid)"> <member name="M:IRaCIS.Application.Services.ReadingQuestionService.DeleteReadingTableQuestionSystem(System.Guid)">
@@ -11581,11 +11603,12 @@
</member> </member>
<member name="M:IRaCIS.Application.Services.ReadingQuestionService.VerifyCalculateRelation(System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.CalculateRelationDto},System.Guid,System.Guid,System.Int32)"> <member name="M:IRaCIS.Application.Services.ReadingQuestionService.VerifyCalculateRelation(System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.CalculateRelationDto},System.Guid,System.Guid,System.Int32)">
<summary> <summary>
验证计算关系 验证计算关系
</summary> </summary>
<param name="relationList"></param> <param name="relationList"></param>
<param name="QuestionId"></param> <param name="QuestionId"></param>
<param name="originalId"></param> <param name="originalId"></param>
<param name="count"></param>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception> <exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member> </member>
<member name="M:IRaCIS.Application.Services.ReadingQuestionService.GetQuestionCalculateRelation(IRaCIS.Core.Application.Service.Reading.Dto.GetQuestionCalculateRelationInDto)"> <member name="M:IRaCIS.Application.Services.ReadingQuestionService.GetQuestionCalculateRelation(IRaCIS.Core.Application.Service.Reading.Dto.GetQuestionCalculateRelationInDto)">
@@ -11851,6 +11874,8 @@
</summary> </summary>
<param name="trialReadingCriterionId"></param> <param name="trialReadingCriterionId"></param>
<param name="visitTaskId"></param> <param name="visitTaskId"></param>
<param name="questionClassify"></param>
<param name="groupClassifyList"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Application.Services.ReadingImageTaskService.GetReadingReportEvaluation(IRaCIS.Core.Application.Service.Reading.Dto.GetReadingReportEvaluationInDto)"> <member name="M:IRaCIS.Application.Services.ReadingImageTaskService.GetReadingReportEvaluation(IRaCIS.Core.Application.Service.Reading.Dto.GetReadingReportEvaluationInDto)">
@@ -11893,11 +11918,18 @@
</member> </member>
<member name="M:IRaCIS.Application.Services.ReadingImageTaskService.FindChildQuestion(IRaCIS.Core.Application.Service.Reading.Dto.TrialReadQuestionData,System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.TrialReadQuestionData},System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.TableQuestionTrial},System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionAnswerInfo},System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.TableAnsweRowInfo},System.Collections.Generic.List{IRaCIS.Core.Domain.Models.OrganInfo},System.Collections.Generic.List{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},System.Boolean,System.Collections.Generic.List{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},System.Nullable{System.Guid})"> <member name="M:IRaCIS.Application.Services.ReadingImageTaskService.FindChildQuestion(IRaCIS.Core.Application.Service.Reading.Dto.TrialReadQuestionData,System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.TrialReadQuestionData},System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.TableQuestionTrial},System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionAnswerInfo},System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.TableAnsweRowInfo},System.Collections.Generic.List{IRaCIS.Core.Domain.Models.OrganInfo},System.Collections.Generic.List{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},System.Boolean,System.Collections.Generic.List{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},System.Nullable{System.Guid})">
<summary> <summary>
获取子元素 获取子元素
</summary> </summary>
<param name="item"></param> <param name="item"></param>
<param name="questionlists"></param> <param name="questionlists"></param>
<param name="tableQuestionLists"></param> <param name="tableQuestionLists"></param>
<param name="tableAnswers"></param>
<param name="tableAnsweRowInfos"></param>
<param name="organInfos"></param>
<param name="baseLineTableAnswer"></param>
<param name="isFirstChangeTask"></param>
<param name="lastTaskTableAnswer"></param>
<param name="TaskId"></param>
</member> </member>
<member name="M:IRaCIS.Application.Services.ReadingImageTaskService.SplitLesion(IRaCIS.Core.Application.Service.Reading.Dto.SplitLesionInDto)"> <member name="M:IRaCIS.Application.Services.ReadingImageTaskService.SplitLesion(IRaCIS.Core.Application.Service.Reading.Dto.SplitLesionInDto)">
<summary> <summary>
@@ -78,120 +78,7 @@ namespace IRaCIS.Core.Application.Service
return ResponseOutput.Ok(); return ResponseOutput.Ok();
} }
/// <summary>
/// 产生医学审核
/// </summary>
/// <returns></returns>
[Obsolete]
public async Task<IResponseOutput> GenerateMedicalReviewTask(GenerateMedicalReviewTaskCommand generateCommand)
{
var trialId = generateCommand.TrialId;
//var mimUserList = await _trialUserRepository.Where(t => t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MIM && t.TrialId == trialId).Select(t => t.User).ProjectTo<UserSimpleInfo>(_mapper.ConfigurationProvider).ToListAsync();
Guid? defalutMIMUserId = null /*mimUserList.FirstOrDefault()?.UserId*/;
//获取当前医生数据 已经生成的,和配置的数量
var taskTaskMedicalReviewRuleList = await _taskMedicalReviewRuleRepository.Where(t => t.TrialId == trialId).ProjectTo<TaskMedicalReviewRuleView>(_mapper.ConfigurationProvider).ToListAsync();
foreach (var item in taskTaskMedicalReviewRuleList)
{
if (item.IsEnable)
{
if (item.PlanGlobalCount > item.GeneratedGlobalCount)
{
var needGenerateCount = item.PlanGlobalCount - item.GeneratedGlobalCount;
var canGenerateCount = item.ActualGlobalCount - item.GeneratedGlobalCount;
var toGenerateCount = canGenerateCount > needGenerateCount ? needGenerateCount : canGenerateCount;
//分配给MIM
if (toGenerateCount > 0)
{
var toGenerateTaskList = item.ActualGlobalTaskList.ExceptBy(item.GeneratedGlobalTaskList.Select(t => t.TaskId), t => t.TaskId).Take(toGenerateCount).ToList();
foreach (var toGenerateTask in toGenerateTaskList)
{
await _taskMedicalReviewRepository.AddAsync(new TaskMedicalReview() { DoctorUserId = toGenerateTask.DoctorUserId!.Value, TrialId = toGenerateTask.TrialId, VisitTaskId = toGenerateTask.TaskId, MedicalManagerUserId = defalutMIMUserId });
}
}
}
if (item.PlanJudgeCount > item.GeneratedJudgeCount)
{
var needGenerateCount = item.PlanJudgeCount - item.GeneratedJudgeCount;
var canGenerateCount = item.ActualJudgeCount - item.GeneratedGlobalCount;
var toGenerateCount = canGenerateCount > needGenerateCount ? needGenerateCount : canGenerateCount;
if (toGenerateCount > 0)
{
var toGenerateTaskList = item.ActualJudgeTaskList.ExceptBy(item.GeneratedJudgeTaskList.Select(t => t.TaskId), t => t.TaskId).Take(toGenerateCount).ToList();
foreach (var toGenerateTask in toGenerateTaskList)
{
await _taskMedicalReviewRepository.AddAsync(new TaskMedicalReview() { DoctorUserId = toGenerateTask.DoctorUserId!.Value, TrialId = toGenerateTask.TrialId, VisitTaskId = toGenerateTask.TaskId, MedicalManagerUserId = defalutMIMUserId });
}
}
}
if (item.PlanTumorCount > item.GeneratedTumorCount)
{
var needGenerateCount = item.PlanTumorCount - item.GeneratedTumorCount;
var canGenerateCount = item.ActualTumorCount - item.GeneratedGlobalCount;
var toGenerateCount = canGenerateCount > needGenerateCount ? needGenerateCount : canGenerateCount;
if (toGenerateCount > 0)
{
var toGenerateTaskList = item.ActualTumorTaskList.ExceptBy(item.GeneratedTumorTaskList.Select(t => t.TaskId), t => t.TaskId).Take(toGenerateCount).ToList();
foreach (var toGenerateTask in toGenerateTaskList)
{
await _taskMedicalReviewRepository.AddAsync(new TaskMedicalReview() { DoctorUserId = toGenerateTask.DoctorUserId!.Value, TrialId = toGenerateTask.TrialId, VisitTaskId = toGenerateTask.TaskId, MedicalManagerUserId = defalutMIMUserId });
}
}
}
if (item.PlanVisitCount > item.GeneratedVisitCount)
{
var needGenerateCount = item.PlanVisitCount - item.GeneratedVisitCount;
var canGenerateCount = item.ActualVisitCount - item.GeneratedGlobalCount;
var toGenerateCount = canGenerateCount > needGenerateCount ? needGenerateCount : canGenerateCount;
if (toGenerateCount > 0)
{
var toGenerateTaskList = item.ActualVisitTaskList.ExceptBy(item.GeneratedVisitTaskList.Select(t => t.TaskId), t => t.TaskId).Take(toGenerateCount).ToList();
foreach (var toGenerateTask in toGenerateTaskList)
{
await _taskMedicalReviewRepository.AddAsync(new TaskMedicalReview() { DoctorUserId = toGenerateTask.DoctorUserId!.Value, TrialId = toGenerateTask.TrialId, VisitTaskId = toGenerateTask.TaskId, MedicalManagerUserId = defalutMIMUserId });
}
}
}
}
}
await _taskMedicalReviewRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
} }
@@ -233,83 +233,8 @@ namespace IRaCIS.Core.Application.Service
&& t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.TaskState == TaskState.Effect
&& t.SourceSubjectVisitId == subjectVisit.Id).ToList(); && t.SourceSubjectVisitId == subjectVisit.Id).ToList();
if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double) //只有单重阅片
{ if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single)
VisitTask? task1 = existCurrentVisitTaskList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1);
VisitTask? task2 = existCurrentVisitTaskList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2);
if (!existCurrentVisitTaskList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1))
{
currentMaxCodeInt = currentMaxCodeInt + 1;
task1 = await _visitTaskRepository.AddAsync(new VisitTask()
{
TrialId = trialId,
SubjectId = subjectVisit.SubjectId,
IsUrgent = subjectVisit.IsUrgent,
TaskBlindName = blindTaskName,
TaskName = subjectVisit.VisitName,
VisitTaskNum = subjectVisit.VisitNum,
TaskUrgentType = taskUrgentType,
IsCanEditUrgentState = isCanEditUrgentState,
//CheckPassedTime = subjectVisit.CheckPassedTime,
ArmEnum = Arm.DoubleReadingArm1,//特殊
Code = currentMaxCodeInt,
SourceSubjectVisitId = subjectVisit.Id,
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt, nameof(VisitTask)),
ReadingCategory = ReadingCategory.Visit,
TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId,
IsNeedClinicalDataSign = isNeedClinicalDataSign,
IsClinicalDataSign = isClinicalDataSign
});
}
if (!existCurrentVisitTaskList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2))
{
currentMaxCodeInt = currentMaxCodeInt + 1;
task2 = await _visitTaskRepository.AddAsync(new VisitTask()
{
TrialId = trialId,
SubjectId = subjectVisit.SubjectId,
IsUrgent = subjectVisit.IsUrgent,
TaskBlindName = blindTaskName,
TaskName = subjectVisit.VisitName,
TaskUrgentType = taskUrgentType,
IsCanEditUrgentState = isCanEditUrgentState,
VisitTaskNum = subjectVisit.VisitNum,
//CheckPassedTime = subjectVisit.CheckPassedTime,
ArmEnum = Arm.DoubleReadingArm2,//特殊
Code = currentMaxCodeInt,
SourceSubjectVisitId = subjectVisit.Id,
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt, nameof(VisitTask)),
ReadingCategory = ReadingCategory.Visit,
TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId,
IsNeedClinicalDataSign = isNeedClinicalDataSign,
IsClinicalDataSign = isClinicalDataSign
});
}
_provider.Set<int>($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30));
var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated;
}
else if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single)
{ {
VisitTask? singleTask = existCurrentVisitTaskList.FirstOrDefault(t => t.ArmEnum == Arm.SingleReadingArm); VisitTask? singleTask = existCurrentVisitTaskList.FirstOrDefault(t => t.ArmEnum == Arm.SingleReadingArm);
@@ -336,8 +261,12 @@ namespace IRaCIS.Core.Application.Service
ReadingCategory = ReadingCategory.Visit, ReadingCategory = ReadingCategory.Visit,
TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId,
IsNeedClinicalDataSign = isNeedClinicalDataSign, IsNeedClinicalDataSign = isNeedClinicalDataSign,
IsClinicalDataSign = isClinicalDataSign IsClinicalDataSign = isClinicalDataSign,
});
SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget)
});
} }
@@ -620,6 +549,7 @@ namespace IRaCIS.Core.Application.Service
var isNeedClinicalDataSign = IsNeedClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionId, clinicalDataConfirmList); var isNeedClinicalDataSign = IsNeedClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionId, clinicalDataConfirmList);
var isClinicalDataSign = IsClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionId, clinicalDataConfirmList, subjectVisit.Id, trialId); var isClinicalDataSign = IsClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionId, clinicalDataConfirmList, subjectVisit.Id, trialId);
var isFrontTaskNeedSignButNotSign = await _visitTaskRepository.AnyAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.TaskState == TaskState.Effect && t.VisitTaskNum < subjectVisit.VisitNum && t.IsNeedClinicalDataSign == true && t.IsClinicalDataSign == false);
if (visitNumList.IndexOf(subjectVisit.VisitNum) == 0) if (visitNumList.IndexOf(subjectVisit.VisitNum) == 0)
{ {
@@ -661,7 +591,8 @@ namespace IRaCIS.Core.Application.Service
TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId,
IsNeedClinicalDataSign = isNeedClinicalDataSign, IsNeedClinicalDataSign = isNeedClinicalDataSign,
IsClinicalDataSign = isClinicalDataSign IsClinicalDataSign = isClinicalDataSign,
IsFrontTaskNeedSignButNotSign= isFrontTaskNeedSignButNotSign
}); });
@@ -681,11 +612,11 @@ namespace IRaCIS.Core.Application.Service
//之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的) //之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的)
var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.TrialReadingCriterionId== trialReadingCriterionId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.TrialReadingCriterionId== trialReadingCriterionId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
singleTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
if (beforeBackVisitTask == null) if (beforeBackVisitTask == null)
{ {
singleTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
@@ -765,7 +696,11 @@ namespace IRaCIS.Core.Application.Service
} }
else
{
singleTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
#endregion #endregion
@@ -876,6 +811,8 @@ namespace IRaCIS.Core.Application.Service
// AllocateTime = DateTime.Now, // AllocateTime = DateTime.Now,
//DoctorUserId = reReadingVisitTask.DoctorUserId, //DoctorUserId = reReadingVisitTask.DoctorUserId,
SuggesteFinishedTime= reReadingVisitTask.SuggesteFinishedTime,
}); });
generateTaskCommand.Action(newTask); generateTaskCommand.Action(newTask);
@@ -642,13 +642,11 @@ namespace IRaCIS.Core.Application.Service.Allocation
/// 获取有序阅片IQuery对象 /// 获取有序阅片IQuery对象
/// </summary> /// </summary>
/// <param name="inDto"></param> /// <param name="inDto"></param>
/// <returns></returns> /// <returns></returns>
public async Task<(int, List<IRUnReadSubjectView>)> GetOrderReadingIQueryable(GetOrderReadingIQueryableInDto inDto) public async Task<(int, List<IRUnReadSubjectView>)> GetOrderReadingIQueryable(GetOrderReadingIQueryableInDto inDto)
{ {
var trialReadingCriterionId = inDto.TrialReadingCriterionId; var trialReadingCriterionId = inDto.TrialReadingCriterionId;
//Expression<Func<VisitTask, bool>> visitTaskLambda = x => x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId;
var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId); var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId);
@@ -844,7 +842,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
var requestRecordList = await _visitTaskReReadingRepository.Where(t => baseLineTaskIdList.Contains(t.OriginalReReadingTaskId) && t.RequestReReadingUserId == _userInfo.Id && t.RequestReReadingReason == "AIR自动重阅基线").ToListAsync(); var requestRecordList = await _visitTaskReReadingRepository.Where(t => baseLineTaskIdList.Contains(t.OriginalReReadingTaskId) && t.RequestReReadingUserId == _userInfo.Id && t.RequestReReadingReason == "AIR自动重阅基线").ToListAsync();
if (requestRecordList.Count() != baseLineTaskIdList.Count()) if (requestRecordList.Count != baseLineTaskIdList.Count)
{ {
//---后台数据有错误 //---后台数据有错误
return ResponseOutput.NotOk(_localizer["VisitTask_DoctorConfiguration"]); return ResponseOutput.NotOk(_localizer["VisitTask_DoctorConfiguration"]);
@@ -967,6 +965,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
/// </summary> /// </summary>
/// <param name="origenalTask"></param> /// <param name="origenalTask"></param>
/// <param name="agreeReReadingCommand"></param> /// <param name="agreeReReadingCommand"></param>
/// <exception cref="BusinessValidationFailedException"></exception>
private void ReReadingTaskTrackingDeal(VisitTask origenalTask, ConfirmReReadingCommand agreeReReadingCommand) private void ReReadingTaskTrackingDeal(VisitTask origenalTask, ConfirmReReadingCommand agreeReReadingCommand)
{ {
if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
@@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Application.Contracts;
namespace IRaCIS.Core.Application.Service namespace IRaCIS.Core.Application.Service
{ {
@@ -99,15 +100,58 @@ namespace IRaCIS.Core.Application.Service
//---读取模板内容失败, 请将文件另存为docx格式尝试! //---读取模板内容失败, 请将文件另存为docx格式尝试!
return ResponseOutput.NotOk(_localizer["Document_ TemplateRead"]); return ResponseOutput.NotOk(_localizer["Document_ TemplateRead"]);
} }
} }
} }
var entity = await _commonDocumentRepository.InsertOrUpdateAsync(addOrEditCommonDocument, true, verifyExp1, verifyExp2);
if (addOrEditCommonDocument.Id == null) //insert
{
return ResponseOutput.Ok(entity.Id.ToString());
var entity = await _commonDocumentRepository.InsertFromDTOAsync(addOrEditCommonDocument, true, verifyExp1, verifyExp2);
return ResponseOutput.Ok(entity.Id.ToString());
}
else //update
{
var dbbeforeEntity = await _commonDocumentRepository.UpdateFromDTOAsync(addOrEditCommonDocument, true, true, verifyExp1, verifyExp2);
var filePath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, dbbeforeEntity.Path);
if (File.Exists(filePath))
{
File.Delete(filePath);
}
return ResponseOutput.Ok();
}
}
[HttpDelete("{commonDocumentId:guid}")]
public async Task<IResponseOutput> DeleteCommonDocument(Guid commonDocumentId)
{
var find= await _commonDocumentRepository.FirstOrDefaultNoTrackingAsync(t=>t.Id== commonDocumentId);
var success = await _commonDocumentRepository.DeleteFromQueryAsync(t => t.Id == commonDocumentId, true,true);
if (find != null)
{
var filePath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, find.Path);
if (File.Exists(filePath))
{
File.Delete(filePath);
}
}
return ResponseOutput.Ok();
} }
} }
@@ -25,7 +25,6 @@ namespace IRaCIS.Application.Services
private readonly IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository; private readonly IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository;
private readonly IRepository<ReadingQuestionCriterionSystem> _readingQuestionCriterionSystem; private readonly IRepository<ReadingQuestionCriterionSystem> _readingQuestionCriterionSystem;
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrial; private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrial;
private readonly IReadingQuestionService _readingQuestionService;
public DictionaryService(IRepository<Dictionary> sysDicRepository, IRepository<TrialDictionary> trialDictionaryRepository, public DictionaryService(IRepository<Dictionary> sysDicRepository, IRepository<TrialDictionary> trialDictionaryRepository,
IRepository<Trial> trialRepository, IRepository<Trial> trialRepository,
@@ -35,8 +34,7 @@ namespace IRaCIS.Application.Services
IRepository<ReadingTrialCriterionDictionary> readingTrialCriterionDictionaryRepository, IRepository<ReadingTrialCriterionDictionary> readingTrialCriterionDictionaryRepository,
IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository, IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository,
IRepository<ReadingQuestionCriterionSystem> readingQuestionCriterionSystem, IRepository<ReadingQuestionCriterionSystem> readingQuestionCriterionSystem,
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrial, IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrial
IReadingQuestionService readingQuestionService
) )
@@ -52,7 +50,6 @@ namespace IRaCIS.Application.Services
this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository; this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository;
this._readingQuestionCriterionSystem = readingQuestionCriterionSystem; this._readingQuestionCriterionSystem = readingQuestionCriterionSystem;
this._readingQuestionCriterionTrial = readingQuestionCriterionTrial; this._readingQuestionCriterionTrial = readingQuestionCriterionTrial;
this._readingQuestionService = readingQuestionService;
} }
/// <summary> /// <summary>
@@ -490,7 +490,7 @@ namespace IRaCIS.Core.Application.Service.Common
} }
var memoryStream2 = new MemoryStream(); var memoryStream2 = new MemoryStream();
wb.Write(memoryStream2); wb.Write(memoryStream2,true);
memoryStream2.Seek(0, SeekOrigin.Begin); memoryStream2.Seek(0, SeekOrigin.Begin);
return new FileStreamResult(memoryStream2, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") return new FileStreamResult(memoryStream2, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
@@ -970,7 +970,6 @@ namespace IRaCIS.Core.Application.Service.Common
/// <param name="_commonDocumentRepository"></param> /// <param name="_commonDocumentRepository"></param>
/// <param name="_dictionaryService"></param> /// <param name="_dictionaryService"></param>
/// <param name="_trialRepository"></param> /// <param name="_trialRepository"></param>
/// <param name="inQuery"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<IActionResult> GetGroupAnalysisTaskList_Export(VisitTaskQuery queryVisitTask, public async Task<IActionResult> GetGroupAnalysisTaskList_Export(VisitTaskQuery queryVisitTask,
@@ -42,12 +42,10 @@ namespace IRaCIS.Application.Services
private readonly IRepository<SystemBasicData> _systemBasicDatarepository; private readonly IRepository<SystemBasicData> _systemBasicDatarepository;
private readonly IWebHostEnvironment _hostEnvironment;
private readonly IRepository<User> _userRepository; private readonly IRepository<User> _userRepository;
private readonly ITokenService _tokenService; private readonly ITokenService _tokenService;
private readonly IMapper _mapper;
private readonly IRepository<Trial> _trialRepository; private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<UserType> _userTypeRepository; private readonly IRepository<UserType> _userTypeRepository;
@@ -61,7 +59,6 @@ namespace IRaCIS.Application.Services
public MailVerificationService(IRepository<VerificationCode> verificationCodeRepository, public MailVerificationService(IRepository<VerificationCode> verificationCodeRepository,
IRepository<SystemBasicData> systemBasicDatarepository, IRepository<SystemBasicData> systemBasicDatarepository,
IWebHostEnvironment hostEnvironment,
IRepository<User> userRepository, IRepository<User> userRepository,
ITokenService tokenService, ITokenService tokenService,
IRepository<Trial> trialRepository, IRepository<Trial> trialRepository,
@@ -72,9 +69,7 @@ namespace IRaCIS.Application.Services
_verificationCodeRepository = verificationCodeRepository; _verificationCodeRepository = verificationCodeRepository;
_systemBasicDatarepository = systemBasicDatarepository; _systemBasicDatarepository = systemBasicDatarepository;
_hostEnvironment = hostEnvironment;
_mapper = mapper;
_tokenService = tokenService; _tokenService = tokenService;
_userRepository = userRepository; _userRepository = userRepository;
@@ -163,7 +158,7 @@ namespace IRaCIS.Application.Services
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress)); messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
//主题 //主题
//---[来自展影IRC] 关于重置密码的提醒 //---[来自展影IRC] 关于重置密码的提醒
messageToSend.Subject = _localizer["Mail_IRCResettingPassword "]; messageToSend.Subject = _localizer["Mail_IRCResettingPassword"];
@@ -183,7 +178,7 @@ namespace IRaCIS.Application.Services
builder.HtmlBody = string.Format(templateInfo, builder.HtmlBody = string.Format(templateInfo,
//---您正在进行邮箱重置密码操作 //---您正在进行邮箱重置密码操作
_localizer["Mail_ResettingPassword "], _localizer["Mail_ResettingPassword"],
verificationCode verificationCode
); );
} }
@@ -31,6 +31,8 @@ namespace IRaCIS.Core.Application.Service
Task SendTrialQCQuestionEmailAsync(Guid trialId); Task SendTrialQCQuestionEmailAsync(Guid trialId);
Task SendTrialImageQuestionAsync(Guid trialId); Task SendTrialImageQuestionAsync(Guid trialId);
Task SendPIAuditResultAsync(Guid visitTaskId); Task SendPIAuditResultAsync(Guid visitTaskId);
Task<(TrialEmailNoticeConfig?, SMTPEmailConfig?)> BuildEmailConfig(Guid trialId, EmailBusinessScenario businessScenario, Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc, Guid? siteId = null, Guid? trialReadingCriterionId = null);
} }
public class EmailSendService : BaseService, IEmailSendService public class EmailSendService : BaseService, IEmailSendService
@@ -41,18 +43,19 @@ namespace IRaCIS.Core.Application.Service
private readonly IRepository<Trial> _trialRepository; private readonly IRepository<Trial> _trialRepository;
private readonly IDictionaryService _dictionaryService;
private readonly IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig; private readonly IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig;
public readonly static string EmailNamePlaceholder = "EmailNamePlaceholder"; public readonly static string EmailNamePlaceholder = "EmailNamePlaceholder";
public EmailSendService(IRepository<TrialEmailNoticeConfig> trialEmailNoticeConfigRepository, IRepository<EmailNoticeConfig> emailNoticeConfigRepository, IRepository<Trial> trialRepository, IOptionsMonitor<SystemEmailSendConfig> systemEmailSendConfig, IDictionaryService dictionaryService) private readonly IRepository<Dictionary> _dictionaryRepository;
public EmailSendService(IRepository<TrialEmailNoticeConfig> trialEmailNoticeConfigRepository, IRepository<EmailNoticeConfig> emailNoticeConfigRepository, IRepository<Trial> trialRepository, IOptionsMonitor<SystemEmailSendConfig> systemEmailSendConfig,IRepository<Dictionary> dictionaryRepository)
{ {
_trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository; _trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository;
_emailNoticeConfigRepository = emailNoticeConfigRepository; _emailNoticeConfigRepository = emailNoticeConfigRepository;
_trialRepository = trialRepository; _trialRepository = trialRepository;
_SystemEmailSendConfig = systemEmailSendConfig; _SystemEmailSendConfig = systemEmailSendConfig;
_dictionaryService = dictionaryService; _dictionaryRepository=dictionaryRepository;
} }
//入组确认/PD确认 //入组确认/PD确认
@@ -309,7 +312,11 @@ namespace IRaCIS.Core.Application.Service
var needTranslateDicNameList = answerList.Where(t => !string.IsNullOrEmpty(t.DictionaryCode)).Select(t => t.DictionaryCode).ToList(); var needTranslateDicNameList = answerList.Where(t => !string.IsNullOrEmpty(t.DictionaryCode)).Select(t => t.DictionaryCode).ToList();
var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslateDicNameList.ToArray());
var searchList = await _dictionaryRepository.Where(t => needTranslateDicNameList.ToArray().Contains(t.Parent.Code) && t.ParentId != null && t.IsEnable).ProjectTo<BasicDicSelectCopy>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).ToListAsync();
var translateDataList = searchList.GroupBy(t => t.ParentCode).ToDictionary(g => g.Key, g => g.OrderBy(t => t.ShowOrder).ToList());
Func<bool, string, string, string> transFunc = (bool isNeedTranslate, string dicCode, string answer) => Func<bool, string, string, string> transFunc = (bool isNeedTranslate, string dicCode, string answer) =>
@@ -414,7 +421,7 @@ namespace IRaCIS.Core.Application.Service
sendEmailConfig.HtmlBodyStr = htmlBodyStr.Replace(EmailNamePlaceholder, string.Join(isEn_us ? ", " : "、", toUserList.Select(t => t.FullName).ToList())); sendEmailConfig.HtmlBodyStr = htmlBodyStr.Replace(EmailNamePlaceholder, string.Join(isEn_us ? ", " : "、", toUserList.Select(t => t.FullName).ToList()));
} }
if (toUserList.Count() == 0) if (toUserList.Count == 0)
{ {
//---没有收件人,无法发送邮件 //---没有收件人,无法发送邮件
throw new BusinessValidationFailedException(_localizer["TrialEmailN_NoRecipient"]); throw new BusinessValidationFailedException(_localizer["TrialEmailN_NoRecipient"]);
@@ -463,6 +470,142 @@ namespace IRaCIS.Core.Application.Service
} }
} }
public async Task<(TrialEmailNoticeConfig?, SMTPEmailConfig?)> BuildEmailConfig(Guid trialId, EmailBusinessScenario businessScenario, Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc, Guid? siteId = null, Guid? trialReadingCriterionId = null)
{
//找到配置
var trialEmailConfig = await _trialEmailNoticeConfigRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.BusinessScenarioEnum == businessScenario, ignoreQueryFilters: true)
.Include(t => t.TrialEmailNoticeUserList).Include(t => t.TrialEmailBlackUserList).FirstOrDefaultAsync();
if (trialEmailConfig == null || trialEmailConfig.IsAutoSend == false)
{
return (null, null);
}
else
{
var sendEmailConfig = new SMTPEmailConfig();
var (topicStr, htmlBodyStr, isEn_us, onlyToUserId) = topicAndHtmlFunc(trialEmailConfig);
sendEmailConfig.TopicDescription = topicStr;
sendEmailConfig.HtmlBodyStr = htmlBodyStr;
var blackUserIdList = trialEmailConfig.TrialEmailBlackUserList.Select(t => t.UserId).ToList();
var toUserTypeEnumList = trialEmailConfig.TrialEmailNoticeUserList.Where(t => t.EmailUserType == EmailUserType.To).Select(c => c.UserType).ToList();
var copyUserTypeEnumList = trialEmailConfig.TrialEmailNoticeUserList.Where(t => t.EmailUserType == EmailUserType.Copy).Select(c => c.UserType).ToList();
var allUserTypeEnumList = toUserTypeEnumList.Union(copyUserTypeEnumList).Distinct().ToList();
var allUserList = await _repository.Where<TrialUser>(t => t.TrialId == trialId && allUserTypeEnumList.Contains(t.User.UserTypeEnum)).Select(t => new { t.UserId, t.User.EMail, t.User.FullName, t.User.UserTypeEnum }).ToListAsync();
var toUserList = allUserList.Where(t => toUserTypeEnumList.Contains(t.UserTypeEnum))
.ToList();
//收件人 有CRC CRA , CRC CRA的账户要按照中心发送
if (siteId == null && toUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA) && onlyToUserId == null)
{
throw new BusinessValidationFailedException("当前场景收件人包含CRC CRA,但是没有siteId,请联系后端开发");
}
if (siteId != null && toUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA))
{
var curentSiteUserIdList = _repository.Where<TrialSiteUser>(t => t.TrialId == trialId && t.SiteId == siteId).Select(t => t.UserId).ToList();
toUserList = toUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList();
}
//去除黑名单
toUserList = toUserList.Where(t => !blackUserIdList.Contains(t.UserId)).ToList();
var copyUserList = allUserList.Where(t => copyUserTypeEnumList.Contains(t.UserTypeEnum))
.Where(t => !blackUserIdList.Contains(t.UserId)).ToList();
if (siteId != null && copyUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA))
{
var curentSiteUserIdList = _repository.Where<TrialSiteUser>(t => t.TrialId == trialId && t.SiteId == siteId).Select(t => t.UserId).ToList();
copyUserList = copyUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList();
}
if (onlyToUserId != null)
{
toUserList = toUserList.Where(t => t.UserId == onlyToUserId).ToList();
}
else
{
sendEmailConfig.HtmlBodyStr = htmlBodyStr.Replace(EmailNamePlaceholder, string.Join(isEn_us ? ", " : "、", toUserList.Select(t => t.FullName).ToList()));
}
if (toUserList.Count == 0)
{
//---没有收件人,无法发送邮件
throw new BusinessValidationFailedException(_localizer["TrialEmailN_NoRecipient"]);
}
if (trialEmailConfig.FromEmail.Contains("@") && !string.IsNullOrEmpty(trialEmailConfig.FromEmail))
{
sendEmailConfig.FromEmailAddress = new MimeKit.MailboxAddress(trialEmailConfig.FromName, trialEmailConfig.FromEmail);
sendEmailConfig.AuthorizationCode = trialEmailConfig.AuthorizationCode;
sendEmailConfig.UserName = trialEmailConfig.FromEmail;
sendEmailConfig.Host = trialEmailConfig.SMTPServerAddress;
sendEmailConfig.Port = trialEmailConfig.SMTPServerPort;
}
else
{
//---项目发件邮箱配置有误,请核实
throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidEmailConfig"]);
}
foreach (var item in toUserList)
{
if (item.EMail.Contains("@") && !string.IsNullOrEmpty(item.EMail))
{
sendEmailConfig.ToMailAddressList.Add(new MimeKit.MailboxAddress(item.FullName, item.EMail));
}
}
foreach (var item in copyUserList)
{
if (item.EMail.Contains("@") && !string.IsNullOrEmpty(item.EMail))
{
sendEmailConfig.CopyToMailAddressList.Add(new MimeKit.MailboxAddress(item.FullName, item.EMail));
}
}
//邮件附件 这里是原格式发送,不是PDF
//if (trialEmailConfig.AttachCNPath != string.Empty && trialEmailConfig.AttachPath != string.Empty)
//{
// var phyPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, isEn_us? trialEmailConfig.AttachName: trialEmailConfig.AttachNameCN);
// //先预先生成了邮件,发送预先生成的邮件
// sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig()
// {
// FileName = $"{attachPrefix}_{Path.GetFileName(_userInfo.IsEn_Us ? trialEmailConfig.AttachName : trialEmailConfig.AttachNameCN)}",
// FileStream = File.OpenRead(phyPath),
// });
//}
return (trialEmailConfig, sendEmailConfig);
}
}
} }
} }
@@ -658,7 +658,7 @@ namespace IRaCIS.Core.Application.Services
/// <param name="isSystemDoc"></param> /// <param name="isSystemDoc"></param>
/// <returns></returns> /// <returns></returns>
[HttpPut("{documentId:guid}/{isSystemDoc:bool}")] [HttpPut("{documentId:guid}/{isSystemDoc:bool}")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "AfterStopCannNotOpt", "SignSystemDocNoTrialId" })]
public async Task<IResponseOutput> UserAbandonDoc(Guid documentId, bool isSystemDoc) public async Task<IResponseOutput> UserAbandonDoc(Guid documentId, bool isSystemDoc)
{ {
if (isSystemDoc) if (isSystemDoc)
@@ -21,6 +21,11 @@ using IRaCIS.Core.Domain.Share.Common;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Spire.Doc; using Spire.Doc;
using Microsoft.AspNetCore.Http;
using System;
using System.Runtime.InteropServices;
using SharpCompress.Common;
using SkiaSharp;
namespace IRaCIS.Core.Application.Service namespace IRaCIS.Core.Application.Service
{ {
@@ -42,7 +47,7 @@ namespace IRaCIS.Core.Application.Service
private readonly IRepository<TrialUser> _trialUserRepository; private readonly IRepository<TrialUser> _trialUserRepository;
private readonly IRepository<Subject> _subjectRepository; private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<SubjectVisit> _subjectVisitRepository; private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IEmailSendService _emailSendService;
@@ -56,6 +61,7 @@ namespace IRaCIS.Core.Application.Service
IRepository<SubjectVisit> subjectVisitRepository, IRepository<SubjectVisit> subjectVisitRepository,
IRepository<TrialEmailBlackUser> trialEmailBlackUserRepository, IRepository<TrialEmailBlackUser> trialEmailBlackUserRepository,
IRepository<EmailNoticeConfig> emailNoticeConfigRepository IRepository<EmailNoticeConfig> emailNoticeConfigRepository
, IEmailSendService emailSendService
) )
{ {
_trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository; _trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository;
@@ -67,6 +73,7 @@ namespace IRaCIS.Core.Application.Service
_subjectVisitRepository = subjectVisitRepository; _subjectVisitRepository = subjectVisitRepository;
_trialEmailBlackUserRepository = trialEmailBlackUserRepository; _trialEmailBlackUserRepository = trialEmailBlackUserRepository;
_emailNoticeConfigRepository = emailNoticeConfigRepository; _emailNoticeConfigRepository = emailNoticeConfigRepository;
_emailSendService = emailSendService;
} }
/// <summary> /// <summary>
@@ -255,8 +262,8 @@ namespace IRaCIS.Core.Application.Service
/// <exception cref="BusinessValidationFailedException"></exception> /// <exception cref="BusinessValidationFailedException"></exception>
public async Task<string> BaseBusinessScenarioSendEmailAsync(Guid visitTaskId, bool? isHandSend, EmailStoreSendMode emailStoreMode, string sendFileRelativePath) public async Task<string> BaseBusinessScenarioSendEmailAsync(Guid visitTaskId, bool? isHandSend, EmailStoreSendMode emailStoreMode, string sendFileRelativePath)
{ {
var isEn_us = _userInfo.IsEn_Us;
EmailBusinessScenario? businessScenarioEnum = null; EmailBusinessScenario businessScenarioEnum = EmailBusinessScenario.None;
#region subject #region subject
var taskInfo = await _visitTaskRepository.Where(t => t.Id == visitTaskId).Select(t => new var taskInfo = await _visitTaskRepository.Where(t => t.Id == visitTaskId).Select(t => new
@@ -352,286 +359,119 @@ namespace IRaCIS.Core.Application.Service
#endregion #endregion
#region #region
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
var emailConfig = await _trialEmailNoticeConfigRepository.Where(t => t.TrialId == taskInfo.TrialId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.BusinessScenarioEnum == businessScenarioEnum)
.Include(t => t.TrialEmailNoticeUserList).FirstOrDefaultAsync();
if (emailConfig == null || (emailConfig.IsAutoSend == false && isHandSend == null))
{ {
//throw new BusinessValidationFailedException("找不到该项目标准场景下邮件的配置"); var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode);
return string.Empty; var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
} StaticData.EmailSend.EmailNamePlaceholder, taskInfo.ResearchProgramNo, taskInfo.SubjectCode);
var sendEmailConfig = new SMTPEmailConfig(); return (topicStr, htmlBodyStr, isEn_us, null);
};
//收件人 如果是CRC CRA 要按照中心发送
var toUserTypeEnumList = emailConfig.TrialEmailNoticeUserList.Where(t => t.EmailUserType == EmailUserType.To).Select(c => c.UserType).ToList();
var (trialEmailConfig, sendEmailConfig) = await _emailSendService.BuildEmailConfig(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc, taskInfo.SiteId);
var toUserList = _repository.Where<TrialSiteUser>(t => t.TrialId == taskInfo.TrialId && toUserTypeEnumList.Contains(t.User.UserTypeEnum) && t.SiteId == taskInfo.SiteId).Select(t => new { t.User.EMail, t.User.FullName }).ToList();
var copyUserTypeEnumList = emailConfig.TrialEmailNoticeUserList.Where(t => t.EmailUserType == EmailUserType.Copy).Select(c => c.UserType).ToList();
var copyUserList = _repository.Where<TrialUser>(t => t.TrialId == taskInfo.TrialId && copyUserTypeEnumList.Contains(t.User.UserTypeEnum)).Select(t => new { t.User.EMail, t.User.FullName }).ToList();
if (toUserList.Count() == 0)
{
//---没有收件人,无法发送邮件
throw new BusinessValidationFailedException(_localizer["TrialEmailN_NoRecipient"]);
}
if (emailConfig.FromEmail.Contains("@") && !string.IsNullOrEmpty(emailConfig.FromEmail))
{
sendEmailConfig.FromEmailAddress = new MimeKit.MailboxAddress(emailConfig.FromName, emailConfig.FromEmail);
sendEmailConfig.AuthorizationCode = emailConfig.AuthorizationCode;
sendEmailConfig.UserName = emailConfig.FromEmail;
sendEmailConfig.Host = emailConfig.SMTPServerAddress;
sendEmailConfig.Port = emailConfig.SMTPServerPort;
//测试
//sendEmailConfig.ToMailAddressList.Add(new MimeKit.MailboxAddress("ddd", "872297557@qq.com"));
}
else
{
//---项目发件邮箱配置有误,请核实
throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidEmailConfig"]);
}
foreach (var item in toUserList)
{
if (item.EMail.Contains("@") && !string.IsNullOrEmpty(item.EMail))
{
sendEmailConfig.ToMailAddressList.Add(new MimeKit.MailboxAddress(item.FullName, item.EMail));
}
}
foreach (var item in copyUserList)
{
if (item.EMail.Contains("@") && !string.IsNullOrEmpty(item.EMail))
{
sendEmailConfig.CopyToMailAddressList.Add(new MimeKit.MailboxAddress(item.FullName, item.EMail));
}
}
#endregion
#region Html存在
//邮件附件
var path = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, _userInfo.IsEn_Us ? emailConfig.AttachPath : emailConfig.AttachCNPath);
if (!File.Exists(path))
{
//---找不到该项目标准场景下邮件模板
throw new BusinessValidationFailedException(_localizer["TrialEmailN_EmailTemplateNotFound"]);
}
var pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
//+ "SubjectEnrollConfirmOrPDProgress.html";
+ (_userInfo.IsEn_Us ? "SubjectEnrollConfirmOrPDProgress_US.html" : "SubjectEnrollConfirmOrPDProgress.html");
#endregion #endregion
#region Tile
if (businessScenarioEnum == EmailBusinessScenario.EnrollConfirmed) //自动发送
if (sendEmailConfig != null && trialEmailConfig !=null)
{ {
sendEmailConfig.TopicDescription = _localizer["TrialEmailN_EnrollmentConfirmation", taskInfo.ResearchProgramNo, taskInfo.SubjectCode]; #region
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) var answer = "否";
var isNeedSend = true;
var minUserIdList = _trialUserRepository.Where(t => t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MIM && t.TrialId == taskInfo.TrialId).Select(t => t.UserId).ToList();
//入组确认 根据每个标准配置的是否自动发送,发送邮件与否
if (businessScenarioEnum == EmailBusinessScenario.EnrollConfirmed)
{ {
var templateInfo = SourceReader.ReadToEnd(); if (await _repository.Where<ReadingTableQuestionAnswer>().AnyAsync(x => x.VisitTaskId == visitTaskId && x.Answer == TargetState.Exist.GetEnumInt() &&
x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion))
sendEmailConfig.HtmlBodyStr = string.Format(templateInfo,
//--- 附件为疾病进展确认报告,请查收
_localizer["TrialEmailN_SubjectDiseaseProgression"]
);
}
}
else if (businessScenarioEnum == EmailBusinessScenario.PDConfirmed)
{
sendEmailConfig.TopicDescription = _localizer["TrialEmailN_PDReport", taskInfo.ResearchProgramNo, taskInfo.SubjectCode];
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
sendEmailConfig.HtmlBodyStr = string.Format(templateInfo,
//--- 附件为疾病进展确认报告,请查收
_localizer["TrialEmailN_SubjectDiseaseProgression"]
);
}
}
else
{
//
}
#endregion
#region
var answer = "否";
var isNeedSend = true;
var minUserIdList = _trialUserRepository.Where(t => t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MIM && t.TrialId == taskInfo.TrialId).Select(t => t.UserId).ToList();
//入组确认 根据每个标准配置的是否自动发送,发送邮件与否
if (businessScenarioEnum == EmailBusinessScenario.EnrollConfirmed)
{
if (await _repository.Where<ReadingTableQuestionAnswer>().AnyAsync(x => x.VisitTaskId == visitTaskId && x.Answer == TargetState.Exist.GetEnumInt() &&
x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion))
{
answer = "是";
}
//如果其他阅片人已经做了,说明发送了入组确认报告,第二个人做完就不发送了
//入组确认一直交给第一个人,如果第一个人重阅 还未做完,第二个人先做完了,此时不发
var existFirstEnrollTask = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.IsAnalysisCreate == false
&& t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId).OrderBy(t => t.SignTime).FirstOrDefaultAsync();
//入组确认的医生已确定
if ((existFirstEnrollTask != null) && (taskInfo.DoctorUserId != existFirstEnrollTask.DoctorUserId))
{
isNeedSend = false;
}
else
{
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List<Guid>() { visitTaskId }, minUserIdList);
if (answer == "是")
{ {
//把另外一个人的任务设置为不加急(如果项目加急是否 subject 加急是否) answer = "是";
var urgent = _repository.Where<SubjectVisit>(t => t.Id == taskInfo.SourceSubjectVisitId).Select(t => new { IsSubjectUrgent = t.Subject.IsUrgent, t.Trial.IsUrgent }).FirstOrDefault();
if (urgent?.IsUrgent == false || urgent?.IsSubjectUrgent == false)
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false &&
t.Id != visitTaskId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId, u => new VisitTask() { IsUrgent = false });
}
} }
//如果其他阅片人已经做了,说明发送了入组确认报告,第二个人做完就不发送了
//入组确认一直交给第一个人,如果第一个人重阅 还未做完,第二个人先做完了,此时不发
var existFirstEnrollTask = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.IsAnalysisCreate == false
&& t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId).OrderBy(t => t.SignTime).FirstOrDefaultAsync();
//入组确认的医生已确定
if ((existFirstEnrollTask != null) && (taskInfo.DoctorUserId != existFirstEnrollTask.DoctorUserId))
{
isNeedSend = false;
}
else
{
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List<Guid>() { visitTaskId }, minUserIdList);
if (answer == "是")
{
//把另外一个人的任务设置为不加急(如果项目加急是否 subject 加急是否)
var urgent = _repository.Where<SubjectVisit>(t => t.Id == taskInfo.SourceSubjectVisitId).Select(t => new { IsSubjectUrgent = t.Subject.IsUrgent, t.Trial.IsUrgent }).FirstOrDefault();
if (urgent?.IsUrgent == false || urgent?.IsSubjectUrgent == false)
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false &&
t.Id != visitTaskId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId, u => new VisitTask() { IsUrgent = false });
}
}
}
} }
else if (businessScenarioEnum == EmailBusinessScenario.PDConfirmed)
}
else if (businessScenarioEnum == EmailBusinessScenario.PDConfirmed)
{
//有序
if (taskInfo.IsReadingTaskViewInOrder)
{ {
//有序
//双重 if (taskInfo.IsReadingTaskViewInOrder)
if (taskInfo.ReadingType == ReadingMethod.Double)
{ {
//仲裁在访视上 就没有全局阅片 没有阅片期
if (taskInfo.ArbitrationRule == ArbitrationRule.Visit) //双重
if (taskInfo.ReadingType == ReadingMethod.Double)
{ {
//找到 访视,裁判 所有有效任务(不可能有全局的) 访视和裁判任务的SourceSubjectVisitId 一样
var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect &&
(t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync();
//这里要求 到这里已经如果有裁判 已经生成裁判了保存数据库 //仲裁在访视上 就没有全局阅片 没有阅片期
//双人阅片,没有产生裁判 第二个人读完发 if (taskInfo.ArbitrationRule == ArbitrationRule.Visit)
if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit) == 2)
{ {
//找到 访视,裁判 所有有效任务(不可能有全局的) 访视和裁判任务的SourceSubjectVisitId 一样
answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType); var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect &&
(t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync();
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList); //这里要求 到这里已经如果有裁判 已经生成裁判了保存数据库
//双人阅片,没有产生裁判 第二个人读完发
} if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit) == 2)
//双人 产生裁判,并且裁判完成 发
else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1)
{
var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().JudgeResultTaskId.Value;
answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Visit, taskInfo.CriterionType);
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList);
}
else
{
isNeedSend = false;
}
}
//仲裁在阅片期
else if (taskInfo.ArbitrationRule == ArbitrationRule.Reading)
{
//是访视任务 不可能是裁判任务(访视上不会生成裁判),也不会是全局任务(全局任务 SourceSubjectVisitId=null
if (taskInfo.SourceSubjectVisitId != null)
{
//访视类型的任务 根本就不需要发送邮件
isNeedSend = false;
}
//是全局任务 或者全局的裁判任务 (如果是全局任务,那么此时裁判任务已经生成)
else if (taskInfo.SouceReadModuleId != null)
{
var taskList = await _visitTaskRepository.Where(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.SouceReadModuleId == taskInfo.SouceReadModuleId
&& (t.ReadingCategory == ReadingCategory.Global || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync();
//两个全局没有裁判
if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Global) == 2)
{ {
answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType); answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType);
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList);
}
//双人全局产生裁判
else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Global).Count() == 2)
{
var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().JudgeResultTaskId.Value; isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList);
answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Global, taskInfo.CriterionType);
}
//双人 产生裁判,并且裁判完成 发
else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1)
{
var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First()!.JudgeResultTaskId!.Value;
answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Visit, taskInfo.CriterionType);
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList); isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList);
@@ -641,256 +481,350 @@ namespace IRaCIS.Core.Application.Service
isNeedSend = false; isNeedSend = false;
} }
}
//仲裁在阅片期
else if (taskInfo.ArbitrationRule == ArbitrationRule.Reading)
{
//是访视任务 不可能是裁判任务(访视上不会生成裁判),也不会是全局任务(全局任务 SourceSubjectVisitId=null
if (taskInfo.SourceSubjectVisitId != null)
{
//访视类型的任务 根本就不需要发送邮件
isNeedSend = false;
}
//是全局任务 或者全局的裁判任务 (如果是全局任务,那么此时裁判任务已经生成)
else if (taskInfo.SouceReadModuleId != null)
{
var taskList = await _visitTaskRepository.Where(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.SouceReadModuleId == taskInfo.SouceReadModuleId
&& (t.ReadingCategory == ReadingCategory.Global || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync();
//两个全局没有裁判
if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Global) == 2)
{
answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType);
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList);
}
//双人全局产生裁判
else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Global).Count() == 2)
{
var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().JudgeResultTaskId!.Value;
answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Global, taskInfo.CriterionType);
isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList);
}
else
{
isNeedSend = false;
}
}
else
{
//---发送PD 进展邮件中发现任务数据有问题!
throw new BusinessValidationFailedException(_localizer["TrialEmailN_PDProgressEmailTask"]);
}
} }
else else
{ {
//---发送PD 进展邮件中发现任务数据有问题!
throw new BusinessValidationFailedException(_localizer["TrialEmailN_PDProgressEmailTask"]); //---双重有序阅片 没有定义该仲裁规则处理逻辑,请联系业务和后台开发核查!
throw new BusinessValidationFailedException(_localizer["TrialEmailN_DoubleBlindedError"]);
} }
} }
//屏蔽单重阅片添加
else else
{ {
isNeedSend = false;
//---双重有序阅片 没有定义该仲裁规则处理逻辑,请联系业务和后台开发核查! return string.Empty;
throw new BusinessValidationFailedException(_localizer["TrialEmailN_DoubleBlindedError"]);
} }
#region
////单重
//else if (taskInfo.ReadingType == ReadingMethod.Single)
//{
// //仲裁在访视上 或者在阅片期
// if (taskInfo.ArbitrationRule != ArbitrationRule.None)
// {
//---单重有序阅片配置有误(不应该有仲裁对象配置),请核查!
// throw new BusinessValidationFailedException(_localizer["TrialEmailN_SingleBlindedSet"]);
// }
// //要求PD 确认的访视 是截止访视 还是非截止访视(根据该访视有没有配置阅片期来判断)
// if (taskInfo.ReadingCategory == ReadingCategory.Visit)
// {
// //存在阅片期 那么就是截止访视
// if (await _repository.Where<ReadModule>(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.SubjectVisitId == taskInfo.SourceSubjectVisitId && t.ReadingSetType == ReadingSetType.ImageReading).AnyAsync())
// {
// isNeedSend = false;
// }
// else//非截止访视 在访视读完后,发送
// {
// answer = await TranslatePdStateAsync(visitTaskId, ReadingCategory.Visit, taskInfo.CriterionType);
// }
// }
// //截止访视 在访视读完,并完成全局阅片后发送全局的结果
// else if (taskInfo.ReadingCategory == ReadingCategory.Global)
// {
// answer = await TranslatePdStateAsync(visitTaskId, ReadingCategory.Global, taskInfo.CriterionType);
// }
// else
// {
//---单重有序阅片 该类型的任务不应进入此处逻辑,请联系后台开发核查!
// throw new BusinessValidationFailedException(_localizer["TrialEmailN_SingleBlindedSequenced"]);
// }
// isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List<Guid>() { visitTaskId }, minUserIdList);
//}
//else
//{
//---有序阅片配置有误(应为单重或者双重阅片),请核查!
// throw new BusinessValidationFailedException(_localizer["TrialEmailN_BlindedSequencedReading"]);
//}
#endregion
} }
//屏蔽无序阅片添加
//屏蔽单重阅片添加
else else
{ {
isNeedSend = false; isNeedSend = false;
return string.Empty; return string.Empty;
} }
#region #region
////单重 // //无序
//else if (taskInfo.ReadingType == ReadingMethod.Single) //else
//{ //{
// //仲裁在访视上 或者在阅片期 // //单重
// if (taskInfo.ArbitrationRule != ArbitrationRule.None)
// {
//---单重有序阅片配置有误(不应该有仲裁对象配置),请核查!
// throw new BusinessValidationFailedException(_localizer["TrialEmailN_SingleBlindedSet"]); // if (taskInfo.ReadingType == ReadingMethod.Single && taskInfo.ArbitrationRule == ArbitrationRule.None)
// {
// answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType);
// isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List<Guid>() { visitTaskId }, minUserIdList);
// } // }
// //双重 截止访视只在阅片期的时候存在 要求PD确认的访视 肯定是非截止访视
// else if (taskInfo.ReadingType == ReadingMethod.Double && taskInfo.ArbitrationRule == ArbitrationRule.Visit)
// //要求PD 确认的访视 是截止访视 还是非截止访视(根据该访视有没有配置阅片期来判断)
// if (taskInfo.ReadingCategory == ReadingCategory.Visit)
// { // {
// //存在阅片期 那么就是截止访视 // //在两位阅片人读完访视后,如果有裁判者等裁判读完,如果无裁判则等第二个人的读完
// if (await _repository.Where<ReadModule>(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.SubjectVisitId == taskInfo.SourceSubjectVisitId && t.ReadingSetType == ReadingSetType.ImageReading).AnyAsync())
// var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect
// && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync();
// //这里要求 到这里已经如果有裁判 已经生成裁判了保存数据库
// if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit) == 2)
// {
// answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType);
// isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList);
// }
// else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1)
// {
// var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().JudgeResultTaskId.Value;
// answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Visit, taskInfo.CriterionType);
// isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList);
// }
// else
// { // {
// isNeedSend = false; // isNeedSend = false;
// } // }
// else//非截止访视 在访视读完后,发送
// {
// answer = await TranslatePdStateAsync(visitTaskId, ReadingCategory.Visit, taskInfo.CriterionType);
// }
// }
// //截止访视 在访视读完,并完成全局阅片后发送全局的结果
// else if (taskInfo.ReadingCategory == ReadingCategory.Global)
// {
// answer = await TranslatePdStateAsync(visitTaskId, ReadingCategory.Global, taskInfo.CriterionType);
// } // }
// else // else
// { // {
//---单重有序阅片 该类型的任务不应进入此处逻辑,请联系后台开发核查! //---无序阅片配置有误(应为单重无仲裁对象,双重针对访视仲裁),请核查!
// throw new BusinessValidationFailedException(_localizer["TrialEmailN_SingleBlindedSequenced"]); // throw new BusinessValidationFailedException(_localizer["TrialEmailN_UnblindedSequencedReading"]);
// } // }
// isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List<Guid>() { visitTaskId }, minUserIdList);
//}
//else
//{
//---有序阅片配置有误(应为单重或者双重阅片),请核查!
// throw new BusinessValidationFailedException(_localizer["TrialEmailN_BlindedSequencedReading"]);
//} //}
#endregion #endregion
} }
//屏蔽无序阅片添加
else else
{ {
isNeedSend = false; isNeedSend = false;
}
#endregion
#region MiniWord
if (emailStoreMode == EmailStoreSendMode.NotStoreLocalOnlySentEmail)
{
var phyPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, sendFileRelativePath);
var attachPrefix = $"{taskInfo.SubjectCode}";
//先预先生成了邮件,发送预先生成的邮件
sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig()
{
FileName = $"{attachPrefix}_{Path.GetFileNameWithoutExtension(_userInfo.IsEn_Us ? trialEmailConfig.AttachName : trialEmailConfig!.AttachNameCN)}.pdf",
FileStream = File.OpenRead(phyPath),
});
await SendEmailHelper.SendEmailAsync(sendEmailConfig);
return string.Empty; return string.Empty;
} }
#region var value = new Dictionary<string, object>()
// //无序 {
//else ["SponsorName"] = taskInfo.SponsorName,
//{ ["ResearchProgramNo"] = taskInfo.ResearchProgramNo,
// //单重 ["TrialSiteCode"] = taskInfo.TrialSiteCode,
["SubjectCode"] = taskInfo.SubjectCode,
["VisitName"] = taskInfo.SourceSubjectVisitId != null ? taskInfo.VisitName : taskInfo.ModuleVisitName,
["EarliestScanDate"] = taskInfo.SourceSubjectVisitId != null ? taskInfo.VisitEarliestScanDate?.ToString("yyyy-MM-dd") : taskInfo.ModuleEarliestScanDate?.ToString("yyyy-MM-dd"),
["SignTime"] = taskInfo.SignTime?.ToString("yyyy-MM-dd"),
["Result"] = answer
};
var path = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, _userInfo.IsEn_Us ? trialEmailConfig.AttachPath : trialEmailConfig.AttachCNPath);
var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetSubjectEnrollConfirmOrPDEmailPath(_hostEnvironment, Path.GetFileName(path), taskInfo.TrialId, taskInfo.SiteId, taskInfo.SubjectId, true);
if (emailStoreMode == EmailStoreSendMode.StoreLocalSend || emailStoreMode == EmailStoreSendMode.OnlyStoreLocalNotSentEmail)
{
MemoryStream wordMemoryStream = new MemoryStream();
// if (taskInfo.ReadingType == ReadingMethod.Single && taskInfo.ArbitrationRule == ArbitrationRule.None) MiniSoftware.MiniWord.SaveAsByTemplate(wordMemoryStream, path, value);
// {
// answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
// isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List<Guid>() { visitTaskId }, minUserIdList); {
// } Document document = new Document();
// //双重 截止访视只在阅片期的时候存在 要求PD确认的访视 肯定是非截止访视
// else if (taskInfo.ReadingType == ReadingMethod.Double && taskInfo.ArbitrationRule == ArbitrationRule.Visit) document.LoadFromStream(wordMemoryStream, FileFormat.Docx);
// {
// //在两位阅片人读完访视后,如果有裁判者等裁判读完,如果无裁判则等第二个人的读完 document.SaveToFile(serverFilePath, FileFormat.PDF);
}
// var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect else
// && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync(); {
var wordStoreServerPath = Path.Combine(Path.GetDirectoryName(serverFilePath), Path.GetFileNameWithoutExtension(serverFilePath) + ".docx");
// //这里要求 到这里已经如果有裁判 已经生成裁判了保存数据库
// if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit) == 2) using (FileStream fileStream = new FileStream(wordStoreServerPath, FileMode.Create, FileAccess.Write))
// { {
wordMemoryStream.WriteTo(fileStream);
// answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType); }
FileConvertHelper.ConvertWordToPdf(wordStoreServerPath, Path.GetDirectoryName(serverFilePath));
// isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList);
// } File.Delete(wordStoreServerPath);
// else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1) }
// {
// var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().JudgeResultTaskId.Value;
// answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Visit, taskInfo.CriterionType);
}
// isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList); //手动生成发送的邮件内容,但是并不发送
if (emailStoreMode == EmailStoreSendMode.OnlyStoreLocalNotSentEmail)
{
isNeedSend = false;
return relativePath;
}
//正常的即时生成邮件 并发送邮件
if (isNeedSend)
{
MemoryStream wordMemoryStream = new MemoryStream();
MemoryStream pdfMemoryStream = new MemoryStream();
MiniSoftware.MiniWord.SaveAsByTemplate(wordMemoryStream, path, value);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Document document = new Document();
document.LoadFromStream(wordMemoryStream, FileFormat.Docx);
document.SaveToStream(pdfMemoryStream, FileFormat.PDF);
}
else
{
var wordStoreServerPath = Path.Combine(Path.GetDirectoryName(serverFilePath), Path.GetFileNameWithoutExtension(serverFilePath) + ".docx");
using (FileStream fileStream = new FileStream(wordStoreServerPath, FileMode.Create, FileAccess.Write))
{
wordMemoryStream.WriteTo(fileStream);
}
FileConvertHelper.ConvertWordToPdf(wordStoreServerPath, Path.GetDirectoryName(serverFilePath));
File.Delete(wordStoreServerPath);
using (FileStream fileStream = new FileStream(serverFilePath, FileMode.Open, FileAccess.Read))
{
fileStream.CopyTo(pdfMemoryStream);
}
}
pdfMemoryStream.Seek(0, SeekOrigin.Begin);
sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig()
{
FileName = $"{taskInfo.SubjectCode}_{Path.GetFileNameWithoutExtension(_userInfo.IsEn_Us ? trialEmailConfig.AttachName : trialEmailConfig.AttachNameCN)}.pdf",
FileStream = pdfMemoryStream
});
await SendEmailHelper.SendEmailAsync(sendEmailConfig);
}
return string.Empty;
// }
// else
// {
// isNeedSend = false;
// }
// }
// else
// {
//---无序阅片配置有误(应为单重无仲裁对象,双重针对访视仲裁),请核查!
// throw new BusinessValidationFailedException(_localizer["TrialEmailN_UnblindedSequencedReading"]);
// }
//}
#endregion #endregion
} }
else else
{ {
isNeedSend = false;
}
#endregion
#region MiniWord
if (emailStoreMode == EmailStoreSendMode.NotStoreLocalOnlySentEmail)
{
var phyPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, sendFileRelativePath);
//先预先生成了邮件,发送预先生成的邮件
sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig()
{
FileName = $"{taskInfo.SubjectCode}_{Path.GetFileNameWithoutExtension(_userInfo.IsEn_Us ? emailConfig.AttachName : emailConfig.AttachNameCN)}.pdf",
FileStream = File.OpenRead(phyPath),
});
await SendEmailHelper.SendEmailAsync(sendEmailConfig);
return string.Empty; return string.Empty;
} }
var value = new Dictionary<string, object>()
{
["SponsorName"] = taskInfo.SponsorName,
["ResearchProgramNo"] = taskInfo.ResearchProgramNo,
["TrialSiteCode"] = taskInfo.TrialSiteCode,
["SubjectCode"] = taskInfo.SubjectCode,
["VisitName"] = taskInfo.SourceSubjectVisitId != null ? taskInfo.VisitName : taskInfo.ModuleVisitName,
["EarliestScanDate"] = taskInfo.SourceSubjectVisitId != null ? taskInfo.VisitEarliestScanDate?.ToString("yyyy-MM-dd") : taskInfo.ModuleEarliestScanDate?.ToString("yyyy-MM-dd"),
["SignTime"] = taskInfo.SignTime?.ToString("yyyy-MM-dd"),
["Result"] = answer
};
var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetSubjectEnrollConfirmOrPDEmailPath(_hostEnvironment, Path.GetFileName(path), taskInfo.TrialId, taskInfo.SiteId, taskInfo.SubjectId, true);
if (emailStoreMode == EmailStoreSendMode.StoreLocalSend || emailStoreMode == EmailStoreSendMode.OnlyStoreLocalNotSentEmail)
{
MemoryStream wordMemoryStream = new MemoryStream();
Document document = new Document();
MiniSoftware.MiniWord.SaveAsByTemplate(wordMemoryStream, path, value);
document.LoadFromStream(wordMemoryStream, FileFormat.Docx);
document.SaveToFile(serverFilePath, FileFormat.PDF);
}
//手动生成发送的邮件内容,但是并不发送
if (emailStoreMode == EmailStoreSendMode.OnlyStoreLocalNotSentEmail)
{
isNeedSend = false;
return relativePath;
}
//正常的即时生成邮件 并发送邮件
if (isNeedSend)
{
MemoryStream memoryStream = new MemoryStream();
MemoryStream pdfMemoryStream = new MemoryStream();
MiniSoftware.MiniWord.SaveAsByTemplate(memoryStream, path, value);
Document document = new Document();
document.LoadFromStream(memoryStream, FileFormat.Docx);
document.SaveToStream(pdfMemoryStream, FileFormat.PDF);
pdfMemoryStream.Seek(0, SeekOrigin.Begin);
sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig()
{
FileName = $"{taskInfo.SubjectCode}_{Path.GetFileNameWithoutExtension(_userInfo.IsEn_Us ? emailConfig.AttachName : emailConfig.AttachNameCN)}.pdf",
FileStream = pdfMemoryStream
});
await SendEmailHelper.SendEmailAsync(sendEmailConfig);
}
return string.Empty;
#endregion
} }
@@ -1027,7 +961,7 @@ namespace IRaCIS.Core.Application.Service
{ {
var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Visit); var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Visit);
var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); var filePath = await BaseBusinessScenarioSendEmailAsync(task!.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty);
return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id });
} }
@@ -1036,7 +970,7 @@ namespace IRaCIS.Core.Application.Service
{ {
var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge); var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge);
var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); var filePath = await BaseBusinessScenarioSendEmailAsync(task!.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty);
return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id });
} }
@@ -1073,7 +1007,7 @@ namespace IRaCIS.Core.Application.Service
{ {
var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Global); var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Global);
var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); var filePath = await BaseBusinessScenarioSendEmailAsync(task!.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty);
return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id });
} }
@@ -1082,7 +1016,7 @@ namespace IRaCIS.Core.Application.Service
{ {
var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge); var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge);
var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); var filePath = await BaseBusinessScenarioSendEmailAsync(task!.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty);
return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id });
} }
@@ -21,7 +21,6 @@ namespace IRaCIS.Core.Application.Services
private readonly IRepository<Dictionary> _dictionaryRepository; private readonly IRepository<Dictionary> _dictionaryRepository;
private readonly IEasyCachingProvider _provider; private readonly IEasyCachingProvider _provider;
private readonly IWebHostEnvironment _hostEnvironment;
private readonly IDistributedLockProvider _distributedLockProvider; private readonly IDistributedLockProvider _distributedLockProvider;
@@ -31,12 +30,10 @@ namespace IRaCIS.Core.Application.Services
public DicomArchiveService(IRepository<DicomStudy> studyRepository, public DicomArchiveService(IRepository<DicomStudy> studyRepository,
IRepository<DicomSeries> seriesRepository, IRepository<DicomSeries> seriesRepository,
IRepository<DicomInstance> instanceRepository, IRepository<DicomInstance> instanceRepository,
IWebHostEnvironment hostEnvironment,
IRepository<Dictionary> dictionaryRepository, IRepository<Dictionary> dictionaryRepository,
IEasyCachingProvider provider, IDistributedLockProvider distributedLockProvider) IEasyCachingProvider provider, IDistributedLockProvider distributedLockProvider)
{ {
_distributedLockProvider = distributedLockProvider; _distributedLockProvider = distributedLockProvider;
_hostEnvironment = hostEnvironment;
_studyRepository = studyRepository; _studyRepository = studyRepository;
_seriesRepository = seriesRepository; _seriesRepository = seriesRepository;
@@ -723,7 +723,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{ {
// $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能早于前序访视检查时间{before?.ToString("yyyy-MM-dd")},请核对检查数据是否有误", // $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能早于前序访视检查时间{before?.ToString("yyyy-MM-dd")},请核对检查数据是否有误",
result.Add(new VerifyStudyUploadResult() { ErrorMesseage = _localizer["Study_VisitBeforePrevError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd"), before?.ToString("yyyy-MM-dd")], StudyInstanceUid = waitUploadItem.StudyInstanceUid }); result.Add(new VerifyStudyUploadResult() { ErrorMesseage = _localizer["Study_VisitBeforePrevError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, before?.ToString("yyyy-MM-dd")!], StudyInstanceUid = waitUploadItem.StudyInstanceUid });
return; return;
} }
@@ -733,7 +733,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
if (after != null && waitUploadItem.StudyDate != null && after < waitUploadItem.StudyDate) if (after != null && waitUploadItem.StudyDate != null && after < waitUploadItem.StudyDate)
{ {
// $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能晚于该访视之后的检查时间{after?.ToString("yyyy-MM-dd")},请核对检查数据是否有误" // $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能晚于该访视之后的检查时间{after?.ToString("yyyy-MM-dd")},请核对检查数据是否有误"
result.Add(new VerifyStudyUploadResult() { ErrorMesseage = _localizer["Study_VisitAfterSubseqError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd"), after?.ToString("yyyy-MM-dd")], StudyInstanceUid = waitUploadItem.StudyInstanceUid }); result.Add(new VerifyStudyUploadResult() { ErrorMesseage = _localizer["Study_VisitAfterSubseqError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, after?.ToString("yyyy-MM-dd")!], StudyInstanceUid = waitUploadItem.StudyInstanceUid });
return; return;
} }
} }
@@ -298,7 +298,7 @@ namespace IRaCIS.Core.Application.Service.Inspection.DTO
public T Data { get; set; } public T Data { get; set; }
public SignDTO SignInfo { get; set; } public SignDTO? SignInfo { get; set; }
} }
@@ -197,7 +197,7 @@ namespace IRaCIS.Core.Application.Service
//找到上一条Id //找到上一条Id
var currentInspection = await _dataInspectionRepository.Where(t => t.Id == id).Select(t => new { t.GeneralId, t.ObjectRelationParentId, t.CreateTime }).FirstOrDefaultAsync(); var currentInspection = await _dataInspectionRepository.Where(t => t.Id == id).Select(t => new { t.GeneralId, t.ObjectRelationParentId, t.CreateTime }).FirstNotNullAsync();
var beforeId = await _dataInspectionRepository.Where(x => x.GeneralId == currentInspection.GeneralId && x.CreateTime <= currentInspection.CreateTime && x.Id != id).OrderByDescending(x => x.CreateTime).Select(t => t.Id) var beforeId = await _dataInspectionRepository.Where(x => x.GeneralId == currentInspection.GeneralId && x.CreateTime <= currentInspection.CreateTime && x.Id != id).OrderByDescending(x => x.CreateTime).Select(t => t.Id)
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
@@ -214,11 +214,11 @@ namespace IRaCIS.Core.Application.Service
/// <summary> /// <summary>
/// 翻译稽查数据 /// 翻译稽查数据
/// </summary> /// </summary>
/// <param name="dto">传入Dto</param> /// <param name="dto"></param>
/// <param name="currentInspectionId"></param>
/// <returns></returns> /// <returns></returns>
private async Task<List<string>> SetInspectionEnumValueDataList(SetInspectionEnumValueDto dto, Guid currentInspectionId) private async Task<List<string>> SetInspectionEnumValueDataList(SetInspectionEnumValueDto dto, Guid currentInspectionId)
{ {
@@ -241,7 +241,7 @@ namespace IRaCIS.Core.Application.Service
var listIdentification = auditDatas.Select(x => x.Identification).Distinct().ToList(); var listIdentification = auditDatas.Select(x => x.Identification).Distinct().ToList();
foreach (var item in auditDatas) foreach (var item in auditDatas)
{ {
Dictionary<string, object> jsonDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(item.JsonStr); Dictionary<string, object> jsonDict = (JsonConvert.DeserializeObject<Dictionary<string, object>>(item.JsonStr)).IfNullThrowException();
if (!jsonDict.ContainsKey(nameof(InspectionJsonDetail.CommonData))) if (!jsonDict.ContainsKey(nameof(InspectionJsonDetail.CommonData)))
{ {
@@ -366,7 +366,7 @@ namespace IRaCIS.Core.Application.Service
resultJsonStrList.Add(auditData?.JsonStr); resultJsonStrList.Add(auditData?.JsonStr);
}); });
if (resultJsonStrList.Count() < 2) if (resultJsonStrList.Count < 2)
{ {
resultJsonStrList.Add(String.Empty); resultJsonStrList.Add(String.Empty);
} }
@@ -386,7 +386,7 @@ namespace IRaCIS.Core.Application.Service
if (relationParentInspection != null) if (relationParentInspection != null)
{ {
Dictionary<string, object> jsonDic = JsonConvert.DeserializeObject<Dictionary<string, object>>(relationParentInspection.JsonDetail); Dictionary<string, object> jsonDic = (JsonConvert.DeserializeObject<Dictionary<string, object>>(relationParentInspection.JsonDetail)).IfNullThrowConvertException();
//避免对象信息记录 把 Data里面的信息也取过去 但是加上稽查对象的前缀 //避免对象信息记录 把 Data里面的信息也取过去 但是加上稽查对象的前缀
@@ -539,7 +539,7 @@ namespace IRaCIS.Core.Application.Service
}).ToList(); }).ToList();
var jsonDataValueDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(jsonStr); var jsonDataValueDic = (JsonConvert.DeserializeObject<IDictionary<string, object>>(jsonStr)).IfNullThrowConvertException();
foreach (var item in list) foreach (var item in list)
{ {
if (!jsonDataValueDic.ContainsKey(item.Key)) if (!jsonDataValueDic.ContainsKey(item.Key))
@@ -881,7 +881,7 @@ namespace IRaCIS.Core.Application.Service
DateType = child.DateType, DateType = child.DateType,
}).ToListAsync(); }).ToListAsync();
var JsonData = JsonConvert.DeserializeObject<IDictionary<string, object>>(Data.JsonDetail); var JsonData = (JsonConvert.DeserializeObject<IDictionary<string, object>>(Data.JsonDetail)).IfNullThrowException();
foreach (var item in JsonData.Keys) foreach (var item in JsonData.Keys)
{ {
@@ -892,12 +892,12 @@ namespace IRaCIS.Core.Application.Service
{ {
if (datefirst.DateType == FrontAuditDateType.Date.GetDescription()) if (datefirst.DateType == FrontAuditDateType.Date.GetDescription())
{ {
JsonData[item] = DateTime.Parse(JsonData[item].ToString()).ToString("yyyy-MM-dd"); JsonData[item] = DateTime.Parse(JsonData[item].ToString()!).ToString("yyyy-MM-dd");
} }
if (datefirst.DateType == FrontAuditDateType.DateTime.GetDescription()) if (datefirst.DateType == FrontAuditDateType.DateTime.GetDescription())
{ {
JsonData[item] = DateTime.Parse(JsonData[item].ToString()).ToString("yyyy-MM-dd HH:mm:ss"); JsonData[item] = DateTime.Parse(JsonData[item].ToString()!).ToString("yyyy-MM-dd HH:mm:ss");
} }
} }
catch (Exception) catch (Exception)
@@ -29,7 +29,7 @@ namespace IRaCIS.Core.Application.Service.Inspection
{ {
//_repository.GetQueryable.GetQueryable < DataInspection > //_repository.GetQueryable.GetQueryable < DataInspection >
var trialData = await _repository.GetQueryable<Trial>().Where(x => x.Id == dto.TrialId).AsNoTracking().FirstOrDefaultAsync(); var trialData = await _repository.GetQueryable<Trial>().Where(x => x.Id == dto.TrialId).AsNoTracking().FirstNotNullAsync();
trialData.TrialFinishTime = trialData.TrialFinishTime == null ? DateTime.Now : trialData.TrialFinishTime; trialData.TrialFinishTime = trialData.TrialFinishTime == null ? DateTime.Now : trialData.TrialFinishTime;
@@ -84,9 +84,9 @@ namespace IRaCIS.Core.Application.Service.Inspection
data.Identification.ToLower() data.Identification.ToLower()
equals equals
leftfrontAuditConfig.Identification.ToLower() leftfrontAuditConfig.Identification.ToLower()
join moduleTypec in _repository.GetQueryable<Dictionary>() on new { ModuleType = leftfrontAuditConfig.ModuleTypeId.Value } equals new { ModuleType = moduleTypec.Id } into moduleTypectemp join moduleTypec in _repository.GetQueryable<Dictionary>() on new { ModuleType = leftfrontAuditConfig.ModuleTypeId!.Value } equals new { ModuleType = moduleTypec.Id } into moduleTypectemp
from leftmoduleTypec in moduleTypectemp.DefaultIfEmpty() from leftmoduleTypec in moduleTypectemp.DefaultIfEmpty()
join OptTypec in _repository.GetQueryable<Dictionary>() on new { ModuleType = leftfrontAuditConfig.OptTypeId.Value } equals new { ModuleType = OptTypec.Id } into optTypetemp join OptTypec in _repository.GetQueryable<Dictionary>() on new { ModuleType = leftfrontAuditConfig.OptTypeId!.Value } equals new { ModuleType = OptTypec.Id } into optTypetemp
from leftOptType in optTypetemp.DefaultIfEmpty() from leftOptType in optTypetemp.DefaultIfEmpty()
select new GetDataInspectionOutDto() select new GetDataInspectionOutDto()
@@ -31,8 +31,8 @@ namespace IRaCIS.Application.Services
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.AliasName), t => t.AliasName.Contains(searchModel.AliasName)) .WhereIf(!string.IsNullOrWhiteSpace(searchModel.AliasName), t => t.AliasName.Contains(searchModel.AliasName))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.City), t => t.City.Contains(searchModel.City)) .WhereIf(!string.IsNullOrWhiteSpace(searchModel.City), t => t.City.Contains(searchModel.City))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Country), t => t.Country.Contains(searchModel.Country)) .WhereIf(!string.IsNullOrWhiteSpace(searchModel.Country), t => t.Country.Contains(searchModel.Country))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Province), t => t.Country.Contains(searchModel.Province)) .WhereIf(!string.IsNullOrWhiteSpace(searchModel.Province), t => t.Province.Contains(searchModel.Province))
.ProjectTo<SiteSelectDTO>(_mapper.ConfigurationProvider); .ProjectTo<SiteSelectDTO>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us });
return await siteQueryable.ToPagedListAsync(searchModel.PageIndex, searchModel.PageSize, string.IsNullOrWhiteSpace(searchModel.SortField) ? "SiteName" : searchModel.SortField, searchModel.Asc); return await siteQueryable.ToPagedListAsync(searchModel.PageIndex, searchModel.PageSize, string.IsNullOrWhiteSpace(searchModel.SortField) ? "SiteName" : searchModel.SortField, searchModel.Asc);
@@ -76,11 +76,6 @@ namespace IRaCIS.Application.Services
} }
} }
/// <summary> 删除研究中心 </summary> /// <summary> 删除研究中心 </summary>
@@ -644,7 +644,8 @@ namespace IRaCIS.Application.Services
{ {
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId = Guid.Empty, LoginFaildName = userName,LoginPassword=password, OptType = UserOptType.AccountLocked }, true); await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId = Guid.Empty, LoginFaildName = userName,LoginPassword=password, OptType = UserOptType.AccountLocked }, true);
throw new BusinessValidationFailedException($"密码连续错误{maxFailures}次,当前账号已被限制登录,请等待 {lockoutMinutes} 分钟后再试。"); //$"密码连续错误{maxFailures}次,当前账号已被限制登录,请等待 {lockoutMinutes} 分钟后再试。"
throw new BusinessValidationFailedException(_localizer["User_ErrorLimit", maxFailures, lockoutMinutes]);
} }
var userLoginReturnModel = new LoginReturnDTO(); var userLoginReturnModel = new LoginReturnDTO();
@@ -699,8 +700,8 @@ namespace IRaCIS.Application.Services
.WhereIf(inQuery.OptType != null, t => t.OptType == inQuery.OptType) .WhereIf(inQuery.OptType != null, t => t.OptType == inQuery.OptType)
.WhereIf(inQuery.BeginDate != null, t => t.CreateTime >= inQuery.BeginDate) .WhereIf(inQuery.BeginDate != null, t => t.CreateTime >= inQuery.BeginDate)
.WhereIf(inQuery.EndDate != null, t => t.CreateTime <= inQuery.EndDate) .WhereIf(inQuery.EndDate != null, t => t.CreateTime <= inQuery.EndDate)
.WhereIf(!string.IsNullOrEmpty(inQuery.LoginFaildName), t => t.LoginFaildName.Contains(inQuery.LoginFaildName)) .WhereIf(!string.IsNullOrEmpty(inQuery.LoginFaildName), t => t.LoginFaildName.Contains(inQuery.LoginFaildName!))
.WhereIf(!string.IsNullOrEmpty(inQuery.IP), t => t.IP.Contains(inQuery.IP)) .WhereIf(!string.IsNullOrEmpty(inQuery.IP), t => t.IP.Contains(inQuery.IP!))
.ProjectTo<UserLogView>(_mapper.ConfigurationProvider); .ProjectTo<UserLogView>(_mapper.ConfigurationProvider);
var pageList = await userLogQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? "Id" : inQuery.SortField, inQuery.Asc); var pageList = await userLogQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? "Id" : inQuery.SortField, inQuery.Asc);
@@ -547,7 +547,7 @@ namespace IRaCIS.Core.Application.Contracts
[DictionaryTranslateAttribute("YesOrNo")] [DictionaryTranslateAttribute("YesOrNo")]
public bool IsSuccess { get; set; } public bool IsSuccess { get; set; }
public string Note = string.Empty; public string Note { get; set; }
} }
@@ -1383,6 +1383,10 @@ namespace IRaCIS.Core.Application.Contracts
public DateTime? SubmitTime { get; set; } public DateTime? SubmitTime { get; set; }
public string SubmitUserName { get; set; } = String.Empty;
public string SubmitUserRealName { get; set; } = String.Empty;
public string CurrentActionUserName { get; set; } = String.Empty; public string CurrentActionUserName { get; set; } = String.Empty;
public string PreliminaryAuditUserName { get; set; } = String.Empty; public string PreliminaryAuditUserName { get; set; } = String.Empty;
@@ -19,7 +19,7 @@ namespace IRaCIS.Core.Application.Image.QA
private readonly IRepository<ClinicalDataTrialSet> _clinicalDataTrialSet; private readonly IRepository<ClinicalDataTrialSet> _clinicalDataTrialSet;
private readonly IRepository<TrialQCQuestionAnswer> _trialQCQuestionAnswerRepository; private readonly IRepository<TrialQCQuestionAnswer> _trialQCQuestionAnswerRepository;
private readonly IRepository<TrialQCQuestion> _trialQCQuestionRepository; private readonly IRepository<TrialQCQuestion> _trialQCQuestionRepository;
private readonly IRepository<UserUploadFile> _UserUploadFileRepository; private readonly IRepository<InspectionFile> _consistencyCheckFileRepository;
private IReadingImageTaskService _IReadingImageTaskService; private IReadingImageTaskService _IReadingImageTaskService;
@@ -30,14 +30,14 @@ namespace IRaCIS.Core.Application.Image.QA
IRepository<TrialQCQuestionAnswer> trialQCQuestionAnswerRepository, IRepository<TrialQCQuestionAnswer> trialQCQuestionAnswerRepository,
IRepository<TrialQCQuestion> trialQCQuestionRepository, IRepository<TrialQCQuestion> trialQCQuestionRepository,
IReadingImageTaskService IReadingImageTaskService, IReadingImageTaskService IReadingImageTaskService,
IRepository<UserUploadFile> UserUploadFileRepository IRepository<InspectionFile> consistencyCheckFileRepository
) )
{ {
this._IReadingImageTaskService = IReadingImageTaskService; this._IReadingImageTaskService = IReadingImageTaskService;
_subjectVisitRepository = subjectVisitRepository; _subjectVisitRepository = subjectVisitRepository;
this._trialQCQuestionAnswerRepository = trialQCQuestionAnswerRepository; this._trialQCQuestionAnswerRepository = trialQCQuestionAnswerRepository;
this._trialQCQuestionRepository = trialQCQuestionRepository; this._trialQCQuestionRepository = trialQCQuestionRepository;
this._UserUploadFileRepository = UserUploadFileRepository; this._consistencyCheckFileRepository = consistencyCheckFileRepository;
_trialRepository = trialRepository; _trialRepository = trialRepository;
this._clinicalDataTrialSet = clinicalDataTrialSet; this._clinicalDataTrialSet = clinicalDataTrialSet;
} }
@@ -851,7 +851,7 @@ namespace IRaCIS.Core.Application.Image.QA
[HttpPost] [HttpPost]
public async Task<PageOutput<GetUserUploadFileDto>> GetUserUploadFile(GetUserUploadFileInDto indto) public async Task<PageOutput<GetUserUploadFileDto>> GetUserUploadFile(GetUserUploadFileInDto indto)
{ {
var query = _repository.Where<UserUploadFile>(t => t.TrialId == indto.TrialId) var query = _repository.Where<InspectionFile>(t => t.TrialId == indto.TrialId)
.ProjectTo<GetUserUploadFileDto>(_mapper.ConfigurationProvider); .ProjectTo<GetUserUploadFileDto>(_mapper.ConfigurationProvider);
return await query.ToPagedListAsync(indto.PageIndex, indto.PageSize, "CreateTime", false); return await query.ToPagedListAsync(indto.PageIndex, indto.PageSize, "CreateTime", false);
@@ -891,7 +891,7 @@ namespace IRaCIS.Core.Application.Image.QA
if (nextIQCQuality.VisitId != null) if (nextIQCQuality.VisitId != null)
{ {
var visit = await _subjectVisitRepository.Where(x => x.Id == nextIQCQuality.VisitId).FirstOrDefaultAsync(); var visit = await _subjectVisitRepository.Where(x => x.Id == nextIQCQuality.VisitId).FirstNotNullAsync();
if (!visit.IsTake) if (!visit.IsTake)
{ {
await ObtainOrCancelQCTask(inDto.TrialId, nextIQCQuality.VisitId.Value, true); await ObtainOrCancelQCTask(inDto.TrialId, nextIQCQuality.VisitId.Value, true);
@@ -925,7 +925,7 @@ namespace IRaCIS.Core.Application.Image.QA
return new GetNextIQCQualityOutDto() { }; return new GetNextIQCQualityOutDto() { };
break; break;
case TrialQCProcess.SingleAudit: case TrialQCProcess.SingleAudit:
visitList = await _subjectVisitRepository.Where(x => x.SubmitState != SubmitStateEnum.None && x.TrialId == inDto.TrialId && (x.CurrentActionUserId == _userInfo.Id || (x.AuditState != AuditStateEnum.PrimaryQCPassed && !x.IsTake))).Include(x => x.Subject).ToListAsync(); visitList = await _subjectVisitRepository.Where(x => x.SubmitState != SubmitStateEnum.None && x.TrialId == inDto.TrialId && x.PreliminaryAuditUserId != _userInfo.Id && (x.CurrentActionUserId == _userInfo.Id || (x.AuditState != AuditStateEnum.PrimaryQCPassed && !x.IsTake))).Include(x => x.Subject).ToListAsync();
subjectVisit = visitList.Where(x => x.SubjectId == inDto.SubjectId).OrderBy(x => x.VisitNum).FirstOrDefault(); subjectVisit = visitList.Where(x => x.SubjectId == inDto.SubjectId).OrderBy(x => x.VisitNum).FirstOrDefault();
if (subjectVisit != null) if (subjectVisit != null)
@@ -953,7 +953,9 @@ namespace IRaCIS.Core.Application.Image.QA
break; break;
case TrialQCProcess.DoubleAudit: case TrialQCProcess.DoubleAudit:
visitList = await _subjectVisitRepository.Where(x => x.SubmitState != SubmitStateEnum.None && x.TrialId == inDto.TrialId && x.PreliminaryAuditUserId != _userInfo.Id && (x.CurrentActionUserId == _userInfo.Id || (x.AuditState != AuditStateEnum.QCPassed))).Include(x => x.Subject).ToListAsync(); visitList = await _subjectVisitRepository.Where(x => x.SubmitState != SubmitStateEnum.None && x.TrialId == inDto.TrialId &&
((x.CurrentActionUserId == _userInfo.Id)||(!x.IsTake&& x.AuditState != AuditStateEnum.QCPassed&& (x.PreliminaryAuditUserId != _userInfo.Id)))
).Include(x => x.Subject).ToListAsync();
if (subjectVisit != null) if (subjectVisit != null)
{ {
return new GetNextIQCQualityOutDto() return new GetNextIQCQualityOutDto()
@@ -1172,7 +1174,7 @@ namespace IRaCIS.Core.Application.Image.QA
var dbSubjectVisitList = await _subjectVisitRepository.Where(t => cRCRequestToQCCommand.SubjectVisitIds.Contains(t.Id), true).ProjectTo<QCCRCVisitViewModel>(_mapper.ConfigurationProvider).ToListAsync(); var dbSubjectVisitList = await _subjectVisitRepository.Where(t => cRCRequestToQCCommand.SubjectVisitIds.Contains(t.Id), true).ProjectTo<QCCRCVisitViewModel>(_mapper.ConfigurationProvider).ToListAsync();
//普通提交 //普通提交
if (dbSubjectVisitList.Count() == 1) if (dbSubjectVisitList.Count == 1)
{ {
var sv = dbSubjectVisitList[0]; var sv = dbSubjectVisitList[0];
@@ -1181,7 +1183,7 @@ namespace IRaCIS.Core.Application.Image.QA
if (sv.PDState == PDStateEnum.PDProgress) if (sv.PDState == PDStateEnum.PDProgress)
{ {
if (nameList.Count() > 0) if (nameList.Count > 0)
{ {
//$"当前访视要求进行疾病进展确认。请在提交当前访视前,先处理未提交的前序访视:{string.Join('、', nameList)}。" //$"当前访视要求进行疾病进展确认。请在提交当前访视前,先处理未提交的前序访视:{string.Join('、', nameList)}。"
return ResponseOutput.NotOk(_localizer["QCOperation_DiseaseProgressConfirmation", string.Join('、', nameList)], 1, ApiResponseCodeEnum.NeedTips); return ResponseOutput.NotOk(_localizer["QCOperation_DiseaseProgressConfirmation", string.Join('、', nameList)], 1, ApiResponseCodeEnum.NeedTips);
@@ -1189,7 +1191,7 @@ namespace IRaCIS.Core.Application.Image.QA
} }
else else
{ {
if (nameList.Count() > 0) if (nameList.Count > 0)
{ {
//$"在提交当前访视后,请尽快处理尚未提交的前序访视:{string.Join('、', nameList)}。" //$"在提交当前访视后,请尽快处理尚未提交的前序访视:{string.Join('、', nameList)}。"
return ResponseOutput.NotOk(_localizer["QCOperation_UnsubmittedVisits", string.Join('、', nameList)], 0, ApiResponseCodeEnum.NeedTips); return ResponseOutput.NotOk(_localizer["QCOperation_UnsubmittedVisits", string.Join('、', nameList)], 0, ApiResponseCodeEnum.NeedTips);
@@ -1245,7 +1247,7 @@ namespace IRaCIS.Core.Application.Image.QA
} }
//单个提交提示信息 //单个提交提示信息
if (dbSubjectVisitList.Count() == 1 && dbSubjectVisitList.First().SubmitState == SubmitStateEnum.Submitted) if (dbSubjectVisitList.Count == 1 && dbSubjectVisitList.First().SubmitState == SubmitStateEnum.Submitted)
{ {
//---当前访视的影像数据,已经由其他CRC提交。 //---当前访视的影像数据,已经由其他CRC提交。
return ResponseOutput.NotOk(_localizer["QCOperation_ImagesSubmitted"], 3, ApiResponseCodeEnum.NeedTips); return ResponseOutput.NotOk(_localizer["QCOperation_ImagesSubmitted"], 3, ApiResponseCodeEnum.NeedTips);
@@ -364,6 +364,10 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.QCProcessEnum, u => u.MapFrom(s => s.Trial.QCProcessEnum)) .ForMember(d => d.QCProcessEnum, u => u.MapFrom(s => s.Trial.QCProcessEnum))
.ForMember(d => d.SubjectStatus, u => u.MapFrom(s => s.Subject.Status)) .ForMember(d => d.SubjectStatus, u => u.MapFrom(s => s.Subject.Status))
.ForMember(d => d.StudyCount, u => u.MapFrom(s => s.StudyList.Count())) .ForMember(d => d.StudyCount, u => u.MapFrom(s => s.StudyList.Count()))
.ForMember(d => d.SubmitUserName, u => u.MapFrom(s => s.SubmitUser.UserName))
.ForMember(d => d.SubmitUserRealName, u => u.MapFrom(s => s.SubmitUser.FullName))
.ForMember(d => d.CurrentActionUserName, u => u.MapFrom(s => s.CurrentActionUser.UserName)) .ForMember(d => d.CurrentActionUserName, u => u.MapFrom(s => s.CurrentActionUser.UserName))
.ForMember(d => d.PreliminaryAuditUserName, u => u.MapFrom(s => s.PreliminaryAuditUser.UserName)) .ForMember(d => d.PreliminaryAuditUserName, u => u.MapFrom(s => s.PreliminaryAuditUser.UserName))
.ForMember(d => d.ReviewAuditUserName, u => u.MapFrom(s => s.ReviewAuditUser.UserName)) .ForMember(d => d.ReviewAuditUserName, u => u.MapFrom(s => s.ReviewAuditUser.UserName))
@@ -494,7 +498,7 @@ namespace IRaCIS.Core.Application.Service
; ;
// 一致性核查文件 // 一致性核查文件
CreateMap<UserUploadFile, GetUserUploadFileDto>() CreateMap<InspectionFile, GetUserUploadFileDto>()
.ForMember(d => d.CreateUserName, u => u.MapFrom(t => t.User.FirstName + "/" + t.User.LastName)); .ForMember(d => d.CreateUserName, u => u.MapFrom(t => t.User.FirstName + "/" + t.User.LastName));
@@ -523,7 +523,28 @@ namespace IRaCIS.Core.Application.Service
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync(); var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync();
inDto.TrialReadingCriterionId = readModule.TrialReadingCriterionId; inDto.TrialReadingCriterionId = readModule.TrialReadingCriterionId;
} }
// 有全局就查全局 有肿瘤学就查肿瘤学
var clinicalDataLevelList = await _clinicalDataTrialSetRepository.Where(x => x.TrialId == inDto.TrialId && x.IsConfirm && x.UploadRole == UploadRole.CRC && x.ClinicalUploadType == ClinicalUploadType.Structuring).Select(x => x.ClinicalDataLevel).Distinct().ToListAsync();
var existsCRCStructuring = clinicalDataLevelList.Any(x=>x== ClinicalLevel.OncologyRead|| x == ClinicalLevel.ImageRead);
ReadingSetType? readingSetType = null;
if (clinicalDataLevelList.Contains(ClinicalLevel.ImageRead) && !clinicalDataLevelList.Contains(ClinicalLevel.OncologyRead))
{
readingSetType = ReadingSetType.ImageReading;
}
else if (clinicalDataLevelList.Contains(ClinicalLevel.OncologyRead) && !clinicalDataLevelList.Contains(ClinicalLevel.ImageRead))
{
readingSetType = ReadingSetType.TumorReading;
}
var query = _readModuleRepository.Where(x => x.TrialId == inDto.TrialId) var query = _readModuleRepository.Where(x => x.TrialId == inDto.TrialId)
.Where(x=> existsCRCStructuring)
.WhereIf(inDto.ReadModuleId==null,x=>x.TrialReadingCriterion.IsConfirm)
.WhereIf(inDto.ReadModuleId != null, x => x.Id == inDto.ReadModuleId) .WhereIf(inDto.ReadModuleId != null, x => x.Id == inDto.ReadModuleId)
.WhereIf(inDto.IsCRCConfirm != null, x => x.IsCRCConfirm == inDto.IsCRCConfirm) .WhereIf(inDto.IsCRCConfirm != null, x => x.IsCRCConfirm == inDto.IsCRCConfirm)
.WhereIf(inDto.IsPMConfirm != null, x => x.IsPMConfirm == inDto.IsPMConfirm) .WhereIf(inDto.IsPMConfirm != null, x => x.IsPMConfirm == inDto.IsPMConfirm)
@@ -532,6 +553,7 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(inDto.SubjectId != null, x => x.SubjectId == inDto.SubjectId) .WhereIf(inDto.SubjectId != null, x => x.SubjectId == inDto.SubjectId)
.WhereIf(inDto.StartTime != null, x => x.SubjectVisit.LatestScanDate >= inDto.StartTime) .WhereIf(inDto.StartTime != null, x => x.SubjectVisit.LatestScanDate >= inDto.StartTime)
.WhereIf(inDto.EndTime != null, x => x.SubjectVisit.LatestScanDate <= inDto.EndTime) .WhereIf(inDto.EndTime != null, x => x.SubjectVisit.LatestScanDate <= inDto.EndTime)
.WhereIf(readingSetType != null, x => x.ReadingSetType== readingSetType)
.Select(x => new GetCRCConfirmListOutDto() .Select(x => new GetCRCConfirmListOutDto()
{ {
@@ -169,6 +169,8 @@ namespace IRaCIS.Core.Application.Service
/// <param name="item"></param> /// <param name="item"></param>
/// <param name="questions"></param> /// <param name="questions"></param>
/// <param name="tableQuestions"></param> /// <param name="tableQuestions"></param>
/// <param name="answers"></param>
/// <param name="tableAnswers"></param>
public void FindChildQuestion(ClinicalQuestionPreviewDto item, List<ClinicalQuestionPreviewDto> questions, List<ClinicalTablePreviewDto> tableQuestions,List<ClinicalFormQuestionAnswer> answers, List<ClinicalFormTableQuestionAnswer> tableAnswers) public void FindChildQuestion(ClinicalQuestionPreviewDto item, List<ClinicalQuestionPreviewDto> questions, List<ClinicalTablePreviewDto> tableQuestions,List<ClinicalFormQuestionAnswer> answers, List<ClinicalFormTableQuestionAnswer> tableAnswers)
{ {
item.Childrens = questions.Where(x => (x.ParentId == item.Id)||(x.GroupId== item.Id&&x.ParentId==null)).OrderBy(x => x.ShowOrder).ToList(); item.Childrens = questions.Where(x => (x.ParentId == item.Id)||(x.GroupId== item.Id&&x.ParentId==null)).OrderBy(x => x.ShowOrder).ToList();
@@ -111,7 +111,7 @@ namespace IRaCIS.Application.Services
entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded; entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded;
entity.IsBlind = null; entity.IsBlind = null;
entity.IsComplete = null; entity.IsComplete = null;
entity.FileCount = entity.ReadingClinicalDataPDFList.Count(); entity.FileCount = entity.ReadingClinicalDataPDFList.Count;
await _readingClinicalDataRepository.AddAsync(entity, true); await _readingClinicalDataRepository.AddAsync(entity, true);
var success = await _readingClinicalDataRepository.SaveChangesAsync(); var success = await _readingClinicalDataRepository.SaveChangesAsync();
return ResponseOutput.Ok(entity.Id); return ResponseOutput.Ok(entity.Id);
@@ -366,7 +366,7 @@ namespace IRaCIS.Application.Services
//影像学 //影像学
if (readModule.ReadingSetType == ReadingSetType.ImageReading) if (readModule.ReadingSetType == ReadingSetType.ImageReading)
{ {
needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && t.ClinicalDataLevel == ClinicalLevel.ImageRead).Count(); needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && t.ClinicalDataLevel == ClinicalLevel.ImageRead && t.UploadRole == UploadRole.PM).Count();
// 不存在需要CRC上传的临床数据 或者 PM已确认 // 不存在需要CRC上传的临床数据 或者 PM已确认
crcReadModuleSign = crcReadModuleSign =
@@ -376,12 +376,11 @@ namespace IRaCIS.Application.Services
&& x.ClinicalUploadType == ClinicalUploadType.Structuring && x.ClinicalUploadType == ClinicalUploadType.Structuring
&& x.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId)) || readModule.IsPMConfirm; && x.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId)) || readModule.IsPMConfirm;
} }
//肿瘤学 //肿瘤学
else else
{ {
needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && t.ClinicalDataLevel == ClinicalLevel.OncologyRead).Count(); needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && t.ClinicalDataLevel == ClinicalLevel.OncologyRead && t.UploadRole == UploadRole.PM).Count();
// 不存在需要CRC上传的临床数据 或者 PM已确认 // 不存在需要CRC上传的临床数据 或者 PM已确认
crcReadModuleSign = crcReadModuleSign =
@@ -512,7 +511,7 @@ namespace IRaCIS.Application.Services
inDto.UploadRole = UploadRole.PM; inDto.UploadRole = UploadRole.PM;
} }
ReadModule readModule = null; ReadModule? readModule = null;
if (inDto.IsVisit == false) if (inDto.IsVisit == false)
{ {
readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId).FirstOrDefaultAsync(); readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId).FirstOrDefaultAsync();
@@ -537,7 +536,7 @@ namespace IRaCIS.Application.Services
.WhereIf(inDto.IsVisit && inDto.IsBaseLine, x => x.ClinicalDataLevel == ClinicalLevel.Subject || x.ClinicalDataLevel == ClinicalLevel.SubjectVisit) .WhereIf(inDto.IsVisit && inDto.IsBaseLine, x => x.ClinicalDataLevel == ClinicalLevel.Subject || x.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
.WhereIf(inDto.IsVisit && !inDto.IsBaseLine, x => x.ClinicalDataLevel == ClinicalLevel.SubjectVisit) .WhereIf(inDto.IsVisit && !inDto.IsBaseLine, x => x.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
.WhereIf(!inDto.IsVisit, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead || x.ClinicalDataLevel == ClinicalLevel.OncologyRead) .WhereIf(!inDto.IsVisit, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead || x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
.WhereIf(readModule != null, x => x.ClinicalDataLevel == keyValuePairs[readModule.ModuleType]) .WhereIf(readModule != null, x => x.ClinicalDataLevel == keyValuePairs[readModule!.ModuleType])
.WhereIf(inDto.TrialReadingCriterionId!=null,x=>x.TrialClinicalDataSetCriteriaList.Any(y=>y.TrialReadingCriterionId== inDto.TrialReadingCriterionId)) .WhereIf(inDto.TrialReadingCriterionId!=null,x=>x.TrialClinicalDataSetCriteriaList.Any(y=>y.TrialReadingCriterionId== inDto.TrialReadingCriterionId))
//.WhereIf(criterion!=null,x=>x.CriterionEnumListStr.Contains($"|{(int)criterion.CriterionType}|")) //.WhereIf(criterion!=null,x=>x.CriterionEnumListStr.Contains($"|{(int)criterion.CriterionType}|"))
.Select(x => new GetTrialClinicalDataSelectOutDto() .Select(x => new GetTrialClinicalDataSelectOutDto()
@@ -659,7 +658,7 @@ namespace IRaCIS.Application.Services
return (result, new return (result, new
{ {
IsCanAddClinicalData = clinicalDataList.Count() > 0, IsCanAddClinicalData = clinicalDataList.Count > 0,
}); });
} }
@@ -718,7 +717,7 @@ namespace IRaCIS.Application.Services
CheckDate = y.CheckDate, CheckDate = y.CheckDate,
ClinicalFormId = y.Id ClinicalFormId = y.Id
}).ToList(); }).ToList();
x.FileCount = x.ClinicalFromList.Count(); x.FileCount = x.ClinicalFromList.Count;
}); });
@@ -763,6 +762,7 @@ namespace IRaCIS.Application.Services
IsCRCUpload = x.UploadRole == UploadRole.CRC, IsCRCUpload = x.UploadRole == UploadRole.CRC,
IsNeedMerge = true, IsNeedMerge = true,
ReadModuleId = readModule.Id, ReadModuleId = readModule.Id,
TrialClinicalDataSetCriteriaList=x.TrialClinicalDataSetCriteriaList,
//FileCount = x.FileCount, //FileCount = x.FileCount,
//ReadingClinicalDataState = x.ReadingClinicalDataState, //ReadingClinicalDataState = x.ReadingClinicalDataState,
@@ -891,7 +891,7 @@ namespace IRaCIS.Application.Services
CheckDate = y.CheckDate, CheckDate = y.CheckDate,
ClinicalFormId = y.Id ClinicalFormId = y.Id
}).ToList(); }).ToList();
x.FileCount = x.ClinicalFromList.Count(); x.FileCount = x.ClinicalFromList.Count;
}); });
// 这里处理CRC上传 阅片期的临床数据 // 这里处理CRC上传 阅片期的临床数据
@@ -395,6 +395,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public Arm ArmEnum { get; set; } public Arm ArmEnum { get; set; }
public bool IsExistsClinicalData { get; set; }
public MedicalReviewAuditState AuditState { get; set; } public MedicalReviewAuditState AuditState { get; set; }
@@ -21,5 +21,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Interface
Task<IResponseOutput> CRCCancelConfirmClinical(CRCCancelConfirmClinicalInDto inDto); Task<IResponseOutput> CRCCancelConfirmClinical(CRCCancelConfirmClinicalInDto inDto);
Task<PageOutput<GetCRCConfirmListOutDto>> GetCRCConfirmList(GetCRCConfirmListInDto inDto);
} }
} }
@@ -33,6 +33,7 @@ namespace IRaCIS.Core.Application.Service
private readonly IReadingImageTaskService _iReadingImageTaskService; private readonly IReadingImageTaskService _iReadingImageTaskService;
private readonly IRepository<User> _userTaskRepository; private readonly IRepository<User> _userTaskRepository;
private readonly IVisitTaskService _visitTaskService; private readonly IVisitTaskService _visitTaskService;
private readonly IReadingClinicalDataService _readingClinicalDataService;
private readonly IRepository<TaskMedicalReview> _taskMedicalReviewRepository; private readonly IRepository<TaskMedicalReview> _taskMedicalReviewRepository;
private readonly IRepository<ReadingMedicalReviewDialog> _readingMedicalReviewDialogRepository; private readonly IRepository<ReadingMedicalReviewDialog> _readingMedicalReviewDialogRepository;
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrial; private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrial;
@@ -52,6 +53,7 @@ namespace IRaCIS.Core.Application.Service
IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository, IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository,
IRepository<User> userTaskRepository, IRepository<User> userTaskRepository,
IVisitTaskService visitTaskService, IVisitTaskService visitTaskService,
IReadingClinicalDataService readingClinicalDataService,
IRepository<TaskMedicalReview> taskMedicalReviewRepository, IRepository<TaskMedicalReview> taskMedicalReviewRepository,
IRepository<ReadingMedicalReviewDialog> readingMedicalReviewDialogRepository, IRepository<ReadingMedicalReviewDialog> readingMedicalReviewDialogRepository,
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrial, IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrial,
@@ -71,6 +73,7 @@ namespace IRaCIS.Core.Application.Service
this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository; this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository;
this._userTaskRepository = userTaskRepository; this._userTaskRepository = userTaskRepository;
this._visitTaskService = visitTaskService; this._visitTaskService = visitTaskService;
this._readingClinicalDataService = readingClinicalDataService;
this._taskMedicalReviewRepository = taskMedicalReviewRepository; this._taskMedicalReviewRepository = taskMedicalReviewRepository;
this._readingMedicalReviewDialogRepository = readingMedicalReviewDialogRepository; this._readingMedicalReviewDialogRepository = readingMedicalReviewDialogRepository;
this._readingQuestionCriterionTrial = readingQuestionCriterionTrial; this._readingQuestionCriterionTrial = readingQuestionCriterionTrial;
@@ -109,6 +112,17 @@ namespace IRaCIS.Core.Application.Service
medicalReviewInfo.VisitTaskId = taskInfo.Id; medicalReviewInfo.VisitTaskId = taskInfo.Id;
var clinicalDataList = await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
{
SubjectId = taskInfo.SubjectId,
TrialId = taskInfo.TrialId,
VisitTaskId = taskInfo.Id,
});
medicalReviewInfo.IsExistsClinicalData = clinicalDataList.Count > 0;
medicalReviewInfo.ArmEnum = taskInfo.ArmEnum; medicalReviewInfo.ArmEnum = taskInfo.ArmEnum;
medicalReviewInfo.SubjectCode = taskInfo.IsAnalysisCreate?taskInfo.BlindSubjectCode: taskInfo.Subject.Code; medicalReviewInfo.SubjectCode = taskInfo.IsAnalysisCreate?taskInfo.BlindSubjectCode: taskInfo.Subject.Code;
medicalReviewInfo.TaskBlindName = taskInfo.TaskBlindName; medicalReviewInfo.TaskBlindName = taskInfo.TaskBlindName;
@@ -466,8 +480,12 @@ namespace IRaCIS.Core.Application.Service
{ {
throw new BusinessValidationFailedException(_localizer["MedicalReview_SaveQuestion"]); throw new BusinessValidationFailedException(_localizer["MedicalReview_SaveQuestion"]);
} }
var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync();
await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview() await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
{ {
LatestReplyUserId = (inDto.IsSendDialog && !medicalReview.IsSendMessage && inDto.IsHaveQuestion) ? _userInfo.Id : null,
IsHaveQuestion = inDto.IsHaveQuestion, IsHaveQuestion = inDto.IsHaveQuestion,
Questioning = inDto.Questioning, Questioning = inDto.Questioning,
IsSendMessage = inDto.IsSendDialog && inDto.IsHaveQuestion, IsSendMessage = inDto.IsSendDialog && inDto.IsHaveQuestion,
@@ -476,9 +494,8 @@ namespace IRaCIS.Core.Application.Service
AuditAdviceEnum = inDto.AuditAdviceEnum, AuditAdviceEnum = inDto.AuditAdviceEnum,
SaveConclusionTime = DateTime.Now, SaveConclusionTime = DateTime.Now,
}); }); ;
var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync();
if (inDto.IsSendDialog&& !medicalReview.IsSendMessage && inDto.IsHaveQuestion) if (inDto.IsSendDialog&& !medicalReview.IsSendMessage && inDto.IsHaveQuestion)
{ {
@@ -511,6 +528,7 @@ namespace IRaCIS.Core.Application.Service
{ {
await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview() await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
{ {
LatestReplyUserId=_userInfo.Id,
IsClosedDialog = inDto.IsClosedDialog, IsClosedDialog = inDto.IsClosedDialog,
MedicalDialogCloseEnum=inDto.MedicalDialogCloseEnum, MedicalDialogCloseEnum=inDto.MedicalDialogCloseEnum,
DialogCloseReason=inDto.DialogCloseReason, DialogCloseReason=inDto.DialogCloseReason,
@@ -547,6 +565,11 @@ namespace IRaCIS.Core.Application.Service
throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]); throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]);
} }
await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
{
LatestReplyUserId = _userInfo.Id,
});
var visitTaskId = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => x.VisitTaskId).FirstOrDefaultAsync(); var visitTaskId = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => x.VisitTaskId).FirstOrDefaultAsync();
ReadingMedicalReviewDialog dialog = new ReadingMedicalReviewDialog() ReadingMedicalReviewDialog dialog = new ReadingMedicalReviewDialog()
{ {
@@ -600,6 +623,7 @@ namespace IRaCIS.Core.Application.Service
await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(x => !x.IsClosedDialog && x.Id == inDto.TaskMedicalReviewId, x => new TaskMedicalReview() await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(x => !x.IsClosedDialog && x.Id == inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
{ {
LatestReplyUserId=_userInfo.Id,
IsClosedDialog = true, IsClosedDialog = true,
MedicalDialogCloseEnum = MedicalDialogClose.IRApplyReReading, MedicalDialogCloseEnum = MedicalDialogClose.IRApplyReReading,
@@ -613,6 +637,7 @@ namespace IRaCIS.Core.Application.Service
await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview() await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
{ {
LatestReplyUserId=_userInfo.Id,
DoctorUserIdeaEnum = inDto.DoctorUserIdeaEnum, DoctorUserIdeaEnum = inDto.DoctorUserIdeaEnum,
}); });
ReadingMedicalReviewDialog dialog = new ReadingMedicalReviewDialog() ReadingMedicalReviewDialog dialog = new ReadingMedicalReviewDialog()
@@ -740,10 +765,11 @@ namespace IRaCIS.Core.Application.Service
await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview() await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
{ {
LatestReplyUserId = _userInfo.Id,
DoctorUserIdeaEnum = inDto.DoctorUserIdeaEnum, DoctorUserIdeaEnum = inDto.DoctorUserIdeaEnum,
DisagreeReason = inDto.DisagreeReason, DisagreeReason = inDto.DisagreeReason,
IsApplyHeavyReading=inDto.IsApplyHeavyReading, IsApplyHeavyReading = inDto.IsApplyHeavyReading,
}); }); ;
var visitTaskId = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => x.VisitTaskId).FirstOrDefaultAsync(); var visitTaskId = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => x.VisitTaskId).FirstOrDefaultAsync();
await _readingMedicalReviewDialogRepository.AddAsync(new ReadingMedicalReviewDialog() await _readingMedicalReviewDialogRepository.AddAsync(new ReadingMedicalReviewDialog()
@@ -59,7 +59,7 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(inDto.CriterionTypeEnum != null, x => x.CriterionTypeEnum==inDto.CriterionTypeEnum) .WhereIf(inDto.CriterionTypeEnum != null, x => x.CriterionTypeEnum==inDto.CriterionTypeEnum)
.WhereIf(inDto.TrialReadingCriterionId != null, x => x.CriterionTypeEnum== criterionEnum || x.IsGeneral==true) .WhereIf(inDto.TrialReadingCriterionId != null, x => x.CriterionTypeEnum== criterionEnum || x.IsGeneral==true)
.WhereIf(inDto.IsGeneral != null, x => x.IsGeneral == inDto.IsGeneral) .WhereIf(inDto.IsGeneral != null, x => x.IsGeneral == inDto.IsGeneral)
.WhereIf(inDto.LanguageType != null, x => x.LanguageType == inDto.LanguageType.Value) .WhereIf(inDto.LanguageType != null, x => x.LanguageType == inDto.LanguageType!.Value)
.ProjectTo<ReadingMedicineSystemQuestionView>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder); .ProjectTo<ReadingMedicineSystemQuestionView>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder);
return await query.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, new string[2] { "LanguageType desc", "ShowOrder asc" }); return await query.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, new string[2] { "LanguageType desc", "ShowOrder asc" });
@@ -516,7 +516,7 @@ namespace IRaCIS.Core.Application.Service
} }
} }
await _readingMedicineTrialQuestionRepository.AddRangeAsync(needList); await _readingMedicineTrialQuestionRepository.AddRangeAsync(_mapper.Map<List<ReadingMedicineTrialQuestion>>(needList));
var result = await _readingMedicineTrialQuestionRepository.SaveChangesAsync(); var result = await _readingMedicineTrialQuestionRepository.SaveChangesAsync();
return ResponseOutput.Ok(); return ResponseOutput.Ok();
} }
@@ -368,7 +368,6 @@ namespace IRaCIS.Application.Services
/// <summary> /// <summary>
/// 新增修改系统表格问题 /// 新增修改系统表格问题
/// </summary> /// </summary>
/// <param name="addOrEditReadingTableQuestionSystem"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<IResponseOutput> AddOrUpdateReadingTableQuestionSystem(ReadingTableQuestionSystemAddOrEdit addOrEditReadingTableQuestionSystem) public async Task<IResponseOutput> AddOrUpdateReadingTableQuestionSystem(ReadingTableQuestionSystemAddOrEdit addOrEditReadingTableQuestionSystem)
@@ -481,11 +480,12 @@ namespace IRaCIS.Application.Services
} }
/// <summary> /// <summary>
/// 验证计算关系 /// 验证计算关系
/// </summary> /// </summary>
/// <param name="relationList"></param> /// <param name="relationList"></param>
/// <param name="QuestionId"></param> /// <param name="QuestionId"></param>
/// <param name="originalId"></param> /// <param name="originalId"></param>
/// <param name="count"></param>
/// <exception cref="BusinessValidationFailedException"></exception> /// <exception cref="BusinessValidationFailedException"></exception>
private void VerifyCalculateRelation(List<CalculateRelationDto> relationList,Guid QuestionId,Guid originalId,int count=1) private void VerifyCalculateRelation(List<CalculateRelationDto> relationList,Guid QuestionId,Guid originalId,int count=1)
{ {
@@ -877,7 +877,7 @@ namespace IRaCIS.Application.Services
{ {
var question = x.Clone(); var question = x.Clone();
question.ReadingQuestionCriterionSystemId = inDto.ToSystemCriterionId; question.ReadingQuestionCriterionSystemId = inDto.ToSystemCriterionId;
question.Id = questionRelation[question.Id.Value]; question.Id = questionRelation[question.Id!.Value];
if (question.ParentId != null) if (question.ParentId != null)
{ {
question.ParentId = questionRelation[question.ParentId ?? default(Guid)]; question.ParentId = questionRelation[question.ParentId ?? default(Guid)];
@@ -63,12 +63,10 @@ namespace IRaCIS.Application.Services
private readonly IRepository<NoneDicomStudyFile> _noneDicomStudyFileSystem; private readonly IRepository<NoneDicomStudyFile> _noneDicomStudyFileSystem;
private readonly IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository; private readonly IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository;
private readonly ISchedulerFactory _schedulerFactory; private readonly ISchedulerFactory _schedulerFactory;
private readonly IMemoryCache _cache;
private readonly ITrialEmailNoticeConfigService _trialEmailNoticeConfigService; private readonly ITrialEmailNoticeConfigService _trialEmailNoticeConfigService;
public ReadingImageTaskService( public ReadingImageTaskService(
IMapper mapper,
IRepository<NoneDicomStudy> noneDicomStudyRepository, IRepository<NoneDicomStudy> noneDicomStudyRepository,
IRepository<VisitTask> visitTaskRepository, IRepository<VisitTask> visitTaskRepository,
IRepository<Trial> TrialRepository, IRepository<Trial> TrialRepository,
@@ -109,7 +107,6 @@ namespace IRaCIS.Application.Services
) )
{ {
_schedulerFactory = schedulerFactory; _schedulerFactory = schedulerFactory;
base._mapper = mapper;
this._noneDicomStudyRepository = noneDicomStudyRepository; this._noneDicomStudyRepository = noneDicomStudyRepository;
this._visitTaskRepository = visitTaskRepository; this._visitTaskRepository = visitTaskRepository;
this._trialRepository = TrialRepository; this._trialRepository = TrialRepository;
@@ -145,7 +142,6 @@ namespace IRaCIS.Application.Services
this._readingQuestionSystem = ReadingQuestionSystem; this._readingQuestionSystem = ReadingQuestionSystem;
this._noneDicomStudyFileSystem = noneDicomStudyFileSystem; this._noneDicomStudyFileSystem = noneDicomStudyFileSystem;
this._readingQuestionTrialRepository = readingQuestionTrialRepository; this._readingQuestionTrialRepository = readingQuestionTrialRepository;
this._cache = cache;
this._trialEmailNoticeConfigService = trialEmailNoticeConfigService; this._trialEmailNoticeConfigService = trialEmailNoticeConfigService;
} }
@@ -708,9 +704,9 @@ namespace IRaCIS.Application.Services
{ {
//await AddDefaultValueToTask(inDto.VisitTaskId); //await AddDefaultValueToTask(inDto.VisitTaskId);
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var result = await GetReadingQuestion(taskInfo.TrialReadingCriterionId, taskInfo.Id); var result = await GetReadingQuestion(taskInfo.TrialReadingCriterionId, taskInfo.Id);
return (result, new return (result, new
{ {
ReadingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync() ReadingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync()
@@ -722,6 +718,8 @@ namespace IRaCIS.Application.Services
/// </summary> /// </summary>
/// <param name="trialReadingCriterionId"></param> /// <param name="trialReadingCriterionId"></param>
/// <param name="visitTaskId"></param> /// <param name="visitTaskId"></param>
/// <param name="questionClassify"></param>
/// <param name="groupClassifyList"></param>
/// <returns></returns> /// <returns></returns>
[NonDynamicMethod] [NonDynamicMethod]
public async Task<List<DicomReadingQuestionAnswer>> GetReadingQuestion(Guid trialReadingCriterionId, Guid? visitTaskId) public async Task<List<DicomReadingQuestionAnswer>> GetReadingQuestion(Guid trialReadingCriterionId, Guid? visitTaskId)
@@ -826,10 +824,7 @@ namespace IRaCIS.Application.Services
[HttpGet] [HttpGet]
public async Task<List<GetTableAnswerRowInfoOutDto>> GetTableAnswerRowInfoList(GetTableAnswerRowInfoInDto inDto) public async Task<List<GetTableAnswerRowInfoOutDto>> GetTableAnswerRowInfoList(GetTableAnswerRowInfoInDto inDto)
{ {
await _readingCalculateService.AddTaskLesionAnswerFromLastTask(new AddTaskLesionAnswerFromLastTaskInDto()
{
VisitTaskId = inDto.VisitTaskId
});
var result = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId) var result = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId)
.WhereIf(inDto.QuestionId != null, x => x.QuestionId == inDto.QuestionId) .WhereIf(inDto.QuestionId != null, x => x.QuestionId == inDto.QuestionId)
.ProjectTo<GetTableAnswerRowInfoOutDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex) .ProjectTo<GetTableAnswerRowInfoOutDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex)
@@ -1111,7 +1106,7 @@ namespace IRaCIS.Application.Services
var firstData = newPageQusetionList.FirstOrDefault(); var firstData = newPageQusetionList.FirstOrDefault();
var page = new TrialReadQuestionData() var page = new TrialReadQuestionData()
{ {
PageName = firstData.PageName, PageName = firstData!.PageName,
IsPage = true, IsPage = true,
IsPublicPage = firstData.IsPublicPage, IsPublicPage = firstData.IsPublicPage,
}; };
@@ -1126,8 +1121,8 @@ namespace IRaCIS.Application.Services
groupList.Add(page); groupList.Add(page);
} }
result.PublicPage = groupList.Where(x => x.IsPublicPage.Value).ToList(); result.PublicPage = groupList.Where(x => x.IsPublicPage!.Value).ToList();
result.MultiPage = groupList.Where(x => !x.IsPublicPage.Value).ToList(); result.MultiPage = groupList.Where(x => !x.IsPublicPage!.Value).ToList();
} }
else else
{ {
@@ -1151,12 +1146,19 @@ namespace IRaCIS.Application.Services
} }
/// <summary> /// <summary>
/// 获取子元素 /// 获取子元素
/// </summary> /// </summary>
/// <param name="item"></param> /// <param name="item"></param>
/// <param name="questionlists"></param> /// <param name="questionlists"></param>
/// <param name="tableQuestionLists"></param> /// <param name="tableQuestionLists"></param>
private async void FindChildQuestion(TrialReadQuestionData item, List<TrialReadQuestionData> questionlists, List<TableQuestionTrial> tableQuestionLists, List<ReadingTableQuestionAnswerInfo> tableAnswers, List<TableAnsweRowInfo> tableAnsweRowInfos, List<OrganInfo> organInfos, List<ReadingTableQuestionAnswer> baseLineTableAnswer, bool isFirstChangeTask, List<ReadingTableQuestionAnswer> lastTaskTableAnswer, Guid? TaskId) /// <param name="tableAnswers"></param>
/// <param name="tableAnsweRowInfos"></param>
/// <param name="organInfos"></param>
/// <param name="baseLineTableAnswer"></param>
/// <param name="isFirstChangeTask"></param>
/// <param name="lastTaskTableAnswer"></param>
/// <param name="TaskId"></param>
private async void FindChildQuestion(TrialReadQuestionData item, List<TrialReadQuestionData> questionlists, List<TableQuestionTrial> tableQuestionLists, List<ReadingTableQuestionAnswerInfo> tableAnswers, List<TableAnsweRowInfo> tableAnsweRowInfos, List<OrganInfo> organInfos, List<ReadingTableQuestionAnswer> baseLineTableAnswer,bool isFirstChangeTask, List<ReadingTableQuestionAnswer> lastTaskTableAnswer,Guid? TaskId)
{ {
item.Childrens = questionlists.Where(x => x.ParentId == item.Id || (x.GroupId == item.Id && x.ParentId == null)).ToList(); item.Childrens = questionlists.Where(x => x.ParentId == item.Id || (x.GroupId == item.Id && x.ParentId == null)).ToList();
item.TableQuestions = new TrialReadTableQuestion(); item.TableQuestions = new TrialReadTableQuestion();
@@ -2087,11 +2089,6 @@ namespace IRaCIS.Application.Services
} }
await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
{
ReadingTaskState = ReadingTaskState.Reading,
});
await _readingTableAnswerRowInfoRepository.SaveChangesAsync(); await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
await this._readingCalculateService.CalculateTask(new CalculateTaskInDto() await this._readingCalculateService.CalculateTask(new CalculateTaskInDto()
{ {
@@ -2291,7 +2288,7 @@ namespace IRaCIS.Application.Services
VisitNum = x.VisitTaskNum, VisitNum = x.VisitTaskNum,
TrialReadingCriterionId = x.TrialReadingCriterionId, TrialReadingCriterionId = x.TrialReadingCriterionId,
}).FirstOrDefaultAsync(); }).FirstNotNullAsync();
} }
else if (inDto.SubjectId != null && trialReadingCriterion.IsReadingTaskViewInOrder) else if (inDto.SubjectId != null && trialReadingCriterion.IsReadingTaskViewInOrder)
@@ -2299,7 +2296,7 @@ namespace IRaCIS.Application.Services
var subjectTaskList = (await _visitTaskService.GetOrderReadingIQueryable(new GetOrderReadingIQueryableInDto() var subjectTaskList = (await _visitTaskService.GetOrderReadingIQueryable(new GetOrderReadingIQueryableInDto()
{ {
TrialId = inDto.TrialId, TrialId = inDto.TrialId,
TrialReadingCriterionId = trialReadingCriterionId.Value, TrialReadingCriterionId = trialReadingCriterionId!.Value,
Page = new PageInput() Page = new PageInput()
{ {
PageIndex = 1, PageIndex = 1,
@@ -2452,6 +2449,15 @@ namespace IRaCIS.Application.Services
task.IsNeedReadClinicalData = clinicalDataList.Where(x => x.ClinicalDataLevel != ClinicalLevel.Subject).Count() > 0; task.IsNeedReadClinicalData = clinicalDataList.Where(x => x.ClinicalDataLevel != ClinicalLevel.Subject).Count() > 0;
} }
if (visitTaskInfo.ReadingTaskState == ReadingTaskState.WaitReading)
{
await _readingCalculateService.AddTaskLesionAnswerFromLastTask(new AddTaskLesionAnswerFromLastTaskInDto()
{
VisitTaskId = task.VisitTaskId
});
}
// 如果已经签名 就不需要再读了 // 如果已经签名 就不需要再读了
task.IsNeedReadClinicalData = visitTaskInfo.ReadingTaskState == ReadingTaskState.HaveSigned ? false : task.IsNeedReadClinicalData; task.IsNeedReadClinicalData = visitTaskInfo.ReadingTaskState == ReadingTaskState.HaveSigned ? false : task.IsNeedReadClinicalData;
task.DigitPlaces = criterionInfo.DigitPlaces; task.DigitPlaces = criterionInfo.DigitPlaces;
@@ -2479,7 +2485,7 @@ namespace IRaCIS.Application.Services
var value = _provider.Get<string>(cacheKey).Value; var value = _provider.Get<string>(cacheKey).Value;
if (value == null) if (value == null)
{ {
_provider.Set(cacheKey, DateTime.Now.ToString(), TimeSpan.FromHours(5)); _provider.Set(cacheKey, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(5));
// _cache.Set(cacheKey, DateTime.Now.ToString(), TimeSpan.FromHours(5)); // _cache.Set(cacheKey, DateTime.Now.ToString(), TimeSpan.FromHours(5));
} }
@@ -55,11 +55,6 @@ namespace IRaCIS.Application.Services
TrialId = inDto.TrialId TrialId = inDto.TrialId
}).ToList(); }).ToList();
await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
{
ReadingTaskState = ReadingTaskState.Reading,
});
await _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskAnswerList); await _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskAnswerList);
var result = await _visitTaskRepository.SaveChangesAsync(); var result = await _visitTaskRepository.SaveChangesAsync();
return ResponseOutput.Ok(result); return ResponseOutput.Ok(result);
@@ -191,7 +191,6 @@ namespace IRaCIS.Application.Services
await _readingOncologyTaskInfoRepository.AddRangeAsync(readingOncologies); await _readingOncologyTaskInfoRepository.AddRangeAsync(readingOncologies);
await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == inDto.OncologyTaskId, u => new VisitTask() { ReadingTaskState = ReadingTaskState.Reading });
var result = await _readingOncologyTaskInfoRepository.SaveChangesAsync(); var result = await _readingOncologyTaskInfoRepository.SaveChangesAsync();
@@ -85,7 +85,7 @@ namespace IRaCIS.Application.Services
var firstData = newPageQusetionList.FirstOrDefault(); var firstData = newPageQusetionList.FirstOrDefault();
var page = new GetTrialReadingQuestionOutDto() var page = new GetTrialReadingQuestionOutDto()
{ {
PageName = firstData.PageName, PageName = firstData!.PageName,
IsPage = true, IsPage = true,
IsPublicPage = firstData.IsPublicPage, IsPublicPage = firstData.IsPublicPage,
}; };
@@ -100,8 +100,8 @@ namespace IRaCIS.Application.Services
groupList.Add(page); groupList.Add(page);
} }
result.PublicPage = groupList.Where(x => x.IsPublicPage.Value).ToList(); result.PublicPage = groupList.Where(x => x.IsPublicPage!.Value).ToList();
result.MultiPage = groupList.Where(x => !x.IsPublicPage.Value).ToList(); result.MultiPage = groupList.Where(x => !x.IsPublicPage!.Value).ToList();
} }
else else
{ {
@@ -57,7 +57,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<VisitTask, VisitTaskDto>(); CreateMap<VisitTask, VisitTaskDto>();
CreateMap<ShortcutKey, DefaultShortcutKeyView>(); CreateMap<ShortcutKey, DefaultShortcutKeyView>();
CreateMap<TrialDataFromSystem, ReadingMedicineTrialQuestion>();
CreateMap<ReadingCustomTag, ReadingCustomTagDto>(); CreateMap<ReadingCustomTag, ReadingCustomTagDto>();
CreateMap<ReadingCustomTagDto, ReadingCustomTag>(); CreateMap<ReadingCustomTagDto, ReadingCustomTag>();
@@ -126,36 +126,35 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
{ {
var service = await this.GetService(inDto.VisitTaskId); var service = await this.GetService(inDto.VisitTaskId);
var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
if (service != null && visitTaskInfo.SourceSubjectVisitId != null) var result = new AddTaskLesionAnswerFromLastTaskOutDto();
var readingTaskState = visitTaskInfo.ReadingTaskState;
if (service != null && visitTaskInfo.SourceSubjectVisitId != null)
{ {
var readingTaskState = visitTaskInfo.ReadingTaskState;
var result = new AddTaskLesionAnswerFromLastTaskOutDto();
if (readingTaskState == ReadingTaskState.WaitReading) if (readingTaskState == ReadingTaskState.WaitReading)
{ {
result = await service.AddTaskLesionAnswerFromLastTask(inDto); if (visitTaskInfo.ReadingCategory == ReadingCategory.Visit)
await service.CalculateTask(new CalculateTaskInDto()
{ {
IsChangeOtherTask = false, result = await service.AddTaskLesionAnswerFromLastTask(inDto);
VisitTaskId = inDto.VisitTaskId, await service.CalculateTask(new CalculateTaskInDto()
}); {
IsChangeOtherTask = false,
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask() VisitTaskId = inDto.VisitTaskId,
{ });
ReadingTaskState = ReadingTaskState.Reading, }
});
} }
return result;
}
else
{
return new AddTaskLesionAnswerFromLastTaskOutDto();
} }
if (readingTaskState == ReadingTaskState.WaitReading)
{
await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
{
ReadingTaskState = ReadingTaskState.Reading,
},true);
}
} return result;
}
/// <summary> /// <summary>
/// 获取报告验证的信息(这里每个标准可能不一样 返回用object) /// 获取报告验证的信息(这里每个标准可能不一样 返回用object)
@@ -181,7 +180,6 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
/// <summary> /// <summary>
/// 获取阅片报告 /// 获取阅片报告
/// </summary> /// </summary>
/// <param name="indto"></param>
/// <returns></returns> /// <returns></returns>
public async Task<GetReadingReportEvaluationOutDto> GetReadingReportEvaluation(GetReadingReportEvaluationInDto inDto) public async Task<GetReadingReportEvaluationOutDto> GetReadingReportEvaluation(GetReadingReportEvaluationInDto inDto)
{ {
@@ -149,7 +149,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
result.LesionCountList = tableAnsweRowInfos.GroupBy(x => x.LesionType).Select(x => new LesionDto result.LesionCountList = tableAnsweRowInfos.GroupBy(x => x.LesionType).Select(x => new LesionDto
{ {
LesionType = x.Key.Value, LesionType = x.Key!.Value,
Count = x.ToList().Count() Count = x.ToList().Count()
}).ToList(); }).ToList();
@@ -711,7 +711,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
if (valueOfTypes.Contains(item.ValueType)) if (valueOfTypes.Contains(item.ValueType))
{ {
item.Answer = decimal.Round(decimal.Parse(item.Answer ?? "0"), inDto.DigitPlaces).ToString(); item.Answer = decimal.Round(decimal.Parse(item.Answer ?? "0"), inDto.DigitPlaces).ToString("F" + inDto.DigitPlaces.ToString());
} }
} }
catch (Exception) catch (Exception)
@@ -1775,7 +1775,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
{ {
VisitTaskId = x.VisitTaskId, VisitTaskId = x.VisitTaskId,
Answer = x.Answer, Answer = x.Answer,
QuestionType = x.ReadingQuestionTrial.QuestionType.Value QuestionType = x.ReadingQuestionTrial.QuestionType!.Value
}).ToListAsync(); }).ToListAsync();
compareTaskList.ForEach(y => compareTaskList.ForEach(y =>
@@ -2,7 +2,6 @@
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using Panda.DynamicWebApi.Attributes; using Panda.DynamicWebApi.Attributes;
@@ -650,7 +649,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
if (valueOfTypes.Contains(item.ValueType)) if (valueOfTypes.Contains(item.ValueType))
{ {
item.Answer = decimal.Round(decimal.Parse(item.Answer.IsNullOrEmpty() ? "0": item.Answer), inDto.DigitPlaces).ToString(); item.Answer = decimal.Round(decimal.Parse(item.Answer.IsNullOrEmpty() ? "0": item.Answer), inDto.DigitPlaces).ToString("F" + inDto.DigitPlaces.ToString());
} }
} }
catch (Exception) catch (Exception)
@@ -2,7 +2,6 @@
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using Panda.DynamicWebApi.Attributes; using Panda.DynamicWebApi.Attributes;
@@ -550,7 +549,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
if (valueOfTypes.Contains(item.ValueType)) if (valueOfTypes.Contains(item.ValueType))
{ {
item.Answer = decimal.Round(decimal.Parse(item.Answer ?? "0"), inDto.DigitPlaces).ToString(); item.Answer = decimal.Round(decimal.Parse(item.Answer ?? "0"), inDto.DigitPlaces).ToString("F" + inDto.DigitPlaces.ToString());
} }
} }
catch (Exception) catch (Exception)
@@ -2,7 +2,6 @@
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using Panda.DynamicWebApi.Attributes; using Panda.DynamicWebApi.Attributes;
@@ -546,7 +545,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
if (valueOfTypes.Contains(item.ValueType)) if (valueOfTypes.Contains(item.ValueType))
{ {
item.Answer = decimal.Round(decimal.Parse(item.Answer ?? "0"), inDto.DigitPlaces).ToString(); item.Answer = decimal.Round(decimal.Parse(item.Answer ?? "0"), inDto.DigitPlaces).ToString("F" + inDto.DigitPlaces.ToString());
} }
} }
catch (Exception) catch (Exception)
@@ -2,7 +2,6 @@
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using Panda.DynamicWebApi.Attributes; using Panda.DynamicWebApi.Attributes;
@@ -104,6 +104,8 @@ namespace IRaCIS.Core.Application.Contracts
[DictionaryTranslateAttribute("YesOrNo")] [DictionaryTranslateAttribute("YesOrNo")]
public bool IsGenerateAccount { get; set; } public bool IsGenerateAccount { get; set; }
[DictionaryTranslateAttribute("SiteSurvey_UserRoles")]
public int TrialRoleCode { get; set; } public int TrialRoleCode { get; set; }
public string OrganizationName { get; set; } = string.Empty; public string OrganizationName { get; set; } = string.Empty;
@@ -22,14 +22,14 @@ namespace IRaCIS.Application.Contracts
[DictionaryTranslateAttribute("IsUserExitTrial")] [DictionaryTranslateAttribute("IsUserExitTrial")]
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }
[ExcelFormat("yyyy-MM-dd hh:mm:ss")] [ExcelFormat("yyyy-MM-dd HH:mm:ss")]
public DateTime? DeletedTime { get; set; } public DateTime? DeletedTime { get; set; }
public Guid? SiteId { get; set; } public Guid? SiteId { get; set; }
public string Phone { get; set; } = String.Empty; public string Phone { get; set; } = String.Empty;
public DateTime UpdateTime { get; set; } public DateTime UpdateTime { get; set; }
[ExcelFormat("yyyy-MM-dd hh:mm:ss")] [ExcelFormat("yyyy-MM-dd HH:mm:ss")]
public DateTime CreateTime { get; set; } public DateTime CreateTime { get; set; }
@@ -84,7 +84,7 @@ namespace IRaCIS.Application.Contracts
[ExporterHeader(Format = "yyyy-mm-DD hh:mm:ss")] [ExporterHeader(Format = "yyyy-mm-DD hh:mm:ss")]
[ExcelFormat("yyyy-MM-dd hh:mm:ss")] [ExcelFormat("yyyy-MM-dd HH:mm:ss")]
public DateTime CreateTime { get; set; } public DateTime CreateTime { get; set; }
@@ -118,7 +118,8 @@ namespace IRaCIS.Application.Contracts
public class ExcelExportInfo : TrialSelectDTO public class ExcelExportInfo : TrialSelectDTO
{ {
public DateTime CurrentTime { get; set; } = DateTime.Now;
public string CurrentTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
public bool IsEn_US { get; set; } public bool IsEn_US { get; set; }
@@ -1,6 +1,7 @@
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.Reading.Interface;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
@@ -21,11 +22,13 @@ namespace IRaCIS.Core.Application
private readonly IRepository<TrialDocument> _trialDocumentRepository; private readonly IRepository<TrialDocument> _trialDocumentRepository;
private readonly IRepository<SystemDocument> _systemDocumentRepository; private readonly IRepository<SystemDocument> _systemDocumentRepository;
private readonly IRepository<ReadModule> _readModuleRepository; private readonly IRepository<ReadModule> _readModuleRepository;
private readonly IClinicalAnswerService _clinicalAnswerService;
private readonly IRepository<SystemNotice> _systemNoticeRepository; private readonly IRepository<SystemNotice> _systemNoticeRepository;
public PersonalWorkstation(IRepository<Trial> trialRepository, IRepository<TrialUser> trialUserRepository, IRepository<TrialDocument> trialDocumentRepository, public PersonalWorkstation(IRepository<Trial> trialRepository, IRepository<TrialUser> trialUserRepository, IRepository<TrialDocument> trialDocumentRepository,
IRepository<SystemDocument> systemDocumentRepository, IRepository<SystemDocument> systemDocumentRepository,
IRepository<ReadModule> readModuleRepository, IRepository<ReadModule> readModuleRepository,
IClinicalAnswerService clinicalAnswerService,
IRepository<SystemNotice> systemNoticeRepository) IRepository<SystemNotice> systemNoticeRepository)
{ {
_trialRepository = trialRepository; _trialRepository = trialRepository;
@@ -33,6 +36,7 @@ namespace IRaCIS.Core.Application
_trialDocumentRepository = trialDocumentRepository; _trialDocumentRepository = trialDocumentRepository;
_systemDocumentRepository = systemDocumentRepository; _systemDocumentRepository = systemDocumentRepository;
this._readModuleRepository = readModuleRepository; this._readModuleRepository = readModuleRepository;
this._clinicalAnswerService = clinicalAnswerService;
_systemNoticeRepository = systemNoticeRepository; _systemNoticeRepository = systemNoticeRepository;
} }
@@ -48,11 +52,11 @@ namespace IRaCIS.Core.Application
//正参与的数量 //正参与的数量
TrialCount = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin TrialCount = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin
? await _trialRepository.CountAsync() ? await _trialRepository.CountAsync()
: await _trialUserRepository.Where(t => t.UserId == _userInfo.Id).CountAsync(), : await _trialUserRepository.Where(t => t.UserId == _userInfo.Id && t.Trial.IsDeleted == false).CountAsync(),
DeletedCount = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin DeletedCount = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin
? await _trialRepository.AsQueryable(true).CountAsync(t => t.IsDeleted) ? await _trialRepository.AsQueryable(true).CountAsync(t => t.IsDeleted)
: await _trialUserRepository.AsQueryable(true).Where(t => t.UserId == _userInfo.Id && t.IsDeleted) : await _trialUserRepository.AsQueryable(true).Where(t => t.UserId == _userInfo.Id && t.Trial.IsDeleted)
.CountAsync(), .CountAsync(),
@@ -204,11 +208,12 @@ namespace IRaCIS.Core.Application
ToBeRepliedCount = t.SubjectVisitList.Where(u => u.CheckState == CheckStateEnum.CVIng && ToBeRepliedCount = t.SubjectVisitList.Where(u => u.CheckState == CheckStateEnum.CVIng &&
u.CheckChallengeDialogList.OrderByDescending(t => t.CreateTime).First().UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Count(), u.CheckChallengeDialogList.OrderByDescending(t => t.CreateTime).First().UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Count(),
}).Where(x => x.ToBeRepliedCount > 0); }).Where(x => x.ToBeRepliedCount > 0);
var defalutSortArray = new string[] { nameof(CheckToBeDoneDto.UrgentCount) + " desc", nameof(CheckToBeDoneDto.ToBeCheckedCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(CheckToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc); var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var totalToBeCheckedCount = await _subjectVisitRepository.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) var totalToBeCheckedCount = await _subjectVisitRepository.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.Where(u => u.CheckState == CheckStateEnum.ToCheck).CountAsync(); .Where(u => u.CheckState == CheckStateEnum.ToCheck).CountAsync();
@@ -250,7 +255,9 @@ namespace IRaCIS.Core.Application
}).Where(x => x.ToBeApprovalCount > 0); }).Where(x => x.ToBeApprovalCount > 0);
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ReReadingApplyToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc); var defalutSortArray = new string[] { nameof(ReReadingApplyToBeDoneDto.UrgentCount) + " desc", nameof(ReReadingApplyToBeDoneDto.ToBeApprovalCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var toBeApprovalCount = _visitTaskReReadingRepository var toBeApprovalCount = _visitTaskReReadingRepository
@@ -271,7 +278,7 @@ namespace IRaCIS.Core.Application
[HttpPost] [HttpPost]
public async Task<IResponseOutput<PageOutput<GetPMClinicalDataToBeDoneListOutDto>>> GetPMClinicalDataToBeDoneList(ReviewerSelectToBeDoneQuery inQuery) public async Task<IResponseOutput<PageOutput<GetPMClinicalDataToBeDoneListOutDto>>> GetPMClinicalDataToBeDoneList(ReviewerSelectToBeDoneQuery inQuery)
{ {
var query = _trialRepository var query = _trialRepository
.Where(t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.Select(t => new GetPMClinicalDataToBeDoneListOutDto() .Select(t => new GetPMClinicalDataToBeDoneListOutDto()
@@ -281,14 +288,18 @@ namespace IRaCIS.Core.Application
ExperimentName = t.ExperimentName, ExperimentName = t.ExperimentName,
TrialCode = t.TrialCode, TrialCode = t.TrialCode,
ToBeApprovalCount = t.ReadModuleList.Where(u => u.IsCRCConfirm&&!u.IsPMConfirm).Count() ToBeApprovalCount = t.ReadModuleList.Where(u => u.IsCRCConfirm && !u.IsPMConfirm).Count()
}).Where(x => x.ToBeApprovalCount > 0); }).Where(x => x.ToBeApprovalCount > 0);
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ReviewerSelectToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc);
var all =await _trialRepository var defalutSortArray = new string[] { nameof(GetPMClinicalDataToBeDoneListOutDto.ToBeApprovalCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var all = await _trialRepository
.Where(t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.Select(t => new GetPMClinicalDataToBeDoneListOutDto() .Select(t => new GetPMClinicalDataToBeDoneListOutDto()
{ {
@@ -297,7 +308,7 @@ namespace IRaCIS.Core.Application
ToBeApprovalCount = t.ReadModuleList.Where(u => u.IsCRCConfirm && !u.IsPMConfirm).Count() ToBeApprovalCount = t.ReadModuleList.Where(u => u.IsCRCConfirm && !u.IsPMConfirm).Count()
}).ToListAsync(); }).ToListAsync();
return ResponseOutput.Ok(result, new { ToBeApprovalCount = all.Sum(x=>x.ToBeApprovalCount) }); ; return ResponseOutput.Ok(result, new { ToBeApprovalCount = all.Sum(x => x.ToBeApprovalCount) }); ;
} }
#endregion #endregion
@@ -335,7 +346,10 @@ namespace IRaCIS.Core.Application
}).Where(x => x.ToBeApprovalCount > 0); }).Where(x => x.ToBeApprovalCount > 0);
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ReReadingApprovalToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc); var defalutSortArray = new string[] { nameof(ReReadingApprovalToBeDoneDto.UrgentCount) + " desc", nameof(ReReadingApprovalToBeDoneDto.ToBeApprovalCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var toBeApprovalCount = _visitTaskReReadingRepository var toBeApprovalCount = _visitTaskReReadingRepository
.Where(t => t.OriginalReReadingTask.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.OriginalReReadingTask.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
@@ -356,6 +370,7 @@ namespace IRaCIS.Core.Application
/// </summary> /// </summary>
/// <param name="inQuery"></param> /// <param name="inQuery"></param>
/// <param name="_subjectVisitRepository"></param> /// <param name="_subjectVisitRepository"></param>
/// <param name="_trialRepository"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<IResponseOutput<PageOutput<ImageClinicalDataToBeDoneDto>>> GetImageClinicalDataToBeDoneList(ImageClinicalDataToBeDoneQuery inQuery, public async Task<IResponseOutput<PageOutput<ImageClinicalDataToBeDoneDto>>> GetImageClinicalDataToBeDoneList(ImageClinicalDataToBeDoneQuery inQuery,
@@ -373,13 +388,15 @@ namespace IRaCIS.Core.Application
ExperimentName = t.ExperimentName, ExperimentName = t.ExperimentName,
TrialCode = t.TrialCode, TrialCode = t.TrialCode,
UrgentCount = t.SubjectVisitList.Where(u => u.IsBaseLine && u.SubmitState != SubmitStateEnum.Submitted && u.IsUrgent).Count(), UrgentCount = t.SubjectVisitList.Where(u => u.IsBaseLine && u.SubmitState != SubmitStateEnum.Submitted && u.IsUrgent).Count(),
ToBeDealedCount = t.ReadingClinicalDataList.Where(x=>!x.IsSign&& x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.SubjectVisit&& x.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.Subject).Count(), ToBeDealedCount = t.ReadingClinicalDataList.Where(x => !x.IsSign && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.SubjectVisit && x.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.Subject).Count(),
ToBeVisitCount= t.ReadingClinicalDataList.Where(x => !x.IsSign && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit).Count(), ToBeVisitCount = t.ReadingClinicalDataList.Where(x => !x.IsSign && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit).Count(),
ToAllCount= t.ReadingClinicalDataList.Where(x => !x.IsSign && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC ).Count(), ToAllCount = t.ReadingClinicalDataList.Where(x => !x.IsSign && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC).Count(),
ReadModuleCount =t.ReadModuleList.Where(x=>!x.IsPMConfirm).Count(), ReadModuleCount = t.ReadModuleList.Where(x => !x.IsPMConfirm).Count(),
}).Where(x=>x.ToBeDealedCount > 0); }).Where(x => x.ToBeDealedCount > 0);
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ImageClinicalDataToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc); var defalutSortArray = new string[] { nameof(ImageClinicalDataToBeDoneDto.UrgentCount) + " desc", nameof(ImageClinicalDataToBeDoneDto.ReadModuleCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var toBeDealedCount = _subjectVisitRepository var toBeDealedCount = _subjectVisitRepository
//.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id) && t.Trial.clinicalDataTrialSets.Any(t => t.ClinicalDataLevel == ClinicalLevel.Subject && t.IsConfirm)) //.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id) && t.Trial.clinicalDataTrialSets.Any(t => t.ClinicalDataLevel == ClinicalLevel.Subject && t.IsConfirm))
@@ -395,6 +412,7 @@ namespace IRaCIS.Core.Application
/// </summary> /// </summary>
/// <param name="inQuery"></param> /// <param name="inQuery"></param>
/// <param name="_subjectVisitRepository"></param> /// <param name="_subjectVisitRepository"></param>
/// <param name="_trialRepository"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<IResponseOutput<PageOutput<ImageClinicalDataToBeDoneDto>>> GetImageClinicalDataToBeConfirmList(ImageClinicalDataToBeDoneQuery inQuery, public async Task<IResponseOutput<PageOutput<ImageClinicalDataToBeDoneDto>>> GetImageClinicalDataToBeConfirmList(ImageClinicalDataToBeDoneQuery inQuery,
@@ -415,10 +433,29 @@ namespace IRaCIS.Core.Application
ToBeDealedCount = t.ReadingClinicalDataList.Where(x => !x.IsSign && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.SubjectVisit && x.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.Subject).Count(), ToBeDealedCount = t.ReadingClinicalDataList.Where(x => !x.IsSign && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.SubjectVisit && x.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.Subject).Count(),
ToBeVisitCount = t.ReadingClinicalDataList.Where(x => !x.IsSign && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit).Count(), ToBeVisitCount = t.ReadingClinicalDataList.Where(x => !x.IsSign && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit).Count(),
ToAllCount = t.ReadingClinicalDataList.Where(x => !x.IsSign && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC).Count(), ToAllCount = t.ReadingClinicalDataList.Where(x => !x.IsSign && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC).Count(),
ReadModuleCount = t.ReadModuleList.Where(x => !x.IsPMConfirm).Count(), ReadModuleCount = t.ReadModuleList.Where(x => !x.IsCRCConfirm).Count(),
}).Where(x => x.ReadModuleCount > 0); }).Where(x => x.ReadModuleCount > 0);
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ImageClinicalDataToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc); var defalutSortArray = new string[] { nameof(ImageClinicalDataToBeDoneDto.UrgentCount) + " desc", nameof(ImageClinicalDataToBeDoneDto.ToBeDealedCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
// ReadModuleCount情况太多了 暂时用之前的方法
foreach (var item in result.CurrentPageData)
{
item.ReadModuleCount = (await _clinicalAnswerService.GetCRCConfirmList(new Service.Reading.Dto.GetCRCConfirmListInDto()
{
TrialId = item.TrialId,
IsPMConfirm = false,
PageIndex = 1,
PageSize = 9999,
})).CurrentPageData.Count();
}
result.CurrentPageData = result.CurrentPageData.Where(x => x.ReadModuleCount != 0).ToList();
var toBeDealedCount = _subjectVisitRepository var toBeDealedCount = _subjectVisitRepository
//.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id) && t.Trial.clinicalDataTrialSets.Any(t => t.ClinicalDataLevel == ClinicalLevel.Subject && t.IsConfirm)) //.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id) && t.Trial.clinicalDataTrialSets.Any(t => t.ClinicalDataLevel == ClinicalLevel.Subject && t.IsConfirm))
@@ -461,11 +498,14 @@ namespace IRaCIS.Core.Application
ToBeDealedCount = t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id)) ToBeDealedCount = t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id))
.SelectMany(c => c.QCChallengeList) .SelectMany(c => c.QCChallengeList)
.Where(u => u.IsClosed == false && u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IQC).Count(), .Where(u => u.IsClosed == false && (u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IQC || u.LatestReplyUserId == null)).Count(),
}).Where(x => x.ToBeDealedCount > 0); ; }).Where(x => x.ToBeDealedCount > 0); ;
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ImageQuestionToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc); var defalutSortArray = new string[] { nameof(ImageQuestionToBeDoneDto.UrgentCount) + " desc", nameof(ImageQuestionToBeDoneDto.ToBeDealedCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var toBeDealedCount = _subjectVisitRepository var toBeDealedCount = _subjectVisitRepository
.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
@@ -482,6 +522,7 @@ namespace IRaCIS.Core.Application
/// </summary> /// </summary>
/// <param name="inQuery"></param> /// <param name="inQuery"></param>
/// <param name="_subjectVisitRepository"></param> /// <param name="_subjectVisitRepository"></param>
/// <param name="_trialRepository"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<IResponseOutput<PageOutput<ImageCheckQuestionToBeDoneDto>>> GetImageCheckQuestionToBeDoneList(ImageCheckQuestionToBeDoneQuery inQuery, public async Task<IResponseOutput<PageOutput<ImageCheckQuestionToBeDoneDto>>> GetImageCheckQuestionToBeDoneList(ImageCheckQuestionToBeDoneQuery inQuery,
@@ -507,9 +548,10 @@ namespace IRaCIS.Core.Application
}).Where(x => x.ToBeReplyedCount > 0); }).Where(x => x.ToBeReplyedCount > 0);
var defalutSortArray = new string[] { nameof(ImageCheckQuestionToBeDoneDto.UrgentCount) + " desc", nameof(ImageCheckQuestionToBeDoneDto.ToBeReplyedCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ImageCheckQuestionToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc);
var toBeDealedCount = _subjectVisitRepository var toBeDealedCount = _subjectVisitRepository
.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
@@ -521,12 +563,12 @@ namespace IRaCIS.Core.Application
} }
/// <summary> /// <summary>
/// 影像重传 --CRC 待办 /// 影像重传 --CRC 待办
/// </summary> /// </summary>
/// <param name="inQuery"></param> /// <param name="inQuery"></param>
/// <param name="_subjectVisitRepository"></param> /// <param name="_subjectVisitRepository"></param>
/// <param name="_trialRepository"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<IResponseOutput<PageOutput<ImageReUploadToBeDoneDto>>> GetImageReUploadToBeDoneList(ImageReUploadToBeDoneQuery inQuery, public async Task<IResponseOutput<PageOutput<ImageReUploadToBeDoneDto>>> GetImageReUploadToBeDoneList(ImageReUploadToBeDoneQuery inQuery,
@@ -544,19 +586,22 @@ namespace IRaCIS.Core.Application
TrialCode = t.TrialCode, TrialCode = t.TrialCode,
UrgentCount = t.SubjectVisitList UrgentCount = t.SubjectVisitList
.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id)) .Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id))
.Where(u => u.SubmitState == SubmitStateEnum.ToSubmit && u.IsUrgent && u.IsPMBackOrReReading).Count(), .Where(u => u.IsUrgent && ((u.SubmitState == SubmitStateEnum.ToSubmit && u.IsPMBackOrReReading) || u.IsQCConfirmedReupload)).Count(),
ToBeReUploadCount = t.SubjectVisitList ToBeReUploadCount = t.SubjectVisitList
.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id)) .Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id))
.Where(u => u.SubmitState == SubmitStateEnum.ToSubmit && u.IsPMBackOrReReading).Count(), .Where(u => (u.SubmitState == SubmitStateEnum.ToSubmit && u.IsPMBackOrReReading) || (u.IsQCConfirmedReupload)).Count(),
}).Where(x => x.ToBeReUploadCount > 0); }).Where(x => x.ToBeReUploadCount > 0);
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ImageReUploadToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc);
var defalutSortArray = new string[] { nameof(ImageReUploadToBeDoneDto.UrgentCount) + " desc", nameof(ImageReUploadToBeDoneDto.ToBeReUploadCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var toBeDealedCount = _subjectVisitRepository var toBeDealedCount = _subjectVisitRepository
.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.Where(u => u.SubmitState == SubmitStateEnum.ToSubmit && u.IsPMBackOrReReading).Count(); .Where(u => (u.SubmitState == SubmitStateEnum.ToSubmit && u.IsPMBackOrReReading) || (u.IsQCConfirmedReupload)).Count();
return ResponseOutput.Ok(result, new { TotalToBeReUploadCount = toBeDealedCount }); return ResponseOutput.Ok(result, new { TotalToBeReUploadCount = toBeDealedCount });
@@ -566,10 +611,11 @@ namespace IRaCIS.Core.Application
/// <summary> /// <summary>
/// 加急影像提交 --CRC 待办 /// 加急影像提交 --CRC 待办
/// </summary> /// </summary>
/// <param name="inQuery"></param> /// <param name="inQuery"></param>
/// <param name="_subjectVisitRepository"></param> /// <param name="_subjectVisitRepository"></param>
/// <param name="_trialRepository"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<IResponseOutput<PageOutput<ImageSubmittedToBeDoneDto>>> GetImageSubmittedToBeDoneList(ImageSubmittedToBeDoneQuery inQuery, public async Task<IResponseOutput<PageOutput<ImageSubmittedToBeDoneDto>>> GetImageSubmittedToBeDoneList(ImageSubmittedToBeDoneQuery inQuery,
@@ -587,7 +633,7 @@ namespace IRaCIS.Core.Application
TrialCode = t.TrialCode, TrialCode = t.TrialCode,
UrgentCount = t.SubjectVisitList UrgentCount = t.SubjectVisitList
.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id)) .Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id))
.Where(u => u.SubmitState == SubmitStateEnum.ToSubmit && u.IsUrgent).Count(), .Where(u => u.SubmitState == SubmitStateEnum.ToSubmit && (u.IsEnrollmentConfirm || u.PDState == PDStateEnum.PDProgress || u.Trial.IsUrgent || u.Subject.IsUrgent)/*u.IsUrgent*/).Count(),
ToBeDealedCount = t.SubjectVisitList ToBeDealedCount = t.SubjectVisitList
@@ -596,7 +642,12 @@ namespace IRaCIS.Core.Application
}).Where(x => x.ToBeDealedCount > 0); ; }).Where(x => x.ToBeDealedCount > 0); ;
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ImageSubmittedToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc);
var defalutSortArray = new string[] { nameof(ImageSubmittedToBeDoneDto.UrgentCount) + " desc", nameof(ImageSubmittedToBeDoneDto.ToBeDealedCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var toBeDealedCount = _subjectVisitRepository var toBeDealedCount = _subjectVisitRepository
.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
@@ -620,6 +671,7 @@ namespace IRaCIS.Core.Application
/// </summary> /// </summary>
/// <param name="inQuery"></param> /// <param name="inQuery"></param>
/// <param name="_subjectVisitRepository"></param> /// <param name="_subjectVisitRepository"></param>
/// <param name="_trialRepository"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<IResponseOutput<PageOutput<ImageQualityToBeDoneDto>>> GetImageQualityToBeDoneList(ImageQualityToBeDoneQuery inQuery, public async Task<IResponseOutput<PageOutput<ImageQualityToBeDoneDto>>> GetImageQualityToBeDoneList(ImageQualityToBeDoneQuery inQuery,
@@ -642,18 +694,23 @@ namespace IRaCIS.Core.Application
//待领取量 //待领取量
ToBeClaimedCount = t.SubjectVisitList.Where(u => u.CurrentActionUserId == null && (u.PreliminaryAuditUserId == null || (u.PreliminaryAuditUserId != _userInfo.Id && u.ReviewAuditUserId == null))).Count(), ToBeClaimedCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.AuditState!=AuditStateEnum.QCPassed)
.Where(u => u.CurrentActionUserId == null && (u.PreliminaryAuditUserId == null || (u.PreliminaryAuditUserId != _userInfo.Id && u.ReviewAuditUserId == null))).Count(),
//待审核通过,统计从已领取到QC提交之间的 已领取 待审核 审核中 (审核完成 领取人就会清理 所以只用查询当前领取人是自己的就好了) //待审核通过,统计从已领取到QC提交之间的 已领取 待审核 审核中 (审核完成 领取人就会清理 所以只用查询当前领取人是自己的就好了)
ToBeReviewedCount = t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.Id).Count() ToBeReviewedCount = t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.Id).Count()
}).Where(x => x.UrgentCount > 0); }).Where(x => x.ToBeClaimedCount + x.ToBeReviewedCount > 0);
var defalutSortArray = new string[] { nameof(ImageQualityToBeDoneDto.UrgentCount) + " desc", nameof(ImageQualityToBeDoneDto.ToBeClaimedCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ImageQualityToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc);
var toBeClaimedCount = _subjectVisitRepository var toBeClaimedCount = _subjectVisitRepository
.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)&& t.SubmitState == SubmitStateEnum.Submitted && t.AuditState != AuditStateEnum.QCPassed)
.Where(u => u.CurrentActionUserId == null && (u.PreliminaryAuditUserId == null || (u.PreliminaryAuditUserId != _userInfo.Id && u.ReviewAuditUserId == null))).Count(); .Where(u => u.CurrentActionUserId == null && (u.PreliminaryAuditUserId == null || (u.PreliminaryAuditUserId != _userInfo.Id && u.ReviewAuditUserId == null))).Count();
@@ -667,10 +724,11 @@ namespace IRaCIS.Core.Application
/// <summary> /// <summary>
/// QC 质疑 /// QC 质疑
/// </summary> /// </summary>
/// <param name="inQuery"></param> /// <param name="inQuery"></param>
/// <param name="_subjectVisitRepository"></param> /// <param name="_subjectVisitRepository"></param>
/// <param name="_trialRepository"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<IResponseOutput<PageOutput<ImageQuestionToBeDoneDto>>> GetQCImageQuestionToBeDoneList(ImageQuestionToBeDoneQuery inQuery, public async Task<IResponseOutput<PageOutput<ImageQuestionToBeDoneDto>>> GetQCImageQuestionToBeDoneList(ImageQuestionToBeDoneQuery inQuery,
@@ -694,7 +752,10 @@ namespace IRaCIS.Core.Application
}).Where(x => x.ToBeDealedCount > 0); ; }).Where(x => x.ToBeDealedCount > 0); ;
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ImageQuestionToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc); var defalutSortArray = new string[] { nameof(ImageQuestionToBeDoneDto.UrgentCount) + " desc", nameof(ImageQuestionToBeDoneDto.ToBeDealedCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var toBeDealedCount = _subjectVisitRepository var toBeDealedCount = _subjectVisitRepository
.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
@@ -835,8 +896,9 @@ namespace IRaCIS.Core.Application
#endregion #endregion
var defalutSortArray = new string[] { nameof(IRImageReadingToBeDoneDto.UrgentCount) + " desc", nameof(IRImageReadingToBeDoneDto.UnReadCount) + " desc" };
var result = await newQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(IRImageReadingToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc); var result = await newQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var toBeDealedCount = _trialRepository var toBeDealedCount = _trialRepository
.Where(t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id))
@@ -857,7 +919,7 @@ namespace IRaCIS.Core.Application
/// IR医学反馈 /// IR医学反馈
/// </summary> /// </summary>
/// <param name="inQuery"></param> /// <param name="inQuery"></param>
/// <param name="_taskMedicalReviewRepository"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<IResponseOutput<PageOutput<MedicalCommentsToBeDoneDto>>> GetIRMedicalCommentsToBeDoneList(MedicalCommentsToBeDoneQuery inQuery, public async Task<IResponseOutput<PageOutput<MedicalCommentsToBeDoneDto>>> GetIRMedicalCommentsToBeDoneList(MedicalCommentsToBeDoneQuery inQuery,
@@ -885,20 +947,35 @@ namespace IRaCIS.Core.Application
CriterionName = g.Key.CriterionName, CriterionName = g.Key.CriterionName,
TrialReadingCriterionId = g.Key.TrialReadingCriterionId, TrialReadingCriterionId = g.Key.TrialReadingCriterionId,
#region
UrgentCount = g.Where(u => u.VisitTask.IsUrgent && u.LatestReplyUser.UserTypeEnum== UserTypeEnum.MIM).Count(),
ToBeReplyedCount = g.Where(u => u.LatestReplyUser.UserTypeEnum == UserTypeEnum.MIM).Count(),
#endregion
//UrgentCount = g.Where(u => u.VisitTask.IsUrgent //UrgentCount = g.Where(u => u.VisitTask.IsUrgent
//&& u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First().UserTypeEnumInt == (int)UserTypeEnum.MIM).Count(), //&& u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First().UserTypeEnumInt == (int)UserTypeEnum.MIM).Count(),
//ToBeReplyedCount = g.Where(u => //ToBeReplyedCount = g.Where(u =>
// u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First().UserTypeEnumInt == (int)UserTypeEnum.MIM).Count(), // u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First().UserTypeEnumInt == (int)UserTypeEnum.MIM).Count(),
}); }).Where(t => t.ToBeReplyedCount > 0);
var defalutSortArray = new string[] { nameof(MedicalCommentsToBeDoneDto.UrgentCount) + " desc", nameof(MedicalCommentsToBeDoneDto.ToBeReplyedCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(MedicalCommentsToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc);
var toBeDealedCount = _taskMedicalReviewRepository var toBeDealedCount = _taskMedicalReviewRepository
.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.Where(t => t.IsClosedDialog == false && t.VisitTask.DoctorUserId == _userInfo.Id) .Where(t => t.IsClosedDialog == false && t.VisitTask.DoctorUserId == _userInfo.Id)
.Where(u => u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First().UserTypeEnumInt == (int)UserTypeEnum.MIM).Count(); .Where(u => u.LatestReplyUser.UserTypeEnum == UserTypeEnum.MIM)
//.Where(u => u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First().UserTypeEnumInt == (int)UserTypeEnum.MIM)
.Count();
return ResponseOutput.Ok(result, new { TotalToBeReplyedCount = toBeDealedCount }); return ResponseOutput.Ok(result, new { TotalToBeReplyedCount = toBeDealedCount });
@@ -916,7 +993,7 @@ namespace IRaCIS.Core.Application
/// </summary> /// </summary>
/// <param name="inQuery"></param> /// <param name="inQuery"></param>
/// <param name="_taskMedicalReviewRepository"></param> /// <param name="_taskMedicalReviewRepository"></param>
/// <param name="_trialReadingCriterionRepository"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<IResponseOutput<PageOutput<MedicalCommentsToBeDoneDto>>> GetMIMMedicalCommentsToBeDoneList(MedicalCommentsToBeDoneQuery inQuery, public async Task<IResponseOutput<PageOutput<MedicalCommentsToBeDoneDto>>> GetMIMMedicalCommentsToBeDoneList(MedicalCommentsToBeDoneQuery inQuery,
@@ -945,24 +1022,33 @@ namespace IRaCIS.Core.Application
TrialCode = g.Key.TrialCode, TrialCode = g.Key.TrialCode,
CriterionName = g.Key.CriterionName, CriterionName = g.Key.CriterionName,
UrgentCount = g.Where(u => u.VisitTask.IsUrgent).Select(u => u.VisitTask.IsUrgent && u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IndependentReviewer).Count(),
ToBeReplyedCount = g.Select(u => u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IndependentReviewer).Count(),
//UrgentCount = g.Where(u => u.VisitTask.IsUrgent).Select(u => u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First()).Count(t => t.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer), //UrgentCount = g.Where(u => u.VisitTask.IsUrgent).Select(u => u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First()).Count(t => t.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer),
//ToBeReplyedCount = g.Select(t => t.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First()).Count(t => t.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer), //ToBeReplyedCount = g.Select(t => t.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First()).Count(t => t.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer),
ToBeReviewedCount = g.Where(u => !u.IsInvalid && u.AuditState != MedicalReviewAuditState.HaveSigned).Count() ToBeReviewedCount = g.Where(u => !u.IsInvalid && u.AuditState != MedicalReviewAuditState.HaveSigned).Count()
}); }).Where(t => t.ToBeReplyedCount > 0);
#endregion #endregion
var defalutSortArray = new string[] { nameof(MedicalCommentsToBeDoneDto.UrgentCount) + " desc", nameof(MedicalCommentsToBeDoneDto.ToBeReplyedCount) + " desc" };
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(MedicalCommentsToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc);
var toBeReplyedQuery = _taskMedicalReviewRepository var toBeReplyedQuery = _taskMedicalReviewRepository
.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.Where(t => t.IsClosedDialog == false) .Where(t => t.IsClosedDialog == false)
.Where(u => u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First().UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer); .Where(u => u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IndependentReviewer);
//.Where(u => u.ReadingMedicalReviewDialogList.OrderByDescending(l => l.CreateTime).First().UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer);
var toBeReplyedCount = toBeReplyedQuery.Count(); var toBeReplyedCount = toBeReplyedQuery.Count();
@@ -1031,7 +1117,7 @@ namespace IRaCIS.Core.Application
.WhereIf(!string.IsNullOrEmpty(inQuery.Code), o => o.TrialCode.Contains(inQuery.Code)) .WhereIf(!string.IsNullOrEmpty(inQuery.Code), o => o.TrialCode.Contains(inQuery.Code))
.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, 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)
.Select(t => new TrialToBeDoneDto() .Select(t => new TrialToBeDoneDto()
{ {
TrialId = t.Id, TrialId = t.Id,
@@ -18,7 +18,6 @@ using IRaCIS.Core.Application.Filter;
using static IRaCIS.Core.Domain.Share.StaticData; using static IRaCIS.Core.Domain.Share.StaticData;
using IRaCIS.Core.Application.Service; using IRaCIS.Core.Application.Service;
using DocumentFormat.OpenXml.Office.CustomUI; using DocumentFormat.OpenXml.Office.CustomUI;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
namespace IRaCIS.Core.Application namespace IRaCIS.Core.Application
@@ -105,7 +104,7 @@ namespace IRaCIS.Core.Application
[HttpPost] [HttpPost]
public async Task<IResponseOutput> TrialReadingInfoSignVerify(TrialReadingInfoSignInDto inDto) public async Task<IResponseOutput> TrialReadingInfoSignVerify(TrialReadingInfoSignInDto inDto)
{ {
var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstOrDefaultAsync(); var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstNotNullAsync();
var existsJudge = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialCriterion.Id && x.IsJudgeQuestion && x.JudgeType == JudgeTypeEnum.None) var existsJudge = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialCriterion.Id && x.IsJudgeQuestion && x.JudgeType == JudgeTypeEnum.None)
.WhereIf(trialCriterion.FormType == FormType.SinglePage, x => x.ReadingCriterionPageId == null) .WhereIf(trialCriterion.FormType == FormType.SinglePage, x => x.ReadingCriterionPageId == null)
.WhereIf(trialCriterion.FormType == FormType.MultiplePage, x => x.ReadingCriterionPageId != null) .WhereIf(trialCriterion.FormType == FormType.MultiplePage, x => x.ReadingCriterionPageId != null)
@@ -145,7 +144,7 @@ namespace IRaCIS.Core.Application
[NonDynamicMethod] [NonDynamicMethod]
public async Task<IResponseOutput> TrialReadingInfoSign(TrialReadingInfoSignInDto inDto) public async Task<IResponseOutput> TrialReadingInfoSign(TrialReadingInfoSignInDto inDto)
{ {
var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstOrDefaultAsync(); var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstNotNullAsync();
var existsJudge = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialCriterion.Id && x.IsJudgeQuestion && x.JudgeType == JudgeTypeEnum.None) var existsJudge = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialCriterion.Id && x.IsJudgeQuestion && x.JudgeType == JudgeTypeEnum.None)
.WhereIf(trialCriterion.FormType == FormType.SinglePage, x => x.ReadingCriterionPageId == null) .WhereIf(trialCriterion.FormType == FormType.SinglePage, x => x.ReadingCriterionPageId == null)
@@ -437,7 +436,7 @@ namespace IRaCIS.Core.Application
[HttpPost] [HttpPost]
public async Task<(List<TrialJudgeQuestion>, object)> GetTrialReadingJudgeList(GetTrialReadingInfoInDto inDto) public async Task<(List<TrialJudgeQuestion>, object)> GetTrialReadingJudgeList(GetTrialReadingInfoInDto inDto)
{ {
var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstOrDefaultAsync(); var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstNotNullAsync();
var judgeQuestionList = await _readingQuestionTrialRepository var judgeQuestionList = await _readingQuestionTrialRepository
.WhereIf(trialCriterion.FormType == FormType.SinglePage, x => x.ReadingCriterionPageId == null) .WhereIf(trialCriterion.FormType == FormType.SinglePage, x => x.ReadingCriterionPageId == null)
@@ -485,7 +484,7 @@ namespace IRaCIS.Core.Application
{ {
GetTrialReadingCriterionInfoOutDto result = new GetTrialReadingCriterionInfoOutDto(); GetTrialReadingCriterionInfoOutDto result = new GetTrialReadingCriterionInfoOutDto();
result.ReadingCriterionPageList = await _readingCriterionPageRepository.Where(x => x.TrialId == inDto.TrialId).ProjectTo<ReadingCriterionPageDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ToListAsync(); result.ReadingCriterionPageList = await _readingCriterionPageRepository.Where(x => x.TrialId == inDto.TrialId).ProjectTo<ReadingCriterionPageDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ToListAsync();
var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstOrDefaultAsync(); var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstNotNullAsync();
result.ReadingInfoSignTime = trialCriterion.ReadingInfoSignTime; result.ReadingInfoSignTime = trialCriterion.ReadingInfoSignTime;
result.DigitPlaces = trialCriterion.DigitPlaces; result.DigitPlaces = trialCriterion.DigitPlaces;
@@ -662,7 +661,7 @@ namespace IRaCIS.Core.Application
} }
} }
if (showOrderList.Count() != showOrderList.Select(t => t.ShowOrder).Distinct().Count()) if (showOrderList.Count != showOrderList.Select(t => t.ShowOrder).Distinct().Count())
{ {
//---影像质控审核问题显示序号不能重复。 //---影像质控审核问题显示序号不能重复。
throw new BusinessValidationFailedException(_localizer["TrialConfig_DuplicateAuditQuestionId"]); throw new BusinessValidationFailedException(_localizer["TrialConfig_DuplicateAuditQuestionId"]);
@@ -732,7 +731,7 @@ namespace IRaCIS.Core.Application
} }
} }
if (showOrderList.Count() != showOrderList.Select(t => t.ShowOrder).Distinct().Count()) if (showOrderList.Count != showOrderList.Select(t => t.ShowOrder).Distinct().Count())
{ {
//---影像质控审核问题显示序号不能重复。 //---影像质控审核问题显示序号不能重复。
throw new BusinessValidationFailedException(_localizer["TrialConfig_DuplicateAuditQuestionId"]); throw new BusinessValidationFailedException(_localizer["TrialConfig_DuplicateAuditQuestionId"]);
@@ -95,7 +95,8 @@ namespace IRaCIS.Application.Services
.WhereIf(multiModalityIdSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.Modality) == multiModalityIdSelectCount) .WhereIf(multiModalityIdSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.Modality) == multiModalityIdSelectCount)
.WhereIf(multiCriteriaSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.Criterion) == multiCriteriaSelectCount) .WhereIf(multiCriteriaSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.Criterion) == multiCriteriaSelectCount)
.WhereIf(multiReviewTypeSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.ReviewType) == multiReviewTypeSelectCount) .WhereIf(multiReviewTypeSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.ReviewType) == multiReviewTypeSelectCount)
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, 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)
.ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id , isEn_Us= _userInfo.IsEn_Us }); .ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id , isEn_Us= _userInfo.IsEn_Us });
return await query.ToPagedListAsync(searchParam.PageIndex, searchParam.PageSize, string.IsNullOrWhiteSpace(searchParam.SortField) ? "CreateTime" : searchParam.SortField, searchParam.Asc); return await query.ToPagedListAsync(searchParam.PageIndex, searchParam.PageSize, string.IsNullOrWhiteSpace(searchParam.SortField) ? "CreateTime" : searchParam.SortField, searchParam.Asc);
@@ -107,7 +108,8 @@ namespace IRaCIS.Application.Services
public async Task<List<TrialSelectDTO>> GetTrialSelect() public async Task<List<TrialSelectDTO>> GetTrialSelect()
{ {
return await _trialRepository.AsQueryable().IgnoreQueryFilters() return await _trialRepository.AsQueryable().IgnoreQueryFilters()
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id) && 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)
.ProjectTo<TrialSelectDTO>(_mapper.ConfigurationProvider).ToListAsync(); .ProjectTo<TrialSelectDTO>(_mapper.ConfigurationProvider).ToListAsync();
} }
@@ -304,11 +306,15 @@ namespace IRaCIS.Application.Services
await _repository.BatchDeleteAsync<ClinicalQuestionAnswer>(o => o.ClinicalForm.TrialId == trialId); await _repository.BatchDeleteAsync<ClinicalQuestionAnswer>(o => o.ClinicalForm.TrialId == trialId);
await _repository.BatchDeleteAsync<ClinicalForm>(o => o.TrialId == trialId); await _repository.BatchDeleteAsync<ClinicalForm>(o => o.TrialId == trialId);
await _repository.BatchDeleteAsync<UserUploadFile>(o => o.TrialId == trialId);
await _repository.BatchDeleteAsync<CriterionNidusSystem>(o => o.TrialReadingCriterion.TrialId == trialId); await _repository.BatchDeleteAsync<CriterionNidusSystem>(o => o.TrialReadingCriterion.TrialId == trialId);
await _repository.BatchDeleteAsync<CriterionNidusTrial>(o => o.TrialReadingCriterion.TrialId == trialId); await _repository.BatchDeleteAsync<CriterionNidusTrial>(o => o.TrialReadingCriterion.TrialId == trialId);
await _repository.BatchDeleteAsync<CheckChallengeDialog>(o => o.SubjectVisit.TrialId == trialId);
await _repository.BatchDeleteAsync<ClinicalDataTrialSet>(o => o.TrialId == trialId);
await _repository.BatchDeleteAsync<InspectionFile>(o => o.TrialId == trialId);
await _repository.BatchDeleteAsync<CriterionNidusSystem>(o => o.TrialReadingCriterion.TrialId == trialId);
await _repository.BatchDeleteAsync<DataInspection>(o => o.TrialId == trialId); await _repository.BatchDeleteAsync<DataInspection>(o => o.TrialId == trialId);
await _repository.BatchDeleteAsync<DicomStudy>(t => t.TrialId == trialId); await _repository.BatchDeleteAsync<DicomStudy>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<StudyMonitor>(t => t.TrialId == trialId); await _repository.BatchDeleteAsync<StudyMonitor>(t => t.TrialId == trialId);
@@ -323,7 +323,7 @@ namespace IRaCIS.Core.Application.Services
{ {
//CRC只看到他负责的 //CRC只看到他负责的
var list = await _trialSiteRepository.Where(t => t.TrialId == trialId) var list = await _trialSiteRepository.Where(t => t.TrialId == trialId).IgnoreQueryFilters()
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.ProjectTo<TrialSiteForSelect>(_mapper.ConfigurationProvider).OrderBy(t => t.TrialSiteCode).ToListAsync(); .ProjectTo<TrialSiteForSelect>(_mapper.ConfigurationProvider).OrderBy(t => t.TrialSiteCode).ToListAsync();
@@ -348,7 +348,6 @@ namespace IRaCIS.Core.Application.Services
/// <summary>删除 项目 下某一site </summary> /// <summary>删除 项目 下某一site </summary>
[HttpDelete("{id:guid}/{trialId:guid}")] [HttpDelete("{id:guid}/{trialId:guid}")]
[TrialAudit(AuditType.TrialAudit, AuditOptType.DeleteTrialSite)]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[Obsolete] [Obsolete]
public async Task<IResponseOutput> DeleteTrialSite(Guid id) public async Task<IResponseOutput> DeleteTrialSite(Guid id)
@@ -108,7 +108,7 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.IsSelect, u => u.MapFrom(t => t.UserTrials.Any(t => t.TrialId == trialId))); .ForMember(d => d.IsSelect, u => u.MapFrom(t => t.UserTrials.Any(t => t.TrialId == trialId)));
CreateMap<Site, SiteSelectDTO>() CreateMap<Site, SiteSelectDTO>()
.ForMember(d => d.HospitalName, u => u.MapFrom(s => s.Hospital.HospitalName)); .ForMember(d => d.HospitalName, u => u.MapFrom(s => isEn_Us? s.Hospital.HospitalName:s.Hospital.HospitalNameCN));
//trial site 选择列表 subjectVisit pannel 模式添加的时候 //trial site 选择列表 subjectVisit pannel 模式添加的时候
@@ -26,7 +26,6 @@ namespace IRaCIS.Application.Services
/// <param name="subjectCommand">state:1-访视中,2-出组。0-全部</param> /// <param name="subjectCommand">state:1-访视中,2-出组。0-全部</param>
/// <returns></returns> /// <returns></returns>
[TrialAudit(AuditType.SubjectAudit, AuditOptType.AddOrUpdateSubject)]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//[Authorize(Policy = IRaCISPolicy.PM_APM_CRC_QC)] //[Authorize(Policy = IRaCISPolicy.PM_APM_CRC_QC)]
public async Task<IResponseOutput<string>> AddOrUpdateSubject([FromBody] SubjectCommand subjectCommand) public async Task<IResponseOutput<string>> AddOrUpdateSubject([FromBody] SubjectCommand subjectCommand)
@@ -295,7 +295,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.InstanceList).Count(); t.InstanceCount = t.SeriesList.SelectMany(t => t.InstanceList).Count();
} }
@@ -370,7 +370,7 @@ namespace IRaCIS.Core.Application.Services
{ {
item.SeriesInstanceUid = string.Empty; item.SeriesInstanceUid = string.Empty;
item.InstanceList = thisRowinfo.Where(y => y.InstanceId != null).OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex).Select(y => y.InstanceId.Value).Distinct().ToList(); item.InstanceList = thisRowinfo.Where(y => y.InstanceId != null).OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex).Select(y => y.InstanceId!.Value).Distinct().ToList();
var tempInstanceList = await _repository.Where<DicomInstance>(t => item.InstanceList.Contains(t.Id)).OrderBy(t => t.InstanceNumber) var tempInstanceList = await _repository.Where<DicomInstance>(t => item.InstanceList.Contains(t.Id)).OrderBy(t => t.InstanceNumber)
.Select(t => new TempInstance .Select(t => new TempInstance
@@ -417,7 +417,7 @@ namespace IRaCIS.Core.Application.Services
}) })
.ToList(); .ToList();
item.InstanceCount = item.InstanceList.Count(); item.InstanceCount = item.InstanceList.Count;
item.Description = "Key Series"; item.Description = "Key Series";
@@ -425,7 +425,7 @@ namespace IRaCIS.Core.Application.Services
ThenBy(s => s.SeriesTime).Select(x => x.Modality).Distinct().ToListAsync(); ; 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;
@@ -502,12 +502,12 @@ namespace IRaCIS.Core.Application.Services
}) })
.ToList(); .ToList();
series.WindowWidth = instanceList.FirstOrDefault()?.WindowWidth; series.WindowWidth = instanceList.FirstOrDefault()!.WindowWidth;
series.WindowCenter = instanceList.FirstOrDefault()?.WindowCenter; series.WindowCenter = instanceList.FirstOrDefault()!.WindowCenter;
}); });
//设置为阅片与否 不更改数据库检查 的instance数量 和 SeriesCount 所以这里要实时统计 //设置为阅片与否 不更改数据库检查 的instance数量 和 SeriesCount 所以这里要实时统计
t.SeriesCount = t.SeriesList.Count(); t.SeriesCount = t.SeriesList.Count;
t.InstanceCount = t.SeriesList.SelectMany(t => t.InstanceList).Count(); t.InstanceCount = t.SeriesList.SelectMany(t => t.InstanceList).Count();
} }
@@ -530,7 +530,7 @@ namespace IRaCIS.Core.Application.Services
foreach (var item in noDicomStudyList) foreach (var item in noDicomStudyList)
{ {
var nodicom = noDicomList.Where(x => x.Id == item.StudyId).FirstOrDefault(); var nodicom = noDicomList.Where(x => x.Id == item.StudyId).First();
item.SeriesList = new List<DicomSeriesDTO>() item.SeriesList = new List<DicomSeriesDTO>()
{ {
new DicomSeriesDTO (){ new DicomSeriesDTO (){
+1 -1
View File
@@ -64,7 +64,7 @@ namespace IRaCIS.Application.Services
public async Task<IResponseOutput> TestDistributedLock( ) public async Task<IResponseOutput> TestDistributedLock( )
{ {
_repository.Where<User>().Select(t => t.FullName).FirstOrDefault(); await _repository.Where<User>().Select(t => t.FullName).FirstNotNullAsync();
Console.WriteLine($"我进来了当前值是:" + IntValue); Console.WriteLine($"我进来了当前值是:" + IntValue);
_logger.LogWarning($"我进来了当前值是:" + IntValue); _logger.LogWarning($"我进来了当前值是:" + IntValue);
@@ -1,6 +1,7 @@
using EntityFrameworkCore.Triggered; using EntityFrameworkCore.Triggered;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using Microsoft.Extensions.Localization;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -11,18 +12,19 @@ namespace IRaCIS.Core.Application.Triggers
{ {
// 统一处理 外部用户、中心调研(先添加 再发送邮件)、参与医生加入到项目 ----废弃 // 统一处理 外部用户、中心调研(先添加 再发送邮件)、参与医生加入到项目 ----废弃
public class AddlTrialUserTrigger :BaseService, IBeforeSaveTrigger<TrialUser> public class AddlTrialUserTrigger :IBeforeSaveTrigger<TrialUser>
{ {
public IStringLocalizer _localizer;
private readonly IRepository<Trial> _trialRepository; private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<User> _userRepository; private readonly IRepository<User> _userRepository;
public AddlTrialUserTrigger(IRepository<Trial> trialRepository, IRepository<User> userRepository) public AddlTrialUserTrigger(IRepository<Trial> trialRepository, IRepository<User> userRepository, IStringLocalizer localizer)
{ {
_trialRepository = trialRepository; _trialRepository = trialRepository;
_userRepository = userRepository; _userRepository = userRepository;
_localizer = localizer;
} }
public async Task BeforeSave(ITriggerContext<TrialUser> context, CancellationToken cancellationToken) public async Task BeforeSave(ITriggerContext<TrialUser> context, CancellationToken cancellationToken)
{ {
@@ -1,25 +1,27 @@
using AutoMapper; using AutoMapper;
using EntityFrameworkCore.Triggered; using EntityFrameworkCore.Triggered;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using MassTransit; using MassTransit;
using Microsoft.Extensions.Localization;
namespace IRaCIS.Core.Application.Triggers namespace IRaCIS.Core.Application.Triggers
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class SubjectStateTrigger :BaseService, IAfterSaveTrigger<Subject> public class SubjectStateTrigger : IAfterSaveTrigger<Subject>
{ {
private readonly IRepository<SubjectVisit> _subjectVisitRepository; public IStringLocalizer _localizer;
private readonly IRepository _repository; private readonly IRepository _repository;
private readonly IMapper _mapper; private readonly IRepository<SubjectVisit> _subjectVisitRepository;
public SubjectStateTrigger(IRepository<SubjectVisit> subjectVisitRepository, IRepository repository, IMapper mapper) public SubjectStateTrigger(IRepository<SubjectVisit> subjectVisitRepository, IStringLocalizer localizer, IRepository repository)
{ {
_subjectVisitRepository = subjectVisitRepository;
_repository = repository; _repository = repository;
_mapper = mapper; _localizer = localizer;
_subjectVisitRepository = subjectVisitRepository;
} }
public async Task AfterSave(ITriggerContext<Subject> context, CancellationToken cancellationToken) public async Task AfterSave(ITriggerContext<Subject> context, CancellationToken cancellationToken)
@@ -2,15 +2,17 @@
using IRaCIS.Core.Application.Service; using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using MassTransit; using MassTransit;
using Microsoft.Extensions.Localization;
namespace IRaCIS.Core.Application.Triggers namespace IRaCIS.Core.Application.Triggers
{ {
/// <summary> /// <summary>
/// 处理 访视 末次评估 会影响Subject 状态 /// 处理 访视 末次评估 会影响Subject 状态
/// </summary> /// </summary>
public class SubjectVisitFinalVisitTrigger :BaseService, IAfterSaveTrigger<SubjectVisit> public class SubjectVisitFinalVisitTrigger :IAfterSaveTrigger<SubjectVisit>
{ {
private readonly IRepository<SubjectVisit> _subjectVisitRepository; private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IRepository<ReadingPeriodSet> _readingPeriodSetRepository; private readonly IRepository<ReadingPeriodSet> _readingPeriodSetRepository;
@@ -19,8 +21,8 @@ namespace IRaCIS.Core.Application.Triggers
private readonly IRepository<Subject> _subjectRepository; private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<VisitTask> _visitTaskRepository; private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IVisitTaskHelpeService _ivisitTaskHelpeService; private readonly IVisitTaskHelpeService _ivisitTaskHelpeService;
public IStringLocalizer _localizer;
private readonly IRepository _repository; private readonly IRepository _repository;
public SubjectVisitFinalVisitTrigger(IRepository<SubjectVisit> subjectVisitRepository, public SubjectVisitFinalVisitTrigger(IRepository<SubjectVisit> subjectVisitRepository,
IRepository<ReadingPeriodSet> readingPeriodSetRepository, IRepository<ReadingPeriodSet> readingPeriodSetRepository,
@@ -28,7 +30,9 @@ namespace IRaCIS.Core.Application.Triggers
IRepository<VisitTask> visitTaskRepository, IRepository<VisitTask> visitTaskRepository,
IVisitTaskHelpeService visitTaskHelpeService, IVisitTaskHelpeService visitTaskHelpeService,
IRepository<ReadModule> readModuleRepository, IRepository<ReadModule> readModuleRepository,
IRepository<Subject> subjectRepository, IRepository repository) IRepository<Subject> subjectRepository,
IStringLocalizer localizer,
IRepository repository)
{ {
_subjectVisitRepository = subjectVisitRepository; _subjectVisitRepository = subjectVisitRepository;
this._readingPeriodSetRepository = readingPeriodSetRepository; this._readingPeriodSetRepository = readingPeriodSetRepository;
@@ -38,6 +42,7 @@ namespace IRaCIS.Core.Application.Triggers
this._readModuleRepository = readModuleRepository; this._readModuleRepository = readModuleRepository;
_subjectRepository = subjectRepository; _subjectRepository = subjectRepository;
_repository = repository; _repository = repository;
_localizer = localizer;
} }
public async Task AfterSave(ITriggerContext<SubjectVisit> context, CancellationToken cancellationToken) public async Task AfterSave(ITriggerContext<SubjectVisit> context, CancellationToken cancellationToken)
@@ -22,13 +22,13 @@ namespace IRaCIS.Core.Application.Triggers
private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository; private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;
private readonly IRepository<ReadingJudgeInfo> _readingJudgeInfoRepository;
public VisitTaskIsFrontTaskNeedSignButNotSignTrigger( public VisitTaskIsFrontTaskNeedSignButNotSignTrigger(
IRepository<VisitTask> visitTaskRepository, IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository, IRepository<ReadingQuestionTrial> trialReadingQuestionRepository IRepository<VisitTask> visitTaskRepository, IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository, IRepository<ReadingQuestionTrial> trialReadingQuestionRepository
, IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository) , IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository, IRepository<ReadingJudgeInfo> readingJudgeInfoRepository)
{ {
_trialReadingCriterionRepository = trialReadingCriterionRepository; _trialReadingCriterionRepository = trialReadingCriterionRepository;
@@ -36,6 +36,7 @@ namespace IRaCIS.Core.Application.Triggers
_trialReadingQuestionRepository = trialReadingQuestionRepository; _trialReadingQuestionRepository = trialReadingQuestionRepository;
_readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository; _readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
_readingJudgeInfoRepository = readingJudgeInfoRepository;
} }
@@ -48,7 +49,7 @@ namespace IRaCIS.Core.Application.Triggers
Expression<Func<VisitTask, bool>> visitTaskLambda = x => x.TrialId == visitTask.TrialId && x.SubjectId == visitTask.SubjectId && x.TrialReadingCriterionId == visitTask.TrialReadingCriterionId; Expression<Func<VisitTask, bool>> visitTaskLambda = x => x.TrialId == visitTask.TrialId && x.SubjectId == visitTask.SubjectId && x.TrialReadingCriterionId == visitTask.TrialReadingCriterionId;
if (context.ChangeType == ChangeType.Added) if (context.ChangeType == ChangeType.Added)
{ {
//判断是否需要临床数据签名 不需要 就不用维护 //判断是否需要临床数据签名 不需要 就不用维护
if (visitTask.IsNeedClinicalDataSign) if (visitTask.IsNeedClinicalDataSign)
{ {
@@ -93,12 +94,125 @@ namespace IRaCIS.Core.Application.Triggers
}); });
} }
} }
} }
else if (context.ChangeType == ChangeType.Modified)
{
if (visitTask.ReadingCategory == ReadingCategory.Judge && (visitTask.TaskState == TaskState.Adbandon || visitTask.TaskState == TaskState.HaveReturned))
{
var find = _readingJudgeInfoRepository.Where(t => t.JudgeTaskId == visitTask.Id).FirstOrDefault();
if (find != null)
{
var ids = new Guid[] { find.TaskIdOne, find.TaskIdTwo };
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => ids.Contains(t.Id), u => new VisitTask() { JudgeVisitTaskId = null });
}
}
}
#region
// //从未签名状态 改为签名状态时 判断是否进行了附加评估,将附加评估的结果冗余
// if (context.ChangeType == ChangeType.Modified && visitTask.ReadingTaskState == ReadingTaskState.HaveSigned && context.UnmodifiedEntity.ReadingTaskState != ReadingTaskState.HaveSigned)
// {
// var criterion = _trialReadingCriterionRepository.Where(t => t.Id == visitTask.TrialReadingCriterionId).FirstOrDefault();
// //如果是附加评估
// if (criterion.IsAdditionalAssessment)
// {
// if (visitTask.ReadingCategory == ReadingCategory.Visit)
// {
// switch (criterion.CriterionType)
// {
// case CriterionType.RECIST1Point1:
// var isbaseLine = _visitTaskRepository.Where(t => t.Id == visitTask.Id).Select(t => t.SourceSubjectVisit.IsBaseLine).FirstOrDefault();
// if (isbaseLine)
// {
// var currentTaskAdditionarlAnswer = await _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == visitTask.Id &&
// t.ReadingQuestionTrial.IsAdditional == true && t.ReadingQuestionTrial.Type != "group"
// ).Include(t => t.ReadingQuestionTrial).FirstOrDefaultAsync();
// //双重阅片完成了
// if (criterion.ReadingType == ReadingMethod.Double &&
//(_visitTaskRepository.Where(t => t.SubjectId == visitTask.SubjectId && t.TaskName == visitTask.TaskName && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned).Count() == 2)
// )
// {
// var otherTaskId = await _visitTaskRepository.Where(t => t.SubjectId == visitTask.SubjectId && t.TaskName == visitTask.TaskName && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.Id != visitTask.Id)
// .Select(t => t.Id).FirstOrDefaultAsync();
// var otherTaskAdditionarlAnswer = await _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == otherTaskId &&
// t.ReadingQuestionTrial.IsAdditional == true && t.ReadingQuestionTrial.Type != "group"
// ).Include(t => t.ReadingQuestionTrial).FirstOrDefaultAsync();
// await _subjectAdditionalEvaluationResultRepository.AddAsync(new SubjectAdditionalEvaluationResult()
// {
// TrialReadingCriterionId = visitTask.TrialReadingCriterionId,
// IsFinalResult = true,
// SubjectId = visitTask.SubjectId,
// TrialReadingQuestionId = currentTaskAdditionarlAnswer.ReadingQuestionTrialId,
// FinalAnswer = currentTaskAdditionarlAnswer.Answer,
// FinalTranslateDictionaryCode = currentTaskAdditionarlAnswer.ReadingQuestionTrial.DictionaryCode,
// });
// }
// if (criterion.ReadingType == ReadingMethod.Single)
// {
// await _subjectAdditionalEvaluationResultRepository.AddAsync(new SubjectAdditionalEvaluationResult()
// {
// TrialReadingCriterionId = visitTask.TrialReadingCriterionId,
// IsFinalResult = true,
// SubjectId = visitTask.SubjectId,
// TrialReadingQuestionId = currentTaskAdditionarlAnswer.ReadingQuestionTrialId,
// FinalAnswer = currentTaskAdditionarlAnswer.Answer,
// FinalTranslateDictionaryCode = currentTaskAdditionarlAnswer.ReadingQuestionTrial.DictionaryCode,
// });
// }
// }
// break;
// default:
// break;
// }
// }
// }
// }
#endregion
} }
@@ -5,6 +5,7 @@ using Newtonsoft.Json;
using MediatR; using MediatR;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Text; using System.Text;
using Microsoft.Extensions.Localization;
namespace IRaCIS.Core.Application.MediatR.Handlers namespace IRaCIS.Core.Application.MediatR.Handlers
{ {
@@ -17,6 +18,7 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
private readonly IRepository<TrialSite> _trialSiteRepository; private readonly IRepository<TrialSite> _trialSiteRepository;
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly IRepository<NoneDicomStudy> _noneDicomStudyRepository; private readonly IRepository<NoneDicomStudy> _noneDicomStudyRepository;
public IStringLocalizer _localizer { get; set; }
/// <summary> /// <summary>
/// 构造函数注入 /// 构造函数注入
@@ -25,7 +27,7 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
public ConsistencyVerificationHandler(IRepository<DicomStudy> studyRepository, IUserInfo userInfo, public ConsistencyVerificationHandler(IRepository<DicomStudy> studyRepository, IUserInfo userInfo,
IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository, IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository,
IRepository<TrialSite> trialSiteRepository, IRepository<NoneDicomStudy> noneDicomStudyRepository, IRepository<TrialSite> trialSiteRepository, IRepository<NoneDicomStudy> noneDicomStudyRepository,
IMapper mapper) IMapper mapper, IStringLocalizer localizer)
{ {
_noneDicomStudyRepository = noneDicomStudyRepository; _noneDicomStudyRepository = noneDicomStudyRepository;
_studyRepository = studyRepository; _studyRepository = studyRepository;
@@ -34,6 +36,7 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
_subjectVisitRepository = subjectVisitRepository; _subjectVisitRepository = subjectVisitRepository;
_trialSiteRepository = trialSiteRepository; _trialSiteRepository = trialSiteRepository;
_mapper = mapper; _mapper = mapper;
_localizer = localizer;
} }
async Task<string> IRequestHandler<ConsistencyVerificationRequest, string>.Handle(ConsistencyVerificationRequest request, CancellationToken cancellationToken) async Task<string> IRequestHandler<ConsistencyVerificationRequest, string>.Handle(ConsistencyVerificationRequest request, CancellationToken cancellationToken)
@@ -112,14 +115,18 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
StringBuilder dialogMsg = new StringBuilder(); StringBuilder dialogMsg = new StringBuilder();
//---您好,根据本系统自动识别,该受试者当前访视在IRC系统中已提交的影像检查情况如下: //---您好,根据本系统自动识别,该受试者当前访视在IRC系统中已提交的影像检查情况如下:
dialogMsg.Append(StaticData.International("ConsistencyVerification_Img")); dialogMsg.Append($"<div>{_localizer["ConsistencyVerification_Img"]}</div>");
var num = 0; var num = 0;
List<ParamInfoDto> paramInfoList = new List<ParamInfoDto>(); List<ParamInfoDto> paramInfoList = new List<ParamInfoDto>();
foreach (var item in dbVisitStudyList) foreach (var item in dbVisitStudyList)
{ {
num++; num++;
dialogMsg.AppendLine($"<br>{num}.{item.StudyDate}{StaticData.International("ConsistencyVerification_Of")}{item.Modality}{StaticData.International("ConsistencyVerification_ImgC")}");
dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_ImgC", item.StudyDate, item.Modality]}</div>");
paramInfoList.Add(new ParamInfoDto() paramInfoList.Add(new ParamInfoDto()
{ {
Modality = item.Modality, Modality = item.Modality,
@@ -127,7 +134,7 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
}); });
} }
var subjectVisitId = dbVisitStudyList.FirstOrDefault().SubjectVisitId; var subjectVisitId = dbVisitStudyList.First().SubjectVisitId;
var dbSV = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException(); var dbSV = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException();
#region Excel #region Excel
@@ -176,18 +183,18 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
if (dbExceptExcel.Count() == 0 && excelExceptDB.Count() == 0) if (dbExceptExcel.Count() == 0 && excelExceptDB.Count() == 0)
{ {
dialogMsg.AppendLine($"<br/>"); dialogMsg.AppendLine($"<br/>");
//---核对EDC数据,完全一致, 审核通过 //---核对EDC数据,完全一致, 审核通过
dialogMsg.AppendLine(StaticData.International("ConsistencyVerification_EDCA")); dialogMsg.AppendLine(_localizer["ConsistencyVerification_EDCA"]);
// dialogMsg.AppendLine(@$"<br>说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。"); // dialogMsg.AppendLine(@$"<br>说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。");
dbSV.CheckState = CheckStateEnum.CVPassed; dbSV.CheckState = CheckStateEnum.CVPassed;
dbSV.CheckUserId = _userInfo.Id; dbSV.CheckUserId = _userInfo.Id;
dbSV.CheckPassedTime = DateTime.Now; dbSV.CheckPassedTime = DateTime.Now;
//---核对EDC数据,完全一致 //---核对EDC数据,完全一致
dbSV.CheckResult = StaticData.International("ConsistencyVerification_EDCB"); dbSV.CheckResult = _localizer["ConsistencyVerification_EDCB"];
//---自动核查通过 //---自动核查通过
dbSV.ManualPassReason = StaticData.International("ConsistencyVerification_Auto"); dbSV.ManualPassReason = _localizer["ConsistencyVerification_Auto"];
//维护状态 //维护状态
dbSV.ReadingStatus = ReadingStatusEnum.TaskAllocate; dbSV.ReadingStatus = ReadingStatusEnum.TaskAllocate;
@@ -205,34 +212,34 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
// ETC 和系统的有区别 // ETC 和系统的有区别
else else
{ {
dialogMsg.AppendLine($"<br/>"); //"Problems are as follows:
//存在问题如下: dialogMsg.AppendLine($"<br/><div style='color: #f00'>{_localizer["ConsistencyVerification_Prob"]}</div>");
dialogMsg.AppendLine($"<br><span style='color: #f00'>{StaticData.International("ConsistencyVerification_Prob")}</span>");
num = 0; num = 0;
foreach (var item in dbExceptExcel) foreach (var item in dbExceptExcel)
{ {
num++; num++;
//影像检查(EDC 缺少) ConsistencyVerification_EdcL //影像检查(EDC 缺少) ConsistencyVerification_EdcL
dialogMsg.AppendLine($"<br>{num}.{item.StudyDate}{StaticData.International("ConsistencyVerification_Of")}{item.Modality}{StaticData.International("ConsistencyVerification_EdcL")} "); dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_EdcL", item.StudyDate, item.Modality]}</div>");
} }
foreach (var item in excelExceptDB) foreach (var item in excelExceptDB)
{ {
num++; num++;
// 影像检查(IRC 缺少) // 影像检查(IRC 缺少)
dialogMsg.AppendLine($"<br>{num}.{item.StudyDate}{StaticData.International("ConsistencyVerification_Of")}{item.Modality}{StaticData.International("ConsistencyVerification_IrcL")} "); dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_IrcLi", item.StudyDate, item.Modality]}</div>");
} }
dialogMsg.AppendLine($"<br/>"); dialogMsg.AppendLine($"<br/>");
dialogMsg.AppendLine(@$"<br>{StaticData.International("ConsistencyVerification_Desc")}"); dialogMsg.AppendLine(@$"<div>{_localizer["ConsistencyVerification_Desc"]}<div/>");
dbSV.CheckResult = _localizer["ConsistencyVerification_Conf"] +
String.Join(" | ", dbExceptExcel.Select(t => $"{_localizer["ConsistencyVerification_EdcL", t.StudyDate, t.Modality]}")) + " | "
+ String.Join(" | ", excelExceptDB.Select(t => $"{_localizer["ConsistencyVerification_IrcLi", t.StudyDate, t.Modality]}"));
//---根据导入的一致性核查数据,请确认本访视以下不一致检查项信息:
dbSV.CheckResult = StaticData.International("ConsistencyVerification_Conf") + String.Join(" | ", dbExceptExcel.Select(t => $"{StaticData.International("ConsistencyVerification_Edc")}{t.StudyDate} {t.Modality} ")) + " | "
+ String.Join(" | ", excelExceptDB.Select(t => $"{StaticData.International("ConsistencyVerification_IrcLi")}{t.StudyDate} {t.Modality}"));
//新增一致性核查质疑记录 //新增一致性核查质疑记录
dbSV.CheckState = CheckStateEnum.CVIng; dbSV.CheckState = CheckStateEnum.CVIng;
dbSV.CheckChallengeState = CheckChanllengeTypeEnum.PMWaitCRCReply; dbSV.CheckChallengeState = CheckChanllengeTypeEnum.PMWaitCRCReply;
@@ -46,6 +46,7 @@ namespace IRaCIS.Core.Domain.Share
public enum EmailBusinessScenario public enum EmailBusinessScenario
{ {
None = -1,
EnrollConfirmed = 1, EnrollConfirmed = 1,
PDConfirmed = 2, PDConfirmed = 2,
+1 -1
View File
@@ -42,7 +42,7 @@
QA = 12, QA = 12,
OP=13,
SPM=20, SPM=20,
APM=21, APM=21,
@@ -19,7 +19,10 @@ namespace IRaCIS.Core.Domain.Models
[Table("TaskMedicalReview")] [Table("TaskMedicalReview")]
public class TaskMedicalReview : Entity, IAuditUpdate, IAuditAdd public class TaskMedicalReview : Entity, IAuditUpdate, IAuditAdd
{ {
[JsonIgnore]
public User LatestReplyUser { get; set; }
public Guid? LatestReplyUserId { get; set; }
/// <summary> /// <summary>
/// CreateUserId /// CreateUserId
+1
View File
@@ -8,6 +8,7 @@ namespace IRaCIS.Core.Domain.Models
public partial class Site : Entity, IAuditUpdate, IAuditAdd public partial class Site : Entity, IAuditUpdate, IAuditAdd
{ {
[JsonIgnore] [JsonIgnore]
[ForeignKey("HospitalId")]
public Hospital Hospital { get; set; } public Hospital Hospital { get; set; }
public string SiteName { get; set; } = string.Empty; public string SiteName { get; set; } = string.Empty;
public string SiteNameCN{ get; set; } = string.Empty; public string SiteNameCN{ get; set; } = string.Empty;
+1 -1
View File
@@ -13,7 +13,7 @@ namespace IRaCIS.Core.Domain.Models
public string RoleDescription { get; set; } = string.Empty; public string RoleDescription { get; set; } = string.Empty;
public int Status { get; set; } public int Status { get; set; }
public int PrivilegeLevel { get; set; } //ȨĎŢźśąđ public int PrivilegeLevel { get; set; } //权限级别
public DateTime CreateTime { get; set; } = DateTime.Now; public DateTime CreateTime { get; set; } = DateTime.Now;
public Guid CreateUserId { get; set; } = Guid.Empty; public Guid CreateUserId { get; set; } = Guid.Empty;
+3 -6
View File
@@ -7,18 +7,15 @@ namespace IRaCIS.Core.Domain.Models
///<summary> ///<summary>
/// 一致性核查文件 /// 一致性核查文件
///</summary> ///</summary>
[Table("UserUploadFile")] [Table("InspectionFile")]
public class UserUploadFile : Entity, IAuditAdd public class InspectionFile : Entity, IAuditAdd
{ {
/// <summary> /// <summary>
/// 文件名称 /// 文件名称
/// </summary> /// </summary>
public string FileName { get; set; } public string FileName { get; set; }
/// <summary>
/// 文件路径
/// </summary>
public string FilePath { get; set; }
/// <summary> /// <summary>
/// 相对路径 /// 相对路径
+56 -56
View File
@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
@@ -87,12 +87,12 @@ namespace IRaCIS.Core.Domain.Models
[StringLength(512)] [StringLength(512)]
public string Indication { get; set; } = string.Empty; public string Indication { get; set; } = string.Empty;
//入组那一块的状态 //入组那一块的状态
//[ConcurrencyCheck] //[ConcurrencyCheck]
public int TrialEnrollStatus { get; set; } public int TrialEnrollStatus { get; set; }
//启动状态 //启动状态
[StringLength(500)] [StringLength(500)]
public string TrialStatusStr { get; set; } = StaticData.TrialState.TrialInitializing; public string TrialStatusStr { get; set; } = StaticData.TrialState.TrialInitializing;
@@ -142,15 +142,15 @@ namespace IRaCIS.Core.Domain.Models
//废弃 //废弃
//public AttendedReviewerType AttendedReviewerType { get; set; } = AttendedReviewerType.CN;//0全部中国医生 1美国医生 2既有中国医生,也有美国医生 //public AttendedReviewerType AttendedReviewerType { get; set; } = AttendedReviewerType.CN;//0全部中国医生 1美国医生 2既有中国医生,也有美国医生
////废弃 ////废弃
//[JsonIgnore] //[JsonIgnore]
//[ForeignKey("DeclarationTypeId")] //[ForeignKey("DeclarationTypeId")]
//public Dictionary DeclarationType { get; set; } //public Dictionary DeclarationType { get; set; }
//废弃 //废弃
//public Guid DeclarationTypeId { get; set; } = Guid.Empty; //public Guid DeclarationTypeId { get; set; } = Guid.Empty;
@@ -173,66 +173,66 @@ namespace IRaCIS.Core.Domain.Models
public bool VisitPlanConfirmed { get; set; } public bool VisitPlanConfirmed { get; set; }
/// <summary> /// <summary>
/// 受试者编号具体规则 /// 受试者编号具体规则
/// </summary> /// </summary>
public string SubjectCodeRule { get; set; } = StaticData.International("Trial_number"); public string SubjectCodeRule { get; set; } = StaticData.International("Trial_number");
/// <summary> /// <summary>
/// 是否 提醒受试者编号规则 /// 是否 提醒受试者编号规则
/// </summary> /// </summary>
public bool IsNoticeSubjectCodeRule { get; set; } = true; public bool IsNoticeSubjectCodeRule { get; set; } = true;
/// <summary> /// <summary>
/// 是否 有基准时间(首次给药时间) /// 是否 有基准时间(首次给药时间)
/// </summary> /// </summary>
public bool IsHaveFirstGiveMedicineDate { get; set; } = true; public bool IsHaveFirstGiveMedicineDate { get; set; } = true;
/// <summary> /// <summary>
/// 是否有 受试者年龄 /// 是否有 受试者年龄
/// </summary> /// </summary>
public bool IsHaveSubjectAge { get; set; } = false; public bool IsHaveSubjectAge { get; set; } = false;
/// <summary> /// <summary>
/// 是否有 入组性确认 /// 是否有 入组性确认
/// </summary> /// </summary>
public bool IsEnrollementQualificationConfirm { get; set; } = false; public bool IsEnrollementQualificationConfirm { get; set; } = false;
/// <summary> /// <summary>
/// 出组后计划外访视名称 /// 出组后计划外访视名称
/// </summary> /// </summary>
public string OutEnrollmentVisitName { get; set; } = "EOT"; public string OutEnrollmentVisitName { get; set; } = "EOT";
/// <summary> /// <summary>
/// 是否 验证拍片日期 /// 是否 验证拍片日期
/// </summary> /// </summary>
public bool IsVerifyVisitImageDate { get; set; } = true; public bool IsVerifyVisitImageDate { get; set; } = true;
/// <summary> /// <summary>
/// 临床信息传输 1:系统录入 2:系统录入+PDF 0:无 /// 临床信息传输 1:系统录入 2:系统录入+PDF 0:无
/// </summary> /// </summary>
public int ClinicalInformationTransmissionEnum { get; set; } = 1; public int ClinicalInformationTransmissionEnum { get; set; } = 1;
/// <summary> /// <summary>
/// 是否审核 临床信息 /// 是否审核 临床信息
/// </summary> /// </summary>
public bool IsCRAAuditClinicalInformation { get; set; } = false; public bool IsCRAAuditClinicalInformation { get; set; } = false;
/// <summary> /// <summary>
/// QC流程 0 不审,1 单审,2双审 /// QC流程 0 不审,1 单审,2双审
/// </summary> /// </summary>
public TrialQCProcess QCProcessEnum { get; set; } = TrialQCProcess.NotAudit; public TrialQCProcess QCProcessEnum { get; set; } = TrialQCProcess.NotAudit;
/// <summary> /// <summary>
/// 影像一致性核查 /// 影像一致性核查
/// </summary> /// </summary>
public bool IsImageConsistencyVerification { get; set; } = false; public bool IsImageConsistencyVerification { get; set; } = false;
/// <summary> /// <summary>
/// 影像导出 /// 影像导出
/// </summary> /// </summary>
public bool IsImageExport { get; set; } = false; public bool IsImageExport { get; set; } = false;
@@ -241,7 +241,7 @@ namespace IRaCIS.Core.Domain.Models
//阅片方式 //阅片方式
public int ReadingMode { get; set; } = 1; public int ReadingMode { get; set; } = 1;
@@ -249,12 +249,12 @@ namespace IRaCIS.Core.Domain.Models
public int ChangeDefalutDays { get; set; } = 5; public int ChangeDefalutDays { get; set; } = 5;
/// <summary> /// <summary>
/// 跨项目复制 /// 跨项目复制
/// </summary> /// </summary>
public bool IsImageReplicationAcrossTrial { get; set; } = false; public bool IsImageReplicationAcrossTrial { get; set; } = false;
public string BodyPartTypes { get; set; } = "鼻咽部|脑部|颈部|胸部|上/下腹部|盆腔|全身|其他"; public string BodyPartTypes { get; set; } = "鼻咽部|脑部|颈部|胸部|上/下腹部|盆腔|全身|其他";
@@ -270,25 +270,25 @@ namespace IRaCIS.Core.Domain.Models
//PD 进展是否显示 配置访视 是否显示 PD进展 (从而可以设置状态) //PD 进展是否显示 配置访视 是否显示 PD进展 (从而可以设置状态)
public bool IsPDProgressView { get; set; } public bool IsPDProgressView { get; set; }
//研究方案号 //研究方案号
public string ResearchProgramNo { get; set; } public string ResearchProgramNo { get; set; }
//实验名称 //实验名称
public string ExperimentName { get; set; } public string ExperimentName { get; set; }
//主研单位 //主研单位
public string MainResearchUnit { get; set; } public string MainResearchUnit { get; set; }
// 负责人PI // 负责人PI
public string HeadPI { get; set; } public string HeadPI { get; set; }
public bool IsUrgent { get; set; } public bool IsUrgent { get; set; }
/// <summary> /// <summary>
/// 项目类型 1 正式项目、0 非正式项目 2是培训项目 /// 项目类型 1 正式项目、0 非正式项目 2是培训项目
/// </summary>time /// </summary>time
public TrialType TrialType { get; set; } public TrialType TrialType { get; set; }
@@ -306,7 +306,7 @@ namespace IRaCIS.Core.Domain.Models
public bool IsSubjectSexView { get; set; } = false; public bool IsSubjectSexView { get; set; } = false;
//配置Suject Edit页面 是否显示 加急 //配置Suject Edit页面 是否显示 加急
public bool IsSubjectExpeditedView { get; set; } = false; public bool IsSubjectExpeditedView { get; set; } = false;
@@ -314,14 +314,14 @@ namespace IRaCIS.Core.Domain.Models
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }
//QC 问题流程 //QC 问题流程
public User QCQuestionConfirmedUser { get; set; } public User QCQuestionConfirmedUser { get; set; }
public Guid? QCQuestionConfirmedUserId { get; set; } public Guid? QCQuestionConfirmedUserId { get; set; }
public DateTime? QCQuestionConfirmedTime { get; set; } public DateTime? QCQuestionConfirmedTime { get; set; }
/// <summary> /// <summary>
/// 项目完成时间 /// 项目完成时间
/// </summary> /// </summary>
public DateTime? TrialFinishTime { get; set; } public DateTime? TrialFinishTime { get; set; }
@@ -340,7 +340,7 @@ namespace IRaCIS.Core.Domain.Models
public Guid? DeleteUserId { get; set; } public Guid? DeleteUserId { get; set; }
/// <summary> /// <summary>
/// 同步临床数据时间 /// 同步临床数据时间
/// </summary> /// </summary>
public DateTime? SyncClinicalDataTime { get; set; } public DateTime? SyncClinicalDataTime { get; set; }
@@ -359,34 +359,34 @@ namespace IRaCIS.Core.Domain.Models
public UserTypeEnum? PDProgressDefaultUserType { get; set; } public UserTypeEnum? PDProgressDefaultUserType { get; set; }
#region #region
/// <summary> /// <summary>
/// 发件箱账号 /// 发件箱账号
/// </summary> /// </summary>
public string EmailFromEmail { get; set; } = string.Empty; public string EmailFromEmail { get; set; } = string.Empty;
/// <summary> /// <summary>
/// 发件人 /// 发件人
/// </summary> /// </summary>
public string EmailFromName { get; set; } = string.Empty; public string EmailFromName { get; set; } = string.Empty;
/// <summary> /// <summary>
/// 密码/授权码 /// 密码/授权码
/// </summary> /// </summary>
public string EmailAuthorizationCode { get; set; } = string.Empty; public string EmailAuthorizationCode { get; set; } = string.Empty;
/// <summary> /// <summary>
/// SMTP服务器 /// SMTP服务器
/// </summary> /// </summary>
public string EmailSMTPServerAddress { get; set; } = string.Empty; public string EmailSMTPServerAddress { get; set; } = string.Empty;
/// <summary> /// <summary>
/// SMTP端口 /// SMTP端口
/// </summary> /// </summary>
public int EmailSMTPServerPort { get; set; } public int EmailSMTPServerPort { get; set; }
/// <summary> /// <summary>
/// 是否配置过邮箱 /// 是否配置过邮箱
/// </summary> /// </summary>
public bool IsConfigureEmail { get; set; } = false; public bool IsConfigureEmail { get; set; } = false;
#endregion #endregion
@@ -395,20 +395,20 @@ namespace IRaCIS.Core.Domain.Models
///// <summary> ///// <summary>
///// 图像是否有标注 ///// 图像是否有标注
///// </summary> ///// </summary>
//public bool IsImageIabeled { get; set; } //public bool IsImageIabeled { get; set; }
////阅片类型 ////阅片类型
//public ReadingMethod ReadingType { get; set; } = ReadingMethod.Double; //public ReadingMethod ReadingType { get; set; } = ReadingMethod.Double;
//public bool IsGlobalReading { get; set; } = true; //public bool IsGlobalReading { get; set; } = true;
///// <summary> ///// <summary>
///// 仲裁阅片 ///// 仲裁阅片
///// </summary> ///// </summary>
//public bool? IsArbitrationReading { get; set; } = true; //public bool? IsArbitrationReading { get; set; } = true;
@@ -416,50 +416,50 @@ namespace IRaCIS.Core.Domain.Models
///// <summary> ///// <summary>
///// 1 Mint、2 PACS ///// 1 Mint、2 PACS
///// </summary> ///// </summary>
//public int ImagePlatform { get; set; } = 1; //public int ImagePlatform { get; set; } = 1;
///// <summary> ///// <summary>
///// 仲裁规则 ///// 仲裁规则
///// </summary> ///// </summary>
//public ArbitrationRule ArbitrationRule { get; set; } = ArbitrationRule.None; //public ArbitrationRule ArbitrationRule { get; set; } = ArbitrationRule.None;
////任务分配对象 ////任务分配对象
//public TaskAllocateObj TaskAllocateObjEnum { get; set; } //public TaskAllocateObj TaskAllocateObjEnum { get; set; }
////后续访视任务自动分配 ////后续访视任务自动分配
//public bool IsFollowVisitAutoAssign { get; set; } = true; //public bool IsFollowVisitAutoAssign { get; set; } = true;
////后续全局自动分配 ////后续全局自动分配
//public bool IsFollowGlobalVisitAutoAssign { get; set; } = true; //public bool IsFollowGlobalVisitAutoAssign { get; set; } = true;
//public bool IsFollowJudgeTaskAutoAssign { get; set; } = true; //public bool IsFollowJudgeTaskAutoAssign { get; set; } = true;
//public TaskAllocateDefaultState FollowJudgeTaskAutoAssignDefaultState { get; set; } = TaskAllocateDefaultState.Allocated; //public TaskAllocateDefaultState FollowJudgeTaskAutoAssignDefaultState { get; set; } = TaskAllocateDefaultState.Allocated;
////后续访视自动分配默认状态 ////后续访视自动分配默认状态
//public TaskAllocateDefaultState FollowVisitAutoAssignDefaultState { get; set; } = TaskAllocateDefaultState.Allocated; //public TaskAllocateDefaultState FollowVisitAutoAssignDefaultState { get; set; } = TaskAllocateDefaultState.Allocated;
////后续全局自动分配默认状态 ////后续全局自动分配默认状态
//public TaskAllocateDefaultState FollowGlobalVisitAutoAssignDefaultState { get; set; } = TaskAllocateDefaultState.Allocated; //public TaskAllocateDefaultState FollowGlobalVisitAutoAssignDefaultState { get; set; } = TaskAllocateDefaultState.Allocated;
////读片任务显示规则 ////读片任务显示规则
//public ReadingTaskViewMethod ReadingTaskViewEnum { get; set; } //public ReadingTaskViewMethod ReadingTaskViewEnum { get; set; }
////读片任务显示是否顺序 ////读片任务显示是否顺序
//public bool IsReadingTaskViewInOrder { get; set; } = true; //public bool IsReadingTaskViewInOrder { get; set; } = true;
///// <summary> ///// <summary>
///// 阅片是否显示受试者信息 ///// 阅片是否显示受试者信息
///// </summary> ///// </summary>
//public bool IsReadingShowSubjectInfo { get; set; } = false; //public bool IsReadingShowSubjectInfo { get; set; } = false;
///// <summary> ///// <summary>
///// 阅片是否显示既往结果 ///// 阅片是否显示既往结果
///// </summary> ///// </summary>
//public bool IsReadingShowPreviousResults { get; set; } = false; //public bool IsReadingShowPreviousResults { get; set; } = false;
@@ -467,7 +467,7 @@ namespace IRaCIS.Core.Domain.Models
///// <summary> ///// <summary>
///// 是确认医学审核问题 ///// 是确认医学审核问题
///// </summary> ///// </summary>
//public bool IsConfirmMedicineQuestion { get; set; } = false; //public bool IsConfirmMedicineQuestion { get; set; } = false;
@@ -476,12 +476,12 @@ namespace IRaCIS.Core.Domain.Models
///// <summary> ///// <summary>
///// 阅片信息签名时间 ///// 阅片信息签名时间
///// </summary> ///// </summary>
//public DateTime? ReadingInfoSignTime { get; set; } //public DateTime? ReadingInfoSignTime { get; set; }
///// <summary> ///// <summary>
///// 阅片工具 ///// 阅片工具
///// </summary> ///// </summary>
//public ReadingTool? ReadingTool { get; set; } //public ReadingTool? ReadingTool { get; set; }
@@ -6,7 +6,7 @@ using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.Domain.Models namespace IRaCIS.Core.Domain.Models
{ {
/// <summary> /// <summary>
/// 运维人员与项目关联关系表 - 实体 /// 运维人员与项目关联关系表 - 实体
/// </summary> /// </summary>
[Table("TrialUser")] [Table("TrialUser")]
public partial class TrialUser : Entity, IAuditUpdate, IAuditAdd ,ISoftDelete public partial class TrialUser : Entity, IAuditUpdate, IAuditAdd ,ISoftDelete
+2
View File
@@ -82,6 +82,8 @@ namespace IRaCIS.Core.Domain.Models
public DateTime? PreliminaryAuditTime { get; set; } public DateTime? PreliminaryAuditTime { get; set; }
public Guid? ForwardUserId { get; set; } public Guid? ForwardUserId { get; set; }
public DateTime? ForwardTime { get; set; } public DateTime? ForwardTime { get; set; }
// 质控领取人
public Guid? CurrentActionUserId { get; set; } public Guid? CurrentActionUserId { get; set; }
public DateTime? CurrentActionUserExpireTime { get; set; } public DateTime? CurrentActionUserExpireTime { get; set; }
+4 -1
View File
@@ -121,7 +121,10 @@ public static class StaticData
public static readonly string UploadFileFolder = "UploadFile"; public static readonly string UploadFileFolder = "UploadFile";
} }
public static class EmailSend
{
public static string EmailNamePlaceholder = "EmailNamePlaceholder";
}
public static class TrialOpt public static class TrialOpt
{ {
+6 -6
View File
@@ -5,10 +5,10 @@
"RemoteNew": "Server=123.56.181.144,14333\\MSSQLExpress14;Database=IRaCIS_New;User ID=sa;Password=dev123456DEV;" "RemoteNew": "Server=123.56.181.144,14333\\MSSQLExpress14;Database=IRaCIS_New;User ID=sa;Password=dev123456DEV;"
}, },
"JwtSetting": { "JwtSetting": {
"SecurityKey": "3e6dbfa227234a03977a2f421bdb7f4f", // "SecurityKey": "3e6dbfa227234a03977a2f421bdb7f4f", //
"Issuer": "IRaCIS", // "Issuer": "IRaCIS", //
"Audience": "ZhiZhun", // "Audience": "ZhiZhun", //
"TokenExpireDays": "7" // 7day "TokenExpireDays": "7" // 7day
}, },
"IpRateLimiting": { "IpRateLimiting": {
"EnableEndpointRateLimiting": true, //False: globally executed, true: executed for each "EnableEndpointRateLimiting": true, //False: globally executed, true: executed for each
@@ -69,7 +69,7 @@
}, },
//访 dicom ... ip //访 dicom ... ip
//"RootUrl": "http://localhost:8060", //"RootUrl": "http://localhost:8060",
"GrpcAddress": "http://123.56.181.144:7200", "GrpcAddress": "http://123.56.181.144:7200",
@@ -83,7 +83,7 @@
"UserCodePrefix": "U", "UserCodePrefix": "U",
"Share": false, // "Share": false, //
"FileSizeLimit": 1073741824, "FileSizeLimit": 1073741824,
"LoginExpiredTimeSpan": "15", // Minute "LoginExpiredTimeSpan": "15", // Minute
"OpenLog": true, "OpenLog": true,
"AddClinicalInfo": true "AddClinicalInfo": true
@@ -1130,7 +1130,10 @@ namespace IRaCIS.Core.Infra.EFCore.Common
await InsertInspection<ReadingMedicineTrialQuestion>(entity, type, x => new InspectionConvertDTO() await InsertInspection<ReadingMedicineTrialQuestion>(entity, type, x => new InspectionConvertDTO()
{ {
IsDistinctionInterface = false, IsDistinctionInterface = false,
ObjectRelationParentId = x.TrialId
ObjectRelationParentId = entity.TrialId,
TrialReadingCriterionId = x.TrialReadingCriterionId,
}, new { ParentQuestionName = parentQuestionName }); }, new { ParentQuestionName = parentQuestionName });
} }
@@ -1353,11 +1356,11 @@ namespace IRaCIS.Core.Infra.EFCore.Common
// 一致性核查文件 是否需要单独一个表记录? // 一致性核查文件 是否需要单独一个表记录?
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(UserUploadFile))) foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(InspectionFile)))
{ {
var type = GetEntityAuditOpt(item); var type = GetEntityAuditOpt(item);
await InsertInspection<UserUploadFile>(item.Entity as UserUploadFile, type, x => new InspectionConvertDTO() await InsertInspection<InspectionFile>(item.Entity as InspectionFile, type, x => new InspectionConvertDTO()
{ {
ObjectRelationParentId = x.TrialId ObjectRelationParentId = x.TrialId
@@ -1408,6 +1411,30 @@ namespace IRaCIS.Core.Infra.EFCore.Common
}); });
} }
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialSiteUserSurvey)))
{
var type = GetEntityAuditOpt(item);
var entity = item.Entity as TrialSiteUserSurvey;
await InsertInspection<TrialSiteUserSurvey>(entity, type, x => new InspectionConvertDTO()
{
IsDistinctionInterface = false
});
}
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialSiteEquipmentSurvey)))
{
var type = GetEntityAuditOpt(item);
var entity = item.Entity as TrialSiteEquipmentSurvey;
await InsertInspection<TrialSiteEquipmentSurvey>(entity, type, x => new InspectionConvertDTO()
{
IsDistinctionInterface = false
});
}
#endregion #endregion
@@ -1516,6 +1543,7 @@ namespace IRaCIS.Core.Infra.EFCore.Common
} }
await InsertInspection<TrialSite>(entity, type, x => new InspectionConvertDTO() await InsertInspection<TrialSite>(entity, type, x => new InspectionConvertDTO()
{ {
IsDistinctionInterface= type == AuditOpt.Update ? true : false,
TrialId = x.TrialId, TrialId = x.TrialId,
ObjectRelationParentId = x.TrialId ObjectRelationParentId = x.TrialId
@@ -1566,6 +1594,7 @@ namespace IRaCIS.Core.Infra.EFCore.Common
await InsertInspection<TrialSiteUser>(item.Entity as TrialSiteUser, type, x => new InspectionConvertDTO await InsertInspection<TrialSiteUser>(item.Entity as TrialSiteUser, type, x => new InspectionConvertDTO
{ {
IsDistinctionInterface= type == AuditOpt.Update ? true : false,
TrialId = x.TrialId, TrialId = x.TrialId,
ObjectRelationParentId = entity.TrialSite.Id, ObjectRelationParentId = entity.TrialSite.Id,
ObjectRelationParentId2 = x.UserId, ObjectRelationParentId2 = x.UserId,
@@ -1709,6 +1738,8 @@ namespace IRaCIS.Core.Infra.EFCore.Common
SubjectVisitId = x.Id, SubjectVisitId = x.Id,
SiteId = x.SiteId, SiteId = x.SiteId,
ExtraIndentification = extraIdentification,
}, },
//兼容之前的配置名 //兼容之前的配置名
new { SubjectVisitName = entity.VisitName } new { SubjectVisitName = entity.VisitName }
@@ -2106,12 +2137,12 @@ namespace IRaCIS.Core.Infra.EFCore.Common
if (entity.RequestReReadingResultEnum == RequestReReadingResult.Agree) if (entity.RequestReReadingResultEnum == RequestReReadingResult.Agree)
{ {
extraIdentification = "/" + 1; extraIdentification = extraIdentification+"/" + 1;
} }
else if (entity.RequestReReadingResultEnum == RequestReReadingResult.Reject) else if (entity.RequestReReadingResultEnum == RequestReReadingResult.Reject)
{ {
extraIdentification = "/" + 2; extraIdentification = extraIdentification+ "/" + 2;
} }
break; break;
} }
@@ -466,7 +466,7 @@ namespace IRaCIS.Core.Infra.EFCore
public virtual DbSet<FrontAuditConfig> FrontAuditConfig { get; set; } public virtual DbSet<FrontAuditConfig> FrontAuditConfig { get; set; }
public virtual DbSet<UserUploadFile> UserUploadFile { get; set; } public virtual DbSet<InspectionFile> InspectionFile { get; set; }
public virtual DbSet<CommonDocument> CommonDocument { get; set; } public virtual DbSet<CommonDocument> CommonDocument { get; set; }
@@ -558,12 +558,12 @@ namespace IRaCIS.Core.Infra.EFCore
throw new DBSaveFailedException("SQL 事务失败,请检查环境。"); throw new DBSaveFailedException("SQL 事务失败,请检查环境。");
} }
catch (Exception ex) //catch (Exception ex)
{ //{
_logger.LogError(ex.InnerException is null ? ex.Message : ex.InnerException?.Message); // _logger.LogError(ex.InnerException is null ? ex.Message : ex.InnerException?.Message);
throw new DBSaveFailedException("数据保存异常。"); // throw new DBSaveFailedException(ex.Message);
} //}
} }
@@ -12,7 +12,7 @@ namespace IRaCIS.Core.Infrastructure.Extention
{ {
if(businessObject == null) if(businessObject == null)
{ {
throw new QueryBusinessObjectNotExistException($"The query object {typeof(TEntity).Name} does not exist in database, Please check the query parameters"); throw new QueryBusinessObjectNotExistException($"The query object {typeof(TEntity).Name} is null, Please check ");
} }
else else
{ {
@@ -25,7 +25,7 @@ namespace IRaCIS.Core.Infrastructure.Extention
{ {
if (businessStruct == null) if (businessStruct == null)
{ {
throw new QueryBusinessObjectNotExistException($"The query object {typeof(TEntity).Name} does not exist in database, Please check the query parameters"); throw new QueryBusinessObjectNotExistException($"The query object {typeof(TEntity).Name} is null, Please check ");
} }
else else
{ {
@@ -38,7 +38,7 @@ namespace IRaCIS.Core.Infrastructure.Extention
{ {
if (businessObject == null) if (businessObject == null)
{ {
throw new QueryBusinessObjectNotExistException($" Can not Convert to {typeof(TEntity).Name} Type, Please check parameter"); throw new QueryBusinessObjectNotExistException($" {typeof(TEntity).Name} Type object should not null, Please check ");
} }
else else
{ {
@@ -1,5 +1,7 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic;
using System.Reflection;
namespace IRaCIS.Core.Infrastructure.Extention namespace IRaCIS.Core.Infrastructure.Extention
{ {
@@ -38,7 +40,38 @@ namespace IRaCIS.Core.Infrastructure.Extention
public static string ToJsonNotIgnoreNull(this object obj) public static string ToJsonNotIgnoreNull(this object obj)
{ {
return JsonConvert.SerializeObject(obj, new JsonSerializerSettings { DateFormatString = "yyyy-MM-dd HH:mm:ss", ReferenceLoopHandling = ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Include }); return JsonConvert.SerializeObject(obj, new JsonSerializerSettings { DateFormatString = "yyyy-MM-dd HH:mm:ss", Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Include });
} }
}
public static Dictionary<string, object> ConvertToDictionary(this object obj)
{
if (obj == null)
{
throw new ArgumentNullException(nameof(obj));
}
Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties();
Dictionary<string, object> dictionary = new Dictionary<string, object>();
foreach (PropertyInfo property in properties)
{
string propertyName = property.Name;
object propertyValue = property.GetValue(obj);
// 如果属性的类型是枚举,将其值保留为整数
if (property.PropertyType.IsEnum)
{
dictionary.Add(propertyName, (int)propertyValue);
}
else
{
dictionary.Add(propertyName, propertyValue);
}
}
return dictionary;
}
}
} }

Some files were not shown because too many files have changed in this diff Show More