Compare commits

...

162 Commits

Author SHA1 Message Date
hang da57773cd3 邮箱验证修改
continuous-integration/drone/push Build is passing
2024-05-31 17:42:59 +08:00
hang d3c2ded3d4 返回 SliceThickness
continuous-integration/drone/push Build is passing
2024-05-31 15:56:29 +08:00
hang 37e7ab575f 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-05-31 15:39:31 +08:00
hang 39a9a0c05d 日志遗漏接口
continuous-integration/drone/push Build is passing
2024-05-31 09:09:28 +08:00
hang 570c5863c0 ip所在地遗漏
continuous-integration/drone/push Build is passing
2024-05-30 16:04:42 +08:00
hang 343f9211e2 区域 依赖注入
continuous-integration/drone/push Build is passing
2024-05-30 15:57:53 +08:00
hang 4b7fff9869 修改日志区域
continuous-integration/drone/push Build is passing
2024-05-30 15:53:16 +08:00
hang 1b1ac3ee65 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-05-28 17:39:04 +08:00
he 37b4860668 修改
continuous-integration/drone/push Build is passing
2024-05-28 14:44:54 +08:00
he 96f3ecb45d 代码提交
continuous-integration/drone/push Build is passing
2024-05-28 14:33:15 +08:00
he 4966a32bcb 问题修改
continuous-integration/drone/push Build is passing
2024-05-27 15:07:46 +08:00
he 07dcb6fe47 稽查翻译修改
continuous-integration/drone/push Build is passing
2024-05-24 14:55:24 +08:00
he f802897b14 修改
continuous-integration/drone/push Build is passing
2024-05-23 16:19:20 +08:00
he 0642b9e4fb Merge branch 'Test.Study' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-23 15:01:17 +08:00
he f945793d6d 稽查翻译修改 2024-05-23 15:01:16 +08:00
hang 7b4eb7a459 修改Study 加急设置
continuous-integration/drone/push Build is passing
2024-05-23 13:50:46 +08:00
hang 5fbebe9cc0 一致性核查通过自动关闭质疑
continuous-integration/drone/push Build is passing
2024-05-23 11:16:09 +08:00
hang 6feb2b20f8 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-05-23 09:15:26 +08:00
hang 2f87048f65 修改导表格式 2024-05-23 09:15:26 +08:00
he 5e613fd9d3 Merge branch 'Test.Study' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-23 09:08:30 +08:00
he 3fa4db75d0 异常修改 2024-05-23 09:08:29 +08:00
hang 0c4bc87ee9 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-05-23 09:00:15 +08:00
hang 6fb0562a0b 修改邮箱验证正则 2024-05-23 09:00:15 +08:00
he 10fc07ec03 修改
continuous-integration/drone/push Build is passing
2024-05-22 17:56:28 +08:00
he 400421a337 修改
continuous-integration/drone/push Build is passing
2024-05-22 17:53:31 +08:00
he 4983def85b Merge branch 'Test.Study' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-22 17:49:01 +08:00
he d60a2567c1 修改 2024-05-22 17:48:59 +08:00
hang 2cd9716e68 修改临床数据维护
continuous-integration/drone/push Build is passing
2024-05-22 17:39:28 +08:00
hang 1cf0ac0c53 临床数据bug
continuous-integration/drone/push Build is passing
2024-05-22 09:42:26 +08:00
hang 74dd5369cb 增加查询条件
continuous-integration/drone/push Build is passing
2024-05-20 17:43:18 +08:00
hang 9d6a046d7f 清理多余的字段
continuous-integration/drone/push Build is passing
2024-05-20 15:36:10 +08:00
hang a31eef5ccd 修改评估结果
continuous-integration/drone/push Build is passing
2024-05-20 15:34:24 +08:00
hang 21beeecb7d 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-05-20 15:19:31 +08:00
hang c5c3c3334d 缓存清理 2024-05-20 15:19:29 +08:00
he 92008fe6ba Merge branch 'Test.Study' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-20 15:10:02 +08:00
he 138a967283 修改 2024-05-20 15:10:01 +08:00
hang ed72ed9a5e 自定义阅片显示评估结果
continuous-integration/drone/push Build is passing
2024-05-20 15:04:25 +08:00
hang 5d0dca121f 修改site 和hospital 以及增加字段
continuous-integration/drone/push Build is passing
2024-05-20 14:34:35 +08:00
hang 3d656dfa17 修改提交事务地点
continuous-integration/drone/push Build is passing
2024-05-16 14:25:55 +08:00
hang 7adb291a0f 先一致性核查,再确认标准的时候,批量生成任务的时候,前序任务是否需要签名但是没签名状态有误
continuous-integration/drone/push Build is passing
2024-05-16 14:02:20 +08:00
hang 3c790965fe 阅片界面调整-查询条件 2024-05-15 13:27:39 +08:00
hang da4fe122ab 重阅跟踪修改 2024-05-15 13:27:14 +08:00
hang e029f32bad 迁移study 打包
continuous-integration/drone/push Build is failing
2024-05-06 14:00:43 +08:00
hang 4320f06b77 x 2024-04-17 10:06:51 +08:00
hang ac43952c18 修改测试环境存放bucket 2024-04-17 09:59:42 +08:00
hang 5ef97ff742 修改PI 自动审核通过的 2024-04-15 17:01:32 +08:00
hang 2c8056c77b 设置访视上入组和pd默认值 2024-04-15 16:17:17 +08:00
hang 5ac6e186c0 修改中心调研bug 需要迁移 2024-04-10 14:54:56 +08:00
hang e4e02225c5 稽查排序修改,需要迁移 2024-04-08 17:40:01 +08:00
hang 72b21fc021 study 列表修改
continuous-integration/drone/push Build is passing
2024-04-07 15:01:47 +08:00
he b8175c8ed5 修改 2024-04-02 13:09:17 +08:00
hang 885b115927 修改访视默认值 2024-03-19 10:45:54 +08:00
hang 776c8f5c5e 修改阅片任务查询 2024-03-19 10:05:17 +08:00
hang 5564d8cc42 一致性分析修改 2024-03-06 14:09:19 +08:00
hang 2b9d3785d6 修改生产配置文件
continuous-integration/drone/push Build is passing
2024-02-02 17:40:19 +08:00
hang 46db19f513 修改邮件bug
continuous-integration/drone/push Build is passing
2024-02-02 15:22:25 +08:00
hang 3a479fe724 修改邮件发送
continuous-integration/drone/push Build is passing
2024-02-02 15:20:34 +08:00
hang a1afb299b3 修改邮件发送bug 2024-02-02 15:03:37 +08:00
hang c54074dd3d 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-02-01 16:54:24 +08:00
he 203bce15ea 修改查询阅片图像
continuous-integration/drone/push Build is passing
2024-02-01 13:40:37 +08:00
he c1096ae473 阅片图像查询修改
continuous-integration/drone/push Build is passing
2024-02-01 13:30:20 +08:00
hang f2cd5f35e3 [修改一致性核查模板] 2024-01-31 16:37:17 +08:00
hang 40afae1f37 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-31 11:05:38 +08:00
hang 845c532134 [修改subject 查询 不依赖系统site] 2024-01-31 11:04:36 +08:00
hang 8615c90ebe 【修改 查询写入dicom的信息】 2024-01-31 11:04:29 +08:00
he eb1d90e304 study去掉疲劳阅片
continuous-integration/drone/push Build is passing
2024-01-29 14:34:50 +08:00
hang 88f015183d [赋值study code dicom]
continuous-integration/drone/push Build is passing
2024-01-26 12:36:42 +08:00
hang 4f9560c3a6 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-26 11:11:59 +08:00
hang 9abb78400a [site搜索三个名字] 2024-01-26 09:41:03 +08:00
he 8f5e2c5b0c 添加LimitShow 限制显示
continuous-integration/drone/push Build is passing
2024-01-25 16:03:35 +08:00
he efe96203d9 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-25 16:00:35 +08:00
hang 65de94079a 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-25 15:52:57 +08:00
hang 6e706c4fc9 [上传监控增加字段] 2024-01-25 15:52:31 +08:00
hang 84e2e14b73 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-24 14:20:22 +08:00
hang 49d4a71f36 [修改回退] 2024-01-24 14:20:20 +08:00
hang 7dcf73176c 去掉内存缓存
continuous-integration/drone/push Build is passing
2024-01-24 12:28:33 +08:00
hang f9bf9d752c 测试
continuous-integration/drone/push Build is passing
2024-01-24 12:20:38 +08:00
hang acac7ec995 升级net8 准备
continuous-integration/drone/push Build is passing
2024-01-24 12:17:02 +08:00
hang 6cfcb9bfe1 修改测试
continuous-integration/drone/push Build is passing
2024-01-24 11:22:20 +08:00
hang 9adf2ad52b 请求前端国际化增加缓存-需要迁移 2024-01-24 11:21:47 +08:00
hang 403885ef3f 修改国际化取消权限限制 2024-01-24 11:21:43 +08:00
hang 7b1a0affbe 增加前端国际化修改 2024-01-24 11:21:32 +08:00
hang 85897f990d [邮件模板启用与否没用bug修复]
continuous-integration/drone/push Build is passing
2024-01-24 10:14:18 +08:00
hang be477818d7 [AWS 对接上传 需要传递文件大小] 2024-01-24 10:13:22 +08:00
hang 41bbb75407 [修改重传没有检查id] 2024-01-24 10:13:13 +08:00
hang fd9fdcb8be [修改医生bug 和site bug] 2024-01-24 10:13:06 +08:00
hang 0e8ecdaf46 [上传失败过,返回标志] 2024-01-24 10:12:22 +08:00
hang 81b033885e [上传监控增加字段] 2024-01-24 10:11:06 +08:00
hang fca2a81c66 [遗漏 get set] 2024-01-24 10:10:59 +08:00
hang 353f5df217 [修改上传,失败数量传递不准问题] 2024-01-24 10:10:54 +08:00
hang 4874533804 [增加默认值] 2024-01-24 10:10:48 +08:00
hang 025a8e7af1 [上传增加稽查字段]迁移 2024-01-24 10:10:40 +08:00
hang 79c5824051 统一日志记录信息 2024-01-24 10:08:32 +08:00
hang 2c47842e13 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study 2024-01-24 10:03:24 +08:00
hang 39d9cefda9 [上传监控修改,增加搜索条件] 2024-01-24 09:58:51 +08:00
hang 2c0d1cdc82 [邮件模板启用与否没用bug修复] 2024-01-24 09:55:22 +08:00
hang af77d5be56 修改邮件模板
continuous-integration/drone/push Build is passing
2024-01-22 11:09:19 +08:00
he f662a988e0 修改 2024-01-16 10:27:48 +08:00
hang b9cace17b2 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-15 16:10:46 +08:00
hang c8d0ef9043 修改study 配置文件 2024-01-15 16:10:44 +08:00
hang 2491fd1fff 请求前端国际化增加缓存-需要迁移 2024-01-11 18:03:25 +08:00
hang 7cc9731edf 修改国际化取消权限限制 2024-01-11 18:03:21 +08:00
hang ff333219d4 增加前端国际化修改 2024-01-11 18:03:16 +08:00
hang 0eae520f0d 适配AWS 和MinIO
continuous-integration/drone/push Build is passing
2024-01-11 17:59:49 +08:00
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
111 changed files with 2354 additions and 1113 deletions
@@ -146,7 +146,7 @@ namespace IRaCIS.Api.Controllers
var ossOptions = serviceOption.AliyunOSS;
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO ,AliyunOSS= serviceOption.AliyunOSS });
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO, AliyunOSS = serviceOption.AliyunOSS, AWS = serviceOption.AWS });
#region token
//IClientProfile profile = DefaultProfile.GetProfile(ossOptions.RegionId, ossOptions.AccessKeyId, ossOptions.AccessKeySecret);
@@ -189,11 +189,11 @@ namespace IRaCIS.Api.Controllers
}
else if (Enum.TryParse<ObjectStoreUse>(serviceOption.ObjectStoreUse, out var parsedValue) && parsedValue == ObjectStoreUse.MinIO)
{
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO });
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO, AWS = serviceOption.AWS });
}
else
{
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO });
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO, AWS = serviceOption.AWS });
}
}
@@ -800,7 +800,7 @@ namespace IRaCIS.Core.API.Controllers
templateFileStream.Seek(0, SeekOrigin.Begin);
var ossRelativePath = oSSService.UploadToOSS(fileStream, "InspectionUpload/Check", realFileName);
var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/Check", realFileName);
await _repository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId });
@@ -1024,7 +1024,7 @@ namespace IRaCIS.Core.API.Controllers
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_TemplateUploadData"));
}
var ossRelativePath = oSSService.UploadToOSS(fileStream, "InspectionUpload/SiteSurvey", realFileName);
var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/SiteSurvey", realFileName);
await _inspectionFileRepository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId });
-126
View File
@@ -1,126 +0,0 @@
using System;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;
using MediatR;
using IRaCIS.Core.Application.MediatR.Handlers;
using System.Threading.Tasks;
using MassTransit;
using MassTransit.NewIdProviders;
using System.IO;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Application.Helper;
using System.Runtime.InteropServices;
namespace IRaCIS.Core.API
{
public class Program
{
public readonly string environment;
public static async Task Main(string[] args)
{
try
{
//以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数)
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
var enviromentName = config["ASPNETCORE_ENVIRONMENT"];
if (string.IsNullOrWhiteSpace(enviromentName))
{
var index = Array.IndexOf(args, "--env");
enviromentName = index > -1
? args[index + 1]
: "Development";
}
//Dicom 浏览
//ImageManager.SetImplementation(WinFormsImageManager.Instance);
var host = CreateHostBuilder(args)
.UseEnvironment(enviromentName) //命令行传入环境
.ConfigureAppConfiguration((hostContext, config) =>
{
//Console.WriteLine(hostContext.HostingEnvironment.EnvironmentName);
config.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{enviromentName}.json", false, true);
})
.Build();
//// Serilog
SerilogExtension.AddSerilogSetup(enviromentName, host.Services);
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());
host.Run();
}
catch (Exception e)
{
Log.Logger.Error(e.InnerException is null ? e.Message + e.StackTrace : e.InnerException?.Message + e.InnerException?.StackTrace);
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel((context, options) =>
{
//设置应用服务器Kestrel请求体最大为1GB // if don't set default value is: 30 MB
options.Limits.MaxRequestBodySize = long.MaxValue;
options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(30);
options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(20);
});
//webBuilder.UseSerilog();//在宿主机启动的时候配置serilog,与微软ILogger进行整合
webBuilder.UseStartup<Startup>();
}).UseSerilog()
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
private static async Task InitCache(IHost host)
{
var _repository = host.Services.GetService(typeof(IRepository)) as IRepository;
//初始化 国际化数据,并且监测国际化文件变更
//await InternationalizationHelper.InitInternationlizationDataAndWatchJsonFileAsync(_repository);
}
}
}
+309
View File
@@ -0,0 +1,309 @@
using System;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;
using MediatR;
using IRaCIS.Core.Application.MediatR.Handlers;
using System.Threading.Tasks;
using MassTransit;
using MassTransit.NewIdProviders;
using System.IO;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Application.Helper;
using System.Runtime.InteropServices;
using Microsoft.AspNetCore.Builder;
using IRaCIS.Core.API;
using Autofac;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.HttpOverrides;
using IRaCIS.Application.Services.BackGroundJob;
using LogDashboard;
using OfficeOpenXml.Utils;
using IP2Region.Net.Abstractions;
using IP2Region.Net.XDB;
#region
//以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数)
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
var enviromentName = config["ASPNETCORE_ENVIRONMENT"];
if (string.IsNullOrWhiteSpace(enviromentName))
{
var index = Array.IndexOf(args, "--env");
enviromentName = index > -1
? args[index + 1]
: "Development";
}
#endregion
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
EnvironmentName = enviromentName
});
#region windows
//foreach (var arg in args)
//{
// Console.WriteLine(arg);
//}
int urlsIndex = Array.FindIndex(args, arg => arg != null && arg.StartsWith("--urls"));
if (urlsIndex > -1)
{
var url = args[urlsIndex].Substring("--urls=".Length);
Console.WriteLine(url);
builder.WebHost.UseUrls(url);
}
#endregion
#region
NewId.SetProcessIdProvider(new CurrentProcessIdProvider());
builder.Configuration.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{enviromentName}.json", false, true);
builder.Host
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
containerBuilder.RegisterModule<AutofacModuleSetup>();
})
.UseWindowsService().UseSerilog();
#endregion
#region
var _configuration = builder.Configuration;
//健康检查
builder.Services.AddHealthChecks();
//本地化
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
builder.Services.AddControllers(options =>
{
//options.Filters.Add<LogActionFilter>();
options.Filters.Add<ModelActionFilter>();
options.Filters.Add<ProjectExceptionFilter>();
options.Filters.Add<UnitOfWorkFilter>();
if (_configuration.GetSection("BasicSystemConfig").GetValue<bool>("OpenLoginLimit"))
{
options.Filters.Add<LimitUserRequestAuthorization>();
}
})
.AddNewtonsoftJsonSetup(); // NewtonsoftJson 序列化 处理
builder.Services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig"));
builder.Services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
builder.Services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
builder.Services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
builder.Services.AddDynamicWebApiSetup();
//AutoMapper
builder.Services.AddAutoMapperSetup();
//EF ORM QueryWithNoLock
builder.Services.AddEFSetup(_configuration);
//Http 响应压缩
builder.Services.AddResponseCompressionSetup();
//Swagger Api 文档
builder.Services.AddSwaggerSetup();
//JWT Token 验证
builder.Services.AddJWTAuthSetup(_configuration);
// MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<ConsistencyVerificationHandler>());
// EasyCaching 缓存
builder.Services.AddEasyCachingSetup(_configuration);
// hangfire 定时任务框架 有界面,更友好~
builder.Services.AddhangfireSetup(_configuration);
//
builder.Services.AddQuartZSetup(_configuration);
//Serilog 日志可视化 LogDashboard日志
builder.Services.AddLogDashboardSetup();
builder.Services.AddJsonConfigSetup(_configuration);
//转发头设置 获取真实IP
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
//Dicom影像渲染图片 跨平台
builder.Services.AddDicomSetup();
// 实时应用
builder.Services.AddSignalR();
builder.Services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
//builder.Services.AddMemoryCache();
#region
////上传限制 配置
//builder.Services.Configure<FormOptions>(options =>
//{
// options.MultipartBodyLengthLimit = int.MaxValue;
// options.ValueCountLimit = int.MaxValue;
// options.ValueLengthLimit = int.MaxValue;
//});
//IP 限流 可设置白名单 或者黑名单
//services.AddIpPolicyRateLimitSetup(_configuration);
// 用户类型 策略授权
//services.AddAuthorizationPolicySetup(_configuration);
#endregion
builder.Services.AddSingleton<ISearcher>(new Searcher(CachePolicy.Content, Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, "ip2region.xdb")));
#endregion
var app = builder.Build();
var env = app.Environment;
#region
// Configure the HTTP request pipeline.
//本地化
app.UseLocalization();
app.UseForwardedHeaders();
//响应压缩
app.UseResponseCompression();
//app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
//不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();
//app.UseMiddleware<MultiDiskStaticFilesMiddleware>();
//LogDashboard
app.UseLogDashboard("/LogDashboard");
//hangfire
app.UseHangfireConfig(env);
////限流 中间件
//app.UseIpRateLimiting();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
//app.UseHsts();
}
// 特殊异常处理 比如 404
app.UseStatusCodePagesWithReExecute("/Error/{0}");
SwaggerSetup.Configure(app, env);
////serilog 记录请求的用户信息
app.UseSerilogConfig(env);
app.UseRouting();
app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
//app.UseIRacisHostStaticFileStore(env);
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapHub<UploadHub>("/UploadHub");
app.MapHealthChecks("/health");
// Serilog
SerilogExtension.AddSerilogSetup(enviromentName, app.Services);
var hangfireJobService = app.Services.GetRequiredService<IIRaCISHangfireJob>();
await hangfireJobService.InitHangfireJobTaskAsync();
#endregion
try
{
#region
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");
}
#endregion
Log.Logger.Warning($"ContentRootPath{env.ContentRootPath}");
string parentDirectory = Path.GetFullPath(Path.Combine(env.ContentRootPath, ".."));
Log.Logger.Warning($"ContentRootPath——parentDirectory{parentDirectory}");
//Log.Logger.Warning($"ContentRootPath——GetParent{Directory.GetParent(env.ContentRootPath).Parent.FullName}");
//Log.Logger.Warning($"ContentRootPath——xx{Path.GetDirectoryName(Path.GetDirectoryName(env.ContentRootPath))}");
app.Run();
}
catch (Exception e)
{
Log.Logger.Error(e.InnerException is null ? e.Message + e.StackTrace : e.InnerException?.Message + e.InnerException?.StackTrace);
}
-262
View File
@@ -1,262 +0,0 @@
using Autofac;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using IRaCIS.Core.Application.Filter;
using LogDashboard;
using MediatR;
using IRaCIS.Core.Application.MediatR.Handlers;
using Microsoft.Extensions.Logging;
using AspNetCoreRateLimit;
using Microsoft.AspNetCore.HttpOverrides;
using IRaCIS.Core.Infra.EFCore;
using System.Globalization;
using Microsoft.AspNetCore.Localization;
using Localization;
using Magicodes.ExporterAndImporter.Core.Filters;
using IRaCIS.Core.Application.MediatR.CommandAndQueries;
using IRaCIS.Core.Infra.EFCore.Common;
using Invio.Extensions.Authentication.JwtBearer;
using Microsoft.AspNetCore.SignalR;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.StaticFiles;
using IRaCIS.Application.Services.BackGroundJob;
using IRaCIS.Core.Application.Helper;
using Microsoft.AspNetCore.Http;
using Autofac.Core;
using DocumentFormat.OpenXml.InkML;
using EasyCaching.Core;
namespace IRaCIS.Core.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
_configuration = configuration;
}
public ILogger<Startup> _logger { get; }
public IConfiguration _configuration { get; }
//// ConfigureContainer is where you can register things directly
//// with Autofac. This runs after ConfigureServices so the things
//// here will override registrations made in ConfigureServices.
//// Don't build the container; that gets done for you by the factory.
// for castle
public void ConfigureContainer(ContainerBuilder containerBuilder)
{
containerBuilder.RegisterModule<AutofacModuleSetup>();
#region Test
//containerBuilder.RegisterType<ClinicalDataService>().PropertiesAutowired().InstancePerLifetimeScope();//注册仓储
//var container = containerBuilder.Build();
//// Now you can resolve services using Autofac. For example,
//// this line will execute the lambda expression registered
//// to the IConfigReader service.
//using (var scope = container.BeginLifetimeScope())
//{
// var reader = scope.Resolve<BaseService>();
// var test = scope.Resolve<ClinicalDataService>();
// var test2 = scope.Resolve<IClinicalDataService>();
// var test3 = scope.Resolve<IEFUnitOfWork<IRaCISDBContext>>();
//}
#endregion
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//健康检查
services.AddHealthChecks();
//本地化
services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
services.AddControllers(options =>
{
//options.Filters.Add<LogActionFilter>();
options.Filters.Add<ModelActionFilter>();
options.Filters.Add<ProjectExceptionFilter>();
options.Filters.Add<UnitOfWorkFilter>();
if (_configuration.GetSection("BasicSystemConfig").GetValue<bool>("OpenLoginLimit"))
{
options.Filters.Add<LimitUserRequestAuthorization>();
}
})
.AddNewtonsoftJsonSetup(); // NewtonsoftJson 序列化 处理
services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig"));
services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
services.AddDynamicWebApiSetup();
//AutoMapper
services.AddAutoMapperSetup();
//EF ORM QueryWithNoLock
services.AddEFSetup(_configuration);
//Http 响应压缩
services.AddResponseCompressionSetup();
//Swagger Api 文档
services.AddSwaggerSetup();
//JWT Token 验证
services.AddJWTAuthSetup(_configuration);
// MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系
services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<ConsistencyVerificationHandler>());
// EasyCaching 缓存
services.AddEasyCachingSetup(_configuration);
//services.AddDistributedMemoryCache();
// hangfire 定时任务框架 有界面,更友好~
services.AddhangfireSetup(_configuration);
// QuartZ 定时任务框架 使用了hangfire 暂时不用,后续需要可以打开,已经配好
services.AddQuartZSetup(_configuration);
// 保护上传文件
//services.AddStaticFileAuthorizationSetup();
////HttpReports 暂时废弃
//services.AddHttpReports().AddHttpTransport();
//Serilog 日志可视化 LogDashboard日志
services.AddLogDashboardSetup();
//上传限制 配置
services.Configure<FormOptions>(options =>
{
options.MultipartBodyLengthLimit = int.MaxValue;
options.ValueCountLimit = int.MaxValue;
options.ValueLengthLimit = int.MaxValue;
});
//IP 限流 可设置白名单 或者黑名单
//services.AddIpPolicyRateLimitSetup(_configuration);
// 用户类型 策略授权
//services.AddAuthorizationPolicySetup(_configuration);
services.AddJsonConfigSetup(_configuration);
//转发头设置 获取真实IP
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
//Dicom影像渲染图片 跨平台
services.AddDicomSetup();
// 实时应用
services.AddSignalR();
services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
//services.AddSingleton<IImportResultFilter, ImportResultFilteTest>();
services.AddMemoryCache();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public async void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//app.UsePathBase(PathString.FromUriComponent("/api"));
//本地化
app.UseLocalization();
app.UseForwardedHeaders();
//响应压缩
app.UseResponseCompression();
//app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
//不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();
//LogDashboard
app.UseLogDashboard("/back/logs");
//hangfire
app.UseHangfireConfig(env);
////暂时废弃
//app.UseHttpReports();
////限流 中间件
//app.UseIpRateLimiting();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
//app.UseHsts();
}
Console.WriteLine("当前环境: " + env.EnvironmentName);
//app.UseMiddleware<AuthMiddleware>();
// 特殊异常处理 比如 404
app.UseStatusCodePagesWithReExecute("/Error/{0}");
SwaggerSetup.Configure(app, env);
////serilog 记录请求的用户信息
app.UseSerilogConfig(env);
app.UseRouting();
app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
//app.UseIRacisHostStaticFileStore(env);
app.UseMiddleware<MultiDiskStaticFilesMiddleware>();
app.UseAuthentication();
//app.UseJwtBearerQueryString();
app.UseAuthorization();
////文件伺服 必须带Token 访问
////app.UseIRacisHostStaticFileStore(env);
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<UploadHub>("/UploadHub");
endpoints.MapHealthChecks("/health");
});
var hangfireJobService = app.ApplicationServices.GetRequiredService<IIRaCISHangfireJob>();
await hangfireJobService.InitHangfireJobTaskAsync();
//有的时候每调用
//HangfireJobHelper.NotImmediatelyOnceOnlyJob<IIRaCISHangfireJob>(t => t.InitHangfireJobTaskAsync(),TimeSpan.FromSeconds(1));
}
}
}
@@ -17,7 +17,7 @@ namespace IRaCIS.Core.API
app.UseSerilogRequestLogging(opts
=>
{
opts.MessageTemplate = "{TokenUserRealName} {TokenUserType} {ClientIp} {RequestIP} {Host} {Protocol} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
opts.MessageTemplate = "{TokenUserRealName} {TokenUserTypeShortName} {ClientIp} {LocalIP} {Host} {Protocol} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
opts.EnrichDiagnosticContext = SerilogHelper.EnrichFromRequest;
});
@@ -1,4 +1,5 @@
using IRaCIS.Core.Infrastructure.Extention;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Http;
using Serilog;
using System;
@@ -41,9 +42,9 @@ namespace IRaCIS.Core.API
// Set the content-type of the Response at this point
diagnosticContext.Set("ContentType", httpContext.Response.ContentType);
diagnosticContext.Set("TokenUserRealName", httpContext?.User?.FindFirst("realName")?.Value);
diagnosticContext.Set("TokenUserRealName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.RealName)?.Value);
diagnosticContext.Set("TokenUserType", httpContext?.User?.FindFirst("userTypeEnumName")?.Value);
diagnosticContext.Set("TokenUserTypeShortName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value);
// Retrieve the IEndpointFeature selected for the request
var endpoint = httpContext.GetEndpoint();
@@ -50,7 +50,8 @@ namespace IRaCIS.Core.API
//triggerOptions.AddTrigger<AddlTrialUserTrigger>();
triggerOptions.AddTrigger<VisitTaskIsFrontTaskNeedSignButNotSignTrigger>();
triggerOptions.AddTrigger<VisitTaskIAfterSignTrigger>();
triggerOptions.AddTrigger<UserLogTrigger>();
});
@@ -26,24 +26,26 @@ namespace IRaCIS.Core.API
//控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning,
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3} ] {LocalIP} {ClientIp} {TokenUserRealName} {TokenUserType} {Message:lj} {Properties:j}{NewLine} {Exception}")
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}")
.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day,
outputTemplate: "{Timestamp:HH:mm:ss} || {Level} || {SourceContext:l} || {Message} ||{Exception} ||end {NewLine}");
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}");
//.WriteTo.MSSqlServer("Data Source=DESKTOP-4TU9A6M;Initial Catalog=CoreFrame;User ID=sa;Password=123456", "logs", autoCreateSqlTable: true, restrictedToMinimumLevel: LogEventLevel.Information)//从左至右四个参数分别是数据库连接字符串、表名、如果表不存在是否创建、最低等级。Serilog会默认创建一些列。
if (environment == "Production")
{
config.WriteTo.Email(new EmailConnectionInfo()
{
EmailSubject = "系统警告,请速速查看!",//邮件标题
FromEmail = "test@extimaging.com",//发件人邮箱
MailServer = "smtp.qiye.aliyun.com",//smtp服务器地址
NetworkCredentials = new NetworkCredential("test@extimaging.com", "SHzyyl2021"),//两个参数分别是发件人邮箱与客户端授权码
Port = 465,//端口号
ToEmail = "872297557@qq.com"//收件人
}, restrictedToMinimumLevel: LogEventLevel.Error,
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [ {Level} {ClientIp} {ClientAgent} {TokenUserRealName} {TokenUserType} ] || [path: {RequestPath} arguments: {RequestBody}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine})");
}
//if (environment == "Production")
//{
// config.WriteTo.Email(new EmailConnectionInfo()
// {
// EmailSubject = "系统警告,请速速查看!",//邮件标题
// FromEmail = "test@extimaging.com",//发件人邮箱
// MailServer = "smtp.qiye.aliyun.com",//smtp服务器地址
// NetworkCredentials = new NetworkCredential("test@extimaging.com", "SHzyyl2021"),//两个参数分别是发件人邮箱与客户端授权码
// Port = 465,//端口号
// ToEmail = "872297557@qq.com"//收件人
// }, restrictedToMinimumLevel: LogEventLevel.Error,
// outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [ {Level} {ClientIp} {ClientAgent} {TokenUserRealName} {TokenUserType} ] || [path: {RequestPath} arguments: {RequestBody}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine})");
//}
//扩展方法 获取上下文的ip 用户名 用户类型
Log.Logger = config.Enrich.WithHttpContextInfo(serviceProvider).CreateLogger();
+4 -2
View File
@@ -30,8 +30,10 @@
},
"ConnectionStrings": {
"RemoteNew": "Server=47.117.165.18,1434;Database=Prod_Study;User ID=sa;Password=WHxckj@2019;TrustServerCertificate=true",
"Hangfire": "Server=47.117.165.18,1434;Database=Prod_Study.hangfire;User ID=sa;Password=WHxckj@2019;TrustServerCertificate=true"
//"RemoteNew": "Server=47.117.165.18,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=zhanying@2021;TrustServerCertificate=true",
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_Study;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_Study_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
},
"BasicSystemConfig": {
+18 -8
View File
@@ -20,18 +20,28 @@
},
"MinIO": {
"endpoint": "http://192.168.3.68",
"port": "8001",
"endPoint": "123.56.94.154",
"port": "9001",
"useSSL": true,
"accessKey": "fbStsVYCIPKHQneeqMwD",
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"bucketName": "study-test",
"viewEndpoint": "http://study.test.extimaging.com/oss/study-test"
},
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": false,
"accessKey": "IDFkwEpWej0b4DtiuThL",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
"bucketName": "test"
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
"secretKey": "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",
"bucketName": "ei-irc-test-store",
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=Test.Study;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true",
"Hangfire": "Server=123.56.94.154,1433\\MSSQLSERVER;Database=Test.Study.hangfire;User ID=sa;Password=dev123456DEV;TrustServerCertificate=true"
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_Study;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=106.14.89.110,1435;Database=Test_Study_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"BasicSystemConfig": {
@@ -55,7 +65,7 @@
"FromName": "Test_Study",
"AuthorizationCode": "zhanying123",
"SiteUrl": "http://test.study.extimaging.com/login"
"SiteUrl": "http://study.test.extimaging.com/login"
}
}
+1 -1
View File
@@ -53,7 +53,7 @@
"FromEmail": "uat-study@extimaging.com",
"FromName": "Uat_Study",
"AuthorizationCode": "zhanying123",
"SiteUrl": "http://uat.study.extimaging.com/login"
"SiteUrl": "http://study.uat.extimaging.com/login"
}
}
@@ -31,7 +31,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -28,7 +28,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -18,7 +18,7 @@
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -14,7 +14,7 @@
Thank you for using our IRC imaging system.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
{0}
{0}.
</div>
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
@@ -42,7 +42,7 @@
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -43,7 +43,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -40,7 +40,7 @@
</a>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -8,7 +8,7 @@
<div style='padding-left: 40px;background: #f6f6f6;font-size: 16px'>
<div style='padding-top: 20px;font-size: 16px'>
<div style='line-height: 40px;font-size: 16px'>
Dear {0} ,
Dear {0} ,
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
The site survey questionnaire you filled in has been rejected. Details are as follows:
@@ -43,7 +43,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -43,7 +43,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -8,17 +8,17 @@
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
亲爱的用户 ,
Hello {0},
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
感谢您使用展影云平台。
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{0},验证码是: {1},请在3分钟内输入该验证码,进行后续操作。如非本人操作,请忽略该邮件。
{1},验证码是: {2},请在3分钟内输入该验证码,进行后续操作。如非本人操作,请忽略该邮件。
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -8,13 +8,13 @@
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 16px'>
Dear Sir or Madam:
Hello {0},
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
Thank you for using our imaging system.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
{0}, the verification code is {1}. Please enter this code within 3 minutes for follow-up operations.
{1}, the verification code is {2}. Please enter this code within 3 minutes for follow-up operations.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
If you are not the intended person, please ignore this email.
@@ -32,8 +32,10 @@ namespace IRaCIS.Core.Application.Filter
if (context.Exception.GetType() == typeof(BusinessValidationFailedException))
{
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message,ApiResponseCodeEnum.BusinessValidationFailed));
}
var error = context.Exception as BusinessValidationFailedException;
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, error!.Code));
}
else if(context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException))
{
context.Result = new JsonResult(ResponseOutput.NotOk( context.Exception.Message, ApiResponseCodeEnum.DataNotExist));
@@ -16,6 +16,7 @@ using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using SkiaSharp;
using System.Collections;
using System.IO;
namespace IRaCIS.Core.Application.Service;
@@ -52,21 +53,24 @@ public static class ExcelExportHelper
var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());
var dic = (JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull())).IfNullThrowException();
var dic = data.ConvertToDictionary();
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 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)
@@ -74,7 +78,7 @@ public static class ExcelExportHelper
//翻译的属性依赖其他属性
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();
@@ -232,29 +236,30 @@ public static class ExcelExportHelper
var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());
var dic = (JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull())).IfNullThrowException();
var dic = data.ConvertToDictionary();
//var dic = (JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull())).IfNullThrowException();
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 no = 1;
foreach (var item in dic[key] as JArray)
foreach (var item in dic[key] as IList)
//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)
{
//翻译的属性依赖其他属性
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();
@@ -142,8 +142,9 @@ public static class FileStoreHelper
//API vue 部署目录
public static string GetIRaCISRootPath(IWebHostEnvironment _hostEnvironment)
{
var rootPath = (Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\'))).IfNullThrowException().FullName;
return rootPath;
string parentDirectory = Path.GetFullPath(Path.Combine(_hostEnvironment.ContentRootPath, ".."));
return parentDirectory;
}
@@ -163,7 +164,7 @@ public static class FileStoreHelper
{
var rootPath = GetIRaCISRootPath(_hostEnvironment);
var physicalFilePath = Path.Combine(rootPath, relativePath.Trim('/'));
var physicalFilePath = Path.Combine(rootPath, relativePath.TrimStart('/'));
return physicalFilePath;
}
+186 -50
View File
@@ -3,6 +3,8 @@ using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Infrastructure;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Minio.DataModel.Args;
using Minio;
using NPOI.HPSF;
using SharpCompress.Common;
using System;
@@ -13,17 +15,24 @@ using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
using SkiaSharp;
namespace IRaCIS.Core.Application.Helper
{
public class MinIOOptions
public class MinIOOptions : AWSOptions
{
public string endpoint { get; set; }
public string port { get; set; }
public int port { get; set; }
}
public class AWSOptions
{
public string endPoint { get; set; }
public bool useSSL { get; set; }
public string accessKey { get; set; }
public string secretKey { get; set; }
public string bucketName { get; set; }
public string viewEndpoint { get; set; }
}
public class AliyunOSSOptions
@@ -48,6 +57,8 @@ namespace IRaCIS.Core.Application.Helper
public AliyunOSSOptions AliyunOSS { get; set; }
public MinIOOptions MinIO { get; set; }
public AWSOptions AWS { get; set; }
}
public class ObjectStoreDTO
@@ -58,6 +69,8 @@ namespace IRaCIS.Core.Application.Helper
public MinIOOptions MinIO { get; set; }
public AWSOptions AWS { get; set; }
}
public class AliyunOSSTempToken
@@ -81,76 +94,110 @@ namespace IRaCIS.Core.Application.Helper
AWS = 2,
}
public interface IOSSService
{
public string UploadToOSS(Stream fileStream, string oosFolderPath, string fileRealName);
public string UploadToOSS(string localFilePath, string oosFolderPath);
public Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName);
public Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath);
public void DownLoadFromOSS(string ossRelativePath, string localFilePath);
public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath);
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
}
public class OSSService : IOSSService
{
public AliyunOSSOptions _OSSConfig { get; set; }
public OssClient _ossClient { get; set; }
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
public OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options)
{
var ossOptions = options.CurrentValue;
_OSSConfig = ossOptions.AliyunOSS;
_ossClient = new OssClient(_OSSConfig.endPoint, _OSSConfig.accessKeyId, _OSSConfig.accessKeySecret);
ObjectStoreServiceOptions = options.CurrentValue;
}
/// <summary>
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
/// 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)
public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName)
{
var ossRelativePath = oosFolderPath + "/" + fileRealName;
try
var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}";
//var ossRelativePath = oosFolderPath + "/" + fileRealName;
using (var memoryStream = new MemoryStream())
{
using (var memoryStream = new MemoryStream())
fileStream.Seek(0, SeekOrigin.Begin);
fileStream.CopyTo(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
fileStream.Seek(0, SeekOrigin.Begin);
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
fileStream.CopyTo(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
// 上传文件
var result = _ossClient.PutObject(_OSSConfig.bucketName, ossRelativePath, memoryStream);
var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, memoryStream);
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{
var minIOConfig = ObjectStoreServiceOptions.MinIO;
return "/" + ossRelativePath;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
var putObjectArgs = new PutObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithStreamData(memoryStream)
.WithObjectSize(memoryStream.Length);
await minioClient.PutObjectAsync(putObjectArgs);
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
var minIOConfig = ObjectStoreServiceOptions.AWS;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
var putObjectArgs = new PutObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithStreamData(memoryStream)
.WithObjectSize(memoryStream.Length);
await minioClient.PutObjectAsync(putObjectArgs);
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
}
catch (Exception ex)
{
throw new BusinessValidationFailedException("oss上传失败" + ex.Message);
}
return "/" + ossRelativePath;
}
/// <summary>
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
/// </summary>
@@ -158,38 +205,124 @@ namespace IRaCIS.Core.Application.Helper
/// <param name="oosFolderPath"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public string UploadToOSS(string localFilePath, string oosFolderPath)
public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath)
{
var localFileName = Path.GetFileName(localFilePath);
var ossRelativePath = oosFolderPath + "/" + localFileName;
var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}";
//var ossRelativePath = oosFolderPath + "/" + localFileName;
try
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
// 上传文件
var result = _ossClient.PutObject(_OSSConfig.bucketName, ossRelativePath, localFilePath);
var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, localFilePath);
return ossRelativePath;
}
catch (Exception ex)
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{
throw new BusinessValidationFailedException("oss上传失败" + ex.Message);
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
var putObjectArgs = new PutObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithFileName(localFilePath);
await minioClient.PutObjectAsync(putObjectArgs);
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
var minIOConfig = ObjectStoreServiceOptions.AWS;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
var putObjectArgs = new PutObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithFileName(localFilePath);
await minioClient.PutObjectAsync(putObjectArgs);
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
return "/" + ossRelativePath;
}
public void DownLoadFromOSS(string ossRelativePath, string localFilePath)
public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath)
{
ossRelativePath = ossRelativePath.TrimStart('/');
try
{
var result = _ossClient.GetObject(_OSSConfig.bucketName, ossRelativePath);
// 将下载的文件流保存到本地文件
using (var fs = File.OpenWrite(localFilePath))
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
result.Content.CopyTo(fs);
fs.Close();
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
// 上传文件
var result = _ossClient.GetObject(aliConfig.bucketName, ossRelativePath);
// 将下载的文件流保存到本地文件
using (var fs = File.OpenWrite(localFilePath))
{
result.Content.CopyTo(fs);
fs.Close();
}
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
var getObjectArgs = new GetObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithFile(localFilePath);
await minioClient.GetObjectAsync(getObjectArgs);
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
var minIOConfig = ObjectStoreServiceOptions.AWS;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
var getObjectArgs = new GetObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithFile(localFilePath);
await minioClient.GetObjectAsync(getObjectArgs);
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
}
catch (Exception ex)
@@ -199,6 +332,9 @@ namespace IRaCIS.Core.Application.Helper
}
}
@@ -77,6 +77,7 @@
<PackageReference Include="fo-dicom.Codecs" Version="5.10.8" />
<PackageReference Include="FreeSpire.Doc" Version="11.6.0" />
<PackageReference Include="Hangfire.Core" Version="1.8.5" />
<PackageReference Include="IP2Region.Net" Version="2.0.2" />
<PackageReference Include="Magicodes.IE.Core" Version="2.7.4.5" />
<PackageReference Include="Magicodes.IE.Csv" Version="2.7.4.5">
<TreatAsUsed>true</TreatAsUsed>
@@ -89,6 +90,7 @@
<PackageReference Include="MediatR" Version="12.1.1" />
<PackageReference Include="MimeKit" Version="4.2.0" />
<PackageReference Include="MiniExcel" Version="1.31.2" />
<PackageReference Include="Minio" Version="6.0.1" />
<PackageReference Include="MiniWord" Version="0.7.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.0.0">
<TreatAsUsed>true</TreatAsUsed>
@@ -106,4 +108,10 @@
<ProjectReference Include="..\IRaCIS.Core.Infra.EFCore\IRaCIS.Core.Infra.EFCore.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="Resources\ip2region.xdb">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
@@ -94,17 +94,16 @@
<param name="type"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Helper.OSSService.UploadToOSS(System.IO.Stream,System.String,System.String)">
<member name="M:IRaCIS.Core.Application.Helper.OSSService.UploadToOSSAsync(System.IO.Stream,System.String,System.String)">
<summary>
oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
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)">
<member name="M:IRaCIS.Core.Application.Helper.OSSService.UploadToOSSAsync(System.String,System.String)">
<summary>
oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
</summary>
@@ -548,6 +547,32 @@
InternationalizationService
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Service.InternationalizationService.GetFrontInternationalizationList">
<summary>
前端国际化内容接口
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.InternationalizationService.BatchAddOrUpdateFrontInternationalization(System.Collections.Generic.List{IRaCIS.Core.Application.ViewModel.BatchInternationalizationDto})">
<summary>
前端批量提交,后端判断不存在就添加,存在就更新
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.InternationalizationService.BatchAddInternationalization(IRaCIS.Core.Application.ViewModel.BatchAddInternationalization)">
<summary>
后端之前批量添加接口
</summary>
<param name="batchAdd"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.InternationalizationService.AddOrUpdateInternationalization(IRaCIS.Core.Application.ViewModel.InternationalizationAddOrEdit)">
<summary>
前后端添加的时候,区分了,前端判断重复多了多了一个路由 路由+标识唯一
</summary>
<param name="addOrEditInternationalization"></param>
<returns></returns>
</member>
<member name="T:IRaCIS.Core.Application.Service.PublishLogService">
<summary>
PublishLogService
@@ -953,7 +978,7 @@
<param name="currentInspectionId"></param>
<returns></returns>
</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,System.String)">
<summary>
格式化日期和时间
</summary>
@@ -961,7 +986,7 @@
<param name="jsonStr"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.GetInspectionEnumValue(System.Collections.Generic.List{System.String},System.String)">
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.GetInspectionEnumValue(System.Collections.Generic.List{System.String},System.String,System.String)">
<summary>
获取外键表数据
</summary>
@@ -969,7 +994,7 @@
<param name="jsonStr"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.SetEnum(System.Guid,System.Collections.Generic.List{System.String},System.String)">
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.SetEnum(System.Guid,System.Collections.Generic.List{System.String},System.String,System.String)">
<summary>
获取枚举
</summary>
@@ -4496,6 +4521,11 @@
是否是第一次转化的任务
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetRelatedVisitTaskOutDto.IsExistsClinicalData">
<summary>
是否存在临床数据
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetGlobalReadingInfoInDto.UsingOriginalData">
<summary>
当新答案为空的时候 是否是有原数据
@@ -5886,6 +5916,11 @@
限制编辑
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionTrialAddOrEdit.LimitShow">
<summary>
限制显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionTrialAddOrEdit.MaxAnswerLength">
<summary>
最大答案长度
@@ -5964,6 +5999,11 @@
限制编辑
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionSystemAddOrEdit.LimitShow">
<summary>
限制显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionSystemAddOrEdit.MaxAnswerLength">
<summary>
最大答案长度
@@ -6307,6 +6347,11 @@
限制编辑
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionTrialView.LimitShow">
<summary>
限制显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionTrialView.MaxAnswerLength">
<summary>
最大答案长度
@@ -6357,6 +6402,11 @@
限制编辑
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionSystemView.LimitShow">
<summary>
限制显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionSystemView.MaxAnswerLength">
<summary>
最大答案长度
@@ -6692,6 +6742,11 @@
限制编辑
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionSystemInDto.LimitShow">
<summary>
限制显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionSystemInDto.MaxAnswerLength">
<summary>
最大答案长度
@@ -7017,6 +7072,11 @@
限制编辑
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionTrialInDto.LimitShow">
<summary>
限制显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionTrialInDto.MaxAnswerLength">
<summary>
最大答案长度
@@ -12414,6 +12474,12 @@
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Application.Services.TestService.OldLocalImageResizeJpg(IRaCIS.Core.Application.Helper.IOSSService,IRaCIS.Core.Infra.EFCore.IRepository,Microsoft.AspNetCore.Hosting.IWebHostEnvironment)">
<summary>
维护OSS 影像数据
</summary>
<returns></returns>
</member>
<member name="T:IRaCIS.Application.Contracts.DoctorSearchDTO">
<summary>
Reviewer 列表查询参数
Binary file not shown.
@@ -56,9 +56,15 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid SiteId { get; set; }
public string BlindTrialSiteCode { get; set; }
public String TrialSiteCode { get; set; } = String.Empty;
public string SubjectCode { get; set; } = String.Empty;
public string MedicalNo { get; set; } = string.Empty;
public string BlindSubjectCode { get; set; } = string.Empty;
public bool IsPMSetBack { get; set; }
@@ -358,7 +364,10 @@ namespace IRaCIS.Core.Application.ViewModel
{
public Guid TrialId { get; set; }
public Guid TrialReadingCriterionId { get; set; }
public Guid? SubjectId { get; set; }
public Guid TrialReadingCriterionId { get; set; }
public string? SubjectCode { get; set; } = null;
@@ -431,6 +440,7 @@ namespace IRaCIS.Core.Application.ViewModel
public DateTime? LatestReplyTimeBegin { get; set; }
public DateTime? LatestReplyTimeEnd { get; set; }
public string? RequestReReadingReason { get; set; }
}
public class PIAuditTaskEnrollOrPdCommand
@@ -280,12 +280,12 @@ namespace IRaCIS.Core.Application.Service
var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated;
}
await _visitTaskRepository.SaveChangesAsync();
}
}
await _visitTaskRepository.SaveChangesAsync();
}
@@ -549,6 +549,7 @@ namespace IRaCIS.Core.Application.Service
var isNeedClinicalDataSign = IsNeedClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionId, clinicalDataConfirmList);
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)
{
@@ -590,7 +591,8 @@ namespace IRaCIS.Core.Application.Service
TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId,
IsNeedClinicalDataSign = isNeedClinicalDataSign,
IsClinicalDataSign = isClinicalDataSign
IsClinicalDataSign = isClinicalDataSign,
IsFrontTaskNeedSignButNotSign= isFrontTaskNeedSignButNotSign
});
@@ -26,6 +26,7 @@ using IRaCIS.Application.Services.BackGroundJob;
using Magicodes.ExporterAndImporter.Core.Extension;
using Hangfire;
using MassTransit;
using static IRaCIS.Core.Domain.Models.ReadingQuestionTrial;
namespace IRaCIS.Core.Application.Service.Allocation
{
@@ -103,7 +104,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
var list = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId && t.IsConfirm)
.OrderBy(t => t.ShowOrder)
.Select(t => new TrialReadingCriterionDto() { TrialReadingCriterionId = t.Id, IsAutoCreate = t.IsAutoCreate, IsAdditionalAssessment = t.IsAdditionalAssessment, TrialReadingCriterionName = t.CriterionName, CriterionType = t.CriterionType, ReadingType = t.ReadingType, ReadingInfoSignTime = t.ReadingInfoSignTime })
.Select(t => new TrialReadingCriterionDto() { TrialReadingCriterionId = t.Id, IsAutoCreate = t.IsAutoCreate, IsAdditionalAssessment = t.IsAdditionalAssessment, TrialReadingCriterionName = t.CriterionName, CriterionType = t.CriterionType, ReadingType = t.ReadingType, ReadingInfoSignTime = t.ReadingInfoSignTime , IsReadingPeriod= t.IsReadingPeriod })
.ToListAsync();
return list.AsQueryable().WhereIf(isHaveSigned == true, t => t.ReadingInfoSignTime != null)
@@ -209,8 +210,8 @@ namespace IRaCIS.Core.Application.Service.Allocation
.WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
.WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1))
.WhereIf(trialConfig?.EnrollConfirmDefaultUserType == UserTypeEnum.MIM && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM, t => t.SourceSubjectVisit.IsBaseLine == true)
.WhereIf(trialConfig?.PDProgressDefaultUserType == UserTypeEnum.MIM && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM, t => t.SourceSubjectVisit.IsBaseLine == false)
.WhereIf(trialConfig?.EnrollConfirmDefaultUserType == UserTypeEnum.MIM && trialConfig?.PDProgressDefaultUserType != UserTypeEnum.MIM && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM , t => t.SourceSubjectVisit.IsBaseLine == true)
.WhereIf(trialConfig?.EnrollConfirmDefaultUserType != UserTypeEnum.MIM && trialConfig?.PDProgressDefaultUserType == UserTypeEnum.MIM && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM, t => t.SourceSubjectVisit.IsBaseLine == false)
.WhereIf(queryVisitTask.IsWaitPIAudit == true, t => t.FirstAuditUserId == null)
.WhereIf(queryVisitTask.IsWaitPIAudit == false, t => t.FirstAuditUserId != null)
.WhereIf(queryVisitTask.PIAuditState != null, t => t.PIAuditState == queryVisitTask.PIAuditState)
@@ -226,6 +227,8 @@ namespace IRaCIS.Core.Application.Service.Allocation
public async Task<IResponseOutput<PageOutput<PIReaingTaskView>>> GetPIReadingAuditList(VisitTaskQuery queryVisitTask)
{
//CriterionType? criterionType = _trialReadingCriterionRepository.Where(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t=>t.CriterionType).FirstOrDefault();
var visitTaskQueryable = GetReadingTaskQueryable(queryVisitTask)
.ProjectTo<PIReaingTaskView>(_mapper.ConfigurationProvider);
@@ -237,6 +240,8 @@ namespace IRaCIS.Core.Application.Service.Allocation
var questionList = _readingQuestionTrialRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.ReadingQuestionCriterionTrialId == queryVisitTask.TrialReadingCriterionId)
.Where(t => t.IsJudgeQuestion == true)
//.WhereIf(criterionType!=null&& criterionType!=CriterionType.SelfDefine,t=>t.IsJudgeQuestion==true)
// .WhereIf(criterionType != null && criterionType == CriterionType.SelfDefine, t => t.AssessmentResultEnum == AssessmentResultType.AssessmentResult)
.Select(t => new { QuestionId = t.Id, QuestionName = _userInfo.IsEn_Us ? t.QuestionEnName : t.QuestionName ,t.DictionaryCode}).ToList();
trialTaskConfig!.OtherObj = questionList;
@@ -418,6 +423,8 @@ namespace IRaCIS.Core.Application.Service.Allocation
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == queryVisitTask.ReadingCategory)
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.RequestReReadingReason), t => t.RequestReReadingReason.Contains(queryVisitTask.RequestReReadingReason))
.WhereIf(queryVisitTask.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == queryVisitTask.RequestReReadingResultEnum)
.WhereIf(queryVisitTask.PIAuditState != null, t => t.OriginalReReadingTask.PIAuditState == queryVisitTask.PIAuditState)
@@ -647,7 +654,6 @@ namespace IRaCIS.Core.Application.Service.Allocation
{
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);
@@ -657,39 +663,40 @@ namespace IRaCIS.Core.Application.Service.Allocation
var visitQuery = _visitTaskRepository
.Where(x => x.TrialId == inDto.TrialId && x.TaskState == TaskState.Effect)
//PI 读基线的时候,subject 如果PI基线没阅片完,SR就不能看
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline,
.WhereIf(inDto.SubjectId!=null,t=>t.SubjectId==inDto.SubjectId)
//PI 读基线的时候,subject 如果PI基线没阅片完,SR就不能看
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline && readingDivisionEnum == ReadingDivisionEnum.PIandSR,
t => t.Subject.SubjectVisitTaskList.Any(c => c.SourceSubjectVisit.IsBaseLine == true && c.ReadingTaskState == ReadingTaskState.HaveSigned && c.TaskState == TaskState.Effect && c.TrialReadingCriterionId == trialReadingCriterionId))
//PI 读随访的时候, subject 如果SR基线没阅片完,PI就不能看
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllVisit,
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllVisit && readingDivisionEnum == ReadingDivisionEnum.PIandSR,
t => t.Subject.SubjectVisitTaskList.Any(c => c.SourceSubjectVisit.IsBaseLine == true && c.ReadingTaskState == ReadingTaskState.HaveSigned && c.TaskState == TaskState.Effect && c.TrialReadingCriterionId == trialReadingCriterionId))
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR, t => t.Subject.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id))
// 仅仅SR阅片 PI 没有任务列表
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.OnlySR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI, t => t.TrialId == Guid.Empty)
//PI查看 PI阅片所有基线
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline,
t => t.SourceSubjectVisit.IsBaseLine == true)
//PI 阅片所有
// PI查看 PI 阅片所有
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllBaselineandVisit,
t => true)
// PI查看 PI 阅片访视
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllVisit,
t => t.SourceSubjectVisit.IsBaseLine == false)
//SR查看 PI阅片所有基线
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline,
t => t.SourceSubjectVisit.IsBaseLine == false)
//SR 不阅片
//SR查看 PI 阅片所有
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaselineandVisit,
t => t.TrialId == Guid.Empty)
//SR查看 PI 阅片访视
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllVisit,
t => t.SourceSubjectVisit.IsBaseLine == true)
@@ -1548,7 +1555,10 @@ namespace IRaCIS.Core.Application.Service.Allocation
#region
var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault();
//var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault();
var origenalTask = await _visitTaskRepository.FindAsync(task.Id);
foreach (var influenceTask in influenceTaskList)
{
@@ -1611,7 +1621,9 @@ namespace IRaCIS.Core.Application.Service.Allocation
await SetMedicalReviewInvalidAsync(currentVisitList);
var origenalTask = currentVisitList.Where(t => t.Id == task.Id).First();
//var origenalTask = currentVisitList.Where(t => t.Id == task.Id).First();
var origenalTask = await _visitTaskRepository.FindAsync(task.Id);
foreach (var influenceTask in currentVisitList)
{
@@ -4,6 +4,7 @@ using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using static IRaCIS.Core.Domain.Models.ReadingQuestionTrial;
namespace IRaCIS.Core.Application.Service
{
@@ -63,8 +64,10 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.SiteId, t => t.MapFrom(u => u.Subject.SiteId))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindTrialSiteCode :*/ u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindSubjectCode :*/ u.Subject.Code))
.ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.Subject.MedicalNo))
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
@@ -83,7 +86,8 @@ namespace IRaCIS.Core.Application.Service
CreateMap<VisitTask, ReadingTaskView>().IncludeBase<VisitTask, VisitTaskView>()
.ForMember(t=>t.PIReadingResultList,u=>u.MapFrom(c=>c.ReadingTaskQuestionAnswerList
.Where(t=>t.ReadingQuestionTrial.IsJudgeQuestion==true ).Select(d=>new PIReadingResult() { QuestionId= d.ReadingQuestionTrialId,Answer=d.Answer})));
.Where(t=> /*t.ReadingQuestionCriterionTrial.CriterionType==CriterionType.SelfDefine? t.ReadingQuestionTrial.AssessmentResultEnum == AssessmentResultType.AssessmentResult:*/ t.ReadingQuestionTrial.IsJudgeQuestion==true)
.Select(d=>new PIReadingResult() { QuestionId= d.ReadingQuestionTrialId,Answer=d.Answer})));
CreateMap<VisitTask, PIReaingTaskView>().IncludeBase<VisitTask, ReadingTaskView>()
.ForMember(o => o.FirstAuditUserName, t => t.MapFrom(u => u.FirstAuditUser.UserName))
@@ -165,13 +169,13 @@ namespace IRaCIS.Core.Application.Service
CreateMap<VisitTask, TaskMedicalReviewView>()
.ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code));
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u =>/* u.IsAnalysisCreate == true ? u.BlindTrialSiteCode :*/ u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindSubjectCode :*/ u.Subject.Code));
CreateMap<VisitTask, GenerateMedicalReviewTaskView>()
.ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindTrialSiteCode :*/ u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindSubjectCode :*/ u.Subject.Code))
.ForMember(o => o.GeneratedMedicalReviewCount, t => t.MapFrom(u => u.TaskMedicalReviewList.Count()))
.ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.Subject.MedicalNo))
.ForMember(o => o.IsGeneratedJudge, t => t.MapFrom(u => u.JudgeVisitTaskId != null))
@@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Application.Contracts;
namespace IRaCIS.Core.Application.Service
{
@@ -99,14 +100,36 @@ namespace IRaCIS.Core.Application.Service
//---读取模板内容失败, 请将文件另存为docx格式尝试!
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();
}
}
@@ -114,7 +137,20 @@ namespace IRaCIS.Core.Application.Service
[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();
}
@@ -42,6 +42,8 @@ namespace IRaCIS.Core.Application.ViewModel
public string Value { get; set; } = string.Empty;
public string ValueCN { get; set; } = string.Empty;
public string FrontType { get; set; } = string.Empty;
public int InternationalizationType { get; set; }
}
@@ -55,19 +57,23 @@ namespace IRaCIS.Core.Application.ViewModel
}
public class BatchAddInternationalizationDto
public class BatchInternationalizationDto
{
public string Description { get; set; } = string.Empty;
public string Code { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
public string FrontType { get; set; } = string.Empty;
public string ValueCN { get; set; } = string.Empty;
}
public class InternationalizationSimpleDto
public class BatchAddInternationalizationDto : BatchInternationalizationDto
{
public string Code { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
public string ValueCN { get; set; } = string.Empty;
}
public class InternationalizationSimpleDto: BatchInternationalizationDto
{
}
}
@@ -755,6 +755,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null)
.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
@@ -10,6 +10,9 @@ using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Helper;
using EasyCaching.Core;
using IRaCIS.Core.Domain.Share;
using OfficeOpenXml.FormulaParsing.Utilities;
namespace IRaCIS.Core.Application.Service
{
@@ -19,28 +22,77 @@ namespace IRaCIS.Core.Application.Service
[ApiExplorerSettings(GroupName = "Common")]
public class InternationalizationService : BaseService, IInternationalizationService
{
private readonly IEasyCachingProvider _provider;
private readonly IRepository<Internationalization> _internationalizationRepository;
public InternationalizationService(IRepository<Internationalization> internationalizationRepository)
public InternationalizationService(IRepository<Internationalization> internationalizationRepository, IEasyCachingProvider provider)
{
_internationalizationRepository = internationalizationRepository;
_provider = provider;
}
/// <summary>
/// 前端国际化内容接口
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public async Task<List<InternationalizationSimpleDto>> GetFrontInternationalizationList()
[HttpGet]
public async Task<IEnumerable<InternationalizationSimpleDto>> GetFrontInternationalizationList()
{
var cacheList= _provider.Get<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front).Value;
var list = await _internationalizationRepository.Where(t => t.InternationalizationType == 0).Select(t => new InternationalizationSimpleDto()
if(cacheList != null && cacheList.Count!=0)
{
Code = t.Code,
Value = t.Value,
ValueCN = t.ValueCN
}).ToListAsync();
return cacheList;
}
else
{
var list = await _internationalizationRepository.Where(t => t.InternationalizationType == 0).Select(t => new InternationalizationSimpleDto()
{
Code = t.Code,
Value = t.Value,
ValueCN = t.ValueCN,
FrontType = t.FrontType,
Description = t.Description,
}).ToListAsync();
return list;
_provider.Set<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front, list, TimeSpan.FromDays(1));
return list;
}
}
/// <summary>
/// 前端批量提交,后端判断不存在就添加,存在就更新
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public async Task<IResponseOutput> BatchAddOrUpdateFrontInternationalization(List<BatchInternationalizationDto> batchList)
{
foreach (var item in batchList)
{
var find = await _internationalizationRepository.FirstOrDefaultAsync(t => t.Code == item.Code && t.Description == item.Description && t.InternationalizationType == 0);
if (find != null)
{
_mapper.Map(item, find);
}
else
{
var mapItem = _mapper.Map<Internationalization>(item);
mapItem.InternationalizationType = 0;
mapItem.State = 1;
await _internationalizationRepository.AddAsync(mapItem);
}
}
await _internationalizationRepository.SaveChangesAsync();
//清理缓存
_provider.Set<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front, new List<InternationalizationSimpleDto>(), TimeSpan.FromDays(1));
return ResponseOutput.Ok();
}
[HttpPost]
@@ -63,6 +115,11 @@ namespace IRaCIS.Core.Application.Service
return pageList;
}
/// <summary>
/// 后端之前批量添加接口
/// </summary>
/// <param name="batchAdd"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> BatchAddInternationalization(BatchAddInternationalization batchAdd)
{
@@ -87,21 +144,39 @@ namespace IRaCIS.Core.Application.Service
await _internationalizationRepository.SaveChangesAsync();
//清理缓存
_provider.Set<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front, new List<InternationalizationSimpleDto>(), TimeSpan.FromDays(1));
return ResponseOutput.Ok();
}
/// <summary>
/// 前后端添加的时候,区分了,前端判断重复多了多了一个路由 路由+标识唯一
/// </summary>
/// <param name="addOrEditInternationalization"></param>
/// <returns></returns>
public async Task<IResponseOutput> AddOrUpdateInternationalization(InternationalizationAddOrEdit addOrEditInternationalization)
{
var internationalizationType = addOrEditInternationalization.InternationalizationType;
//后端验证标识重复与否
var verifyExp1 = new EntityVerifyExp<Internationalization>()
{
VerifyExp = t => t.Code == addOrEditInternationalization.Code && t.InternationalizationType == addOrEditInternationalization.InternationalizationType,
VerifyMsg = $"该类型已有{addOrEditInternationalization.Code}名称的国际化标识",
IsVerify = true
IsVerify = internationalizationType == 1
};
var entity = await _internationalizationRepository.InsertOrUpdateAsync(addOrEditInternationalization, true, verifyExp1);
//前端验证标识重复与否
var verifyExp2 = new EntityVerifyExp<Internationalization>()
{
VerifyExp = t => t.Code == addOrEditInternationalization.Code && t.InternationalizationType == addOrEditInternationalization.InternationalizationType && t.Description == addOrEditInternationalization.Description,
VerifyMsg = $"该类型已有{addOrEditInternationalization.Description}下的{addOrEditInternationalization.Code}名称的国际化标识",
IsVerify = internationalizationType == 0
};
var entity = await _internationalizationRepository.InsertOrUpdateAsync(addOrEditInternationalization, true, verifyExp1, verifyExp2);
if (addOrEditInternationalization.InternationalizationType == 1)
{
@@ -109,6 +184,9 @@ namespace IRaCIS.Core.Application.Service
}
//清理缓存
_provider.Set<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front, new List<InternationalizationSimpleDto>(), TimeSpan.FromDays(1));
return ResponseOutput.Ok(entity.Id.ToString());
}
@@ -118,6 +196,9 @@ namespace IRaCIS.Core.Application.Service
public async Task<IResponseOutput> DeleteInternationalization(Guid internationalizationId)
{
var success = await _internationalizationRepository.DeleteFromQueryAsync(t => t.Id == internationalizationId, true);
//清理缓存
_provider.Set<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front, new List<InternationalizationSimpleDto>(), TimeSpan.FromDays(1));
return ResponseOutput.Ok();
}
@@ -158,7 +158,7 @@ namespace IRaCIS.Application.Services
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
//主题
//---[来自展影IRC] 关于重置密码的提醒
messageToSend.Subject = _localizer["Mail_IRCResettingPassword "];
messageToSend.Subject = _localizer["Mail_IRCResettingPassword"];
@@ -177,8 +177,9 @@ namespace IRaCIS.Application.Services
builder.HtmlBody = string.Format(templateInfo,
"",
//---您正在进行邮箱重置密码操作
_localizer["Mail_ResettingPassword "],
_localizer["Mail_ResettingPassword"],
verificationCode
);
}
@@ -244,6 +245,7 @@ namespace IRaCIS.Application.Services
builder.HtmlBody = string.Format(templateInfo,
"",
//---您正在参与展影医疗IRC项目
_localizer["Mail_IRCProject"],
verificationCode
@@ -310,6 +312,7 @@ namespace IRaCIS.Application.Services
builder.HtmlBody = string.Format(templateInfo,
"",
//---您正在参与展影医疗IRC项目中心调研工作
_localizer["Mail_CenterResearchReminder"],
verificationCode
@@ -74,6 +74,9 @@ namespace IRaCIS.Core.Application.Service
CreateMap<Internationalization, InternationalizationView>();
CreateMap<Internationalization, InternationalizationAddOrEdit>().ReverseMap();
CreateMap<Internationalization, BatchInternationalizationDto>().ReverseMap();
CreateMap<BatchAddInternationalizationDto, InternationalizationAddOrEdit>();
@@ -356,7 +356,7 @@ namespace IRaCIS.Core.Application.Service
.Include(t => t.TrialEmailNoticeUserList).Include(t => t.TrialEmailBlackUserList).FirstOrDefaultAsync();
if (trialEmailConfig == null || trialEmailConfig.IsAutoSend == false)
if (trialEmailConfig == null || trialEmailConfig.IsAutoSend == false || trialEmailConfig.IsEnable==false)
{
return;
}
@@ -477,7 +477,7 @@ namespace IRaCIS.Core.Application.Service
.Include(t => t.TrialEmailNoticeUserList).Include(t => t.TrialEmailBlackUserList).FirstOrDefaultAsync();
if (trialEmailConfig == null || trialEmailConfig.IsAutoSend == false)
if (trialEmailConfig == null || trialEmailConfig.IsAutoSend == false || trialEmailConfig.IsEnable==false)
{
return (null, null);
}
@@ -658,7 +658,7 @@ namespace IRaCIS.Core.Application.Services
/// <param name="isSystemDoc"></param>
/// <returns></returns>
[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)
{
if (isSystemDoc)
@@ -1322,13 +1322,14 @@ namespace IRaCIS.Core.Application.Service
/// </summary>
/// <param name="queryEmailNoticeConfig"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<TrialSelectEmailNoticeConfigView>> GetSysEmailNoticeConfigList(EmailNoticeConfigQuery queryEmailNoticeConfig)
{
var emailNoticeConfigQueryable = _emailNoticeConfigRepository
.WhereIf(queryEmailNoticeConfig.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == queryEmailNoticeConfig.BusinessScenarioEnum)
.WhereIf(queryEmailNoticeConfig.IsReturnRequired != null, t => t.IsReturnRequired == queryEmailNoticeConfig.IsReturnRequired)
.WhereIf(queryEmailNoticeConfig.IsEnable != null, t => t.IsEnable == queryEmailNoticeConfig.IsEnable)
.WhereIf(queryEmailNoticeConfig.CriterionTypeEnum != null, t => t.CriterionTypeEnum == queryEmailNoticeConfig.CriterionTypeEnum)
.ProjectTo<TrialSelectEmailNoticeConfigView>(_mapper.ConfigurationProvider, new { trialId = queryEmailNoticeConfig.TrialId });
return await emailNoticeConfigQueryable.ToPagedListAsync(queryEmailNoticeConfig.PageIndex, queryEmailNoticeConfig.PageSize, queryEmailNoticeConfig.SortField, queryEmailNoticeConfig.Asc);
@@ -30,6 +30,8 @@ namespace IRaCIS.Core.Application.Contracts
public bool IsDeleted { get; set; }
public bool IsReading { get; set; } = true;
public string SliceThickness { get; set; } = String.Empty;
public string ImageResizePath { get; set; }
}
@@ -38,8 +40,8 @@ namespace IRaCIS.Core.Application.Contracts
public class DicomTrialSiteSubjectInfo
{
public string TrialSiteCode { get; set; } = string.Empty;
public string SiteCode { get; set; } = string.Empty;
public string SiteName { get; set; } = string.Empty;
public string TrialSiteAliasName { get; set; } = string.Empty;
public string SubjectCode { get; set; } = string.Empty;
public int? SubjectAge { get; set; }
public string SubjectSex { get; set; } = string.Empty;
@@ -42,6 +42,7 @@ namespace IRaCIS.Core.Application.Contracts
//[JsonIgnore]
//public int NoneDicomCode { get; set; }
public string RecordPath { get; set; } = string.Empty;
public bool IsDicom { get; set; }
}
@@ -173,7 +174,16 @@ namespace IRaCIS.Core.Application.Contracts
public string[]? VisitPlanArray { get; set; }
}
public Guid? VisitTaskId { get; set; }
public bool? IsDicom { get; set; }
public string? Uploader { get; set; }
public bool? IsSuccess { get; set; }
public string? StudyCode { get; set; }
}
public class PreArchiveDicomStudyCommand
@@ -215,6 +225,8 @@ namespace IRaCIS.Core.Application.Contracts
public int FailedFileCount { get; set; }
public string RecordPath { get; set; }
public AddOrUpdateStudyDto Study { get; set; }
@@ -151,7 +151,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
studyMonitor.UploadFinishedTime = DateTime.Now;
studyMonitor.ArchiveFinishedTime = DateTime.Now;
studyMonitor.FailedFileCount = incommand.FailedFileCount;
studyMonitor.IsSuccess = true;
studyMonitor.IsSuccess = incommand.FailedFileCount==0;
studyMonitor.RecordPath=incommand.RecordPath;
//上传
if (studyMonitor.IsDicomReUpload == false)
@@ -209,6 +210,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
series.SubjectId = incommand.SubjectId;
series.SubjectVisitId = incommand.SubjectVisitId;
//前端传递的数量不准,上传的时候,把失败的也加进来了,以实际数组的数字为准
series.InstanceCount = seriesItem.InstanceList.Count;
await _dicomSeriesRepository.AddAsync(series);
foreach (var instanceItem in seriesItem.InstanceList)
@@ -241,6 +245,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var study = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == studyId);
//重传的时候也要赋值检查Id
studyMonitor.StudyId = study.Id;
studyMonitor.StudyCode = study.StudyCode;
//特殊处理逻辑
study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Union(study.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct());
@@ -457,6 +464,10 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
.WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId)
.WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId)
.WhereIf(studyQuery.SiteId != null, t => t.SiteId == studyQuery.SiteId)
.WhereIf(studyQuery.IsDicom != null, t => t.IsDicom == studyQuery.IsDicom )
.WhereIf(!string.IsNullOrWhiteSpace(studyQuery.Uploader), t => t.Uploader.UserName.Contains(studyQuery.Uploader))
.WhereIf(studyQuery.IsSuccess != null, t => t.IsSuccess == studyQuery.IsSuccess)
.WhereIf(!string.IsNullOrWhiteSpace(studyQuery.StudyCode), t => t.StudyCode.Contains(studyQuery.StudyCode))
.Select(t => new UnionStudyMonitorModel()
{
TrialId = t.TrialId,
@@ -489,7 +500,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
ArchiveFinishedTime = t.ArchiveFinishedTime,
RecordPath=t.RecordPath,
IsDicomReUpload = t.IsDicomReUpload,
StudyId = t.Id,
@@ -62,6 +62,7 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.UploadedTime, t => t.MapFrom(u => u.CreateTime))
.ForMember(o => o.Uploader, t => t.MapFrom(u => u.Uploader.LastName + " / " + u.Uploader.FirstName))
.ForMember(o => o.StudyId, t => t.MapFrom(u => u.Id))
.ForMember(o => o.IsHaveUploadFailed, t => t.MapFrom(u => u.DicomStudyMonitorList.Any(t=>t.FailedFileCount>0)))
.ForMember(o => o.Modalities, t => t.MapFrom(u => string.Join('、', u.SeriesList.Select(t => t.Modality).Distinct()) ));
@@ -80,6 +81,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<DicomInstance, DicomInstanceDTO>()
.ForMember(o => o.IsDeleted, t => t.MapFrom(u => u.DicomSerie.IsDeleted))
.ForMember(o => o.SliceThickness, t => t.MapFrom(u => u.DicomSerie.SliceThickness))
.ForMember(o => o.IsReading, t => t.MapFrom(u => u.DicomSerie.IsReading));
CreateMap<DicomStudy, DicomStudyDTO>();
CreateMap<DicomSeries, DicomSeriesDTO>();
@@ -298,7 +298,7 @@ namespace IRaCIS.Core.Application.Service.Inspection.DTO
public T Data { get; set; }
public SignDTO SignInfo { get; set; }
public SignDTO? SignInfo { get; set; }
}
@@ -319,9 +319,9 @@ namespace IRaCIS.Core.Application.Service
{
continue;
}
str = await GetInspectionEnumValue(listIdentification, str);
str = await SetEnum(dto.TrialId, listIdentification, str);
str = await SetDataInspectionDateType(listIdentification, str);
str = await GetInspectionEnumValue(listIdentification, item.Identification, str);
str = await SetEnum(dto.TrialId, listIdentification, item.Identification, str);
str = await SetDataInspectionDateType(listIdentification, item.Identification, str);
jsonDict[nameof(InspectionJsonDetail.Data)] = JsonConvert.DeserializeObject<object>(str);
@@ -331,9 +331,9 @@ namespace IRaCIS.Core.Application.Service
{
continue;
}
str2 = await GetInspectionEnumValue(listIdentification, str2);
str2 = await SetEnum(dto.TrialId, listIdentification, str2);
str2 = await SetDataInspectionDateType(listIdentification, str2);
str2 = await GetInspectionEnumValue(listIdentification, item.Identification, str2);
str2 = await SetEnum(dto.TrialId, listIdentification, item.Identification, str2);
str2 = await SetDataInspectionDateType(listIdentification, item.Identification, str2);
jsonDict[nameof(InspectionJsonDetail.CommonData)] = JsonConvert.DeserializeObject<object>(str2);
#endregion
@@ -456,20 +456,23 @@ namespace IRaCIS.Core.Application.Service
/// <param name="identificationList"></param>
/// <param name="jsonStr"></param>
/// <returns></returns>
private async Task<string> SetDataInspectionDateType(List<string> identificationList, string jsonStr)
private async Task<string> SetDataInspectionDateType(List<string> identificationList,string identification, string jsonStr)
{
var list = await (from parent in _frontAuditConfigRepository.AsQueryable().Where(x => identificationList.Contains(x.Identification))
join child in _frontAuditConfigRepository.AsQueryable().Where(x => x.EnumType == "Date" && x.IsEnable) on parent.Id equals child.ParentId
select new DateDto()
{
Code = child.Code,
Identification= parent.Identification,
Code = child.Code,
DateType = child.DateType,
}).ToListAsync();
list = list.GroupBy(x => new { x.Code }, (key, lst) => new DateDto()
{
Code = key.Code,
DateType = lst.Max(x => x.DateType),
DateType = lst.FirstOrDefault(y => y.Identification == identification)?.DateType ?? lst.Max(x => x.DateType),
}).ToList();
var jsonDataDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(jsonStr);
@@ -519,23 +522,25 @@ namespace IRaCIS.Core.Application.Service
///// <param name="ForeignKeyValue">外键value</param>
///// <param name="ForeignKeyText">要查询的外键值</param>
///// <param name="value">传入的纸</param>
private async Task<string> GetInspectionEnumValue(List<string> identificationList, string jsonStr)
private async Task<string> GetInspectionEnumValue(List<string> identificationList,string identification, string jsonStr)
{
var list = await (from u in _frontAuditConfigRepository.Where(x => identificationList.Contains(x.Identification))
join p in _frontAuditConfigRepository.Where(x => x.EnumType == "Foreign" && x.IsEnable) on u.Id equals p.ParentId
select new
{
Key = p.Code,
ForeignKeyValue = p.ForeignKeyValue,
Identification=u.Identification,
ForeignKeyValue = p.ForeignKeyValue,
ForeignKeyText = p.ForeignKeyText,
ForeignKeyTable = p.ForeignKeyTableName
}).ToListAsync();
list = list.GroupBy(x => new { x.Key }, (key, lst) => new
{
Key = key.Key,
ForeignKeyValue = lst.Max(x => x.ForeignKeyValue),
ForeignKeyText = lst.Max(x => x.ForeignKeyText),
ForeignKeyTable = lst.Max(x => x.ForeignKeyTable),
Identification=string.Empty,
ForeignKeyValue= lst.FirstOrDefault(y => y.Identification == identification)?.ForeignKeyValue ?? lst.Max(x => x.ForeignKeyValue),
ForeignKeyText = lst.FirstOrDefault(y => y.Identification == identification)?.ForeignKeyText ?? lst.Max(x => x.ForeignKeyText),
ForeignKeyTable = lst.FirstOrDefault(y => y.Identification == identification)?.ForeignKeyTable ?? lst.Max(x => x.ForeignKeyTable),
}).ToList();
@@ -585,7 +590,7 @@ namespace IRaCIS.Core.Application.Service
/// <param name="identificationList">标识</param>
/// <param name="jsonStr">Json对象</param>
/// <returns></returns>
private async Task<string> SetEnum(Guid trialId, List<string> identificationList, string jsonStr)
private async Task<string> SetEnum(Guid trialId, List<string> identificationList, string identification, string jsonStr)
{
if (jsonStr == null || jsonStr == "null")
{
@@ -598,27 +603,41 @@ namespace IRaCIS.Core.Application.Service
join p in _frontAuditConfigRepository.Where(x => (x.DictionaryCode != string.Empty && x.EnumType == "Dictionary") || (x.DataType == "Table") && x.IsEnable) on u.Id equals p.ParentId
select new
{
//前端展示类型
DataType = p.DataType,
TableConfigJsonStr = p.TableConfigJsonStr,
Key = p.Code,
Key = p.Code,
Identification = u.Identification,
//前端展示类型
DataType = p.DataType,
TableConfigJsonStr = p.TableConfigJsonStr,
Code = p.DictionaryCode,
Type = p.DictionaryType
}).ToListAsync();
//两条不同的标识 但是里面配置有相同的翻译字典
list = list.Distinct().ToList();
list = list.GroupBy(x => new { x.Key }, (key, lst) => new
{
Key = key.Key,
Identification = string.Empty,
DataType = lst.FirstOrDefault(y => y.Identification == identification)?.DataType ?? lst.Max(x => x.DataType),
TableConfigJsonStr = lst.FirstOrDefault(y => y.Identification == identification)?.TableConfigJsonStr ?? lst.Max(x => x.TableConfigJsonStr),
Code = lst.FirstOrDefault(y => y.Identification == identification)?.Code ?? lst.Max(x => x.Code),
Type = lst.FirstOrDefault(y => y.Identification == identification)?.Type ?? lst.Max(x => x.Type),
// 添加单双审
var trialtype = await _trialRepository.AsQueryable().Where(x => x.Id == trialId).Select(x => x.QCProcessEnum).FirstOrDefaultAsync();
}).ToList();
// 添加单双审
var trialtype = await _trialRepository.AsQueryable().Where(x => x.Id == trialId).Select(x => x.QCProcessEnum).FirstOrDefaultAsync();
if (!list.Any(x => x.Key == "AuditState"))
{
list.Add(new
{
DataType = string.Empty,
TableConfigJsonStr = string.Empty,
Key = "AuditState",
{
Key = "AuditState",
Identification = string.Empty,
DataType = string.Empty,
TableConfigJsonStr = string.Empty,
Code = trialtype == TrialQCProcess.SingleAudit ? "AuditStatePE" : "AuditStateRC",
Type = "Code",
});
@@ -1076,7 +1095,8 @@ namespace IRaCIS.Core.Application.Service
[HttpGet]
public async Task<List<string>> GetModuleTypeDescriptionList(Guid moduleTypeId)
{
var result = await _frontAuditConfigRepository.Where(x => x.ModuleTypeId == moduleTypeId && x.ObjectTypeId != null && x.OptTypeId != null && x.Description.Length > 0).Select(x => new { x.Description, x.DescriptionCN, x.Sort }).OrderBy(t => t.Sort).Select(t => _userInfo.IsEn_Us? t.Description:t.DescriptionCN).Distinct().ToListAsync();
var result =( await _frontAuditConfigRepository.Where(x => x.ModuleTypeId == moduleTypeId && x.ObjectTypeId != null && x.OptTypeId != null && x.Description.Length > 0).Select(x => new { x.Description, x.DescriptionCN, x.Sort }).OrderBy(t => t.Sort).ToListAsync()
).Select(t => _userInfo.IsEn_Us? t.Description:t.DescriptionCN).Distinct().ToList();
return result;
}
@@ -3,9 +3,9 @@ using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Contracts
{
public class SiteDTO: SiteCommand
public class SiteDTO : SiteCommand
{
}
public class SiteCommand
@@ -24,7 +24,7 @@ namespace IRaCIS.Application.Contracts
public string AliasName { get; set; } = string.Empty;
public string City { get; set; } = string.Empty;
public string Country { get; set; } = string.Empty;
public Guid? HospitalId { get; set; }
public Guid? HospitalId { get; set; }
public string DirectorName { get; set; } = string.Empty;
public string DirectorPhone { get; set; } = string.Empty;
public string ContactName { get; set; } = string.Empty;
@@ -35,6 +35,9 @@ namespace IRaCIS.Application.Contracts
{
public Guid Id { get; set; }
public string SiteName { get; set; } = String.Empty;
public string SiteNameCN { get; set; } = String.Empty;
public string City { get; set; } = String.Empty;
public string Province { get; set; } = string.Empty;
@@ -3,18 +3,20 @@ using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infra.EFCore;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Infrastructure;
using Microsoft.Data.Sqlite;
namespace IRaCIS.Application.Services
{
[ ApiExplorerSettings(GroupName = "Institution")]
[ApiExplorerSettings(GroupName = "Institution")]
public class HospitalService : BaseService, IHospitalService
{
private readonly IRepository<Hospital> _hospitalRepository;
private readonly IRepository<Site> _siteRepository;
public HospitalService(IRepository<Hospital> hospitalRepository )
public HospitalService(IRepository<Hospital> hospitalRepository, IRepository<Site> siteRepository)
{
_hospitalRepository = hospitalRepository;
_siteRepository = siteRepository;
}
/// <summary> 获取所有医院列表 </summary>
@@ -37,15 +39,26 @@ namespace IRaCIS.Application.Services
var exp1 = new EntityVerifyExp<Hospital>()
{
VerifyExp = x => x.SiteId == hospitalCommand.SiteId && hospitalCommand.SiteId != null,
//---已经存在同名的医院,请确认
//---当前中心已经添加到其他医院了
VerifyMsg = _localizer["Hospital_SiteAdded"]
};
var hospital = await _hospitalRepository.InsertOrUpdateAsync(hospitalCommand, true, exp,exp1);
var hospital = await _hospitalRepository.InsertOrUpdateAsync(hospitalCommand, true, exp, exp1);
//手动解绑医院与site的关系
if (hospitalCommand.SiteId == null && hospital.SiteId != null)
{
await _siteRepository.BatchUpdateNoTrackingAsync(t => t.Id == hospital.SiteId, u => new Site() { HospitalId = null });
}
//手动绑
if (hospitalCommand.SiteId != null)
{
await _siteRepository.BatchUpdateNoTrackingAsync(t => t.Id == hospitalCommand.SiteId, u => new Site() { HospitalId = hospital.Id });
}
return ResponseOutput.Ok(hospital.Id.ToString());
}
@@ -54,11 +67,6 @@ namespace IRaCIS.Application.Services
[HttpDelete("{hospitalId:guid}")]
public async Task<IResponseOutput> DeleteHospital(Guid hospitalId)
{
//if (_userRepository.Find().Any(t => t.OrganizationId == hospitalId))
//{
// return ResponseOutput.NotOk("该医院下存在用户,暂时无法删除。");
//}
var success = await _hospitalRepository.BatchDeleteNoTrackingAsync(x => x.Id == hospitalId);
@@ -67,12 +75,12 @@ namespace IRaCIS.Application.Services
/// <summary> 分页获取医院列表 </summary>
[HttpPost]
public async Task<PageOutput<HospitalDTO>> GetHospitalPageList(HospitalQueryDTO hospitalSearchModel)
public async Task<PageOutput<HospitalDTO>> GetHospitalPageList(HospitalQueryDTO hospitalSearchModel)
{
var hospitalQueryable =
_hospitalRepository
.WhereIf(hospitalSearchModel.HospitalName!=null, t => t.HospitalName.Contains(hospitalSearchModel.HospitalName!) || t.HospitalNameCN.Contains(hospitalSearchModel.HospitalName!))
.WhereIf(hospitalSearchModel.HospitalName != null, t => t.HospitalName.Contains(hospitalSearchModel.HospitalName!) || t.HospitalNameCN.Contains(hospitalSearchModel.HospitalName!))
.WhereIf(hospitalSearchModel.City != null, t => t.City.Contains(hospitalSearchModel.City!) || t.HospitalNameCN.Contains(hospitalSearchModel.City!))
.WhereIf(hospitalSearchModel.Province != null, t => t.Province.Contains(hospitalSearchModel.Province!) || t.HospitalNameCN.Contains(hospitalSearchModel.Province!))
.ProjectTo<HospitalDTO>(_mapper.ConfigurationProvider);
@@ -4,6 +4,7 @@ using IRaCIS.Core.Infra.EFCore;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Share;
using Medallion.Threading;
using IRaCIS.Core.Domain.Models;
namespace IRaCIS.Application.Services
{
@@ -13,12 +14,14 @@ namespace IRaCIS.Application.Services
private readonly IRepository<Site> _siteRepository;
private readonly IRepository<TrialSiteUser> _trialSiteUserRepository;
private readonly IDistributedLockProvider _distributedLockProvider;
private readonly IRepository<Hospital> _hospitalRepository;
public SiteService(IRepository<Site> siteRepository, IRepository<TrialSiteUser> trialSiteUserRepository, IDistributedLockProvider distributedLockProvider)
public SiteService(IRepository<Site> siteRepository, IRepository<TrialSiteUser> trialSiteUserRepository, IDistributedLockProvider distributedLockProvider, IRepository<Hospital> hospitalRepository)
{
_siteRepository = siteRepository;
_trialSiteUserRepository = trialSiteUserRepository;
_distributedLockProvider = distributedLockProvider;
_hospitalRepository = hospitalRepository;
}
/// <summary> 分页获取研究中心列表 </summary>
@@ -32,7 +35,7 @@ namespace IRaCIS.Application.Services
.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.Province), t => t.Province.Contains(searchModel.Province))
.ProjectTo<SiteSelectDTO>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us });
.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);
@@ -67,11 +70,23 @@ namespace IRaCIS.Application.Services
siteCommand.Code = await _siteRepository.Select(t => t.Code).DefaultIfEmpty().MaxAsync() + 1;
siteCommand.SiteCode = AppSettings.GetCodeStr(siteCommand.Code, nameof(User));
siteCommand.SiteCode = AppSettings.GetCodeStr(siteCommand.Code, nameof(Site));
}
var site = await _siteRepository.InsertOrUpdateAsync(siteCommand, true, exp);
//手动解绑医院与site的关系
if (siteCommand.HospitalId == null && site.HospitalId != null)
{
await _hospitalRepository.BatchUpdateNoTrackingAsync(t => t.Id == site.HospitalId, u => new Hospital() { SiteId = null });
}
//手动绑
if (siteCommand.HospitalId != null)
{
await _hospitalRepository.BatchUpdateNoTrackingAsync(t => t.Id == siteCommand.HospitalId, u => new Hospital() { SiteId = site.Id });
}
return ResponseOutput.Ok(site.Id.ToString());
}
@@ -34,6 +34,8 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid? LoginUserId { get; set; }
public Guid? OptUserId { get; set; }
public string IPRegion { get; set; }
}
///<summary>UserLogQuery 列表查询参数模型</summary>
@@ -47,10 +49,17 @@ namespace IRaCIS.Core.Application.ViewModel
public string? LoginFaildName { get; set; }
public string? LoginUserName { get; set; }
public DateTime? BeginDate { get; set; }
public DateTime? EndDate { get; set; }
public UserTypeEnum? LoginUserTypeEnum { get; set; }
public Guid? UserTypeId { get; set; }
public Guid? UserId { get; set; }
}
@@ -12,6 +12,7 @@ using Microsoft.Identity.Client;
using static IRaCIS.Core.Domain.Share.StaticData;
using IRaCIS.Core.Application.ViewModel;
using Medallion.Threading;
using EasyCaching.Core;
namespace IRaCIS.Application.Services
{
@@ -25,7 +26,7 @@ namespace IRaCIS.Application.Services
private readonly IRepository<UserLog> _userLogRepository;
private readonly IDistributedLockProvider _distributedLockProvider;
private readonly IMemoryCache _cache;
private readonly IEasyCachingProvider _cache;
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
@@ -34,7 +35,7 @@ namespace IRaCIS.Application.Services
IMailVerificationService mailVerificationService,
IRepository<VerificationCode> verificationCodeRepository,
IMemoryCache cache,
IEasyCachingProvider cache,
IRepository<TrialUser> userTrialRepository,
IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig,
IRepository<UserLog> userLogRepository
@@ -128,7 +129,7 @@ namespace IRaCIS.Application.Services
{
//检查手机或者邮箱是否有效
if (!Regex.IsMatch(email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"))
if (!Regex.IsMatch(email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
{
//---Please input a legal email
return ResponseOutput.NotOk(_localizer["User_LegalEmail"]);
@@ -310,7 +311,7 @@ namespace IRaCIS.Application.Services
{
//检查手机或者邮箱是否有效
if (!Regex.IsMatch(email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"))
if (!Regex.IsMatch(email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
{
//---请输入一个正确的邮箱。
@@ -629,7 +630,7 @@ namespace IRaCIS.Application.Services
string cacheKey = $"{cachePrefix}{userName}";
// 从缓存中获取登录失败次数
int? failCount = _cache.Get<int?>(cacheKey);
int? failCount = _cache.Get<int?>(cacheKey).Value;
if (failCount == null)
{
@@ -644,7 +645,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);
throw new BusinessValidationFailedException($"密码连续错误{maxFailures}次,当前账号已被限制登录,请等待 {lockoutMinutes} 分钟后再试。");
//$"密码连续错误{maxFailures}次,当前账号已被限制登录,请等待 {lockoutMinutes} 分钟后再试。"
throw new BusinessValidationFailedException(_localizer["User_ErrorLimit", maxFailures, lockoutMinutes]);
}
var userLoginReturnModel = new LoginReturnDTO();
@@ -659,7 +661,9 @@ namespace IRaCIS.Application.Services
failCount++;
_cache.Set(cacheKey, failCount, TimeSpan.FromMinutes(lockoutMinutes));
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId=Guid.Empty, LoginFaildName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError }, true);
var errorPwdUserId = await _userRepository.Where(u => u.UserName == userName).Select(t => t.Id).FirstOrDefaultAsync();
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = errorPwdUserId, OptUserId=Guid.Empty, LoginFaildName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError }, true);
return ResponseOutput.NotOk(_localizer["User_CheckNameOrPw"], new LoginReturnDTO());
@@ -692,15 +696,22 @@ namespace IRaCIS.Application.Services
[HttpPost]
public async Task<PageOutput<UserLogView>> GetUserLogList(UserLogQuery inQuery)
{
DateTime? trialCreateTime = inQuery.TrialId != null ? _repository.Where<Trial>(t => t.Id == inQuery.TrialId).Select(t => t.CreateTime).FirstOrDefault() : null;
var userLogQueryable =
_userLogRepository
.WhereIf(inQuery.TrialId != null, t => t.LoginUser.UserTrials.Any(c => c.TrialId == inQuery.TrialId && c.UserId == t.LoginUserId))
.WhereIf(inQuery.TrialId != null, t => t.LoginUser.UserTrials.Any(c => c.TrialId == inQuery.TrialId && (c.UserId == t.LoginUserId || c.UserId == t.OptUserId)))
.WhereIf(trialCreateTime != null, t => t.CreateTime >= trialCreateTime)
.WhereIf(inQuery.OptType != null, t => t.OptType == inQuery.OptType)
.WhereIf(inQuery.UserId != null, t => t.LoginUserId == inQuery.UserId)
.WhereIf(inQuery.BeginDate != null, t => t.CreateTime >= inQuery.BeginDate)
.WhereIf(inQuery.EndDate != null, t => t.CreateTime <= inQuery.EndDate)
.WhereIf(!string.IsNullOrEmpty(inQuery.LoginUserName), t => t.LoginUser.UserName.Contains(inQuery.LoginUserName!))
.WhereIf(!string.IsNullOrEmpty(inQuery.LoginFaildName), t => t.LoginFaildName.Contains(inQuery.LoginFaildName!))
.WhereIf(!string.IsNullOrEmpty(inQuery.IP), t => t.IP.Contains(inQuery.IP!))
.WhereIf(inQuery.LoginUserTypeEnum != null, t => t.LoginUser.UserTypeEnum == inQuery.LoginUserTypeEnum)
.WhereIf(inQuery.UserTypeId != null, t => t.LoginUser.UserTypeId == inQuery.UserTypeId)
.ProjectTo<UserLogView>(_mapper.ConfigurationProvider);
var pageList = await userLogQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? "Id" : inQuery.SortField, inQuery.Asc);
@@ -386,7 +386,7 @@ namespace IRaCIS.Core.Application.Contracts.DTO
public string ModalityForEdit { get; set; } = string.Empty;
public bool IsHaveUploadFailed { get; set; }
}
public class QASeriesInfoDto
@@ -547,7 +547,7 @@ namespace IRaCIS.Core.Application.Contracts
[DictionaryTranslateAttribute("YesOrNo")]
public bool IsSuccess { get; set; }
public string Note = string.Empty;
public string Note { get; set; }
}
@@ -1099,6 +1099,8 @@ namespace IRaCIS.Core.Application.Contracts
public int? Age { get; set; }
public string Sex { get; set; } = string.Empty;
public bool IsHaveUploadFailed { get; set; }
}
@@ -1383,6 +1385,10 @@ namespace IRaCIS.Core.Application.Contracts
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 PreliminaryAuditUserName { get; set; } = String.Empty;
@@ -925,7 +925,7 @@ namespace IRaCIS.Core.Application.Image.QA
return new GetNextIQCQualityOutDto() { };
break;
case TrialQCProcess.SingleAudit:
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();
visitList = await _subjectVisitRepository.Where(x => x.SubmitState == SubmitStateEnum.Submitted && 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();
if (subjectVisit != null)
@@ -953,7 +953,7 @@ namespace IRaCIS.Core.Application.Image.QA
break;
case TrialQCProcess.DoubleAudit:
visitList = await _subjectVisitRepository.Where(x => x.SubmitState != SubmitStateEnum.None && x.TrialId == inDto.TrialId &&
visitList = await _subjectVisitRepository.Where(x => x.SubmitState == SubmitStateEnum.Submitted && 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)
@@ -1224,7 +1224,7 @@ namespace IRaCIS.Core.Application.Image.QA
var trialId = cRCRequestToQCCommand.TrialId;
var trialConfig = (await _trialRepository
.Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification, t.IsUrgent, t.IsHaveFirstGiveMedicineDate, t.ClinicalInformationTransmissionEnum })
.Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification, t.IsUrgent, t.IsEnrollementQualificationConfirm,t.IsPDProgressView, t.IsHaveFirstGiveMedicineDate, t.ClinicalInformationTransmissionEnum })
.FirstOrDefaultAsync(t => t.TrialId == cRCRequestToQCCommand.TrialId)).IfNullThrowException();
//找到符合配置的标准 确认的并且签名的、双重,有序,阅片期仲裁
@@ -1307,10 +1307,15 @@ namespace IRaCIS.Core.Application.Image.QA
//已确认临床数据完整性
dbSubjectVisit.IsConfirmedClinicalData = true;
// 根据项目配置 设置访视的入组确认和pd进展
// CRC 上传的基线数据签名
dbSubjectVisit.IsEnrollmentConfirm= dbSubjectVisit.IsBaseLine && trialConfig.IsEnrollementQualificationConfirm ?true:false;
await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(x =>
dbSubjectVisit.PDState = dbSubjectVisit.IsBaseLine==false && trialConfig.IsPDProgressView ? PDStateEnum.PDProgress:PDStateEnum.None;
// CRC 上传的基线数据签名
await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(x =>
(x.ClinicalDataTrialSet.ClinicalDataLevel== ClinicalLevel.Subject|| x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)&&
@@ -1355,40 +1360,40 @@ namespace IRaCIS.Core.Application.Image.QA
//dbSubjectVisit.Subject.IsMissingImages = await _subjectVisitRepository.AnyAsync(t => (t.VisitNum < maxVisitNum && t.SubmitState != SubmitStateEnum.Submitted && t.IsLostVisit == false));
//项目或者Subject IsUrgent 提交时 访视也设置为紧急
if (trialConfig.IsUrgent || dbSubjectVisit.Subject.IsUrgent || (dbSubjectVisit.PDState == PDStateEnum.PDProgress && !dbSubjectVisit.IsBaseLine) || (dbSubjectVisit.IsEnrollmentConfirm && dbSubjectVisit.IsBaseLine))
if (trialConfig.IsUrgent || dbSubjectVisit.Subject.IsUrgent || (dbSubjectVisit.IsEnrollmentConfirm && dbSubjectVisit.IsBaseLine))
{
if (dbSubjectVisit.PDState == PDStateEnum.PDProgress)
{
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(x => x.SubjectId == dbSubjectVisit.SubjectId && x.VisitNum <= dbSubjectVisit.VisitNum, x => new SubjectVisit()
{
IsUrgent = true
});
//if (dbSubjectVisit.PDState == PDStateEnum.PDProgress)
//{
// await _subjectVisitRepository.BatchUpdateNoTrackingAsync(x => x.SubjectId == dbSubjectVisit.SubjectId && x.VisitNum <= dbSubjectVisit.VisitNum, x => new SubjectVisit()
// {
// IsUrgent = true
// });
// await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => trialInOrderCriterionIdList.Contains(x.TrialReadingCriterionId) && x.SubjectId == dbSubjectVisit.SubjectId &&
// dbSubjectVisit.VisitNum <= x.VisitTaskNum && x.VisitTaskNum < Math.Ceiling(dbSubjectVisit.VisitNum + 0.01m) // 当前的访视 全局 裁判 及之前 全都加急
// && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.TaskState == TaskState.Effect, x => new VisitTask()
// {
// IsUrgent = true,
// TaskUrgentType = TaskUrgentType.PDProgress,
// IsCanEditUrgentState = false,
// });
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => trialInOrderCriterionIdList.Contains(x.TrialReadingCriterionId)&& x.SubjectId == dbSubjectVisit.SubjectId&&
dbSubjectVisit.VisitNum<= x.VisitTaskNum && x.VisitTaskNum < Math.Ceiling(dbSubjectVisit.VisitNum+0.01m) // 当前的访视 全局 裁判 及之前 全都加急
&& x.ReadingTaskState != ReadingTaskState.HaveSigned && x.TaskState == TaskState.Effect, x => new VisitTask()
{
// await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => trialInOrderCriterionIdList.Contains(x.TrialReadingCriterionId) && x.SubjectId == dbSubjectVisit.SubjectId
// && x.VisitTaskNum < dbSubjectVisit.VisitNum // 当前的访视 全局 裁判 及之前 全都加急
// && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.TaskState == TaskState.Effect, x => new VisitTask()
// {
IsUrgent = true,
TaskUrgentType = TaskUrgentType.PDProgress,
IsCanEditUrgentState=false,
});
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => trialInOrderCriterionIdList.Contains(x.TrialReadingCriterionId) && x.SubjectId == dbSubjectVisit.SubjectId
&& x.VisitTaskNum < dbSubjectVisit.VisitNum // 当前的访视 全局 裁判 及之前 全都加急
&& x.ReadingTaskState != ReadingTaskState.HaveSigned && x.TaskState == TaskState.Effect, x => new VisitTask()
{
IsUrgent = true,
TaskUrgentType = TaskUrgentType.Other,
TaskUrgentRemake= "后续访视设为pd",
IsCanEditUrgentState = false,
});
}
else if (dbSubjectVisit.IsEnrollmentConfirm)
// IsUrgent = true,
// TaskUrgentType = TaskUrgentType.Other,
// TaskUrgentRemake = "后续访视设为pd",
// IsCanEditUrgentState = false,
// });
//}
//else
if (dbSubjectVisit.IsEnrollmentConfirm)
{
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(x => x.Id == dbSubjectVisit.Id, x => new SubjectVisit()
{
@@ -1420,14 +1425,14 @@ namespace IRaCIS.Core.Application.Image.QA
dbSubjectVisit.IsUrgent = true;
//PD确认的紧急会把前面所有未QC完成的访视均标记为紧急
////PD确认的紧急会把前面所有未QC完成的访视均标记为紧急
var previosSVlist = await _subjectVisitRepository.Where(t => t.SubjectId == dbSubjectVisit.SubjectId && t.VisitNum < dbSubjectVisit.VisitNum && t.IsUrgent == false && t.SubmitState == SubmitStateEnum.Submitted, true).ToListAsync();
//var previosSVlist = await _subjectVisitRepository.Where(t => t.SubjectId == dbSubjectVisit.SubjectId && t.VisitNum < dbSubjectVisit.VisitNum && t.IsUrgent == false && t.SubmitState == SubmitStateEnum.Submitted, true).ToListAsync();
previosSVlist.ForEach(t =>
{
t.IsUrgent = true;
});
//previosSVlist.ForEach(t =>
//{
// t.IsUrgent = true;
//});
}
@@ -104,7 +104,7 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.Subject.Code))
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode))
.ForMember(d => d.CheckDialogStr, u => u.MapFrom(t => string.Join(" | ", t.CheckChallengeDialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUser.UserName + " " + c.CreateTime.ToString("yyyy-mm-dd hh:mm:ss") + " :" + c.TalkContent))))
.ForMember(d => d.CheckDialogStr, u => u.MapFrom(t => string.Join(" | ", t.CheckChallengeDialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUser.UserName + " " + c.CreateTime.ToString("yyyy-MM-dd HH:mm:ss") + " :" + c.TalkContent))))
.ForMember(d => d.ModalityList, c => c.MapFrom(s =>
(s.NoneDicomStudyList.Select(t => t.Modality)
.Union(s.StudyList.Select(k => k.ModalityForEdit))).Distinct()))
@@ -364,6 +364,10 @@ namespace IRaCIS.Core.Application.Service
.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.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.PreliminaryAuditUserName, u => u.MapFrom(s => s.PreliminaryAuditUser.UserName))
.ForMember(d => d.ReviewAuditUserName, u => u.MapFrom(s => s.ReviewAuditUser.UserName))
@@ -391,6 +395,8 @@ namespace IRaCIS.Core.Application.Service
|| t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count() > 0)
|| t.PreviousSurgeryList.Any()))
.ForMember(d => d.IsHaveUploadFailed, u => u.MapFrom(t => t.StudyList.SelectMany(c=>c.DicomStudyMonitorList).Any(h => h.FailedFileCount>0) ))
//.ForMember(d => d.VisitName, u => u.MapFrom(t =>t.InPlan? t.VisitStage.VisitName : t.VisitName))
//.ForMember(d => d.VisitNum, u => u.MapFrom(t => t.InPlan ? t.VisitStage.VisitNum : t.VisitNum))
//.ForMember(d => d.VisitDay, u => u.MapFrom(t => t.InPlan ? t.VisitStage.VisitDay : t.VisitDay))
@@ -523,7 +523,28 @@ namespace IRaCIS.Core.Application.Service
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync();
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)
.Where(x=> existsCRCStructuring)
.WhereIf(inDto.ReadModuleId==null,x=>x.TrialReadingCriterion.IsConfirm)
.WhereIf(inDto.ReadModuleId != null, x => x.Id == inDto.ReadModuleId)
.WhereIf(inDto.IsCRCConfirm != null, x => x.IsCRCConfirm == inDto.IsCRCConfirm)
.WhereIf(inDto.IsPMConfirm != null, x => x.IsPMConfirm == inDto.IsPMConfirm)
@@ -532,6 +553,7 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(inDto.SubjectId != null, x => x.SubjectId == inDto.SubjectId)
.WhereIf(inDto.StartTime != null, x => x.SubjectVisit.LatestScanDate >= inDto.StartTime)
.WhereIf(inDto.EndTime != null, x => x.SubjectVisit.LatestScanDate <= inDto.EndTime)
.WhereIf(readingSetType != null, x => x.ReadingSetType== readingSetType)
.Select(x => new GetCRCConfirmListOutDto()
{
@@ -190,23 +190,24 @@ namespace IRaCIS.Application.Services
.WhereIf(inDto.IsBaseline, x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
.WhereIf(!inDto.IsBaseline, x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
.Where(x => x.ClinicalDataTrialSet.TrialId == inDto.TrialId && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC)
.Include(x=>x.ClinicalDataTrialSet)
.OrderBy(x=>x.ClinicalDataTrialSet.CreateTime)
.Include(x => x.ClinicalDataTrialSet)
.OrderBy(x => x.ClinicalDataTrialSet.CreateTime)
.Select(x => new GetCRCClinicalDataOutDto()
{
Id = x.Id,
ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us) ,
ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us),
ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
ClinicalDataSetEnName=x.ClinicalDataTrialSet.ClinicalDataSetEnName,
ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName,
ClinicalDataTrialSetId = x.ClinicalDataTrialSet.Id,
FileName = x.ClinicalDataTrialSet.FileName,
UploadRole = x.ClinicalDataTrialSet.UploadRole,
Path = x.ClinicalDataTrialSet.Path,
IsBlind = x.IsBlind,
IsComplete = x.IsComplete,
ClinicalFromList=x.Subject.ClinicalFormList.Where(y=>y.ReadingId==x.ReadingId&&y.ClinicalDataTrialSetId==x.ClinicalDataTrialSetId).Select(y=> new ClinicalFromData() {
CheckDate=y.CheckDate,
ClinicalFormId=y.Id
ClinicalFromList = x.Subject.ClinicalFormList.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
{
CheckDate = y.CheckDate,
ClinicalFormId = y.Id
}).ToList(),
PDFFileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
{
@@ -215,7 +216,7 @@ namespace IRaCIS.Application.Services
Path = y.Path,
CreateTime = y.CreateTime,
}).ToList(),
}).ToListAsync();
var previousHistoryList = await _previousHistoryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousHistoryView>(_mapper.ConfigurationProvider).ToListAsync();
@@ -287,7 +288,7 @@ namespace IRaCIS.Application.Services
//}
data.IsBlind = inDto.IsBlind;
data.IsComplete=inDto.IsComplete;
data.IsComplete = inDto.IsComplete;
data.IsSign = true;
data.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned;
@@ -304,7 +305,24 @@ namespace IRaCIS.Application.Services
await this.iServiceProvider.GetService<IReadingImageTaskService>().AddOncologyTask(readingId);
await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, inDto.TrialReadingCriterionId);
//如果先生成了任务,再签名subject级别 PM 临床数据,那么会导致其他标准的任务签名状态无法得到维护
if (await _repository.AnyAsync<ClinicalDataTrialSet>(t => t.Id == data.ClinicalDataTrialSetId && t.UploadRole == UploadRole.PM && t.ClinicalDataLevel == ClinicalLevel.Subject))
{
var needDealTrialReadingCriterionIdList = _repository.Where<ClinicalDataTrialSet>(t => t.Id == data.ClinicalDataTrialSetId)
.SelectMany(t => t.TrialClinicalDataSetCriteriaList)
.Select(u => u.TrialReadingCriterionId).Distinct().ToList();
foreach (var trialReadingCriterionId in needDealTrialReadingCriterionIdList)
{
await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, trialReadingCriterionId);
}
}
else
{
await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, inDto.TrialReadingCriterionId);
}
return ResponseOutput.Result(result);
}
@@ -313,7 +331,7 @@ namespace IRaCIS.Application.Services
public async Task DealVisiTaskClinicalDataSignedAsync(Guid trialId, Guid subjectId, Guid readingId, bool isVisit, Guid trialReadingCritrialId)
{
//获取确认的临床数据配置
var trialClinicalDataSetList = _clinicalDataTrialSetRepository.Where(t => t.TrialId == trialId && t.IsConfirm).Include(t => t.TrialClinicalDataSetCriteriaList).ToList();
var trialClinicalDataSetList = _clinicalDataTrialSetRepository.Where(t => t.TrialId == trialId && t.IsConfirm).Include(t => t.TrialClinicalDataSetCriteriaList).ToList();
//var criterionType = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == trialReadingCritrialId).Select(t => t.CriterionType).FirstOrDefaultAsync();
@@ -328,7 +346,7 @@ namespace IRaCIS.Application.Services
{
var isBaseLine = await _subjectVisitRepository.Where(t => t.Id == readingId).Select(t => t.IsBaseLine).FirstOrDefaultAsync();
//判断是否基线
if (isBaseLine)
@@ -414,7 +432,7 @@ namespace IRaCIS.Application.Services
}
//有序阅片才维护 IsFrontTaskNeedSignButNotSign 这个状态
if (_readingQuestionCriterionTrialRepository.Any(t=>t.Id==trialReadingCritrialId && t.IsReadingTaskViewInOrder == true))
if (_readingQuestionCriterionTrialRepository.Any(t => t.Id == trialReadingCritrialId && t.IsReadingTaskViewInOrder == true))
{
@@ -429,8 +447,8 @@ namespace IRaCIS.Application.Services
(t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)
// 前序存在 未一致性核查未通过的
|| t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum>sv.VisitNum)
|| t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum)
))
.Select(t => t.Id);
@@ -442,7 +460,7 @@ namespace IRaCIS.Application.Services
var visitTaskIdQueryable2 = _visitTaskRepository.Where(visitTaskLambda) //该Subject 该标准的任务
.Where(t => t.IsFrontTaskNeedSignButNotSign == true &&
//前序任务 不存在需要签名 但是没签名
@@ -461,14 +479,14 @@ namespace IRaCIS.Application.Services
}
}
// 废弃 接口合并到签名哪里
[HttpPut]
public async Task<IResponseOutput> PMClinicalDataConfirm(PMClinicalDataConfirmCommand command)
{
@@ -522,7 +540,7 @@ namespace IRaCIS.Application.Services
keyValuePairs.Add(ModuleTypeEnum.Oncology, ClinicalLevel.OncologyRead);
var usedIdsQuery = _readingClinicalDataRepository.Where(x => x.ReadingId == inDto.ReadingId && x.Id != inDto.ReadingClinicalDataId).Select(x => x.ClinicalDataTrialSetId);
@@ -537,20 +555,20 @@ namespace IRaCIS.Application.Services
.WhereIf(inDto.IsVisit && !inDto.IsBaseLine, x => x.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
.WhereIf(!inDto.IsVisit, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead || x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
.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}|"))
.Select(x => new GetTrialClinicalDataSelectOutDto()
{
ClinicalDataLevel = x.ClinicalDataLevel,
ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us),
ClinicalDataSetEnName=x.ClinicalDataSetEnName,
ClinicalDataSetEnName = x.ClinicalDataSetEnName,
ClinicalUploadType = x.ClinicalUploadType,
FileName = x.FileName,
Path = x.Path,
Id = x.Id,
CriterionEnumList = x.CriterionEnumList,
}).ToListAsync();
return clinicalList;
}
@@ -699,20 +717,21 @@ namespace IRaCIS.Application.Services
Path = y.Path,
CreateTime = y.CreateTime,
}).ToList(),
});
var result = new List<GetReadingClinicalDataListOutDto>();
if (!inDto.IsOnlyGetCRCReadModule)
{
result = await resultQuery.ToListAsync();
result = await resultQuery.ToListAsync();
}
var readingIds = result.Select(x => x.ReadingId).ToList();
var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId??default(Guid))).ToListAsync();
result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x => {
var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId ?? default(Guid))).ToListAsync();
result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x =>
{
x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId&&y.ClinicalDataTrialSetId==x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
{
CheckDate = y.CheckDate,
ClinicalFormId = y.Id
@@ -723,35 +742,36 @@ namespace IRaCIS.Application.Services
// 这里处理CRC上传 阅片期的临床数据
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId)
.WhereIf(inDto.SelectIsSign,x=>x.IsPMConfirm)
.WhereIf(!inDto.SelectIsSign, x => x.IsCRCConfirm)
.FirstOrDefaultAsync();
.WhereIf(inDto.SelectIsSign, x => x.IsPMConfirm)
.WhereIf(!inDto.SelectIsSign, x => x.IsCRCConfirm)
.FirstOrDefaultAsync();
if (readModule != null)
{
var moduleCriterionFromList = await _readModuleCriterionFromRepository
.WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalForm.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId)
.Where(x => x.ReadModuleId == readModule.Id).Select(x => new{
ClinicalFormId= x.ClinicalFormId,
CheckDate= x.ClinicalForm.CheckDate,
ClinicalDataTrialSetId= x.ClinicalForm.ClinicalDataTrialSetId
}).ToListAsync();
.Where(x => x.ReadModuleId == readModule.Id).Select(x => new
{
ClinicalFormId = x.ClinicalFormId,
CheckDate = x.ClinicalForm.CheckDate,
ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSetId
}).ToListAsync();
var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC && x.ClinicalUploadType == ClinicalUploadType.Structuring)
.WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead)
.WhereIf(readModule.ReadingSetType == ReadingSetType.TumorReading, x => x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
.Where(x=>x.TrialClinicalDataSetCriteriaList.Any(y=>y.TrialReadingCriterionId==readModule.TrialReadingCriterionId))
.Where(x => x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == readModule.TrialReadingCriterionId))
.Select(x => new GetReadingClinicalDataListOutDto()
{
ClinicalDataLevel = x.ClinicalDataLevel,
SubjectId = inDto.SubjectId,
ReadingId = default(Guid),
IsCRCApplicationRevoke=readModule.IsCRCApplicationRevoke,
IsCRCConfirm= readModule.IsCRCConfirm,
IsPMConfirm= readModule.IsPMConfirm,
IsCRCApplicationRevoke = readModule.IsCRCApplicationRevoke,
IsCRCConfirm = readModule.IsCRCConfirm,
IsPMConfirm = readModule.IsPMConfirm,
ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us),
ClinicalDataSetEnName = x.ClinicalDataSetEnName,
ClinicalDataTrialSetId = x.Id,
@@ -762,7 +782,7 @@ namespace IRaCIS.Application.Services
IsCRCUpload = x.UploadRole == UploadRole.CRC,
IsNeedMerge = true,
ReadModuleId = readModule.Id,
TrialClinicalDataSetCriteriaList=x.TrialClinicalDataSetCriteriaList,
TrialClinicalDataSetCriteriaList = x.TrialClinicalDataSetCriteriaList,
//FileCount = x.FileCount,
//ReadingClinicalDataState = x.ReadingClinicalDataState,
@@ -791,8 +811,8 @@ namespace IRaCIS.Application.Services
});
result.AddRange(clinicalresult);
}
result.AddRange(clinicalresult);
}
@@ -813,7 +833,7 @@ namespace IRaCIS.Application.Services
result = result.Where(x => x.UploadRole == UploadRole.PM).ToList();
break;
case GetClinicalType.CRCConfirm:
result = result.Where(x => x.UploadRole == UploadRole.CRC&&x.IsCRCConfirm&&!x.IsPMConfirm).ToList();
result = result.Where(x => x.UploadRole == UploadRole.CRC && x.IsCRCConfirm && !x.IsPMConfirm).ToList();
break;
case GetClinicalType.HasSign:
result = result.Where(x => x.IsSign).ToList();
@@ -849,15 +869,15 @@ namespace IRaCIS.Application.Services
{
var resultQuery = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId)
.Where(x => x.ReadingId == inDto.ReadingId)
.WhereIf(inDto.ClinicalDataTrialSetId!=null, x=>x.ClinicalDataTrialSetId==inDto.TrialReadingCriterionId)
.Where(x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t=>t.TrialReadingCriterionId==inDto.TrialReadingCriterionId))
.WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.TrialReadingCriterionId)
.Where(x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId))
.Select(x => new GetReadingClinicalDataListOutDto()
{
ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
SubjectId = x.SubjectId,
ReadingId = x.ReadingId,
ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us),
ClinicalDataSetEnName =x.ClinicalDataTrialSet.ClinicalDataSetEnName,
ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName,
ClinicalDataTrialSetId = x.ClinicalDataTrialSetId,
IsSign = x.IsSign,
ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
@@ -884,7 +904,8 @@ namespace IRaCIS.Application.Services
var readingIds = result.Select(x => x.ReadingId).ToList();
var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId ?? default(Guid))).ToListAsync();
result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x => {
result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x =>
{
x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
{
@@ -895,77 +916,78 @@ namespace IRaCIS.Application.Services
});
// 这里处理CRC上传 阅片期的临床数据
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId&&x.IsCRCConfirm)
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId && x.IsCRCConfirm)
.FirstOrDefaultAsync();
if (readModule != null)
{
var moduleCriterionFromList = await _readModuleCriterionFromRepository.Where(x => x.ReadModuleId == readModule.Id)
var moduleCriterionFromList = await _readModuleCriterionFromRepository.Where(x => x.ReadModuleId == readModule.Id)
.WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalForm.ClinicalDataTrialSetId == inDto.TrialReadingCriterionId)
.Select(x => new {
ClinicalFormId = x.ClinicalFormId,
CheckDate = x.ClinicalForm.CheckDate,
ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSetId
.Select(x => new
{
ClinicalFormId = x.ClinicalFormId,
CheckDate = x.ClinicalForm.CheckDate,
ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSetId
}).ToListAsync();
}).ToListAsync();
var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC&&x.ClinicalUploadType== ClinicalUploadType.Structuring)
.WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading,x=>x.ClinicalDataLevel== ClinicalLevel.ImageRead)
var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC && x.ClinicalUploadType == ClinicalUploadType.Structuring)
.WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead)
.WhereIf(readModule.ReadingSetType == ReadingSetType.TumorReading, x => x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
.Where(x => x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == readModule.TrialReadingCriterionId))
.Select(x => new GetReadingClinicalDataListOutDto()
{
{
ClinicalDataLevel = x.ClinicalDataLevel,
SubjectId = inDto.SubjectId,
ReadingId = default(Guid),
IsCRCApplicationRevoke= readModule.IsCRCApplicationRevoke,
ClinicalDataLevel = x.ClinicalDataLevel,
SubjectId = inDto.SubjectId,
ReadingId = default(Guid),
IsCRCApplicationRevoke = readModule.IsCRCApplicationRevoke,
IsCRCConfirm = readModule.IsCRCConfirm,
IsPMConfirm=readModule.IsPMConfirm,
IsPMConfirm = readModule.IsPMConfirm,
ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us),
ClinicalDataSetEnName = x.ClinicalDataSetEnName,
ClinicalDataTrialSetId = x.Id,
IsSign = readModule.IsPMConfirm,
ClinicalUploadType = x.ClinicalUploadType,
Id = default(Guid),
UploadRole = x.UploadRole,
IsCRCUpload = x.UploadRole == UploadRole.CRC,
IsNeedMerge = true,
ReadModuleId = readModule.Id,
//FileCount = x.FileCount,
ClinicalDataSetEnName = x.ClinicalDataSetEnName,
ClinicalDataTrialSetId = x.Id,
IsSign = readModule.IsPMConfirm,
ClinicalUploadType = x.ClinicalUploadType,
Id = default(Guid),
UploadRole = x.UploadRole,
IsCRCUpload = x.UploadRole == UploadRole.CRC,
IsNeedMerge = true,
ReadModuleId = readModule.Id,
//FileCount = x.FileCount,
//ReadingClinicalDataState = x.ReadingClinicalDataState,
//ReadingClinicalDataState = x.ReadingClinicalDataState,
//FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
//{
// Id = y.Id,
// FileName = y.FileName,
// Path = y.Path,
// CreateTime = y.CreateTime,
//}).ToList()
//FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
//{
// Id = y.Id,
// FileName = y.FileName,
// Path = y.Path,
// CreateTime = y.CreateTime,
//}).ToList()
}).ToListAsync();
}).ToListAsync();
clinicalresult.ForEach(x =>
{
x.FileCount = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Count();
x.ClinicalFromList = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).OrderBy(y => y.CheckDate).Select(x => new ClinicalFromData
{
CheckDate = x.CheckDate,
ClinicalFormId = x.ClinicalFormId
clinicalresult.ForEach(x =>
{
x.FileCount = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Count();
x.ClinicalFromList = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).OrderBy(y => y.CheckDate).Select(x => new ClinicalFromData
{
CheckDate = x.CheckDate,
ClinicalFormId = x.ClinicalFormId
}).ToList();
}).ToList();
x.IsSign = readModule.IsPMConfirm ?true : false;
x.IsSign = readModule.IsPMConfirm ? true : false;
x.ReadingClinicalDataState = readModule.IsPMConfirm ? ReadingClinicalDataStatus.HaveSigned : ReadingClinicalDataStatus.HaveChecked;
});
});
result.AddRange(clinicalresult);
}
result.AddRange(clinicalresult);
}
if (inDto.GetClinicalType != null)
@@ -976,7 +998,7 @@ namespace IRaCIS.Application.Services
result = result.Where(x => x.UploadRole == UploadRole.PM).ToList();
break;
case GetClinicalType.CRCConfirm:
result = result.Where(x => x.UploadRole == UploadRole.CRC&&x.IsCRCConfirm&&!x.IsPMConfirm).ToList();
result = result.Where(x => x.UploadRole == UploadRole.CRC && x.IsCRCConfirm && !x.IsPMConfirm).ToList();
break;
case GetClinicalType.HasSign:
result = result.Where(x => x.IsSign).ToList();
@@ -984,7 +1006,7 @@ namespace IRaCIS.Application.Services
}
}
return result;
}
@@ -1162,7 +1162,13 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// 是否是第一次转化的任务
/// </summary>
public bool IsFirstChangeTask { get; set; } = false;
}
/// <summary>
/// 是否存在临床数据
/// </summary>
public bool IsExistsClinicalData { get; set; } = false;
}
public class GetVisitReadingQuestionOutDto
{
@@ -395,6 +395,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public Arm ArmEnum { get; set; }
public bool IsExistsClinicalData { get; set; }
public MedicalReviewAuditState AuditState { get; set; }
@@ -5,6 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static IRaCIS.Core.Domain.Models.ReadingQuestionTrial;
namespace IRaCIS.Core.Application.Service.Reading.Dto
{
@@ -346,6 +347,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 最大答案长度
/// </summary>
@@ -454,6 +460,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 最大答案长度
/// </summary>
@@ -1000,6 +1011,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 最大答案长度
/// </summary>
@@ -1029,7 +1045,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public List<string> RelevanceValueList { get; set; }
public List<CalculateInfo> CalculateQuestionList { get; set; }
}
}
public class ReadingQuestionSystemView
{
@@ -1058,6 +1075,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 最大答案长度
/// </summary>
@@ -1560,6 +1582,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 最大答案长度
/// </summary>
@@ -1916,6 +1943,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 最大答案长度
/// </summary>
@@ -1953,8 +1985,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public List<string> ParentTriggerValueList { get; set; }
public List<string> RelevanceValueList { get; set; }
}
}
public class GetSystemCriterionSelectDto
{
@@ -21,5 +21,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Interface
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 IRepository<User> _userTaskRepository;
private readonly IVisitTaskService _visitTaskService;
private readonly IReadingClinicalDataService _readingClinicalDataService;
private readonly IRepository<TaskMedicalReview> _taskMedicalReviewRepository;
private readonly IRepository<ReadingMedicalReviewDialog> _readingMedicalReviewDialogRepository;
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrial;
@@ -52,6 +53,7 @@ namespace IRaCIS.Core.Application.Service
IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository,
IRepository<User> userTaskRepository,
IVisitTaskService visitTaskService,
IReadingClinicalDataService readingClinicalDataService,
IRepository<TaskMedicalReview> taskMedicalReviewRepository,
IRepository<ReadingMedicalReviewDialog> readingMedicalReviewDialogRepository,
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrial,
@@ -71,6 +73,7 @@ namespace IRaCIS.Core.Application.Service
this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository;
this._userTaskRepository = userTaskRepository;
this._visitTaskService = visitTaskService;
this._readingClinicalDataService = readingClinicalDataService;
this._taskMedicalReviewRepository = taskMedicalReviewRepository;
this._readingMedicalReviewDialogRepository = readingMedicalReviewDialogRepository;
this._readingQuestionCriterionTrial = readingQuestionCriterionTrial;
@@ -109,6 +112,17 @@ namespace IRaCIS.Core.Application.Service
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.SubjectCode = taskInfo.IsAnalysisCreate?taskInfo.BlindSubjectCode: taskInfo.Subject.Code;
medicalReviewInfo.TaskBlindName = taskInfo.TaskBlindName;
@@ -1013,8 +1013,8 @@ namespace IRaCIS.Application.Services
SynchronizeTime = DateTime.Now,
IsMustGlobalReading = systemCriterion.IsMustGlobalReading,
IseCRFShowInDicomReading=systemCriterion.IseCRFShowInDicomReading,
IsGlobalReading = systemCriterion.IsMustGlobalReading ? true : trialCriterion.IsGlobalReading,
IsReadingPeriod = systemCriterion.IsMustGlobalReading ? true : trialCriterion.IsReadingPeriod,
//IsGlobalReading = systemCriterion.IsMustGlobalReading ? true : trialCriterion.IsGlobalReading,
//IsReadingPeriod = systemCriterion.IsMustGlobalReading ? true : trialCriterion.IsReadingPeriod,
}) ;
@@ -89,7 +89,6 @@ namespace IRaCIS.Application.Services
IRepository<User> userRepository,
IEasyCachingProvider provider,
IRepository<ReadingCustomTag> readingCustomTagRepository,
IMemoryCache cache,
IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository,
IRepository<ReadingTrialCriterionDictionary> readingTrialCriterionDictionaryRepository,
IRepository<TumorAssessment_RECIST1Point1> tumorAssessmentRepository,
@@ -540,7 +539,21 @@ namespace IRaCIS.Application.Services
}).ToListAsync();
if (!taskInfo.TrialReadingCriterion.IsReadingTaskViewInOrder)
foreach (var item in result)
{
var clinicalDataList = await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
{
SubjectId = taskInfo.SubjectId,
TrialId = taskInfo.TrialId,
VisitTaskId = item.VisitTaskId,
});
item.IsExistsClinicalData = clinicalDataList.Count > 0;
}
if (!taskInfo.TrialReadingCriterion.IsReadingTaskViewInOrder)
{
result = result.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToList();
}
@@ -704,9 +717,9 @@ namespace IRaCIS.Application.Services
{
//await AddDefaultValueToTask(inDto.VisitTaskId);
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()
@@ -749,6 +762,16 @@ namespace IRaCIS.Application.Services
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
if (taskinfo.VisitTaskNum == 0)
{
questions = questions.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow).ToList();
}
else
{
questions = questions.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow).ToList();
}
questions.ForEach(x =>
{
x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(taskinfo.IsConvertedTask);
@@ -824,10 +847,7 @@ namespace IRaCIS.Application.Services
[HttpGet]
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)
.WhereIf(inDto.QuestionId != null, x => x.QuestionId == inDto.QuestionId)
.ProjectTo<GetTableAnswerRowInfoOutDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex)
@@ -976,8 +996,18 @@ namespace IRaCIS.Application.Services
if (inDto.TaskId != null)
{
taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.TaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
if (taskInfo.VisitTaskNum == 0)
{
qusetionList = qusetionList.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow).ToList();
qusetionList.ForEach(x =>
}
else
{
qusetionList = qusetionList.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow).ToList();
}
qusetionList.ForEach(x =>
{
x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(taskInfo.IsConvertedTask);
});
@@ -2092,11 +2122,6 @@ namespace IRaCIS.Application.Services
}
await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
{
ReadingTaskState = ReadingTaskState.Reading,
});
await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
await this._readingCalculateService.CalculateTask(new CalculateTaskInDto()
{
@@ -2304,6 +2329,7 @@ namespace IRaCIS.Application.Services
var subjectTaskList = (await _visitTaskService.GetOrderReadingIQueryable(new GetOrderReadingIQueryableInDto()
{
TrialId = inDto.TrialId,
SubjectId=inDto.SubjectId,
TrialReadingCriterionId = trialReadingCriterionId!.Value,
Page = new PageInput()
{
@@ -2325,7 +2351,7 @@ namespace IRaCIS.Application.Services
if (currentSubject == null)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"]);
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
}
task = currentSubject.UnReadCanReadTaskList.Select(x => new GetReadingTaskDto()
@@ -2398,7 +2424,7 @@ namespace IRaCIS.Application.Services
if (task == null)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"]);
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
}
if (task.SubjectCode.IsNullOrEmpty())
@@ -2457,6 +2483,15 @@ namespace IRaCIS.Application.Services
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.DigitPlaces = criterionInfo.DigitPlaces;
@@ -2478,51 +2513,51 @@ namespace IRaCIS.Application.Services
[HttpPost]
public async Task VerifyReadingRestTime()
{
var cacheKey = _userInfo.Id.ToString() + "RestTime";
//var cacheKey = _userInfo.Id.ToString() + "RestTime";
var value = _provider.Get<string>(cacheKey).Value;
if (value == null)
{
_provider.Set(cacheKey, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(5));
// _cache.Set(cacheKey, DateTime.Now.ToString(), TimeSpan.FromHours(5));
//var value = _provider.Get<string>(cacheKey).Value;
//if (value == null)
//{
// _provider.Set(cacheKey, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(5));
// // _cache.Set(cacheKey, DateTime.Now.ToString(), TimeSpan.FromHours(5));
}
else
{
#region
var cacheDate = DateTime.Parse(value.ToString());
int timespanMin = (DateTime.Now - cacheDate).Minutes;
if (timespanMin > 120 && timespanMin < 140)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", 2, 20]);
}
else if (timespanMin > 140)
{
cacheDate = cacheDate.AddMinutes((Math.Floor((double)(timespanMin / 140))) * 140);
_provider.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
// _cache.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
//}
//else
//{
// #region 两小时
// var cacheDate = DateTime.Parse(value.ToString());
// int timespanMin = (DateTime.Now - cacheDate).Minutes;
// if (timespanMin > 120 && timespanMin < 140)
// {
// throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", 2, 20]);
// }
// else if (timespanMin > 140)
// {
// cacheDate = cacheDate.AddMinutes((Math.Floor((double)(timespanMin / 140))) * 140);
// _provider.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
// // _cache.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
}
#endregion
// }
// #endregion
#region 5
//var cacheDate = DateTime.Parse(value.ToString());
//int timespanMin = (DateTime.Now - cacheDate).Minutes;
//if (timespanMin >= 5 && timespanMin <= 10)
//{
// throw new BusinessValidationFailedException("您已连续阅片2个小时,请休息20分钟后,再继续阅片。");
//}
//else if (timespanMin > 10)
//{
// cacheDate = cacheDate.AddMinutes((Math.Floor((double)(timespanMin / 10))) * 10);
// _cache.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
// #region 测试用的5分钟
// //var cacheDate = DateTime.Parse(value.ToString());
// //int timespanMin = (DateTime.Now - cacheDate).Minutes;
// //if (timespanMin >= 5 && timespanMin <= 10)
// //{
// // throw new BusinessValidationFailedException("您已连续阅片2个小时,请休息20分钟后,再继续阅片。");
// //}
// //else if (timespanMin > 10)
// //{
// // cacheDate = cacheDate.AddMinutes((Math.Floor((double)(timespanMin / 10))) * 10);
// // _cache.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
//}
#endregion
// //}
// #endregion
}
//}
@@ -55,11 +55,6 @@ namespace IRaCIS.Application.Services
TrialId = inDto.TrialId
}).ToList();
await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
{
ReadingTaskState = ReadingTaskState.Reading,
});
await _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskAnswerList);
var result = await _visitTaskRepository.SaveChangesAsync();
return ResponseOutput.Ok(result);
@@ -191,7 +191,6 @@ namespace IRaCIS.Application.Services
await _readingOncologyTaskInfoRepository.AddRangeAsync(readingOncologies);
await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == inDto.OncologyTaskId, u => new VisitTask() { ReadingTaskState = ReadingTaskState.Reading });
var result = await _readingOncologyTaskInfoRepository.SaveChangesAsync();
@@ -126,36 +126,35 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
{
var service = await this.GetService(inDto.VisitTaskId);
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)
{
result = await service.AddTaskLesionAnswerFromLastTask(inDto);
await service.CalculateTask(new CalculateTaskInDto()
if (visitTaskInfo.ReadingCategory == ReadingCategory.Visit)
{
IsChangeOtherTask = false,
VisitTaskId = inDto.VisitTaskId,
});
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
{
ReadingTaskState = ReadingTaskState.Reading,
});
result = await service.AddTaskLesionAnswerFromLastTask(inDto);
await service.CalculateTask(new CalculateTaskInDto()
{
IsChangeOtherTask = false,
VisitTaskId = inDto.VisitTaskId,
});
}
}
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>
/// 获取报告验证的信息(这里每个标准可能不一样 返回用object)
@@ -711,7 +711,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
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)
@@ -649,7 +649,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
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)
@@ -549,7 +549,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
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)
@@ -545,7 +545,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
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)
@@ -107,7 +107,7 @@ namespace IRaCIS.Core.Application.Contracts
public bool? IsGenerateAccount { get; set; }
public Guid? TrialRoleNameId { get; set; }
public int? TrialRoleCode { get; set; }
public TrialSiteUserStateEnum? State { get; set; }
@@ -104,6 +104,8 @@ namespace IRaCIS.Core.Application.Contracts
[DictionaryTranslateAttribute("YesOrNo")]
public bool IsGenerateAccount { get; set; }
[DictionaryTranslateAttribute("SiteSurvey_UserRoles")]
public int TrialRoleCode { get; set; }
public string OrganizationName { get; set; } = string.Empty;
@@ -66,7 +66,7 @@ namespace IRaCIS.Core.Application.Contracts
public async Task<IResponseOutput> SendEmialVerifyCode(SendEmialVerifyCodeInDto userInfo)
{
//检查手机或者邮箱是否有效
if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"))
if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
{
//---请输入正确的邮箱地址。
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_InvalidEmail"]);
@@ -124,7 +124,7 @@ namespace IRaCIS.Core.Application.Contracts
public async Task<IResponseOutput> SendVerifyCode(SiteSurveySendVerifyCode userInfo)
{
//检查手机或者邮箱是否有效
if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"))
if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
{
//---请输入正确的邮箱地址。
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_InvalidEmail"]);
@@ -531,6 +531,7 @@ namespace IRaCIS.Core.Application.Contracts
var groupSelectIdQuery =
_trialSiteSurveyRepository.Where(t => t.TrialId == queryParam.TrialId)
.WhereIf(queryParam.SiteId != null, t => t.SiteId == queryParam.SiteId)
.WhereIf(!string.IsNullOrEmpty(queryParam.FormWriterKeyInfo), t => (t.UserName).Contains(queryParam.FormWriterKeyInfo) || t.Email.Contains(queryParam.FormWriterKeyInfo) || t.Phone.Contains(queryParam.FormWriterKeyInfo))
.GroupBy(t => t.SiteId)
.Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First());
@@ -538,6 +539,7 @@ namespace IRaCIS.Core.Application.Contracts
var query = _trialSiteUserSurveyRepository
.Where(t => groupSelectIdQuery.Contains(t.TrialSiteSurveyId))
.WhereIf(queryParam.TrialRoleCode != null, t => t.TrialRoleCode == queryParam.TrialRoleCode)
.WhereIf(queryParam.UserTypeId != null, t => t.UserTypeId == queryParam.UserTypeId)
.WhereIf(queryParam.IsGenerateAccount != null, t => t.IsGenerateAccount == queryParam.IsGenerateAccount)
.WhereIf(queryParam.State != null && queryParam.State != TrialSiteUserStateEnum.OverTime, t => t.InviteState == queryParam.State)
@@ -22,14 +22,14 @@ namespace IRaCIS.Application.Contracts
[DictionaryTranslateAttribute("IsUserExitTrial")]
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 Guid? SiteId { get; set; }
public string Phone { get; set; } = String.Empty;
public DateTime UpdateTime { get; set; }
[ExcelFormat("yyyy-MM-dd hh:mm:ss")]
[ExcelFormat("yyyy-MM-dd HH:mm:ss")]
public DateTime CreateTime { get; set; }
@@ -53,6 +53,16 @@ namespace IRaCIS.Application.Contracts
public string RealName { get; set; } = String.Empty;
public string UserName { get; set; } = String.Empty;
}
public class TrialUserBasicInfo
{
public Guid UserTypeId { get; set; }
public string UserName { get; set; }
public string FullName { get; set; }
public Guid UserId { get; set; }
}
public class TrialMaintenanceDTO : UserTrialCommand
{
@@ -84,7 +94,7 @@ namespace IRaCIS.Application.Contracts
[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; }
@@ -118,7 +128,8 @@ namespace IRaCIS.Application.Contracts
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; }
@@ -1,6 +1,7 @@
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.Reading.Interface;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
@@ -21,11 +22,13 @@ namespace IRaCIS.Core.Application
private readonly IRepository<TrialDocument> _trialDocumentRepository;
private readonly IRepository<SystemDocument> _systemDocumentRepository;
private readonly IRepository<ReadModule> _readModuleRepository;
private readonly IClinicalAnswerService _clinicalAnswerService;
private readonly IRepository<SystemNotice> _systemNoticeRepository;
public PersonalWorkstation(IRepository<Trial> trialRepository, IRepository<TrialUser> trialUserRepository, IRepository<TrialDocument> trialDocumentRepository,
IRepository<SystemDocument> systemDocumentRepository,
IRepository<ReadModule> readModuleRepository,
IClinicalAnswerService clinicalAnswerService,
IRepository<SystemNotice> systemNoticeRepository)
{
_trialRepository = trialRepository;
@@ -33,6 +36,7 @@ namespace IRaCIS.Core.Application
_trialDocumentRepository = trialDocumentRepository;
_systemDocumentRepository = systemDocumentRepository;
this._readModuleRepository = readModuleRepository;
this._clinicalAnswerService = clinicalAnswerService;
_systemNoticeRepository = systemNoticeRepository;
}
@@ -429,7 +433,7 @@ 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(),
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(),
ReadModuleCount = t.ReadModuleList.Where(x => !x.IsPMConfirm).Count(),
ReadModuleCount = t.ReadModuleList.Where(x => !x.IsCRCConfirm).Count(),
}).Where(x => x.ReadModuleCount > 0);
var defalutSortArray = new string[] { nameof(ImageClinicalDataToBeDoneDto.UrgentCount) + " desc", nameof(ImageClinicalDataToBeDoneDto.ToBeDealedCount) + " desc" };
@@ -437,6 +441,22 @@ namespace IRaCIS.Core.Application
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
//.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id) && t.Trial.clinicalDataTrialSets.Any(t => t.ClinicalDataLevel == ClinicalLevel.Subject && t.IsConfirm))
.Where(u => u.IsBaseLine && u.SubmitState != SubmitStateEnum.Submitted).Count();
@@ -674,7 +694,8 @@ namespace IRaCIS.Core.Application
//待领取量
ToBeClaimedCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted).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提交之间的 已领取 待审核 审核中 (审核完成 领取人就会清理 所以只用查询当前领取人是自己的就好了)
ToBeReviewedCount = t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.Id).Count()
@@ -689,7 +710,7 @@ namespace IRaCIS.Core.Application
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();
@@ -62,7 +62,13 @@ namespace IRaCIS.Application.Services
#endregion
[HttpGet]
public async Task<List<TrialUserBasicInfo>> GetTrialUserList(Guid trialId)
{
return await _trialUseRepository.Where(t => t.TrialId == trialId, ignoreQueryFilters: true)
.Select(t => new TrialUserBasicInfo() { FullName = t.User.FullName, UserId = t.UserId, UserTypeId = t.User.UserTypeId, UserName = t.User.UserName })
.ToListAsync();
}
/// <summary>
/// Setting页面 获取项目参与人员列表
@@ -194,10 +194,10 @@ namespace IRaCIS.Core.Application.Services
var siteQueryable = _siteRepository.AsQueryable(true)
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.SiteName), t => t.SiteName.Contains(searchModel.SiteName)|| t.SiteNameCN.Contains(searchModel.SiteName))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.SiteName), t => t.SiteName.Contains(searchModel.SiteName) || t.SiteNameCN.Contains(searchModel.SiteName) || t.AliasName.Contains(searchModel.SiteName))
.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.Country), t => t.Country.Contains(searchModel.Country))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.City), t => t.City.Contains(searchModel.City))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Country), t => t.Country.Contains(searchModel.Country))
.ProjectTo<TrialSiteScreeningDTO>(_mapper.ConfigurationProvider, new { trialId = searchModel.TrialId , isEn_Us =_userInfo.IsEn_Us});
@@ -330,8 +330,8 @@ namespace IRaCIS.Core.Application.Services
var tag = await _readingCustomTagRepository.Where(x => x.VisitTaskId == indto.VisitTaskId && x.StudyId != null).Select(x => new
{
ShowOrder= 0,
RowIndex= 0m,
ShowOrder = 0,
RowIndex = 0m,
x.SeriesId,
x.StudyId,
x.InstanceId,
@@ -447,23 +447,23 @@ namespace IRaCIS.Core.Application.Services
var studyList = await _repository.Where<DicomStudy>(t => t.TrialId == indto.TrialId && t.SubjectVisitId == indto.SujectVisitId)
.Select(k => new VisitStudyDTO()
{
InstanceCount = k.InstanceCount,
Modalities = k.Modalities,
SeriesCount = k.SeriesCount,
StudyCode = k.StudyCode,
StudyId = k.Id,
{
InstanceCount = k.InstanceCount,
Modalities = k.Modalities,
SeriesCount = k.SeriesCount,
StudyCode = k.StudyCode,
StudyId = k.Id,
}).ToListAsync();
}).ToListAsync();
var studyIds = studyList.Select(t => t.StudyId).ToList();
var instanceList = await _repository.Where<DicomInstance>(t => studyIds.Contains(t.StudyId))
.Select(t => new { t.SeriesId, t.Id, t.InstanceNumber, t.Path, t.NumberOfFrames,t.WindowCenter,t.WindowWidth }).ToListAsync();
.Select(t => new { t.SeriesId, t.Id, t.InstanceNumber, t.Path, t.NumberOfFrames, t.WindowCenter, t.WindowWidth }).ToListAsync();
List<DicomSeriesDTO> seriesLists = await _repository.Where<DicomSeries>(s => studyIds.Contains(s.StudyId) /*&& s.IsReading*/)
.WhereIf(isManualGenerate==false, t => t.IsReading)
.WhereIf(isManualGenerate == false, t => t.IsReading)
.OrderBy(s => s.SeriesNumber).
ThenBy(s => s.SeriesTime)
.ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();
@@ -531,23 +531,35 @@ namespace IRaCIS.Core.Application.Services
foreach (var item in noDicomStudyList)
{
var nodicom = noDicomList.Where(x => x.Id == item.StudyId).First();
item.SeriesList = new List<DicomSeriesDTO>()
{
new DicomSeriesDTO (){
IsDicom=false,
Id=item.StudyId,
InstanceCount=await _noneDicomStudyFileRepository.Where(x=>x.NoneDicomStudyId==item.StudyId).CountAsync(),
Modality=item.Modalities,
StudyId=item.StudyId,
TrialId=nodicom.TrialId,
SiteId=nodicom.SiteId,
SubjectVisitId=nodicom.SubjectVisitId,
SubjectId=nodicom.SubjectId,
SeriesNumber=1,
NoneDicomFileFirstFile=await _noneDicomStudyFileRepository.Where(x=>x.NoneDicomStudyId==item.StudyId).Select(x=>x.Path).FirstOrDefaultAsync(),
}
};
var instanceCount = await _noneDicomStudyFileRepository.Where(x => x.NoneDicomStudyId == item.StudyId).CountAsync();
if (instanceCount == 0)
{
item.SeriesList = new List<DicomSeriesDTO>();
item.SeriesCount = 0;
}
else
{
item.SeriesList = new List<DicomSeriesDTO>()
{
new DicomSeriesDTO (){
IsDicom=false,
Id=item.StudyId,
InstanceCount=instanceCount,
Modality=item.Modalities,
StudyId=item.StudyId,
TrialId=nodicom.TrialId,
SiteId=nodicom.SiteId,
SubjectVisitId=nodicom.SubjectVisitId,
SubjectId=nodicom.SubjectId,
SeriesNumber=1,
NoneDicomFileFirstFile=await _noneDicomStudyFileRepository.Where(x=>x.NoneDicomStudyId==item.StudyId).Select(x=>x.Path).FirstOrDefaultAsync(),
}
};
}
}
@@ -35,7 +35,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<VisitStage, VisitStageDTO>();
CreateMap<Subject, SubjectQueryView>()
.ForMember(d => d.SiteName, u => u.MapFrom(s => s.TrialSite.Site.SiteName))
.ForMember(d => d.SiteName, u => u.MapFrom(s => s.TrialSite.TrialSiteAliasName))
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode))
.ForMember(d => d.LatestBlindName, u => u.MapFrom(s => s.LatestSubjectVisit.BlindName))
.ForMember(d => d.LatestVisitName, u => u.MapFrom(s => s.LatestSubjectVisit.VisitName))
@@ -88,8 +88,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<SubjectVisit, DicomTrialSiteSubjectInfo>().IncludeMembers(t=>t.Trial)
.ForMember(d => d.SiteName, u => u.MapFrom(s => s.Site.SiteName))
.ForMember(d => d.SiteCode, u => u.MapFrom(s => s.Site.SiteCode))
.ForMember(d => d.TrialSiteAliasName, u => u.MapFrom(s => s.TrialSite.TrialSiteAliasName))
.ForMember(d => d.SubjectVisitId, u => u.MapFrom(s => s.Id))
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode))
.ForMember(d => d.TrialCode, u => u.MapFrom(s => s.Trial.TrialCode))
@@ -354,6 +354,8 @@ namespace IRaCIS.Application.Contracts
public bool IsOncologyReading { get; set; }
public bool IsReadingPeriod { get; set; }
}
public class TrialCriterionReadingCategory
+225 -72
View File
@@ -1,4 +1,6 @@
using DocumentFormat.OpenXml.Office2010.Excel;
using Aliyun.OSS;
using Castle.DynamicProxy.Generators.Emitters.SimpleAST;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
@@ -12,8 +14,15 @@ using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MiniExcelLibs;
using Minio;
using Minio.DataModel.Args;
using NPOI.HPSF;
using NPOI.POIFS.Crypt;
using SharpCompress.Common;
using Spire.Doc;
using System.Linq.Expressions;
using System.Reflection.Metadata;
using System.Security.AccessControl;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
@@ -25,7 +34,7 @@ namespace IRaCIS.Application.Services
public class TestService : BaseService
{
public static int IntValue = 100;
public static int IntValue = 100;
private readonly IRepository<Dictionary> _dicRepository;
private readonly IRepository<Trial> _trialRepository;
@@ -40,7 +49,7 @@ namespace IRaCIS.Application.Services
private readonly ILogger<TestService> _logger;
public TestService(IRepository<Dictionary> dicRepository, IRepository<Trial> trialRepository,ILogger<TestService> logger
public TestService(IRepository<Dictionary> dicRepository, IRepository<Trial> trialRepository, ILogger<TestService> logger
, IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig, IOptionsMonitor<ServiceVerifyConfigOption> basicConfig, IRepository<VisitTask> visitTaskRepository, IDistributedLockProvider distributedLockProvider)
{
@@ -52,31 +61,56 @@ namespace IRaCIS.Application.Services
_dicRepository = dicRepository;
_trialRepository = trialRepository;
_distributedLockProvider= distributedLockProvider;
_distributedLockProvider = distributedLockProvider;
_logger= logger;
_logger = logger;
//_cache = cache;
}
[AllowAnonymous]
public async Task<IResponseOutput> TestDistributedLock( )
public async Task<IResponseOutput> TestEFcore8()
{
await _repository.Where<User>().Select(t => t.FullName).FirstNotNullAsync();
//var aa= _dicRepository._dbContext.Subject.Where(t => t.Id == Guid.Empty).ExecuteUpdate("FirstName","ddd");
await _repository.BatchUpdateAsync<Subject>(t => t.Id == Guid.Empty, u => new Subject() { FirstName = "fddd", LastName = "sss", UpdateTime = DateTime.Now });
await _repository.Where<Subject>().ExecuteUpdateAsync(t => t.SetProperty(t => t.UpdateTime, u => DateTime.Now));
return ResponseOutput.Ok();
}
// 设置 Ne
[AllowAnonymous]
public async Task<IResponseOutput> TestMinIO([FromServices] IOSSService oSSService)
{
await oSSService.UploadToOSSAsync("C:\\Users\\Administrator\\Desktop\\TrialSiteUserImportTemplate.xlsx", "myfolder");
await oSSService.DownLoadFromOSSAsync("/myfolder/TrialSiteUserImportTemplate.xlsx", "C:\\Users\\Administrator\\Desktop\\aws.xlsx");
return ResponseOutput.Ok();
}
[AllowAnonymous]
public async Task<IResponseOutput> TestDistributedLock()
{
await _repository.Where<User>().Select(t => t.FullName).FirstNotNullAsync();
Console.WriteLine($"我进来了当前值是:" + IntValue);
_logger.LogWarning($"我进来了当前值是:" + IntValue);
var @lock = _distributedLockProvider.CreateLock($"UserAccount");
using (await @lock.AcquireAsync())
using (await @lock.AcquireAsync())
{
await Task.Delay(4);
IntValue--;
_logger.LogWarning( IntValue.ToString());
_logger.LogWarning(IntValue.ToString());
Console.WriteLine(IntValue);
}
@@ -85,86 +119,126 @@ namespace IRaCIS.Application.Services
[AllowAnonymous]
public async Task<IResponseOutput> GetMemoryStoreData()
public async Task<IResponseOutput> InternationazitionInit()
{
var rows = await MiniExcel.QueryAsync<InternationalizationAddOrEdit>(@"C:\Users\Administrator\Desktop\i18n-new2.xlsx");
return ResponseOutput.Ok(new { StaticData.En_US_Dic , StaticData.Zh_CN_Dic });
rows = rows.Where(t => !string.IsNullOrEmpty(t.Code)).ToList();
foreach (var row in rows)
{
await _repository.InsertOrUpdateAsync<Internationalization, InternationalizationAddOrEdit>(row);
}
await _repository.SaveChangesAsync();
return ResponseOutput.Ok();
}
//[AllowAnonymous]
//public async Task<IResponseOutput> InternationazitionInit()
//{
// var rows = await MiniExcel.QueryAsync<InternationalizationAddOrEdit>(@"C:\Users\Administrator\Desktop\Export\vue.xlsx");
// foreach (var row in rows)
// {
// await _repository.InsertOrUpdateAsync<Internationalization, InternationalizationAddOrEdit>(row);
// }
// await _repository.SaveChangesAsync();
// return ResponseOutput.Ok();
//}
[AllowAnonymous]
[UnitOfWork]
public async Task<string> Get()
{
return "修改服务器时间自动发布测试--我又修改了";
//Expression<Func<VisitTask, bool>> visitTaskLambda = x => x.TrialId == Guid.Empty && x.SubjectId == Guid.Empty && x.TrialReadingCriterionId == Guid.Empty;
//var visitTaskIdQueryable = _visitTaskRepositoryy.Where(visitTaskLambda).Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)).Select(t => t.Id);
//await _visitTaskRepositoryy.BatchUpdateNoTrackingAsync(t => visitTaskIdQueryable.Contains(t.Id), u => new VisitTask()
//{
// IsFrontTaskNeedSignButNotSign = true
//});
//var a = ((Decimal)1.00).ToString().TrimEnd(new char[] { '.', '0' });
//var b = ((Decimal)1.01).ToString().TrimEnd(new char[] { '.', '0' });
//var c = ((Decimal)100).ToString().TrimEnd(new char[] { '.', '0' });
//var subject1 = Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391693");
//var subject2 = Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391694");
// var subjectList = new List<Guid>() { Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391693") ,
// Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391694") ,
// Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391695")
// };
//string[] citys = new string[] { "广州", "深圳", "上海", "北京" };
//foreach (var item in subjectList)
//{
// Console.WriteLine(await BNRFactory.Default.Create($"[CN:{item}][N:[CN:{item}]/0000000]"));
//}
//foreach (var item in subjectList)
//{
// Console.WriteLine(await BNRFactory.Default.Create($"[N:[CN:{item}]/0000000]"));
//}
//foreach (var item in subjectList)
//{
// Console.WriteLine(await BNRFactory.Default.Create($"[CN:{item}][redis:city/0000000]"));
//}
//var needAddVisitList = await _repository.Where<VisitTask>(t => t.TrialId == Guid.Empty).DistinctBy(t => t.VisitTaskNum).ToListAsync();
//await _repository.BatchUpdateAsync<VisitTask>(t => t.Id == Guid.Empty, u => new VisitTask()
//{
// SuggesteFinishedTime = u.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7),
// Code = u.Code + 1
//});
//var query = from item1 in _repository.Where<ReadingQuestionTrial>()
// join item2 in _repository.Where<ReadingQuestionTrial>() on item1.ValueType equals item2.ValueType
// select new
// {
// item1.ValueType,
// dd = item2.ValueType
// };
//var list2 = query.ToList();
//await Task.CompletedTask;
//var list = await _repository.Where<ClinicalDataTrialSet>(t => t.TrialId == Guid.Parse("40400000-3e2c-0016-239b-08da581f0e74")).ToListAsync();
////await _repository.BatchDeleteAsync<ClinicalDataTrialSet>(t => t.TrialId == Guid.Parse("40400000-3e2c-0016-239b-08da581f0e74"));
//await _repository.AddRangeAsync(list, true);
//await _repository.SaveChangesAsync();
//await _repository.BatchUpdateAsync<DataInspection>(t => t.TrialId == Guid.Parse("40400000-3e2c-0016-239b-08da581f0e74") && t.EntityName== "ClinicalDataTrialSet", t => new DataInspection() { CreateTime= DateTime.Now.AddMonths(-2) } );
//await _visitTaskRepositoryy.UpdatePartialFromQueryAsync( Guid.Parse("78360000-3E2C-0016-9B53-08DA6A002040"), c => new VisitTask() { UpdateTime = DateTime.Now });
//await _visitTaskRepositoryy.UpdatePartialFromQueryAsync( Guid.Parse("78360000-3E2C-0016-9B53-08DA6A002040"), c => new VisitTask() { UpdateTime = DateTime.Now.AddMinutes(1) });
//var a = _userInfo.IsTestUser;
//var list1 = await _repository.Where<Dictionary>().Select(t => t.TranslateValue(t.Value, t.ValueCN, true)).ToListAsync();
//var list2 = await _repository.Where<Dictionary>().Select(t => t.TranslateValue(t.Value, t.ValueCN, false)).ToListAsync();
return "测试自动发布--再次提交";
}
private static Dictionary<string, string> _replacePatterns = new Dictionary<string, string>()
{
{ "test", "Atlanta Knight" },
{ "GAME_TIME", "7:30pm" },
{ "GAME_NUMBER", "161" },
{ "DATE", "October 18 2018" },
};
private static string ReplaceFunc(string findStr)
{
if (_replacePatterns.ContainsKey(findStr))
{
return _replacePatterns[findStr];
}
return findStr;
}
[AllowAnonymous]
public async Task<List<Guid>> testwwwww([FromServices] IWebHostEnvironment env)
public async Task testwwwww([FromServices] IWebHostEnvironment env)
{
int count = 200;
var list=new List<Guid>();
for (int i = 0; i < count; i++)
{
Guid guid = NewId.NextGuid();
list.Add(guid);
}
return list;
await Task.CompletedTask;
}
[AllowAnonymous]
public async Task<object> GetEnvironmentName([FromServices] IWebHostEnvironment env)
{
var a = IdentifierHelper.CreateGuid("1.2.840.113619.2.416.3358551739363725609857319676326094825431.2.840.113619.2.80.2338912612.50499.1563432834.1.4.11.2.840.113619.2.80.2338912612.50499.1563432835.4b8340000-3e2c-0016-fbdd-08db883b137f");
var a = IdentifierHelper.CreateGuid("123456");
var k = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("123456"));
var c = MD5Helper.Md5("1.2.840.113619.2.416.3358551739363725609857319676326094825431.2.840.113619.2.80.2338912612.50499.1563432834.1.4.11.2.840.113619.2.80.2338912612.50499.1563432835.4b8340000-3e2c-0016-fbdd-08db883b137f");
var c = MD5Helper.Md5("123456");
//update DicomInstance set Path = '/IRaCISData/TrialData/' + cast(DicomInstance.TrialId as varchar) + '/' + DicomInstance.SiteId + '/' + DicomInstance.SubjectId + '/' + DicomInstance.SubjectVisitId + '/Dicom/' + DicomInstance.StudyId + '/' + DicomInstance.Id + '.dcm'
@@ -255,11 +329,7 @@ namespace IRaCIS.Application.Services
public string PostData(TestModel testModelList)
{
return String.Empty;
}
#region
/// <summary>
/// 维护临床数据 --一定要在同步表前同步数据才行
/// </summary>
@@ -299,6 +369,89 @@ namespace IRaCIS.Application.Services
}
/// <summary>
/// 维护OSS 影像数据
/// </summary>
/// <returns></returns>
[AllowAnonymous]
[UnitOfWork]
public async Task<IResponseOutput> OldLocalImageResizeJpg([FromServices] IOSSService oSSService, [FromServices] IRepository _repository, [FromServices] IWebHostEnvironment _hostEnvironment)
{
var aliConfig = oSSService.ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
var studyList = _repository.Where<DicomStudy>(t => t.SeriesList.Any(t => t.ImageResizePath.Length < 10)).Select(t => new { t.TrialId, t.SiteId, t.SubjectId, t.SubjectVisitId, t.Id }).ToList();
foreach (var studyitem in studyList)
{
var relativePath = $"{studyitem.TrialId}/{studyitem.SiteId}/{studyitem.SubjectId}/{studyitem.SubjectVisitId}/{StaticData.Folder.DicomFolder}/{studyitem.Id}/";
try
{
string nextMarker = null;
do
{
// 使用 prefix 模拟目录结构,设置 MaxKeys 和 NextMarker
var objectListing = _ossClient.ListObjects(new ListObjectsRequest(aliConfig.bucketName)
{
Prefix = relativePath,
MaxKeys = 1000,
Marker = nextMarker
});
var jpgInfoList = objectListing.ObjectSummaries
.Where(summary => summary.Key.EndsWith(".jpg"))
.Select(summary =>
{
string fileName = summary.Key.Split('/').Last(); // 提取文件夹名
return new
{
Key = summary.Key,
InstanceId = Guid.TryParse(
fileName.Split('.')[0],
out Guid instanceId)
? instanceId
: Guid.Empty
};
})
.Where(info => info.InstanceId != Guid.Empty)
.ToList();
foreach (var jpg in jpgInfoList)
{
var seriesId = _repository.Where<DicomInstance>(t => t.Id == jpg.InstanceId).Select(t => t.SeriesId).FirstOrDefault();
await _repository.BatchUpdateAsync<DicomSeries>(t => t.Id == seriesId, t => new DicomSeries() { ImageResizePath = "/" + jpg.Key });
}
// 设置 NextMarker 以获取下一页的数据
nextMarker = objectListing.NextMarker;
} while (!string.IsNullOrEmpty(nextMarker));
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
await _repository.SaveChangesAsync();
}
return ResponseOutput.Ok();
}
#endregion
}
public class TestModel
@@ -54,7 +54,7 @@ namespace IRaCIS.Core.Application.Triggers
t.TrialId = subject.TrialId;
t.SiteId = subject.SiteId;
t.IsEnrollmentConfirm = t.IsBaseLine ? triconfig.IsEnrollementQualificationConfirm : false;
t.PDState = t.IsBaseLine==false && triconfig.IsPDProgressView ? PDStateEnum.PDProgress : PDStateEnum.None;
t.PDState = t.IsBaseLine == false && triconfig.IsPDProgressView ? PDStateEnum.PDProgress : PDStateEnum.None;
t.Id = NewId.NextGuid();
});
@@ -65,6 +65,7 @@ namespace IRaCIS.Core.Application.Triggers
await _subjectVisitRepository.SaveChangesAsync();
#region f访视计划确认的时候处理 subject添加访视计划
////已添加受试者 都不存在该新增的计划名称 那么该项目所有受试者都增加一个访视记录
//if (!await _subjectVisitRepository.AnyAsync(t => t.VisitName == visitPlan.VisitName && t.TrialId == visitPlan.TrialId))
//{
@@ -0,0 +1,42 @@
using EntityFrameworkCore.Triggered;
using IP2Region.Net.Abstractions;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Triggers
{
public class UserLogTrigger : IBeforeSaveTrigger<UserLog>
{
public ISearcher _searcher;
public ILogger<UserLogTrigger> _logger;
public UserLogTrigger(ISearcher searcher,ILogger<UserLogTrigger> logger)
{
_searcher = searcher;
_logger= logger;
}
//国家|区域|省份|城市|ISP 缺省的地域信息默认是0
//0|0|0|内网IP|内网IP
// 中国|0|湖北省|武汉市|电信
public async Task BeforeSave(ITriggerContext<UserLog> context, CancellationToken cancellationToken)
{
var userLog = context.Entity;
if (context.ChangeType == ChangeType.Added)
{
var ipinfo = _searcher.Search(userLog.IP);
userLog.IPRegion = string.Join('|', ipinfo.Split('|').TakeLast(3));
}
}
}
}
@@ -52,6 +52,7 @@ namespace IRaCIS.Core.Application.Triggers
if (context.ChangeType == ChangeType.Modified && visitTask.ReadingTaskState==ReadingTaskState.HaveSigned && visitTask.ReadingTaskState != context.UnmodifiedEntity.ReadingTaskState && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI)
{
visitTask.PIAuditState = PIAuditState.PIAgree;
visitTask.FirstAuditUserId = _userInfo.Id;
}
if (context.ChangeType == ChangeType.Modified && visitTask.PIAuditState!=context.UnmodifiedEntity.PIAuditState && visitTask.PIAuditState==PIAuditState.PIAgree)
@@ -22,13 +22,13 @@ namespace IRaCIS.Core.Application.Triggers
private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;
private readonly IRepository<ReadingJudgeInfo> _readingJudgeInfoRepository;
public VisitTaskIsFrontTaskNeedSignButNotSignTrigger(
IRepository<VisitTask> visitTaskRepository, IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository, IRepository<ReadingQuestionTrial> trialReadingQuestionRepository
, IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository)
, IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository, IRepository<ReadingJudgeInfo> readingJudgeInfoRepository)
{
_trialReadingCriterionRepository = trialReadingCriterionRepository;
@@ -36,6 +36,7 @@ namespace IRaCIS.Core.Application.Triggers
_trialReadingQuestionRepository = trialReadingQuestionRepository;
_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;
if (context.ChangeType == ChangeType.Added)
{
//判断是否需要临床数据签名 不需要 就不用维护
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
}
@@ -92,10 +92,10 @@ namespace IRaCIS.Core.Application.MediatR.CommandAndQueries
//[Required(ErrorMessage = "检查日期不能为空")]
[CanConvertToTime(ErrorMessage = "Does not conform to Stusy Date format")]
[CanConvertToTime(ErrorMessage = "Does not conform to Study Date format")]
[ImporterHeader(Name = "Stusy Date", AutoTrim = true)]
[ExcelColumnName("Stusy Date")]
[ImporterHeader(Name = "Study Date", AutoTrim = true)]
[ExcelColumnName("Study Date")]
public string StudyDate { get; set; } = string.Empty;
@@ -191,6 +191,8 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
dbSV.CheckState = CheckStateEnum.CVPassed;
dbSV.CheckUserId = _userInfo.Id;
dbSV.CheckPassedTime = DateTime.Now;
dbSV.CheckChallengeState = CheckChanllengeTypeEnum.Closed;
//---核对EDC数据,完全一致
dbSV.CheckResult = _localizer["ConsistencyVerification_EDCB"];
//---自动核查通过
+28 -4
View File
@@ -1811,10 +1811,34 @@ namespace IRaCIS.Core.Domain.Share
}
/// <summary>
/// 限制编辑
/// </summary>
public enum LimitEdit
/// <summary>
/// 显示限制
/// </summary>
public enum LimitShow
{
/// <summary>
/// 全都显示
/// </summary>
AllShow = 0,
/// <summary>
/// 基线显示
/// </summary>
BaseLineShow = 1,
/// <summary>
/// 随访显示
/// </summary>
FollowShow = 2,
}
/// <summary>
/// 限制编辑
/// </summary>
public enum LimitEdit
{
/// <summary>
@@ -33,16 +33,18 @@ namespace IRaCIS.Core.Domain.Models
public int State { get; set; }
public string Description { get; set; }
public string Description { get; set; } = string.Empty;
public string Code { get; set; }
public string Code { get; set; } = string.Empty;
public string Value { get; set; }
public string Value { get; set; } = string.Empty;
public string ValueCN { get; set; }
public string ValueCN { get; set; } = string.Empty;
public int InternationalizationType { get; set; }
public string FrontType { get; set; }=string.Empty;
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ namespace IRaCIS.Core.Domain.Models
///</summary>
[Table("TrialDocument")]
public class TrialDocument : Entity, IAuditUpdate, IAuditAdd
{
{
//需要确认的项目用户 通过TrialId 关联 用中间表过滤
@@ -41,7 +41,7 @@ namespace IRaCIS.Core.Domain.Models
[JsonIgnore]
public List<TrialEmailNoticeUser> TrialEmailNoticeUserList { get; set; } = new List<TrialEmailNoticeUser>();
[JsonIgnore]
public List<TrialEmailBlackUser> TrialEmailBlackUserList { get; set; } = new List<TrialEmailBlackUser>();
@@ -85,7 +85,9 @@ namespace IRaCIS.Core.Domain.Models
public bool IsSuccess { get; set; }
public string Note = string.Empty;
public string Note { get; set; } = string.Empty;
public string RecordPath { get; set; }=string.Empty;
}
+2
View File
@@ -47,6 +47,8 @@ namespace IRaCIS.Core.Domain.Models
[JsonIgnore]
public User OptUser { get; set; }
public string IPRegion { get; set; }
}
/// <summary>
@@ -181,6 +181,10 @@ namespace IRaCIS.Core.Domain.Models
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 数据来源
@@ -231,6 +231,11 @@ namespace IRaCIS.Core.Domain.Models
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 自定义计算标记
/// </summary>
@@ -261,7 +266,11 @@ namespace IRaCIS.Core.Domain.Models
/// </summary>
public Guid? GroupId { get; set; }
[JsonIgnore]
//
[JsonIgnore]
[ForeignKey("GroupId")]
public ReadingQuestionTrial GroupInfo { get; set; }
@@ -284,8 +293,18 @@ namespace IRaCIS.Core.Domain.Models
[JsonIgnore]
public List<ReadingTableQuestionTrial> ReadingTableQuestionTrialList { get; set; }
[NotMapped]
public enum AssessmentResultType
{
//没有特殊标记
None=0,
//评估结果
AssessmentResult = 1,
}
[NotMapped]
public List<string> ParentTriggerValueList
{
get

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