Compare commits

...

877 Commits

Author SHA1 Message Date
hang 41ae2febc7 改为阿里云 2024-06-26 15:12:06 +08:00
hang c072c526e2 修改uat 配置文件 2024-06-26 14:36:56 +08:00
hang d6bb98b84f 中心调研修改 2024-06-25 10:57:42 +08:00
hang 42587ee59f 删掉邮件日志组件 2024-06-25 09:17:28 +08:00
hang 62a964a3ea 发送邮件的包降级 2024-06-25 09:01:58 +08:00
hang 72447eb82f 修改 界面控制bug 2024-06-24 16:53:53 +08:00
hang 2f83c27fde 修改筛选条件 2024-06-24 16:39:43 +08:00
hang b219593f61 医生入组,没有spm修改逻辑 2024-06-24 16:39:40 +08:00
hang 8521b0c28c 增加清理跟踪的方法
continuous-integration/drone/push Build is passing
2024-06-20 17:50:17 +08:00
hang 26a62426f0 修改发布方式
continuous-integration/drone/push Build is passing
2024-06-20 15:08:47 +08:00
hang 1246413e30 修改nonedicom过滤
continuous-integration/drone/push Build is passing
2024-06-19 19:38:16 +08:00
hang f50b5819c0 修改过滤规则
continuous-integration/drone/push Build is passing
2024-06-19 18:40:32 +08:00
hang 6db8d61b7c 修改 非dicom 检查过滤
continuous-integration/drone/push Build is passing
2024-06-19 17:57:40 +08:00
hang 58250fe993 非dicom zip过滤
continuous-integration/drone/push Build is passing
2024-06-19 16:57:08 +08:00
hang 6cae7a1ae4 修改非dicom 文件上传 增加文件类型
continuous-integration/drone/push Build is passing
2024-06-19 15:17:55 +08:00
hang 73541efbf4 uat 截图修改配置文件
continuous-integration/drone/push Build is passing
2024-06-19 14:17:35 +08:00
hang f4bd891deb 记录最新登录时间
continuous-integration/drone/push Build is passing
2024-06-19 13:48:59 +08:00
hang a9831657cc 修改Uat IRC 配置
continuous-integration/drone/push Build is passing
2024-06-19 13:11:20 +08:00
hang 500a9fbaca 修改配置文件
continuous-integration/drone/push Build is passing
2024-06-19 09:08:17 +08:00
hang 5f11c3a602 修改site 启用时间逻辑
continuous-integration/drone/push Build is passing
2024-06-18 19:36:57 +08:00
hang 7680e90d65 修改添加trialSite逻辑
continuous-integration/drone/push Build is passing
2024-06-18 19:28:26 +08:00
hang 06a57cd056 修改中心调样cpm bug
continuous-integration/drone/push Build is passing
2024-06-18 15:09:52 +08:00
hang 7626d17540 记录邮件异常
continuous-integration/drone/push Build is passing
2024-06-18 13:28:40 +08:00
hang 344b92c427 修改配置文件
continuous-integration/drone/push Build is passing
2024-06-18 13:16:26 +08:00
hang 4719177009 时间环境配置修改
continuous-integration/drone/push Build is passing
2024-06-18 11:53:17 +08:00
hang c1461633ce 修改中心调研国际化
continuous-integration/drone/push Build is passing
2024-06-18 11:10:18 +08:00
hang 6be7aa1ad9 修改默认值
continuous-integration/drone/push Build is passing
2024-06-18 10:28:10 +08:00
hang 4da7c2f960 irc minio 修改配置文件
continuous-integration/drone/push Build is passing
2024-06-17 11:48:09 +08:00
hang 47a45df610 修改mfa 配置
continuous-integration/drone/push Build is passing
2024-06-17 10:38:42 +08:00
hang 1a44e48b2d 删除备注
continuous-integration/drone/push Build is passing
2024-06-17 08:59:53 +08:00
hang c566a703eb 修改trialSitte Id 问题
continuous-integration/drone/push Build is passing
2024-06-14 16:04:12 +08:00
hang 001c248cb8 中心调研返回项目modality
continuous-integration/drone/push Build is passing
2024-06-14 15:35:08 +08:00
hang 654462fe6b 插入字符串efbug
continuous-integration/drone/push Build is passing
2024-06-14 14:34:18 +08:00
hang ab6642ce33 过滤检查
continuous-integration/drone/push Build is passing
2024-06-14 14:29:55 +08:00
hang 946386ad43 检查技术修改
continuous-integration/drone/push Build is passing
2024-06-14 13:46:30 +08:00
hang cf9c79a928 过滤失效的任务
continuous-integration/drone/push Build is passing
2024-06-14 13:28:42 +08:00
hang 493e4e8dca 枚举不能识别
continuous-integration/drone/push Build is passing
2024-06-14 11:05:07 +08:00
hang ecbe8434f3 修改编译问题
continuous-integration/drone/push Build is passing
2024-06-14 10:55:52 +08:00
he 644fe1bd3c Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is failing
2024-06-14 10:52:02 +08:00
he 870fca2e93 修改 2024-06-14 10:52:01 +08:00
hang 6207fb5006 修改MFA 接口
continuous-integration/drone/push Build is failing
2024-06-14 10:38:58 +08:00
hang ae913d8213 修改中心调研国际化
continuous-integration/drone/push Build is passing
2024-06-14 09:18:06 +08:00
hang ce969822a0 字段名错误
continuous-integration/drone/push Build is passing
2024-06-13 17:42:49 +08:00
hang 4fc311d4a5 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2024-06-13 17:42:05 +08:00
hang 2b424ff45c site 调研增加配置字段 2024-06-13 17:42:04 +08:00
he e5d9cfc50e Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-13 17:35:19 +08:00
he ac3552818b 修改 2024-06-13 17:35:18 +08:00
hang c004741f95 上传下载 改为不为空
continuous-integration/drone/push Build is passing
2024-06-13 17:08:09 +08:00
hang 2bdc0c7704 修改siteName 国际化
continuous-integration/drone/push Build is passing
2024-06-13 14:57:38 +08:00
hang 35d90d56dd 修改过滤
continuous-integration/drone/push Build is passing
2024-06-13 09:25:26 +08:00
hang f14525ea95 减少赋值字段
continuous-integration/drone/push Build is failing
2024-06-12 17:24:51 +08:00
hang c2350f1418 影像筛选逻辑增加
continuous-integration/drone/push Build is passing
2024-06-12 17:10:22 +08:00
hang 4b8b02fa55 重构检查列表
continuous-integration/drone/push Build is passing
2024-06-12 16:14:14 +08:00
hang 62102b8b03 重构检查列表
continuous-integration/drone/push Build is failing
2024-06-12 16:10:49 +08:00
hang 0655318d2d Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-12 15:44:00 +08:00
hang 0bd2a10091 修改受试者无序阅片 2024-06-12 15:44:00 +08:00
he ce11788878 修改
continuous-integration/drone/push Build is passing
2024-06-12 15:32:17 +08:00
he 0cb74296c3 修改
continuous-integration/drone/push Build is passing
2024-06-12 15:01:23 +08:00
hang def08b72ca 修改返回列表
continuous-integration/drone/push Build is passing
2024-06-12 14:22:01 +08:00
hang 1ef8d2913b Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is failing
2024-06-12 14:11:12 +08:00
hang 7e18b1287e 优化代码 2024-06-12 14:11:11 +08:00
he fdcb6ad12f 修改
continuous-integration/drone/push Build is failing
2024-06-12 14:08:18 +08:00
hang 988bf0e92c 修改任务查询
continuous-integration/drone/push Build is passing
2024-06-12 14:03:38 +08:00
he f6612286d9 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-12 13:45:18 +08:00
he c21845c60d 修改 2024-06-12 13:45:17 +08:00
hang 867ef0ef97 任务名称修改逻辑变更
continuous-integration/drone/push Build is passing
2024-06-12 13:25:34 +08:00
hang f27bee83b7 修改任务列表
continuous-integration/drone/push Build is passing
2024-06-12 13:17:48 +08:00
hang e3b6feb4da 修改待阅列表
continuous-integration/drone/push Build is passing
2024-06-12 13:03:50 +08:00
hang d727703075 返回标准Id
continuous-integration/drone/push Build is passing
2024-06-12 10:56:00 +08:00
hang c49cf0ed12 修改登录逻辑
continuous-integration/drone/push Build is passing
2024-06-12 10:50:18 +08:00
hang f324d207dd 编译错误
continuous-integration/drone/push Build is passing
2024-06-12 09:50:09 +08:00
hang c9bda275f5 生成任务名称修改
continuous-integration/drone/push Build is failing
2024-06-12 09:48:07 +08:00
hang 62ed1a408d 影响筛选逻辑修改
continuous-integration/drone/push Build is passing
2024-06-12 09:13:59 +08:00
hang 25efb34f1f 增加MFA认证
continuous-integration/drone/push Build is passing
2024-06-11 17:58:06 +08:00
he eb0f13c075 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-07 17:59:54 +08:00
he 7ca92a7675 代码修改 2024-06-07 17:59:53 +08:00
hang e313f88bca site列表增加创建时间
continuous-integration/drone/push Build is passing
2024-06-07 15:59:08 +08:00
hang 4823eb29d5 修改bug
continuous-integration/drone/push Build is passing
2024-06-07 15:25:27 +08:00
hang 43ec332f61 修改随机阅片逻辑
continuous-integration/drone/push Build is passing
2024-06-07 15:04:41 +08:00
hang cac0652120 修改项目site 添加问题
continuous-integration/drone/push Build is passing
2024-06-07 13:55:01 +08:00
hang cc088900b6 项目中心改为分页
continuous-integration/drone/push Build is passing
2024-06-07 10:52:50 +08:00
hang 824b165723 修改site 代码
continuous-integration/drone/push Build is passing
2024-06-07 10:32:43 +08:00
hang 443b94b332 siteCode 添加
continuous-integration/drone/push Build is passing
2024-06-06 18:03:00 +08:00
hang dc116d3a6f 修改site参数不必传
continuous-integration/drone/push Build is passing
2024-06-06 17:28:06 +08:00
he bbc8859a16 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-06 17:20:01 +08:00
he 09e388b01a 修改 2024-06-06 17:20:01 +08:00
hang e5fcb75b9f 修改查询接口
continuous-integration/drone/push Build is failing
2024-06-06 17:15:03 +08:00
hang 8e104e133f Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is failing
2024-06-06 16:51:25 +08:00
hang e2a77537f0 增加查询site 2024-06-06 16:51:25 +08:00
he a73a79b627 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is failing
2024-06-06 16:37:29 +08:00
he e79c3a8f37 代码修改 2024-06-06 16:37:28 +08:00
hang ca9a2dad18 自定义添加项目Site
continuous-integration/drone/push Build is passing
2024-06-06 16:34:29 +08:00
hang cd03f5f31d 修改MIM查询
continuous-integration/drone/push Build is failing
2024-06-06 14:37:18 +08:00
hang 33e25de801 修复查询bug
continuous-integration/drone/push Build is passing
2024-06-06 14:25:10 +08:00
hang 9cd60e9575 修改部位初始化
continuous-integration/drone/push Build is passing
2024-06-06 13:48:25 +08:00
hang 4da4a4de89 x
continuous-integration/drone/push Build is passing
2024-06-06 11:03:46 +08:00
hang ec0a88a5ec 修改默认值
continuous-integration/drone/push Build is passing
2024-06-06 10:25:49 +08:00
hang a52a00e58c 增加标准查询字段
continuous-integration/drone/push Build is passing
2024-06-06 09:57:54 +08:00
hang 0a6ffbba07 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-06 09:31:34 +08:00
hang 8cb5423b0b 添加修改 2024-06-06 09:31:33 +08:00
he 5a6411c6c3 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-06 09:28:23 +08:00
he b97a8b5a68 代码修改 2024-06-06 09:28:22 +08:00
hang 91794266e7 修改bug
continuous-integration/drone/push Build is running
2024-06-06 09:27:56 +08:00
hang 2f86e2dae1 修改CRO Sponsor
continuous-integration/drone/push Build is passing
2024-06-06 09:22:39 +08:00
he fb76c5af6c Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-05 17:13:14 +08:00
he 3f6ec5b7ea 修改 2024-06-05 17:13:13 +08:00
hang c95ea8c547 修改 CRO Sponsor 部位
continuous-integration/drone/push Build is passing
2024-06-05 14:54:37 +08:00
hang facd9e0e5f 修改项目部位
continuous-integration/drone/push Build is passing
2024-06-05 13:49:22 +08:00
hang 9d0c3d3fc5 返回提示
continuous-integration/drone/push Build is passing
2024-06-05 10:28:07 +08:00
hang 907d0d39a1 取消医生,增加标准
continuous-integration/drone/push Build is passing
2024-06-05 09:48:56 +08:00
hang 4d689100ee 修改导航属性bug
continuous-integration/drone/push Build is passing
2024-06-04 16:21:06 +08:00
hang 818d9d6f62 导航属性bug
continuous-integration/drone/push Build is passing
2024-06-04 15:51:20 +08:00
hang 9a2059726f Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-04 15:50:15 +08:00
hang 8bcac405e5 项目bodypart 以及bug 2024-06-04 15:50:14 +08:00
he 19661c5e82 修改
continuous-integration/drone/push Build is passing
2024-06-04 13:59:58 +08:00
hang 9875d9622d 修改中心
continuous-integration/drone/push Build is passing
2024-06-04 11:42:44 +08:00
hang 7573ffe941 修改nodicom 查询bug
continuous-integration/drone/push Build is passing
2024-06-03 15:51:54 +08:00
hang 47166ab2eb 修改trialsiteId
continuous-integration/drone/push Build is passing
2024-06-03 15:33:05 +08:00
hang 0295b7d919 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-03 15:25:41 +08:00
hang 3653072497 统计数字修改 2024-06-03 15:25:41 +08:00
he 0e7f203a1b 修改
continuous-integration/drone/push Build is passing
2024-06-03 15:21:13 +08:00
he ab99265c88 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2024-06-03 15:20:55 +08:00
he f774d95f5c 修改 2024-06-03 15:20:54 +08:00
hang 9e1e32f16d Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-03 15:13:53 +08:00
hang 0accb453e5 上传监控bug 2024-06-03 15:13:52 +08:00
he e2b285c792 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-03 14:54:18 +08:00
he 935f95fa3b 代码提交 2024-06-03 14:54:15 +08:00
hang a4d20d9f08 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-03 14:37:42 +08:00
hang 0e23719c7b 修改site关联 2024-06-03 14:37:38 +08:00
hang eb1f06658d 放开cro sponsor 和去掉国际化缓存
continuous-integration/drone/push Build is passing
2024-06-03 11:15:02 +08:00
hang 1e177a2530 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-06-03 11:06:17 +08:00
hang 49031b0e48 国际化修改 2024-06-03 11:06:16 +08:00
hang ca5bbb3064 irc 邮箱验证修改
continuous-integration/drone/push Build is passing
2024-05-31 17:42:12 +08:00
hang b338188c5f 返回 SliceThickness
continuous-integration/drone/push Build is passing
2024-05-31 15:52:33 +08:00
hang 9cbe4cc36e 修改配置
continuous-integration/drone/push Build is passing
2024-05-31 14:58:00 +08:00
hang 6f5f521803 打开限制的配置
continuous-integration/drone/push Build is passing
2024-05-31 13:49:23 +08:00
hang a6db30280b 修改退出接口
continuous-integration/drone/push Build is passing
2024-05-31 13:40:03 +08:00
hang 4db3860ade 修改自动退出时间
continuous-integration/drone/push Build is passing
2024-05-31 11:11:01 +08:00
hang 57837cfe1d CRO Sponsor修改
continuous-integration/drone/push Build is passing
2024-05-31 11:03:13 +08:00
hang b51fdc5769 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-30 14:37:39 +08:00
hang 5038d7ad53 修改上传重传bug 2024-05-30 14:37:38 +08:00
he c1d618326b Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-30 14:31:20 +08:00
he db1a0195fe 代码修改 2024-05-30 14:31:20 +08:00
hang 238def8089 修改判断
continuous-integration/drone/push Build is passing
2024-05-30 11:23:22 +08:00
hang 59e969c2a8 修改逻辑
continuous-integration/drone/push Build is passing
2024-05-30 11:18:05 +08:00
hang 029a288be2 修改多帧的逻辑
continuous-integration/drone/push Build is passing
2024-05-30 10:34:59 +08:00
hang 11e5448acf 用户列表修改
continuous-integration/drone/push Build is passing
2024-05-29 17:43:54 +08:00
hang 71577d0346 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-29 16:39:15 +08:00
hang 681e559cb4 增加邮箱查询和创建时间查询 2024-05-29 16:39:15 +08:00
hang 862390ae78 增加邮箱查询条件 2024-05-29 16:39:11 +08:00
hang f210799c4d Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-29 16:38:02 +08:00
hang d7700c3c77 添加备注 2024-05-29 16:38:01 +08:00
he 44fa4d3fc4 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-29 14:59:26 +08:00
he f0c57c643b 修改 2024-05-29 14:59:26 +08:00
hang 5e48ed1e23 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-28 10:00:32 +08:00
hang a3f12b2a53 增加医生用户名 2024-05-28 10:00:31 +08:00
he cc00cce704 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-27 16:48:16 +08:00
he 9c244c6750 修改 2024-05-27 16:48:16 +08:00
hang ffb5d46ca3 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-27 16:39:15 +08:00
hang 7376732b1a 项目 sponsor cro 修改 2024-05-27 16:39:14 +08:00
he 1caf4ff8e6 修改
continuous-integration/drone/push Build is passing
2024-05-27 16:11:20 +08:00
he 22147483c1 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-27 15:09:25 +08:00
he c7dbf7ba92 修改 2024-05-27 15:09:24 +08:00
hang fd3f76d35c 超窗导出影响列表修改
continuous-integration/drone/push Build is passing
2024-05-24 10:02:44 +08:00
hang e10bca6892 移除 Magicodes 导入excel
continuous-integration/drone/push Build is passing
2024-05-24 09:17:30 +08:00
hang 4a01960426 修改映射
continuous-integration/drone/push Build is passing
2024-05-23 17:22:58 +08:00
hang 318364e70b 修改nuget 包
continuous-integration/drone/push Build is passing
2024-05-23 17:10:38 +08:00
hang 383064a7b7 重传监控
continuous-integration/drone/push Build is passing
2024-05-23 16:02:00 +08:00
hang 78bbfb5f41 一致性核查通过自动关闭质疑
continuous-integration/drone/push Build is passing
2024-05-23 11:15:45 +08:00
hang 9aec1f5f50 修改一致性核查导表
continuous-integration/drone/push Build is passing
2024-05-23 09:12:40 +08:00
hang 66beb43daf 修改邮箱正则
continuous-integration/drone/push Build is passing
2024-05-23 09:03:19 +08:00
hang b02589a957 修改正则
continuous-integration/drone/push Build is passing
2024-05-22 17:49:45 +08:00
hang d4a1d83851 临床数据维护
continuous-integration/drone/push Build is passing
2024-05-22 17:39:52 +08:00
hang 53aee1020d 去掉siteId
continuous-integration/drone/push Build is passing
2024-05-22 13:45:28 +08:00
hang 010c106879 增加删除接口
continuous-integration/drone/push Build is passing
2024-05-22 11:22:15 +08:00
hang fb43e38c7d 测试删除属性
continuous-integration/drone/push Build is passing
2024-05-22 10:34:06 +08:00
hang ca96c67e96 修改多帧接口
continuous-integration/drone/push Build is passing
2024-05-22 10:06:38 +08:00
hang 1fbf635582 增加返回instance 信息
continuous-integration/drone/push Build is passing
2024-05-21 16:00:48 +08:00
hang 44d62b187f Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-05-21 14:29:15 +08:00
hang 57600cbad1 IR上传接口修改 2024-05-21 14:29:13 +08:00
he 311d6507ce 修改 2024-05-21 14:11:50 +08:00
he 8e520ce579 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-05-21 13:53:40 +08:00
he 5a97e15885 代码修改 2024-05-21 13:53:33 +08:00
hang bb36c67159 修改上传列表 2024-05-21 11:01:23 +08:00
hang 7a33edc7a6 修改上传监控导航属性bug
continuous-integration/drone/push Build is passing
2024-05-20 13:38:16 +08:00
hang a7d6303da4 处理返回的信息
continuous-integration/drone/push Build is passing
2024-05-17 16:58:01 +08:00
hang 704c201c33 修改逻辑
continuous-integration/drone/push Build is passing
2024-05-17 16:52:52 +08:00
hang c69d3eec36 修改展示
continuous-integration/drone/push Build is passing
2024-05-17 16:27:45 +08:00
hang 6e5a3a0078 修改下载展示列表
continuous-integration/drone/push Build is running
2024-05-17 15:21:06 +08:00
hang ed62de9135 修改bug
continuous-integration/drone/push Build is passing
2024-05-17 14:53:11 +08:00
hang a8b218ce95 多帧修改2
continuous-integration/drone/push Build is passing
2024-05-17 14:40:55 +08:00
hang f6d2b1e7f1 增加新的影像归档检查表
continuous-integration/drone/push Build is passing
2024-05-17 14:14:51 +08:00
hang 85439213b2 增加打包状态 crc列表增加字段,影像下载打包迁移
continuous-integration/drone/push Build is passing
2024-05-17 10:51:30 +08:00
hang 2933d100f7 标准增加字段
continuous-integration/drone/push Build is passing
2024-05-17 09:56:19 +08:00
hang ac799688d3 增加多帧展示字段
continuous-integration/drone/push Build is passing
2024-05-17 09:38:46 +08:00
hang a4b9c44cfa 多帧配合玲姐修改模块1
continuous-integration/drone/push Build is passing
2024-05-17 09:16:07 +08:00
hang af282d2bb8 自定义标准扩充字段
continuous-integration/drone/push Build is passing
2024-05-17 09:01:29 +08:00
hang a93bbebb61 无序修改字段类型
continuous-integration/drone/push Build is passing
2024-05-16 14:54:34 +08:00
hang 4552a24caa Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-16 14:16:58 +08:00
hang fc22ec0672 修改保存bug 2024-05-16 14:16:57 +08:00
he 963fbcb5e8 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-16 13:59:12 +08:00
he 3da3b9de45 修改 2024-05-16 13:59:11 +08:00
hang a055d1c668 阅片单元配置修改
continuous-integration/drone/push Build is passing
2024-05-16 10:40:47 +08:00
hang 0b130bbc01 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-16 10:13:04 +08:00
hang 9f9bc9c747 稽查搜索条件修改 2024-05-16 10:13:03 +08:00
he 75367ae727 修改
continuous-integration/drone/push Build is passing
2024-05-16 09:49:48 +08:00
hang bd9d78622f 增加搜索条件
continuous-integration/drone/push Build is passing
2024-05-15 16:35:57 +08:00
hang 6b807f419b 修改项目中心查询,文档查询
continuous-integration/drone/push Build is passing
2024-05-15 16:17:17 +08:00
hang f58ee6f63a 医学审核搜索条件增加
continuous-integration/drone/push Build is passing
2024-05-15 14:43:50 +08:00
hang 7510d86a52 修改医学审核bug
continuous-integration/drone/push Build is passing
2024-05-15 14:24:09 +08:00
hang 65fba6ca41 重阅跟踪修改
continuous-integration/drone/push Build is passing
2024-05-15 11:17:35 +08:00
hang 3e2198b7ba 日志查看时间
continuous-integration/drone/push Build is passing
2024-05-15 10:51:27 +08:00
hang 535c0fc419 阅片界面调整-查询条件
continuous-integration/drone/push Build is passing
2024-05-15 09:42:48 +08:00
hang 1c5d30b673 王总界面优化 新增查询条件以及列
continuous-integration/drone/push Build is passing
2024-05-14 16:02:00 +08:00
hang 3bf26dbbef 修改查询
continuous-integration/drone/push Build is passing
2024-05-14 15:01:18 +08:00
hang 329437411d 增加项目用户接口
continuous-integration/drone/push Build is passing
2024-05-14 14:38:35 +08:00
hang 090cdaf2e4 日志增加区域
continuous-integration/drone/push Build is passing
2024-05-14 14:29:38 +08:00
hang 7c257f261c x
continuous-integration/drone/push Build is passing
2024-05-14 14:19:17 +08:00
hang 477bc7baf7 日志格式测试
continuous-integration/drone/push Build is passing
2024-05-14 14:16:49 +08:00
hang 32d6ebef9c 日志修改
continuous-integration/drone/push Build is passing
2024-05-14 10:25:05 +08:00
he 51e0676ce5 修改
continuous-integration/drone/push Build is passing
2024-05-10 17:24:36 +08:00
he 53156e210f 修改
continuous-integration/drone/push Build is passing
2024-05-10 13:44:48 +08:00
he 84f76c09f7 修改
continuous-integration/drone/push Build is passing
2024-05-10 13:36:37 +08:00
he 74e0765d7a 修改 2024-05-10 13:20:04 +08:00
he 51cfadbc77 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-05-10 13:19:25 +08:00
he 01e047f639 问题修改 2024-05-10 13:19:24 +08:00
hang 4050d7e4a3 修改肿瘤学有序阅片 2024-05-10 10:26:56 +08:00
he adab66172d 修改
continuous-integration/drone/push Build is passing
2024-05-09 16:21:16 +08:00
hang 7c850c969e 修改 错误用户名也展示在项目日志
continuous-integration/drone/push Build is passing
2024-05-08 14:26:14 +08:00
he f55fa98dec 修改
continuous-integration/drone/push Build is passing
2024-05-07 14:45:32 +08:00
hang 7f28c984e1 修改打包配置
continuous-integration/drone/push Build is running
2024-05-06 13:40:05 +08:00
hang 6220e53d8f Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-05-06 13:13:39 +08:00
hang 5bb0231354 服务器更换,地址修改 2024-05-06 13:13:38 +08:00
XCKJ 58eec48af7 添加 README.md
continuous-integration/drone/push Build is passing
2024-05-02 12:18:54 +00:00
he 65545dd3e5 修改
continuous-integration/drone/push Build is passing
2024-04-29 15:09:32 +08:00
he 5b92015c98 修改
continuous-integration/drone/push Build is passing
2024-04-29 15:07:29 +08:00
he 64c97b22d5 测试发布
continuous-integration/drone/push Build is passing
2024-04-29 14:43:46 +08:00
he 87adbe9bed 修改
continuous-integration/drone/push Build is pending
2024-04-29 14:43:10 +08:00
he c6ed8b8318 修改
continuous-integration/drone/push Build is passing
2024-04-29 14:39:52 +08:00
he 4d2890976a 修改
continuous-integration/drone/push Build is passing
2024-04-29 13:08:44 +08:00
hang 9cfddf1327 修改打包配置
continuous-integration/drone/push Build is passing
2024-04-29 09:56:00 +08:00
hang 84203d5aa2 修改bug
continuous-integration/drone/push Build encountered an error
2024-04-28 17:50:53 +08:00
hang 4d19fffc5f 修改bug 2024-04-28 17:42:13 +08:00
hang 18683390b7 修改颜色 2024-04-28 17:15:30 +08:00
hang fb137ae840 修改IRC 3个bug 2024-04-28 17:07:59 +08:00
hang c8bc0c4a32 修改中心调研邮件 2024-04-28 13:38:26 +08:00
hang 8ded82fa81 修改统计查询 2024-04-26 15:12:51 +08:00
hang acd1f47f4a IRC 统计数据bug 2024-04-26 14:41:06 +08:00
he 054827bbae 修改 2024-04-25 16:42:44 +08:00
he a5ebe97dc5 问题修改 2024-04-25 14:40:20 +08:00
he 02b2d8f754 问题修改 2024-04-25 13:39:28 +08:00
he cf5da8f55a 修改 2024-04-25 13:22:08 +08:00
he 40947de05a 修改 2024-04-25 13:14:31 +08:00
he 662648691d 修改 2024-04-25 11:48:11 +08:00
he 29836a9c62 修改 2024-04-24 11:19:33 +08:00
he a2b1a0d64b 修改 2024-04-24 11:13:24 +08:00
hang 87fbd2cb59 IRC 没有这个问题 2024-04-22 17:27:07 +08:00
hang c91e21c23a 修改检查获取序列列表 2024-04-22 17:19:47 +08:00
hang 0f25c7db0e 修改排序 2024-04-19 16:10:18 +08:00
hang e5b5cbb8d8 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-19 15:08:36 +08:00
hang 9c1af1b8dc 修改排序 2024-04-19 15:08:36 +08:00
he 0da09da45e 问题修复 2024-04-19 13:01:05 +08:00
he 87aaefadf6 修改 2024-04-19 09:21:34 +08:00
he b5b739a5cb 修改 2024-04-18 18:01:09 +08:00
he 1315d5dc29 修改 2024-04-18 17:25:29 +08:00
he 72b70f5311 修改 2024-04-18 17:24:54 +08:00
he fd15a62148 修改 2024-04-18 16:55:25 +08:00
he e9bd625195 修改 2024-04-18 16:52:04 +08:00
he c37fcf588c 问题修改 2024-04-18 16:43:02 +08:00
he 3f8d5027c8 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-18 11:45:10 +08:00
he 972fc32eeb 代码修改 2024-04-18 11:45:08 +08:00
hang 1ba9efe894 修改退出逻辑 2024-04-17 12:26:56 +08:00
hang f85ac8a813 修改状态码 2024-04-17 12:23:38 +08:00
hang 7bf097c127 修改 自动退出用户 2024-04-17 12:20:01 +08:00
hang fc579d9cf4 修改发布参数 2024-04-17 11:35:30 +08:00
hang b1c0933428 x 2024-04-17 11:22:04 +08:00
hang bd7dd906fb Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-17 11:21:07 +08:00
hang 3a8e400f33 编译错误 2024-04-17 11:21:06 +08:00
hang c6dd323b80 编译错误 2024-04-17 11:19:11 +08:00
hang dfb45d8391 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-16 18:00:52 +08:00
hang 0b0df00525 自动退出逻辑测试 2024-04-16 18:00:51 +08:00
he 96fc5ae78c Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-16 17:38:57 +08:00
he a4b2d68995 代码修改 2024-04-16 17:38:57 +08:00
hang 70ababc2d9 自动退出登录 2024-04-16 17:36:48 +08:00
he e57887eba5 问题修改 2024-04-16 14:00:46 +08:00
he aef7fded18 修改 2024-04-16 09:57:54 +08:00
he e0613c1f2d 问题修改 2024-04-15 15:54:46 +08:00
he f6d323cc31 修改 2024-04-15 15:18:01 +08:00
he aa85562076 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-15 15:14:29 +08:00
he 0165688799 问题修改 2024-04-15 15:14:27 +08:00
hang c2aefebedc 修改排序和标准确认生成任务 2024-04-15 11:19:31 +08:00
hang 1c5e4454da Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-15 10:29:00 +08:00
hang 65e2a45d74 增加查询条件 2024-04-15 10:28:59 +08:00
he 99026d6483 脾脏状态修改 2024-04-15 10:13:33 +08:00
he 9190783ac4 修改 2024-04-12 16:45:39 +08:00
he ae8f50dc14 修改 2024-04-12 16:36:34 +08:00
he 2a51de03b7 稽查修改 2024-04-12 16:03:30 +08:00
he 2be9daa443 修改 2024-04-12 15:57:06 +08:00
he 2778b3ea7b 修改 2024-04-12 15:43:54 +08:00
he 4cedb9dbcb 修改 2024-04-12 15:42:49 +08:00
he ed6a6fb844 问题修改 2024-04-12 15:39:43 +08:00
he 8daf02246e Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-12 14:47:17 +08:00
he b3178e6f8d 修改 2024-04-12 14:47:16 +08:00
hang 00cbde90c7 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-12 10:36:20 +08:00
hang 938175c49f 附加评估查询修改 2024-04-12 10:36:19 +08:00
he 146fc916d1 修改 2024-04-12 10:31:23 +08:00
he 87776513fb 修改 2024-04-11 16:30:45 +08:00
he 60d462e5f9 修改 2024-04-11 16:28:23 +08:00
he b39d8dd546 修改 2024-04-11 13:36:10 +08:00
he b65635c41c 修改 2024-04-11 11:41:23 +08:00
he fe2539afba 修改 2024-04-11 11:09:53 +08:00
he d2ff216396 修改 2024-04-11 11:08:34 +08:00
he 4c05da8335 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-11 10:41:14 +08:00
he 6061cf5d93 自动计算触发 2024-04-11 10:41:13 +08:00
hang d313b7d8a6 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-10 14:54:34 +08:00
hang 71c21ccc00 修改中心调研bug 需要迁移 2024-04-10 14:54:33 +08:00
he f415c03daa Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-10 14:54:27 +08:00
he 2bfef364ec 备注 2024-04-10 14:54:24 +08:00
helongjun c822d20d0d 计算条件补充说明 2024-04-10 14:46:28 +08:00
hang 3a996212ed Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-09 16:06:03 +08:00
hang 5a3b6a5f93 中心调研,公司名bug 修改 2024-04-09 16:06:02 +08:00
he 3f7227ce32 修改 2024-04-09 10:31:45 +08:00
he af0df80874 修改 2024-04-08 17:44:12 +08:00
he a163d8a785 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-08 17:36:02 +08:00
he 70fbf8d352 修改 2024-04-08 17:36:02 +08:00
hang d9a8692be8 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-08 17:30:40 +08:00
hang 56fb9c14d1 稽查排序修改,需要迁移 2024-04-08 17:30:39 +08:00
he 8bc0cee81f 修改 2024-04-08 17:25:08 +08:00
he dc86767184 修改 2024-04-08 14:45:58 +08:00
he e1383445e2 修改 2024-04-08 14:45:39 +08:00
he 0a30107859 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-08 13:44:58 +08:00
he ba27925409 添加病灶编号 2024-04-08 13:44:57 +08:00
hang 3a52021cdc 修改导表查询 2024-04-08 13:29:37 +08:00
hang aba4fc70c2 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-08 11:16:55 +08:00
hang 5b89343192 修改导表 2024-04-08 11:16:55 +08:00
he 20f9e90a69 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-08 11:12:40 +08:00
he 5c58171ac3 代码修改 2024-04-08 11:12:38 +08:00
hang e98d80eea6 修改导表错误 2024-04-08 11:02:35 +08:00
hang c14d5be4ac x 2024-04-07 17:39:29 +08:00
hang fea108371f Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-07 16:17:42 +08:00
hang dd47bf05f8 修改一致性分析 2024-04-07 16:17:41 +08:00
he 3a160c1913 iRECIST新病灶评估 修改 2024-04-07 15:41:55 +08:00
he c42c26d76a 临床数据不完备提示 2024-04-07 14:54:41 +08:00
he f7117563f7 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-07 14:32:59 +08:00
he 39968194b1 问题修改 2024-04-07 14:32:58 +08:00
hang 0d5f7e5673 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-04-07 14:30:44 +08:00
hang 7f4e111f7d 修改导表bug 2024-04-07 14:30:43 +08:00
he 0c92fcb011 修改 2024-04-07 13:20:44 +08:00
hang 2f4418e3ed 修改查询 2024-04-01 17:50:39 +08:00
hang 75a3d7c80f 修改查询条件 2024-04-01 11:32:59 +08:00
hang 4605053e50 x 2024-04-01 11:14:17 +08:00
hang a8da0c0b55 修改展示样式,修改排序,增加查询条件 2024-04-01 11:02:21 +08:00
he ba984f9263 修改 2024-03-29 14:29:44 +08:00
he 451a311142 修改 2024-03-29 14:23:21 +08:00
he f86bc219cf 修改 2024-03-29 13:31:01 +08:00
he 06bd63b6d1 修改 2024-03-29 13:29:29 +08:00
he be088d8ba2 修改 2024-03-29 13:24:57 +08:00
he c718ec8446 修改 2024-03-28 10:45:43 +08:00
he 668e1019f0 修改 2024-03-28 10:39:52 +08:00
he e2f5a7fae1 修改 2024-03-27 13:29:58 +08:00
he f1a141c018 修改 2024-03-27 11:08:31 +08:00
he 30a0f428bc 修改 2024-03-26 16:04:03 +08:00
he 7a8346621d 修改 2024-03-26 15:53:28 +08:00
he 6d93054d3d Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-26 15:13:14 +08:00
he 5c53e78aca 修改 2024-03-26 15:13:13 +08:00
hang 1eeb832b0e Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-26 15:05:45 +08:00
hang c8db9431b2 去除 未生效任务状态 2024-03-26 15:05:44 +08:00
he ce8e0e3972 修改 2024-03-26 14:57:06 +08:00
he ed4192838d Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-25 17:52:54 +08:00
he d900c368e2 修改 2024-03-25 17:52:54 +08:00
hang 6926bb877c Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-25 15:27:54 +08:00
hang cb9b54a089 邮件title 重复 2024-03-25 15:27:53 +08:00
he 57c5d14f5a Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-25 14:57:01 +08:00
he 4f19d1638d 修改 2024-03-25 14:57:00 +08:00
hang ace39a7f94 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-25 13:09:44 +08:00
hang e8e0540cc2 返回modalitys 2024-03-25 13:09:43 +08:00
he a98799daaf 修改 2024-03-25 10:46:20 +08:00
he f2b53cd359 修改 2024-03-25 10:42:09 +08:00
he 960f479b91 修改 2024-03-25 09:30:12 +08:00
he d6dacb93dd 修改 2024-03-22 15:22:49 +08:00
he 8823656231 修改 2024-03-22 15:22:09 +08:00
he 2c859e7186 修改 2024-03-22 15:11:41 +08:00
he 99828dd82e 修改 2024-03-22 13:51:55 +08:00
he 855242e6fe 修改 2024-03-22 13:01:26 +08:00
he 90a1a920fa 修改 2024-03-22 11:08:08 +08:00
he c73968f490 修改 2024-03-21 16:22:43 +08:00
he 282368b9e0 修改 2024-03-21 16:18:42 +08:00
he 726a2be71e 修改 2024-03-21 14:07:04 +08:00
he 510104d0ff 需改 2024-03-21 13:26:46 +08:00
he 12318937f4 修改 2024-03-21 11:37:01 +08:00
he 8f17d4b110 修改还 2024-03-21 11:29:16 +08:00
he 18496246b2 修改 2024-03-21 11:22:04 +08:00
he 55f60e897a 修改 2024-03-21 10:49:24 +08:00
he dd2d142340 问题修复 2024-03-21 09:55:32 +08:00
he 49a0cf3ece 修改 2024-03-20 17:08:26 +08:00
he f0d4a1c075 修改 2024-03-20 16:41:03 +08:00
he 5e6db93250 修改 2024-03-20 16:03:57 +08:00
he 12adf2f3a9 修改 2024-03-20 15:56:40 +08:00
he b08908b1dc 修改 2024-03-20 15:12:05 +08:00
he 8f08746377 修改 2024-03-20 13:16:35 +08:00
he 045e9346ad Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-20 10:20:01 +08:00
he 864ab17ff3 疾病进展计算 2024-03-20 10:20:00 +08:00
hang 700d111011 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-20 10:17:08 +08:00
hang 7168d68997 清理缓存 2024-03-20 10:17:06 +08:00
he 40ec535e8a 修改 2024-03-20 10:02:04 +08:00
he 4dfaf29f3d 修改 2024-03-20 09:39:21 +08:00
he 702cd361fe 修改 2024-03-19 17:34:07 +08:00
he b776103328 添加获取Series信息 2024-03-19 16:43:02 +08:00
he 381e7b5046 修改 2024-03-19 16:04:29 +08:00
he ebdec8dd62 修改 2024-03-19 15:39:55 +08:00
he 6677f2a01e Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-19 14:56:52 +08:00
he 5aaa9043ff 修改 2024-03-19 14:56:52 +08:00
hang 48874adda3 升级nuget 2024-03-19 14:47:58 +08:00
he 0cf5a88d63 修改 2024-03-19 11:43:03 +08:00
he 4b92874ca6 修改 2024-03-19 11:33:34 +08:00
he 2d81b05fba 修改 2024-03-19 11:25:47 +08:00
he 78756aa2f4 获取PT CT 序列 2024-03-19 11:18:58 +08:00
he a15c91ebcb 修改 2024-03-19 10:05:46 +08:00
he 4b389c8293 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-19 09:51:02 +08:00
he 2313b5e907 修改 2024-03-19 09:51:01 +08:00
hang e22941d947 注释服务 2024-03-19 09:13:15 +08:00
hang 3efc173056 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-19 08:58:46 +08:00
hang 6389919cfd 归档预处理1 2024-03-19 08:58:45 +08:00
he 984b840fa7 修改 2024-03-18 18:01:23 +08:00
he 2bf01fbf0c 报告修改 2024-03-18 14:12:13 +08:00
he 116eeb753d 修改 2024-03-18 13:57:08 +08:00
he 82a6237323 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-18 13:39:53 +08:00
he 6220a96666 修改 2024-03-18 13:39:53 +08:00
hang 259ab2c569 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-18 13:06:12 +08:00
hang efda4e0fdd 增加site下拉返回属性 2024-03-18 13:06:11 +08:00
he 968264fe9a 修改 2024-03-18 10:44:53 +08:00
he 57911cf567 修改 2024-03-18 10:32:42 +08:00
he a61d9ae4d1 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-15 10:30:29 +08:00
he 5735383cd7 查询既往信息 2024-03-15 10:30:27 +08:00
hang e3607895b4 修改study 列表 排序 2024-03-14 17:10:25 +08:00
hang 16a2e0b53f 修改site user 时间 2024-03-14 16:36:17 +08:00
hang 41e5f9fd78 修改时区 修改时间 2024-03-14 15:59:13 +08:00
hang 64b750b06e 修改多时区问题解决 2024-03-14 14:18:16 +08:00
hang ca90736366 修改时区问题 2024-03-14 13:48:27 +08:00
hang 664b308e31 暂时屏蔽时区 2024-03-14 13:25:51 +08:00
hang 8de0671d31 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-14 10:37:22 +08:00
hang 19d7192842 修改访视 2024-03-14 10:37:21 +08:00
he c3ed54f05f 修改 2024-03-14 10:19:39 +08:00
he ef6655a014 修改验证 2024-03-14 10:14:09 +08:00
he 234e549b22 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-14 09:31:44 +08:00
he 903f72989a 查询修改 2024-03-14 09:31:43 +08:00
hang 3e9900cc45 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-13 17:42:40 +08:00
hang 78d0cffd3d 分配阅片人查询,增加查询条件 2024-03-13 17:42:40 +08:00
he 658e8d983c Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-13 16:31:22 +08:00
he 8174237a82 修改 2024-03-13 16:31:22 +08:00
hang 39a5e8eade 增加efcore 官方批量更新 2024-03-13 16:13:24 +08:00
hang 54dea66f5f 修改一致性分析提示 2024-03-13 16:12:56 +08:00
hang 86fd9ddc0e 修改规则 2024-03-13 15:57:18 +08:00
hang b071d1126b Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-13 15:37:09 +08:00
hang 139e9daec0 修改一致性分析限制 2024-03-13 15:37:09 +08:00
he 4eeda2b3e7 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-13 13:45:20 +08:00
he fa64b42a84 既往图片 2024-03-13 13:45:19 +08:00
hang ce67f4828f Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-13 13:24:14 +08:00
hang 87e3d953d3 oss私有读预提交 2024-03-13 13:24:14 +08:00
he 5d4668eaee Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-13 10:12:04 +08:00
he cfce8dba1f 计算CTMRI 总体评估 2024-03-13 10:12:03 +08:00
hang c11e319472 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-12 15:37:16 +08:00
hang 7c7a0cd20b 修改统计数字bug 2024-03-12 15:37:15 +08:00
he a66bb42126 病灶融合修改 2024-03-12 15:15:00 +08:00
he 7d63f3f5cb 修改 2024-03-12 14:31:56 +08:00
he b102d23477 代码修改 2024-03-12 14:30:43 +08:00
he e19c03412d 分组修改 2024-03-12 14:13:26 +08:00
he 56cba570bf Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-12 14:05:15 +08:00
he c7abcc153e 查询修改 2024-03-12 14:05:14 +08:00
hang 967a77f371 修改项目文档查询 2024-03-12 13:52:00 +08:00
hang 2060f2c62e Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-12 13:28:38 +08:00
hang 193c107539 增加项目编号 2024-03-12 13:28:37 +08:00
he 2fe0851786 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-12 13:25:46 +08:00
he 46b68ca2c9 添加默认医学审核问题修改 2024-03-12 13:25:45 +08:00
hang 396797dc0c 修改查询 2024-03-12 11:47:21 +08:00
hang 5579f543de 修改统计 2024-03-12 11:41:18 +08:00
hang ce31ab3097 修改文档查询 2024-03-12 10:05:04 +08:00
hang daa4764aac Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-12 09:32:03 +08:00
hang a24c6775e8 测试 dicom 注入服务 2024-03-12 09:32:01 +08:00
he eb9de1769e 问题修改 2024-03-11 17:58:53 +08:00
he d675cc50b3 修改 2024-03-11 16:29:42 +08:00
he 350d089c39 修改 2024-03-11 16:18:01 +08:00
he 116969f4f2 修改 2024-03-11 16:03:02 +08:00
he 112d9f9a63 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-11 15:59:42 +08:00
he 5dae9c5d06 代码修改 2024-03-11 15:59:42 +08:00
hang c0a63ecfed Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-11 15:56:25 +08:00
hang 881a5320a8 废弃之前的接口,增加统计 2024-03-11 15:56:25 +08:00
he 22a254890e Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-11 15:55:42 +08:00
he 0912909b68 修改 2024-03-11 15:55:41 +08:00
hang cd7318dd63 增加统计字段 2024-03-11 15:45:12 +08:00
hang 21cc610095 工作台,增加我的已签署系统、项目文件 2024-03-11 15:36:43 +08:00
hang cc8151caf8 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-11 15:10:38 +08:00
hang 8cce399430 增加c-store-scp 2024-03-11 15:10:37 +08:00
he 99688df446 修改 2024-03-11 14:53:21 +08:00
he de0a278cac 修改 2024-03-11 14:39:27 +08:00
he 7031ea1a04 修改 2024-03-11 14:26:46 +08:00
he 541455a08b x修改 2024-03-11 14:25:53 +08:00
he 814efc4e35 修改排序 2024-03-11 14:20:38 +08:00
he f85bbc41c4 计算修改 2024-03-11 13:23:45 +08:00
he c00e8eb809 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-11 09:32:28 +08:00
he 9dd00170af 修改 2024-03-11 09:32:25 +08:00
hang fdba16de86 修改用户类型排序 2024-03-08 16:05:52 +08:00
hang 38f319b425 修改访视计划默认值 2024-03-08 15:36:10 +08:00
hang d35046b277 修改国际化 2024-03-08 14:45:13 +08:00
hang bdcaf2f2be 修改邮件 2024-03-08 14:01:38 +08:00
hang bba622da0e 邮件修改 2024-03-08 13:46:20 +08:00
hang 0d4f694fcf Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-08 13:37:22 +08:00
hang a41824414e 修改邮件 2024-03-08 13:37:21 +08:00
he c54b0abbd7 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-08 13:14:17 +08:00
he d772ea527a 计算修改 2024-03-08 13:14:15 +08:00
helongjun 62b76220d4 更新邮件模板 2024-03-08 12:51:11 +08:00
he 6aa8628c0c 修改 2024-03-08 11:49:25 +08:00
he 7d9f4864d0 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-08 11:32:11 +08:00
he d149d5a5d5 脾脏状态 2024-03-08 11:32:10 +08:00
hang 7572bf9fb0 [医学审核统计修改2] 2024-03-08 11:03:03 +08:00
hang 40ab925a4e Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-08 10:30:35 +08:00
hang 75a989b4f1 修改医学审核bug 2024-03-08 10:30:34 +08:00
he f98f89a51d 肿瘤学重复生成 2024-03-08 10:15:02 +08:00
he 423ea4bc6f 计算修改 2024-03-08 10:03:24 +08:00
he 3c60dd9ae8 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-08 09:58:47 +08:00
he f9006be79b 靶病灶计算修改
疾病进展计算修改
2024-03-08 09:58:47 +08:00
hang 0492563838 修改医院 site 2024-03-08 09:21:46 +08:00
hang d58089b9ee Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-07 17:18:05 +08:00
hang e17a33a16f 删除 临床数据统计 2024-03-07 17:18:01 +08:00
he c935599fcf 代码修改 2024-03-07 15:00:04 +08:00
he efafdc50b8 医学审核问题修改 2024-03-07 13:26:19 +08:00
he 8846c1d728 修改 2024-03-07 13:02:41 +08:00
he 9bfd89cb9b 计算修改 2024-03-07 10:25:05 +08:00
he 35f01818dd Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-07 10:01:07 +08:00
he 875af7e9f7 医学审核问题修改 2024-03-07 10:01:07 +08:00
hang 7dfce2db55 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-07 09:36:49 +08:00
hang cab5772068 x 2024-03-07 09:36:49 +08:00
he 6319f1e82d 添加截止访视 2024-03-07 09:32:12 +08:00
hang d42c8477aa 自动生成增加验证逻辑 2024-03-07 09:26:48 +08:00
he b559a7882b 阅片标准修复 2024-03-07 09:25:22 +08:00
he 30e1d70099 基线摄取值修改 2024-03-06 17:50:26 +08:00
he 84a8d18519 插入问题修复 2024-03-06 17:20:38 +08:00
he 1fc20e5640 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-06 17:11:10 +08:00
he d8f0fba8e2 修改 2024-03-06 17:11:09 +08:00
hang 2921404540 x 2024-03-06 17:08:32 +08:00
hang df79b7b57b 删除参数 2024-03-06 17:00:43 +08:00
hang 0a45638bac 修改规则 2024-03-06 16:31:11 +08:00
hang 4f725af6cd 修改一致性分析 2024-03-06 15:55:37 +08:00
hang 44ae7bde56 一致性分析修改 2024-03-06 14:08:51 +08:00
hang cd5e0405de 一致性分析修改 2024-03-06 14:02:37 +08:00
hang 5bbf2d3c82 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-06 13:47:54 +08:00
hang 09743f7153 修改更新接口 2024-03-06 13:47:54 +08:00
he f88ef2f3fc lugano修改 2024-03-05 18:05:08 +08:00
he ef032b548e 验证修改 2024-03-05 17:13:38 +08:00
he db2f3cc85a 修改 2024-03-05 14:57:16 +08:00
he 7584f4a5b4 修改 2024-03-05 14:53:23 +08:00
he aac559e221 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-05 14:49:55 +08:00
he aee5c17591 医学审核修改 2024-03-05 14:49:54 +08:00
hang d8248a7973 项目VitrualSiteCode 给默认值 2024-03-05 14:40:39 +08:00
hang b68d060f85 一致性分析规则 列表增加配置信息 2024-03-05 11:43:16 +08:00
hang 74399df5eb 修改一致性分析 2024-03-05 09:06:40 +08:00
hang c3b62137d8 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-04 16:36:18 +08:00
hang 352bd23766 修改统计命名 2024-03-04 16:36:18 +08:00
he 398344854b Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-04 16:01:17 +08:00
he e181c3cc82 医学审核问题配置 2024-03-04 16:01:16 +08:00
hang 24e4008b72 修改统计 2024-03-04 16:00:16 +08:00
hang 50d9ed7e3c Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-04 15:47:51 +08:00
hang 9fd113c95f 修改统计 2024-03-04 15:47:50 +08:00
he 5683ced93d 删除也计算病灶状态 2024-03-04 14:31:44 +08:00
he 4360f4b2cb 计算修改 2024-03-04 14:19:43 +08:00
he 43a873defd Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-04 14:11:18 +08:00
he e5d08cdb3e 医生审核问题一件添加 2024-03-04 14:11:18 +08:00
hang c78b80c679 找回密码禁用没有启用的账户 2024-03-04 11:47:14 +08:00
hang 9cd3ba1c67 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-04 10:06:39 +08:00
hang dd22b206dc spm 统计修改 2024-03-04 10:06:38 +08:00
he 12b668642c Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-01 16:04:36 +08:00
he 77fa881d69 临床数据修改 2024-03-01 16:04:35 +08:00
hang 05dcbfed2e Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-01 16:00:42 +08:00
hang 6471041fad [项目site code 一致性分析验证] 2024-03-01 16:00:40 +08:00
he 69ab56f878 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-01 15:55:23 +08:00
he 97538333c0 临床数据修改 2024-03-01 15:55:22 +08:00
hang a094e1a2b7 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-01 14:08:27 +08:00
hang d0c8df1452 【入组增加一致性分析切换按钮】 2024-03-01 14:08:27 +08:00
he 1b6a31e626 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-01 14:07:44 +08:00
he 2c1cde9f69 x修改临床数据 2024-03-01 14:07:43 +08:00
hang 1aa5e45694 修改模型 2024-03-01 13:34:37 +08:00
hang 9fc04193c7 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-01 12:17:38 +08:00
hang b685b9fa13 修改统计列表 2024-03-01 12:17:37 +08:00
he 59f97d0c2d Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-01 11:46:51 +08:00
he 8f94460537 计算修改 2024-03-01 11:46:50 +08:00
hang 26fe947991 修改签署文档统计 2024-03-01 09:24:58 +08:00
hang 16829f9075 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-03-01 09:16:11 +08:00
hang 246314561b 修改面板统计 2024-03-01 09:16:10 +08:00
he 331a3c4178 肿瘤学阅片 2024-02-29 18:12:45 +08:00
he 35ba7861d1 肿瘤学修改 2024-02-29 17:20:17 +08:00
he 59cb66331e 肿瘤学阅片修改 2024-02-29 17:03:55 +08:00
he 782bfaa6c4 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-29 16:09:25 +08:00
he 830af4a164 临床数据修改 2024-02-29 16:09:25 +08:00
hang 994cb73104 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-29 16:08:40 +08:00
hang 8e3dc73408 [一致性分析预提交] 2024-02-29 16:08:39 +08:00
he 6792f9e916 临床数据修改 2024-02-29 16:03:28 +08:00
he a350c35f49 融合修改 2024-02-29 14:12:02 +08:00
he fb498b3723 肿瘤学阅片修改 2024-02-29 14:06:17 +08:00
he 7b9c90b77c Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-29 14:01:04 +08:00
he f4fd16d8fd 验证检查类型临床数据修改 2024-02-29 14:01:04 +08:00
hang 5656e66c28 [增加其他角色统计-2] 2024-02-29 10:37:31 +08:00
hang 39882e43ce [增加其他角色统计 1] 2024-02-29 09:49:59 +08:00
he e5f2d1cde9 代码提交 2024-02-28 15:15:33 +08:00
he 4f978863e4 分裂修改 2024-02-28 14:52:49 +08:00
he f26aafa8cb 肿瘤学修改 2024-02-28 10:47:39 +08:00
he e444354cf7 分列修改 2024-02-28 10:27:11 +08:00
he 0e4ae72016 肿瘤学阅片修改 2024-02-28 10:15:10 +08:00
he c1121a2d3f Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-28 09:43:19 +08:00
he 1737825506 肿瘤学阅片 2024-02-28 09:43:18 +08:00
hang 437c569617 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-27 17:27:06 +08:00
hang 9580d77512 [修改IR 医学审核统计] 2024-02-27 17:27:05 +08:00
he f7fb89313c Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-27 17:26:18 +08:00
he 721a7d2341 全局阅片修改 2024-02-27 17:26:17 +08:00
hang 3529ab6cb6 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-27 15:52:41 +08:00
hang 484bb3ca5b [保证统计,都有TrialId] 2024-02-27 15:52:40 +08:00
he 121b2d5df1 修改 2024-02-27 15:32:10 +08:00
he 472887d627 肿瘤学修改 2024-02-27 15:19:30 +08:00
he 03f514d5fe 肿瘤学修改 2024-02-27 15:05:32 +08:00
he 36d2203e4c Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-27 14:44:58 +08:00
he 4e11cc7db3 重置阅片标准 2024-02-27 14:44:58 +08:00
hang f23963896d 【项目签名文档限制】 2024-02-27 14:17:46 +08:00
he fd2b13b391 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-27 14:17:01 +08:00
he b90743ded1 肿瘤学修改 2024-02-27 14:16:59 +08:00
hang ee499d9352 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-27 14:02:48 +08:00
hang d12f0bddad 【第一层级统计,需要迁移】 2024-02-27 14:02:47 +08:00
he 9eabd9031b 融合修改 2024-02-26 17:15:43 +08:00
he 552e7a430d 字典修改 2024-02-26 13:30:53 +08:00
he b97f9f8f12 融合修改 2024-02-23 15:35:22 +08:00
he 8be0cea193 病灶修改 2024-02-23 15:27:55 +08:00
he bce088bcdf 融合修改 2024-02-23 14:45:10 +08:00
he 6955c42c8b 融合修改 2024-02-23 14:10:44 +08:00
he 07b36279cf 修改 2024-02-23 14:04:07 +08:00
he 5c1dc0754b 融合 2024-02-23 13:39:46 +08:00
he 7eaa644028 融合修改 2024-02-23 13:37:04 +08:00
he 1b29312bef 融合修改 2024-02-23 13:21:59 +08:00
he 930412bf21 融合修改 2024-02-23 13:19:12 +08:00
he 0e1f4931eb 融合修改 2024-02-23 13:15:37 +08:00
he 2e2c4b4397 修改 2024-02-23 13:10:59 +08:00
he 7665cc7f73 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-23 13:08:11 +08:00
he c743335d13 融合问题修改 2024-02-23 13:08:10 +08:00
hang e9aeb1c918 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-22 17:55:20 +08:00
hang c092e9a8d0 [修改邮件模板 4] 2024-02-22 17:55:18 +08:00
he a55ec01992 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-22 15:50:22 +08:00
he 302e503e02 医学审核修改 2024-02-22 15:50:22 +08:00
hang f82639cdf3 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-22 15:49:31 +08:00
hang 9172d8c5f8 【国际化,项目配置 空格问题】 2024-02-22 15:49:28 +08:00
he 69fd8ec123 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-22 14:51:38 +08:00
he d9c7a512e9 提交 2024-02-22 14:51:37 +08:00
hang 38383f34ff [修改邮件模板 -3] 2024-02-22 14:41:03 +08:00
hang b7585fe022 [修改邮件模板- 替换固定字符串] 2024-02-22 14:31:45 +08:00
hang b7d9009ff4 [邮件发送,配置动态公司名称] 2024-02-22 14:02:51 +08:00
hang 9c26745c2a 关闭 时区 发布aws 2024-02-22 13:28:57 +08:00
hang 67f8e57ab6 编译错误 2024-02-22 09:56:18 +08:00
hang b2ef603729 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-21 16:01:37 +08:00
hang 110ea953c4 [国际化-前端也使用code,唯一标识] 2024-02-21 16:01:34 +08:00
hang cef07a5bff 【时区,修改3 前端时间传递“” 问题解决】 2024-02-21 15:28:08 +08:00
hang a5899023b9 [时区修改-调整名称] 2024-02-21 14:33:38 +08:00
hang 61530be208 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-21 13:58:36 +08:00
hang 292bcd7100 [服务器处理时区上线测试] 2024-02-21 13:58:34 +08:00
he 8f4a6fcf80 异常修改 2024-02-21 11:20:04 +08:00
he dfdb3b5951 病灶修改 2024-02-21 11:19:33 +08:00
he 0cc7b373b7 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-21 09:36:03 +08:00
he 7e5cbd92b4 提示语修改 2024-02-21 09:36:03 +08:00
hang 2594ecd27e [修改启用禁用时,启用时间,增加字段] 2024-02-21 09:30:41 +08:00
he edf8af3e4d 修改 2024-02-20 16:30:20 +08:00
he 5a76275571 修改 2024-02-20 16:23:13 +08:00
he b147ee1c99 修改 2024-02-20 15:13:56 +08:00
he 8b7cc8a220 修改 2024-02-20 14:50:38 +08:00
he 88931a4a56 新加字段 2024-02-20 14:32:39 +08:00
he df187bed58 病灶合并 2024-02-20 14:28:52 +08:00
he 8b86bc6b3f 获取可融合的病灶 2024-02-20 14:12:21 +08:00
he f9ac64023a Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-20 13:19:59 +08:00
he 3a710e1e50 病灶分裂计算 2024-02-20 13:19:58 +08:00
hang 1d4f58f362 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-20 10:02:41 +08:00
hang abfd0a0a2e [删除site调研 中心查询] 2024-02-20 10:02:39 +08:00
he 98839b15dc Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-20 09:52:16 +08:00
he 5b885e98cc 融合 2024-02-20 09:52:16 +08:00
hang 58e29608e5 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-20 09:49:35 +08:00
hang db71cfd396 [中心调研-新增查询site 接口] 2024-02-20 09:49:35 +08:00
hang 0de9cfb240 [中心未启用,不用看到] 2024-02-20 09:42:51 +08:00
he 2a8efb246d Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-20 09:42:37 +08:00
he 071cf4eed8 病灶融合 修改 2024-02-20 09:42:37 +08:00
hang 87a8d8d490 [时区预备测试] 2024-02-20 09:41:01 +08:00
he d3caa1dda9 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-02-19 10:16:54 +08:00
he f832d44f3a 提交 2024-02-19 10:16:53 +08:00
hang 103ab700fc 修改查询条件 2024-02-19 09:56:48 +08:00
hang 6419fa6e61 [修改bug] 2024-02-16 22:08:52 +08:00
hang 98cf2adf92 [修改签名状态] 2024-02-16 21:39:57 +08:00
hang 5660d2e83b 修改医生自己编辑信息
continuous-integration/drone/push Build is passing
2024-02-02 15:44:54 +08:00
hang 5e3e242981 修改邮件发送bug
continuous-integration/drone/push Build is passing
2024-02-02 15:02:09 +08:00
hang 65c31fb457 修改配置文件
continuous-integration/drone/push Build is passing
2024-02-01 15:37:05 +08:00
hang 0f891075cc Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-02-01 15:09:56 +08:00
hang 6d898367e4 修改gcp bug 2024-02-01 15:09:54 +08:00
he 003e63b7fb 修改查询阅片图像
continuous-integration/drone/push Build is passing
2024-02-01 13:42:59 +08:00
he 73c9e15976 阅片图像查询修改 2024-02-01 13:42:55 +08:00
hang 1dc1d673dd Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-02-01 11:38:36 +08:00
hang 46818d9a02 修改医生bug 2024-02-01 11:38:28 +08:00
he d6a585c6cc 添加修改
continuous-integration/drone/push Build is passing
2024-02-01 10:46:43 +08:00
he c54fcf920c 修改
continuous-integration/drone/push Build is passing
2024-02-01 09:59:07 +08:00
he 467c7f77f5 修改
continuous-integration/drone/push Build is passing
2024-02-01 09:46:45 +08:00
he 3c51287178 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-02-01 09:16:54 +08:00
he 9d8fdcfa12 修改 2024-02-01 09:16:53 +08:00
hang fadd8a7f79 修改yml文件
continuous-integration/drone/push Build is passing
2024-01-31 15:52:58 +08:00
hang f2afb7ab1a 增加本地打包推送上海阿里云镜像仓库
continuous-integration/drone/push Build encountered an error
2024-01-31 15:48:42 +08:00
hang b52d8785bb Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-31 13:34:57 +08:00
hang 70846525bf 注释 2024-01-31 13:34:56 +08:00
he abe77916a3 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
2024-01-31 11:22:37 +08:00
he 660846a0d8 修改 2024-01-31 11:22:36 +08:00
hang 8dec77f30a Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-31 10:28:35 +08:00
hang 5812c8f939 [修改subject 查询 不依赖系统site] 2024-01-31 10:28:34 +08:00
he 1c673e11ac Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-31 10:18:24 +08:00
he bf54bcfd9b 代码修改 2024-01-31 10:18:23 +08:00
hang 33a0b8f11f Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-31 09:51:35 +08:00
hang 61ffdabc51 【修改 查询写入dicom的信息】 2024-01-31 09:51:32 +08:00
he 2f224047bc Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-30 14:29:31 +08:00
he 2747fa82e3 lugano 修改 2024-01-30 14:29:28 +08:00
hang 5dd80c91cf Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-29 16:58:33 +08:00
hang 495e602599 [修改医生限制] 2024-01-29 16:58:30 +08:00
he 545ddd4ec9 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-29 14:33:43 +08:00
he 9fff53f137 代码提交 2024-01-29 14:33:41 +08:00
hang 1d38fc0879 x
continuous-integration/drone/push Build is passing
2024-01-29 11:01:49 +08:00
hang 48f44b8920 [修改时间]
continuous-integration/drone/push Build is passing
2024-01-26 14:11:20 +08:00
hang e365818ef5 [修改重传没有检查id...]
continuous-integration/drone/push Build is passing
2024-01-26 14:10:19 +08:00
hang c2bb3010cc [修改一致性核查模板]
continuous-integration/drone/push Build is passing
2024-01-26 10:15:22 +08:00
hang 4ca8003d24 [site搜索三个名字]
continuous-integration/drone/push Build is passing
2024-01-26 09:39:34 +08:00
hang 6a212926e0 [退回bug3 ]
continuous-integration/drone/push Build is passing
2024-01-25 12:24:31 +08:00
hang dae5c0440f 删除测试配置
continuous-integration/drone/push Build is passing
2024-01-25 11:24:21 +08:00
hang 6b1d083faa Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-25 11:03:14 +08:00
hang c8510bea2a 增加[RuntimeIdentifiers] 2024-01-25 11:03:07 +08:00
hang a00e84018a [修改导出bug]
continuous-integration/drone/push Build is passing
2024-01-24 17:57:52 +08:00
hang 3435806020 [退回bug2]
continuous-integration/drone/push Build is passing
2024-01-24 14:40:09 +08:00
hang 27f0a0fcfa [修改回退bug]
continuous-integration/drone/push Build is passing
2024-01-24 14:13:15 +08:00
hang 1f4bb0128a [邮件模板启用与否没用bug修复]
continuous-integration/drone/push Build is passing
2024-01-24 09:03:51 +08:00
hang e686b6b7d4 修改正式文件配置
continuous-integration/drone/push Build is passing
2024-01-23 13:38:22 +08:00
hang b74d46b425 修改日志过滤
continuous-integration/drone/push Build is passing
2024-01-23 09:12:19 +08:00
hang aa08628b72 [屏蔽健康检查测试3]
continuous-integration/drone/push Build is passing
2024-01-22 17:35:42 +08:00
hang d4b2c48916 [屏蔽健康检查 测试2]
continuous-integration/drone/push Build is passing
2024-01-22 17:18:12 +08:00
hang 152846cfd5 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-22 16:54:15 +08:00
hang 48ef1c8605 [屏蔽健康检查日志测试1] 2024-01-22 16:54:10 +08:00
he de72cdb61a Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-22 16:16:06 +08:00
he 4c17101e27 添加LimitShow 限制显示 2024-01-22 16:16:03 +08:00
hang 0c1b3b0175 修改配置文件
continuous-integration/drone/push Build is passing
2024-01-22 10:58:15 +08:00
hang 45b51d9bfa 修改邮件模板
continuous-integration/drone/push Build is passing
2024-01-22 10:50:19 +08:00
hang 127916f03e [上传监控修改,增加搜索条件]
continuous-integration/drone/push Build is passing
2024-01-19 16:32:34 +08:00
hang f94e9c98f9 [AWS 对接上传 需要传递文件大小]
continuous-integration/drone/push Build is passing
2024-01-19 16:22:00 +08:00
hang e52523f1fa 修改测试环境aws
continuous-integration/drone/push Build is passing
2024-01-19 15:39:45 +08:00
hang 2d36f75660 修改美国环境配置
continuous-integration/drone/push Build is passing
2024-01-19 15:37:25 +08:00
hang a541423de5 [修改重传没有检查id]
continuous-integration/drone/push Build is passing
2024-01-19 15:33:52 +08:00
hang 8e98d1710b 修改配置文件
continuous-integration/drone/push Build is passing
2024-01-19 15:29:51 +08:00
hang 7b53756753 [修改医生bug 和site bug]
continuous-integration/drone/push Build is passing
2024-01-19 15:12:47 +08:00
hang e20d7982f4 修改配置文件
continuous-integration/drone/push Build is passing
2024-01-19 14:52:42 +08:00
hang ff8604f44a 切换为aws
continuous-integration/drone/push Build is passing
2024-01-19 13:55:40 +08:00
hang aaddd8e26f 增加美国环境
continuous-integration/drone/push Build is passing
2024-01-19 13:41:31 +08:00
hang 5e7fd398f2 [上传失败过,返回标志]
continuous-integration/drone/push Build is passing
2024-01-18 17:41:36 +08:00
hang 53cc5f129f Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-18 14:35:58 +08:00
hang 881e67d3e2 美国环境预修改 2024-01-18 14:35:55 +08:00
he 2c385aba12 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-17 15:28:27 +08:00
he b53616addc 肿瘤学修改 2024-01-17 15:28:26 +08:00
hang ff3796b7a0 [修改裁判重阅逻辑 2]
continuous-integration/drone/push Build is passing
2024-01-17 14:49:18 +08:00
hang 9aa061e093 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-17 14:33:12 +08:00
hang 9524a31fe6 [重阅裁判任务bug ] 2024-01-17 14:33:09 +08:00
he 9c4f2dcf6b 代码修改
continuous-integration/drone/push Build is passing
2024-01-17 13:28:42 +08:00
he c70120bcaa 代码修改
continuous-integration/drone/push Build is passing
2024-01-17 13:10:20 +08:00
he ea693b3ffc 修改
continuous-integration/drone/push Build is passing
2024-01-17 11:16:39 +08:00
he 62ec7d91a9 撤销修改
continuous-integration/drone/push Build is passing
2024-01-17 11:02:25 +08:00
he 01b6799a31 修改
continuous-integration/drone/push Build is passing
2024-01-17 10:50:36 +08:00
he 52f3a88e36 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-17 10:07:59 +08:00
he 35687c01ec 肿瘤学阅片 2024-01-17 10:07:58 +08:00
hang ed01407382 [上传监控增加字段]
continuous-integration/drone/push Build is passing
2024-01-16 11:20:50 +08:00
hang 3dbe92a667 Revert "[上传监控增加字段]"
This reverts commit 3d90eaf32c.
2024-01-16 11:20:43 +08:00
hang 127ae75b5b Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-16 11:19:41 +08:00
hang 3d90eaf32c [上传监控增加字段] 2024-01-16 11:19:39 +08:00
he 4bbfacd7de 修改
continuous-integration/drone/push Build is passing
2024-01-16 10:48:30 +08:00
he 5bb0f30c77 修改
continuous-integration/drone/push Build is passing
2024-01-16 10:47:00 +08:00
he b179a2fa49 修改
continuous-integration/drone/push Build is passing
2024-01-16 10:40:35 +08:00
he 3d0f0b0f52 修改
continuous-integration/drone/push Build is running
2024-01-16 10:30:38 +08:00
he c11f4a5dc7 修改
continuous-integration/drone/push Build is passing
2024-01-16 10:23:24 +08:00
he dcb9d7b7fc 修改
continuous-integration/drone/push Build is passing
2024-01-16 09:52:31 +08:00
he 87a39fa264 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-15 16:36:34 +08:00
he 24f64e9d59 修改计算 2024-01-15 16:36:32 +08:00
hang d7f380fc73 修改前端暂未修改接口,接口报错
continuous-integration/drone/push Build is passing
2024-01-15 15:37:37 +08:00
hang a37a1a6b95 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-15 15:14:41 +08:00
hang 33c3fc158f [遗漏 get set] 2024-01-15 15:14:37 +08:00
he 3a6afd6958 修改PET 5PS评分备注
continuous-integration/drone/push Build is passing
2024-01-15 14:25:53 +08:00
he 378f4e13fb 修改
continuous-integration/drone/push Build is passing
2024-01-15 10:32:45 +08:00
he f4d7e30b5d 修改
continuous-integration/drone/push Build is passing
2024-01-15 10:12:58 +08:00
he 088be2f1a5 修改
continuous-integration/drone/push Build is passing
2024-01-12 16:51:09 +08:00
he 56cab93554 修改
continuous-integration/drone/push Build is passing
2024-01-12 16:33:27 +08:00
he 17734753c8 修改
continuous-integration/drone/push Build is passing
2024-01-12 16:23:31 +08:00
he 36fa5e1d73 代码修改
continuous-integration/drone/push Build is passing
2024-01-12 16:10:24 +08:00
he abc364835c 修改
continuous-integration/drone/push Build is passing
2024-01-12 14:35:57 +08:00
he 061625e474 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-12 14:32:57 +08:00
he 0888577cde 修改 2024-01-12 14:32:55 +08:00
hang 906bf18971 [修改上传,失败数量传递不准问题]
continuous-integration/drone/push Build is passing
2024-01-12 13:58:39 +08:00
hang 4398afe298 [增加默认值]
continuous-integration/drone/push Build is passing
2024-01-12 13:49:03 +08:00
hang 7c14e9e7a3 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-12 13:42:02 +08:00
hang b6798a3466 [上传增加稽查字段]迁移 2024-01-12 13:41:59 +08:00
he 867c7b1752 修改
continuous-integration/drone/push Build is passing
2024-01-12 10:54:45 +08:00
he 0ef8f62a58 代码修改
continuous-integration/drone/push Build is passing
2024-01-12 10:45:53 +08:00
he 03f1f9f157 代码修改
continuous-integration/drone/push Build is passing
2024-01-12 10:43:32 +08:00
he a5e257a2f1 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-12 10:41:30 +08:00
he f550750e30 修改 2024-01-12 10:41:28 +08:00
hang 6865c7f4a1 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-12 10:23:45 +08:00
hang 9d2bb15ffd 增加真实名字 2024-01-12 10:23:25 +08:00
hang 336b14a4ce 增加上传人 2024-01-12 10:23:04 +08:00
he 344e8f50ae 阅片时间修改
continuous-integration/drone/push Build is passing
2024-01-12 10:01:37 +08:00
he ba0b7f33bc 阅片时间修改
continuous-integration/drone/push Build is passing
2024-01-12 09:52:18 +08:00
he 49bc2e1762 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-12 09:40:37 +08:00
he d3ec067224 阅片休息时间 2024-01-12 09:40:35 +08:00
hang 267d0494d3 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-11 16:32:36 +08:00
hang 172f6bc29f 修改OSS 上传通用配置 6 2024-01-11 16:32:35 +08:00
he 4f93db928f 获取脾脏验证
continuous-integration/drone/push Build is passing
2024-01-11 15:36:42 +08:00
he c10ee98076 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-11 15:24:44 +08:00
he 0820cffd9d 脾脏验证 2024-01-11 15:24:42 +08:00
hang 7f90d64064 修改配置
continuous-integration/drone/push Build is passing
2024-01-11 15:12:17 +08:00
hang c4c98910e8 port修改为int
continuous-integration/drone/push Build is passing
2024-01-11 14:57:08 +08:00
hang 06f1ca232e Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-11 14:54:40 +08:00
hang 90320c2b12 修改配置 2024-01-11 14:54:38 +08:00
he f5885f612a Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-11 14:48:31 +08:00
he af74059945 修改 2024-01-11 14:48:28 +08:00
hang 42948185f9 修改OSS 需要迁移4
continuous-integration/drone/push Build is passing
2024-01-11 14:40:25 +08:00
hang 6329778123 修改配置文件
continuous-integration/drone/push Build is passing
2024-01-11 14:40:10 +08:00
he eadf8f5266 修改阅片休息时间验证
continuous-integration/drone/push Build is passing
2024-01-11 14:24:03 +08:00
he c4a0e47a84 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-11 13:21:05 +08:00
he f9661e3b72 脾脏长度 修改返回 2024-01-11 13:21:03 +08:00
hang 1715d4d056 统一日志记录信息
continuous-integration/drone/push Build is passing
2024-01-11 11:43:07 +08:00
hang 40fae42a9e 修改oss2 需要迁移
continuous-integration/drone/push Build is passing
2024-01-11 11:29:27 +08:00
hang 19e55c1185 修改OSS 配置需要迁移
continuous-integration/drone/push Build is passing
2024-01-11 11:26:59 +08:00
hang 6443a46abb 修改导入国际化
continuous-integration/drone/push Build is passing
2024-01-11 10:16:00 +08:00
hang 8fb2e4b7f4 对接AWS 需要迁移
continuous-integration/drone/push Build is passing
2024-01-11 09:19:19 +08:00
hang 0be25fa16a 修改默认配置
continuous-integration/drone/push Build is passing
2024-01-10 16:43:05 +08:00
hang 8743c028a3 增加AWS 需要迁移
continuous-integration/drone/push Build is passing
2024-01-10 16:17:53 +08:00
hang 7174fd056a 测试AWS
continuous-integration/drone/push Build is passing
2024-01-10 16:17:38 +08:00
hang cd188691f6 测试OSS 下载完成
continuous-integration/drone/push Build is passing
2024-01-10 15:52:02 +08:00
hang c9586e7320 请求前端国际化增加缓存-需要迁移
continuous-integration/drone/push Build is passing
2024-01-10 15:24:45 +08:00
hang c35da39ba6 OSS 对接代码修改
continuous-integration/drone/push Build is passing
2024-01-10 14:57:41 +08:00
hang e2639b8055 修改配置
continuous-integration/drone/push Build is passing
2024-01-10 14:56:58 +08:00
hang 558ed48874 修改配置文件
continuous-integration/drone/push Build is passing
2024-01-10 14:56:34 +08:00
hang e38a3e5f53 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-10 13:37:19 +08:00
hang 1175696590 minio 测试修改 2024-01-10 13:37:16 +08:00
he 95862906a4 查询修改
continuous-integration/drone/push Build is passing
2024-01-10 13:18:31 +08:00
he 44cc8d883d Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-10 10:48:23 +08:00
he 4c607302f3 查询验证 2024-01-10 10:48:21 +08:00
hang a37ccac097 修改国际化取消权限限制
continuous-integration/drone/push Build is passing
2024-01-10 10:23:34 +08:00
hang b8c460e252 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-09 18:03:10 +08:00
hang 4df35ef8c0 修改配置 2024-01-09 18:03:09 +08:00
he 397ac4a154 查询条件修改
continuous-integration/drone/push Build is passing
2024-01-09 15:35:55 +08:00
he 3e6854053d Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-09 15:00:39 +08:00
he e155301b60 ir 查询修改 2024-01-09 15:00:38 +08:00
hang 197c315f07 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-01-09 14:27:17 +08:00
hang 5654125091 增加前端国际化修改 2024-01-09 14:27:13 +08:00
he 3768c22aed 休息时间修改
continuous-integration/drone/push Build is passing
2024-01-09 13:58:52 +08:00
he beb43a785e 查询条件修改
continuous-integration/drone/push Build is passing
2024-01-09 11:14:09 +08:00
hang 34e10ac41e 升级net8 模型要求严格了
continuous-integration/drone/push Build is passing
2024-01-05 17:06:50 +08:00
hang 8e26edabba 修改稽查上传文件路径 2024-01-05 13:05:42 +08:00
hang d6cda6337b 修改任务自动生成
continuous-integration/drone/push Build is passing
2024-01-04 15:59:54 +08:00
hang 5b1638ab42 修改待阅列表 临床数据未签名但是可以做后续访视,生成任务逻辑遗漏 2024-01-04 15:55:25 +08:00
hang 3537ccf3cd 清理旧的写法
continuous-integration/drone/push Build is passing
2024-01-04 13:59:19 +08:00
hang d15a9945de 修改打包路径
continuous-integration/drone/push Build is passing
2024-01-04 13:39:18 +08:00
hang 61fa371fd4 升级到最新版的nuget包 2024-01-04 13:24:51 +08:00
hang 05802ae91c 再升级一版本nuget包 2024-01-04 13:24:05 +08:00
hang b4df799a37 升级net8 Program修改 2024-01-04 13:23:03 +08:00
hang 6553bd70c5 升级项目框架提交 2024-01-04 13:22:59 +08:00
hang f3d0c6f28c 修改导表错误
continuous-integration/drone/push Build encountered an error
2024-01-04 12:16:03 +08:00
he 09e35513b0 再次修改
continuous-integration/drone/push Build is passing
2024-01-03 17:17:11 +08:00
he 381e25cda1 修改状态
continuous-integration/drone/push Build is passing
2024-01-03 17:07:49 +08:00
he c763c174d5 修改状态
continuous-integration/drone/push Build is passing
2024-01-03 16:56:55 +08:00
he d4f3239844 Merge branch 'Test.IRC' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.IRC
continuous-integration/drone/push Build is passing
2024-01-03 16:46:52 +08:00
he 806e9528f0 代码修改 修改阅片状态 2024-01-03 16:46:51 +08:00
hang aa59d9ecca Merge branch 'Test.IRC' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.IRC
continuous-integration/drone/push Build is passing
2024-01-03 15:27:24 +08:00
hang 1226af6376 修改中心调研导表 2024-01-03 15:27:11 +08:00
he 596ecba13f 修复
continuous-integration/drone/push Build is passing
2024-01-03 14:26:30 +08:00
he 57290d6a4b 修改
continuous-integration/drone/push Build is passing
2024-01-03 14:26:01 +08:00
he 52251d420f 阅片状态修改
continuous-integration/drone/push Build is passing
2024-01-03 14:24:24 +08:00
he 95e365fe4f Merge branch 'Test.IRC' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.IRC
continuous-integration/drone/push Build is passing
2024-01-03 14:01:39 +08:00
he 4f37f2fa0a 验证代码修改 2024-01-03 14:01:38 +08:00
hang 716b7833b0 修改 正式【OSS】配置修改sir.extimaging.com
continuous-integration/drone/push Build is passing
2024-01-03 09:18:43 +08:00
314 changed files with 14167 additions and 8544 deletions
+30
View File
@@ -0,0 +1,30 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
!**/.gitignore
!.git/HEAD
!.git/config
!.git/packed-refs
!.git/refs/heads/**
-112
View File
@@ -1,112 +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 Program1
{
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());
}
}
-251
View File
@@ -1,251 +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.Core.Application.Helper;
using IRaCIS.Application.Services.BackGroundJob;
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);
// 保护上传文件
//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.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();
}
Console.WriteLine("当前环境: " + env.EnvironmentName);
// 特殊异常处理 比如 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.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<UploadHub>("/UploadHub");
endpoints.MapHealthChecks("/health");
});
var hangfireJobService = app.ApplicationServices.GetRequiredService<IIRaCISHangfireJob>();
await hangfireJobService.InitHangfireJobTaskAsync();
}
}
}
+187 -86
View File
@@ -28,6 +28,10 @@ using Aliyun.Acs.Core.Auth.Sts;
using Aliyun.Acs.Core; using Aliyun.Acs.Core;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using IRaCIS.Core.Application.Contracts;
using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO;
using DocumentFormat.OpenXml.Spreadsheet;
using AutoMapper.QueryableExtensions;
namespace IRaCIS.Api.Controllers namespace IRaCIS.Api.Controllers
{ {
@@ -51,9 +55,10 @@ namespace IRaCIS.Api.Controllers
/// <param name="doctorId"></param> /// <param name="doctorId"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet, Route("doctor/getDetail/{doctorId:guid}")] [HttpGet, Route("doctor/getDetail/{doctorId:guid}")]
public async Task<IResponseOutput<DoctorDetailDTO>> GetDoctorDetail([FromServices] IAttachmentService attachmentService, [FromServices] IDoctorService _doctorService, public async Task<IResponseOutput<DoctorDetailDTO>> GetDoctorDetail([FromServices] IAttachmentService attachmentService, [FromServices] IDoctorService _doctorService,
[FromServices] IEducationService _educationService, [FromServices] ITrialExperienceService _trialExperienceService, [FromServices] IEducationService _educationService, [FromServices] ITrialExperienceService _trialExperienceService,
[FromServices] IResearchPublicationService _researchPublicationService, [FromServices] IVacationService _vacationService, Guid doctorId) [FromServices] IResearchPublicationService _researchPublicationService, [FromServices] IVacationService _vacationService, Guid doctorId)
{ {
var education = await _educationService.GetEducation(doctorId); var education = await _educationService.GetEducation(doctorId);
@@ -63,7 +68,7 @@ namespace IRaCIS.Api.Controllers
var doctorDetail = new DoctorDetailDTO var doctorDetail = new DoctorDetailDTO
{ {
AuditView =await _doctorService.GetAuditState(doctorId), AuditView = await _doctorService.GetAuditState(doctorId),
BasicInfoView = await _doctorService.GetBasicInfo(doctorId), BasicInfoView = await _doctorService.GetBasicInfo(doctorId),
EmploymentView = await _doctorService.GetEmploymentInfo(doctorId), EmploymentView = await _doctorService.GetEmploymentInfo(doctorId),
AttachmentList = await attachmentService.GetAttachments(doctorId), AttachmentList = await attachmentService.GetAttachments(doctorId),
@@ -74,7 +79,7 @@ namespace IRaCIS.Api.Controllers
TrialExperienceView = await _trialExperienceService.GetTrialExperience(doctorId), TrialExperienceView = await _trialExperienceService.GetTrialExperience(doctorId),
ResearchPublicationView = await _researchPublicationService.GetResearchPublication(doctorId), ResearchPublicationView = await _researchPublicationService.GetResearchPublication(doctorId),
SpecialtyView =await _doctorService.GetSpecialtyInfo(doctorId), SpecialtyView = await _doctorService.GetSpecialtyInfo(doctorId),
InHoliday = (await _vacationService.OnVacation(doctorId)).IsSuccess, InHoliday = (await _vacationService.OnVacation(doctorId)).IsSuccess,
IntoGroupInfo = _doctorService.GetDoctorIntoGroupInfo(doctorId), IntoGroupInfo = _doctorService.GetDoctorIntoGroupInfo(doctorId),
SowList = sowList, SowList = sowList,
@@ -93,77 +98,31 @@ namespace IRaCIS.Api.Controllers
/// <summary> 系统用户登录接口[New] </summary> /// <summary> 系统用户登录接口[New] </summary>
[HttpPost, Route("user/login")] [HttpPost, Route("user/login")]
[AllowAnonymous] [AllowAnonymous]
public async Task<IResponseOutput<LoginReturnDTO>> Login(UserLoginDTO loginUser, [FromServices] IEasyCachingProvider provider, [FromServices] IUserService _userService, public async Task<IResponseOutput> Login(UserLoginDTO loginUser,
[FromServices] ITokenService _tokenService, [FromServices] IConfiguration configuration) [FromServices] IEasyCachingProvider provider,
[FromServices] IUserService _userService,
[FromServices] ITokenService _tokenService,
[FromServices] IReadingImageTaskService readingImageTaskService,
IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig,
IMailVerificationService _mailVerificationService)
{ {
//MFA 邮箱验证 前端传递用户Id 和MFACode
var returnModel = await _userService.Login(loginUser.UserName, loginUser.Password); if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA)
if (returnModel.IsSuccess)
{ {
#region GRPC IIS问题 http/2 使 Guid userId = (Guid)loginUser.UserId;
////重试策略 //验证MFA 编码是否有问题 ,前端要拆开,自己调用验证的逻辑
//var defaultMethodConfig = new MethodConfig //await _userService.VerifyMFACodeAsync(userId, loginUser.MFACode);
//{
// Names = { MethodName.Default },
// RetryPolicy = new RetryPolicy
// {
// MaxAttempts = 3,
// InitialBackoff = TimeSpan.FromSeconds(1),
// MaxBackoff = TimeSpan.FromSeconds(5),
// BackoffMultiplier = 1.5,
// RetryableStatusCodes = { Grpc.Core.StatusCode.Unavailable }
// }
//};
//#region unable to trust the certificate then the gRPC client can be configured to ignore the invalid certificate //var loginUser = await _userRepository.Where(u => u.UserName.Equals(userName) && u.Password == password).ProjectTo<UserBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
//var httpHandler = new HttpClientHandler(); var basicInfo = await _userService.GetUserBasicInfo(userId, loginUser.Password);
//// Return `true` to allow certificates that are untrusted/invalid
//httpHandler.ServerCertificateCustomValidationCallback =
// HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var loginReturn = new LoginReturnDTO() { BasicInfo = basicInfo };
//////这一句是让grpc支持本地 http 如果本地访问部署在服务器上,那么是访问不成功的 loginReturn.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(loginReturn.BasicInfo));
//AppContext.SetSwitch(
// "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
//#endregion
//var grpcAdress = configuration.GetValue<string>("GrpcAddress");
////var grpcAdress = "http://localhost:7200";
//var channel = GrpcChannel.ForAddress(grpcAdress, new GrpcChannelOptions
//{
// HttpHandler = httpHandler,
// ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }
//});
////var channel = GrpcChannel.ForAddress(grpcAdress);
//var grpcClient = new TokenGrpcService.TokenGrpcServiceClient(channel);
//var userInfo = returnModel.Data.BasicInfo;
//var tokenResponse = grpcClient.GetUserToken(new GetTokenReuqest()
//{
// Id = userInfo.Id.ToString(),
// ReviewerCode = userInfo.ReviewerCode,
// IsAdmin = userInfo.IsAdmin,
// RealName = userInfo.RealName,
// UserTypeEnumInt = (int)userInfo.UserTypeEnum,
// UserTypeShortName = userInfo.UserTypeShortName,
// UserName = userInfo.UserName
//});
//returnModel.Data.JWTStr = tokenResponse.Token;
#endregion
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
// 创建一个 CookieOptions 对象,用于设置 Cookie 的属性 // 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
var option = new CookieOptions var option = new CookieOptions
@@ -174,19 +133,161 @@ namespace IRaCIS.Api.Controllers
Secure = false // 确保 cookie 只能通过 HTTPS 访问 Secure = false // 确保 cookie 只能通过 HTTPS 访问
}; };
HttpContext.Response.Cookies.Append("access_token", returnModel.Data.JWTStr, option); HttpContext.Response.Cookies.Append("access_token", loginReturn.JWTStr, option);
// 验证阅片休息时间
await readingImageTaskService.ResetReadingRestTime(userId);
await provider.SetAsync(userId.ToString(), loginReturn.JWTStr, TimeSpan.FromDays(7));
await provider.SetAsync($"{userId.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
return ResponseOutput.Ok(loginReturn);
}
else
{
var returnModel = await _userService.Login(loginUser.UserName, loginUser.Password);
if (returnModel.IsSuccess)
{
#region GRPC IIS问题 http/2 使
////重试策略
//var defaultMethodConfig = new MethodConfig
//{
// Names = { MethodName.Default },
// RetryPolicy = new RetryPolicy
// {
// MaxAttempts = 3,
// InitialBackoff = TimeSpan.FromSeconds(1),
// MaxBackoff = TimeSpan.FromSeconds(5),
// BackoffMultiplier = 1.5,
// RetryableStatusCodes = { Grpc.Core.StatusCode.Unavailable }
// }
//};
//#region unable to trust the certificate then the gRPC client can be configured to ignore the invalid certificate
//var httpHandler = new HttpClientHandler();
//// Return `true` to allow certificates that are untrusted/invalid
//httpHandler.ServerCertificateCustomValidationCallback =
// HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
//////这一句是让grpc支持本地 http 如果本地访问部署在服务器上,那么是访问不成功的
//AppContext.SetSwitch(
// "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
//#endregion
//var grpcAdress = configuration.GetValue<string>("GrpcAddress");
////var grpcAdress = "http://localhost:7200";
//var channel = GrpcChannel.ForAddress(grpcAdress, new GrpcChannelOptions
//{
// HttpHandler = httpHandler,
// ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }
//});
////var channel = GrpcChannel.ForAddress(grpcAdress);
//var grpcClient = new TokenGrpcService.TokenGrpcServiceClient(channel);
//var userInfo = returnModel.Data.BasicInfo;
//var tokenResponse = grpcClient.GetUserToken(new GetTokenReuqest()
//{
// Id = userInfo.Id.ToString(),
// ReviewerCode = userInfo.ReviewerCode,
// IsAdmin = userInfo.IsAdmin,
// RealName = userInfo.RealName,
// UserTypeEnumInt = (int)userInfo.UserTypeEnum,
// UserTypeShortName = userInfo.UserTypeShortName,
// UserName = userInfo.UserName
//});
//returnModel.Data.JWTStr = tokenResponse.Token;
#endregion
var userId = returnModel.Data.BasicInfo.Id;
if (_verifyConfig.CurrentValue.OpenLoginMFA)
{
//发版屏蔽
//returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
//MFA 发送邮件
returnModel.Data.IsMFA = true;
var email = returnModel.Data.BasicInfo.EMail;
#region Email
// 找到 "@" 符号的位置
int atIndex = email.IndexOf('@');
// 替换 "@" 符号前的中间两位为星号
string visiblePart = email.Substring(0, atIndex);
int startIndex = (visiblePart.Length - 2) / 2;
// 替换中间两位字符为星号
string hiddenPartBeforeAt = visiblePart.Substring(0, startIndex) + "**" + visiblePart.Substring(startIndex + 2);
string afterAt = email.Substring(atIndex + 1);
// 组合隐藏和可见部分
string hiddenEmail = hiddenPartBeforeAt + "@" + afterAt;
#endregion
returnModel.Data.BasicInfo.EMail = hiddenEmail;
await _userService.SendMFAEmail(userId);
}
else
{
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
// 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
var option = new CookieOptions
{
Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
HttpOnly = false, // 确保 cookie 只能通过 HTTP 访问
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None, // 设置 SameSite 属性
Secure = false // 确保 cookie 只能通过 HTTPS 访问
};
HttpContext.Response.Cookies.Append("access_token", returnModel.Data.JWTStr, option);
// 验证阅片休息时间
await readingImageTaskService.ResetReadingRestTime(returnModel.Data.BasicInfo.Id);
await provider.SetAsync(userId.ToString(), returnModel.Data.JWTStr, TimeSpan.FromDays(7));
await provider.SetAsync($"{userId.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
}
}
return returnModel;
} }
var userId = returnModel.Data.BasicInfo.Id.ToString();
//provider.Set(userId, userId, TimeSpan.FromMinutes(AppSettings.LoginExpiredTimeSpan));
await provider.SetAsync(userId.ToString(), returnModel.Data.JWTStr, TimeSpan.FromDays(7));
return returnModel;
} }
[HttpGet, Route("imageShare/ShareImage")] [HttpGet, Route("imageShare/ShareImage")]
[AllowAnonymous] [AllowAnonymous]
public IResponseOutput ShareImage([FromServices] ITokenService _tokenService) public IResponseOutput ShareImage([FromServices] ITokenService _tokenService)
@@ -216,7 +317,7 @@ namespace IRaCIS.Api.Controllers
var ossOptions = serviceOption.AliyunOSS; 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 #region token
//IClientProfile profile = DefaultProfile.GetProfile(ossOptions.RegionId, ossOptions.AccessKeyId, ossOptions.AccessKeySecret); //IClientProfile profile = DefaultProfile.GetProfile(ossOptions.RegionId, ossOptions.AccessKeyId, ossOptions.AccessKeySecret);
@@ -257,19 +358,19 @@ namespace IRaCIS.Api.Controllers
#endregion #endregion
} }
else if(Enum.TryParse<ObjectStoreUse>(serviceOption.ObjectStoreUse, out var parsedValue) && parsedValue == ObjectStoreUse.MinIO) 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 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 });
} }
} }
[HttpGet("user/GenerateSTS")] [HttpGet("user/GenerateSTS")]
public IResponseOutput GenerateSTS([FromServices]IOptionsMonitor<AliyunOSSOptions> options ) public IResponseOutput GenerateSTS([FromServices] IOptionsMonitor<AliyunOSSOptions> options)
{ {
var ossOptions = options.CurrentValue; var ossOptions = options.CurrentValue;
@@ -297,9 +398,9 @@ namespace IRaCIS.Api.Controllers
SecurityToken = response.Credentials.SecurityToken, SecurityToken = response.Credentials.SecurityToken,
Expiration = response.Credentials.Expiration, Expiration = response.Credentials.Expiration,
Region = ossOptions.region , Region = ossOptions.region,
BucketName = ossOptions.bucketName , BucketName = ossOptions.bucketName,
ViewEndpoint = ossOptions.viewEndpoint , ViewEndpoint = ossOptions.viewEndpoint,
}; };
@@ -311,12 +412,12 @@ namespace IRaCIS.Api.Controllers
[HttpGet("User/UserRedirect")] [HttpGet("User/UserRedirect")]
[AllowAnonymous] [AllowAnonymous]
public async Task<IActionResult> UserRedirect([FromServices] IRepository<User> _userRepository, string url ,[FromServices]ILogger<ExtraController> _logger) public async Task<IActionResult> UserRedirect([FromServices] IRepository<User> _userRepository, string url, [FromServices] ILogger<ExtraController> _logger)
{ {
var decodeUrl = System.Web.HttpUtility.UrlDecode(url); var decodeUrl = System.Web.HttpUtility.UrlDecode(url);
var userId = decodeUrl.Substring(decodeUrl.IndexOf("UserId=") + "UserId=".Length , 36) ; var userId = decodeUrl.Substring(decodeUrl.IndexOf("UserId=") + "UserId=".Length, 36);
var token = decodeUrl.Substring(decodeUrl.IndexOf("access_token=") + "access_token=".Length); var token = decodeUrl.Substring(decodeUrl.IndexOf("access_token=") + "access_token=".Length);
@@ -324,12 +425,12 @@ namespace IRaCIS.Api.Controllers
var domainStrList = decodeUrl.Split("/").ToList().Take(3).ToList(); var domainStrList = decodeUrl.Split("/").ToList().Take(3).ToList();
var errorUrl = domainStrList[0]+"//"+ domainStrList[2]+ "/error"; var errorUrl = domainStrList[0] + "//" + domainStrList[2] + "/error";
if (!await _userRepository.AnyAsync(t => t.Id == Guid.Parse(userId) && t.EmailToken == token && t.IsFirstAdd)) if (!await _userRepository.AnyAsync(t => t.Id == Guid.Parse(userId) && t.EmailToken == token && t.IsFirstAdd))
{ {
decodeUrl = errorUrl+ $"?lang={lang}&ErrorMessage={System.Web.HttpUtility.UrlEncode(lang=="zh"? "": "ErrorThe initialization link has expired. Return")} "; decodeUrl = errorUrl + $"?lang={lang}&ErrorMessage={System.Web.HttpUtility.UrlEncode(lang == "zh" ? "" : "ErrorThe initialization link has expired. Return")} ";
} }
return Redirect(decodeUrl); return Redirect(decodeUrl);
@@ -419,13 +419,30 @@ namespace IRaCIS.Core.API.Controllers
} }
/// <summary>
/// 重置并同步项目阅片标准
/// </summary>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingCriterion/ResetAndAsyncCriterion")]
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
/// <summary> public async Task<IResponseOutput> ResetAndAsyncCriterion(DataInspectionDto<ResetAndAsyncCriterionInDto> opt)
/// CRC RequestToQC 批量提交 {
/// </summary> var singid = await _inspectionService.RecordSing(opt.SignInfo);
/// <param name="opt"></param> var result = await _trialConfigService.ResetAndAsyncCriterion(opt.Data);
/// <returns></returns> await _inspectionService.CompletedSign(singid, result);
[HttpPost, Route("Inspection/QCOperation/CRCRequestToQC")] return result;
}
/// <summary>
/// CRC RequestToQC 批量提交
/// </summary>
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/QCOperation/CRCRequestToQC")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> CRCRequestToQC(DataInspectionDto<CRCRequestToQCCommand> opt) public async Task<IResponseOutput> CRCRequestToQC(DataInspectionDto<CRCRequestToQCCommand> opt)
@@ -20,7 +20,6 @@ using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention; using IRaCIS.Core.Infrastructure.Extention;
using Magicodes.ExporterAndImporter.Excel;
using MassTransit; using MassTransit;
using MediatR; using MediatR;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
@@ -33,12 +32,12 @@ using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.StaticFiles; using Microsoft.AspNetCore.StaticFiles;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using MiniExcelLibs; using MiniExcelLibs;
using Newtonsoft.Json; using Newtonsoft.Json;
using SharpCompress.Archives; using SharpCompress.Archives;
using SkiaSharp;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
@@ -235,13 +234,17 @@ namespace IRaCIS.Core.API.Controllers
public IUserInfo _userInfo { get; set; } public IUserInfo _userInfo { get; set; }
private readonly IMediator _mediator; private readonly IMediator _mediator;
public IStringLocalizer _localizer { get; set; }
private readonly IWebHostEnvironment _hostEnvironment; private readonly IWebHostEnvironment _hostEnvironment;
private readonly IRepository _repository; private readonly IRepository _repository;
private readonly IEasyCachingProvider _provider; private readonly IEasyCachingProvider _provider;
private readonly QCCommon _qCCommon; private readonly QCCommon _qCCommon;
public StudyController(IMapper mapper, IUserInfo userInfo, IWebHostEnvironment hostEnvironment, IMediator mediator, IEasyCachingProvider provider, public StudyController(IMapper mapper, IStringLocalizer localizer, IUserInfo userInfo, IWebHostEnvironment hostEnvironment, IMediator mediator, IEasyCachingProvider provider,
QCCommon qCCommon, QCCommon qCCommon,
IRepository repository) IRepository repository)
{ {
@@ -249,7 +252,7 @@ namespace IRaCIS.Core.API.Controllers
_provider = provider; _provider = provider;
_hostEnvironment = hostEnvironment; _hostEnvironment = hostEnvironment;
_mediator = mediator; _mediator = mediator;
_localizer = localizer;
_mapper = mapper; _mapper = mapper;
_userInfo = userInfo; _userInfo = userInfo;
_repository = repository; _repository = repository;
@@ -273,7 +276,6 @@ namespace IRaCIS.Core.API.Controllers
var studyMonitor = new StudyMonitor() var studyMonitor = new StudyMonitor()
{ {
TrialId = savedInfo.TrialId, TrialId = savedInfo.TrialId,
SiteId = savedInfo.SiteId,
SubjectId = savedInfo.SubjectId, SubjectId = savedInfo.SubjectId,
SubjectVisitId = savedInfo.SubjectVisitId, SubjectVisitId = savedInfo.SubjectVisitId,
@@ -313,7 +315,7 @@ namespace IRaCIS.Core.API.Controllers
string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value)) string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
{ {
//---不支持的MediaType //---不支持的MediaType
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_UnsupportedMedia")); return ResponseOutput.NotOk(_localizer["UploadDownLoad_UnsupportedMedia"]);
} }
var archiveStudyCommand = new ArchiveStudyCommand() { AbandonStudyId = abandonStudyId, StudyInstanceUid = studyInstanceUid, SubjectVisitId = subjectVisitId }; var archiveStudyCommand = new ArchiveStudyCommand() { AbandonStudyId = abandonStudyId, StudyInstanceUid = studyInstanceUid, SubjectVisitId = subjectVisitId };
@@ -402,12 +404,12 @@ namespace IRaCIS.Core.API.Controllers
} }
catch (Exception ) catch (Exception)
{ {
_provider.Remove($"StudyUid_{trialId}_{archiveStudyCommand.StudyInstanceUid}"); _provider.Remove($"StudyUid_{trialId}_{archiveStudyCommand.StudyInstanceUid}");
//---请求异常,请重试! //---请求异常,请重试!
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_RequestError")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_RequestError"]);
} }
studyMonitor.FileSize = (decimal)HttpContext.Request.ContentLength; studyMonitor.FileSize = (decimal)HttpContext.Request.ContentLength;
@@ -477,6 +479,8 @@ namespace IRaCIS.Core.API.Controllers
public string FilePath { get; set; } public string FilePath { get; set; }
public string FileName { get; set; } public string FileName { get; set; }
public int FileFize { get; set; } public int FileFize { get; set; }
public string FileType { get; set; }
} }
} }
@@ -501,7 +505,7 @@ namespace IRaCIS.Core.API.Controllers
await _qCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId); await _qCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
var sv = (await _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.SiteId, t.SubjectId }).FirstOrDefaultAsync()).IfNullThrowConvertException(); var sv = (await _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.TrialSiteId, t.SubjectId }).FirstOrDefaultAsync()).IfNullThrowConvertException();
var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == studyMonitorId); var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == studyMonitorId);
@@ -509,7 +513,7 @@ namespace IRaCIS.Core.API.Controllers
foreach (var item in incommand.UploadedFileList) foreach (var item in incommand.UploadedFileList)
{ {
await _repository.AddAsync(new NoneDicomStudyFile() { FileName = item.FileName, Path = item.FilePath, NoneDicomStudyId = noneDicomStudyId }); await _repository.AddAsync(new NoneDicomStudyFile() { FileName = item.FileName, Path = item.FilePath, NoneDicomStudyId = noneDicomStudyId,FileType=item.FileType });
} }
var uploadFinishedTime = DateTime.Now; var uploadFinishedTime = DateTime.Now;
@@ -559,14 +563,14 @@ namespace IRaCIS.Core.API.Controllers
if (!fileName.EndsWith(".xlsx") && !fileName.EndsWith(".csv") && !fileName.EndsWith(".xls")) if (!fileName.EndsWith(".xlsx") && !fileName.EndsWith(".csv") && !fileName.EndsWith(".xls"))
{ {
//---支持.xlsx、.xls、.csv格式的文件上传。 //---支持.xlsx、.xls、.csv格式的文件上传。
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_SupportedFormats")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_SupportedFormats"]);
} }
fileStream.CopyTo(templateFileStream); fileStream.CopyTo(templateFileStream);
templateFileStream.Seek(0, SeekOrigin.Begin); 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 }); await _repository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId });
@@ -580,9 +584,22 @@ namespace IRaCIS.Core.API.Controllers
var etcCheckList = new List<CheckViewModel>(); var etcCheckList = new List<CheckViewModel>();
#region MiniExcel #region MiniExcel
if (fileName.EndsWith(".xlsx"))
{
etcCheckList = MiniExcel.Query<CheckViewModel>(templateFileStream, excelType: ExcelType.XLSX).ToList();
}
else if (fileName.EndsWith(".csv"))
{
//因为csv 需要加配置文件 不然都是null
etcCheckList = MiniExcel.Query<CheckViewModel>(templateFileStream, null, configuration: new MiniExcelLibs.Csv.CsvConfiguration()
{
StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312"))
}).ToList();
}
//if (fileName.EndsWith(".csv")) //if (fileName.EndsWith(".csv"))
//{ //{
// //因为csv 需要加配置文件 不然都是null // //因为csv 需要加配置文件 不然都是null
@@ -598,67 +615,72 @@ namespace IRaCIS.Core.API.Controllers
#endregion #endregion
#region net8
//Magicodes 支持自定义特性验证 //Magicodes 支持自定义特性验证
if (fileName.EndsWith(".xlsx")) // if (fileName.EndsWith(".xlsx"))
{ //{
var Importer = new ExcelImporter(); // var Importer = new ExcelImporter();
var import = await Importer.Import<CheckViewModel>(templateFileStream); // var import = await Importer.Import<CheckViewModel>(templateFileStream);
if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString()); // if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
//if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors)); // //if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors)); // if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(_localizer["UploadDownLoad_TemplateErrors"]);
etcCheckList = import.Data.ToList(); // etcCheckList = import.Data.ToList();
} //}
else if (fileName.EndsWith(".csv")) //else if (fileName.EndsWith(".csv"))
{ //{
#region MiniExcel读取 xlsx Magicodes验证数据 // #region 临时方案 MiniExcel读取 然后保存为xlsx 再用 Magicodes验证数据
//因为csv 需要加配置文件 不然都是null // //因为csv 需要加配置文件 不然都是null
etcCheckList = MiniExcel.Query<CheckViewModel>(templateFileStream, null, configuration: new MiniExcelLibs.Csv.CsvConfiguration() // etcCheckList = MiniExcel.Query<CheckViewModel>(templateFileStream, null, configuration: new MiniExcelLibs.Csv.CsvConfiguration()
{ // {
StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312")) // StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312"))
}).ToList(); // }).ToList();
var (csVToXlsxPath, csVToXlsxRelativePath) = FileStoreHelper.GetTrialCheckFilePath(_hostEnvironment, Path.GetFileNameWithoutExtension(fileName) + ".xlsx", trialId); // var (csVToXlsxPath, csVToXlsxRelativePath) = FileStoreHelper.GetTrialCheckFilePath(_hostEnvironment, Path.GetFileNameWithoutExtension(fileName) + ".xlsx", trialId);
await MiniExcel.SaveAsAsync(csVToXlsxPath, etcCheckList, excelType: ExcelType.XLSX); // await MiniExcel.SaveAsAsync(csVToXlsxPath, etcCheckList, excelType: ExcelType.XLSX);
var Importer = new ExcelImporter(); // var Importer = new ExcelImporter();
var import = await Importer.Import<CheckViewModel>(System.IO.File.OpenRead(csVToXlsxPath)); // var import = await Importer.Import<CheckViewModel>(System.IO.File.OpenRead(csVToXlsxPath));
if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString()); // if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
//if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors)); // //if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors)); // if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors));
etcCheckList = import.Data.ToList(); // etcCheckList = import.Data.ToList();
#endregion // #endregion
#region excel编码格式 // #region 导入组件有问题 excel编码格式
//var Importer = new CsvImporter(); // //var Importer = new CsvImporter();
//var import = await Importer.Import<CheckViewModel>(File.OpenRead(filePath)); // //var import = await Importer.Import<CheckViewModel>(File.OpenRead(filePath));
//if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString()); // //if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
//if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors)); // //if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
//if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors)); // //if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors));
//etcCheckList = import.Data.ToList(); // //etcCheckList = import.Data.ToList();
#endregion // #endregion
} //}
#endregion
//ExcelReaderFactory 需要自己验证数据 并且从固定列取数据 //ExcelReaderFactory 需要自己验证数据 并且从固定列取数据
else else
{ {
@@ -697,7 +719,7 @@ namespace IRaCIS.Core.API.Controllers
if (etcCheckList == null || etcCheckList.Count == 0) if (etcCheckList == null || etcCheckList.Count == 0)
{ {
//---请保证上传数据符合模板文件中的样式,且存在有效数据。 //---请保证上传数据符合模板文件中的样式,且存在有效数据。
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_InvalidData")); return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]);
} }
else else
{ {
@@ -718,7 +740,7 @@ namespace IRaCIS.Core.API.Controllers
if (etcCheckList.Count == 0) if (etcCheckList.Count == 0)
{ {
//---请保证上传数据符合模板文件中的样式,且存在有效数据。 //---请保证上传数据符合模板文件中的样式,且存在有效数据。
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_InvalidData")); return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]);
} }
} }
@@ -962,12 +984,13 @@ namespace IRaCIS.Core.API.Controllers
public IMapper _mapper { get; set; } public IMapper _mapper { get; set; }
public IUserInfo _userInfo { get; set; } public IUserInfo _userInfo { get; set; }
private readonly IMediator _mediator; private readonly IMediator _mediator;
public IStringLocalizer _localizer { get; set; }
private readonly IWebHostEnvironment _hostEnvironment; private readonly IWebHostEnvironment _hostEnvironment;
public UploadDownLoadController(IMapper mapper, IUserInfo userInfo, IMediator mediator, IWebHostEnvironment hostEnvironment) public UploadDownLoadController(IMapper mapper, IUserInfo userInfo, IStringLocalizer localizer, IMediator mediator, IWebHostEnvironment hostEnvironment)
{ {
_hostEnvironment = hostEnvironment; _hostEnvironment = hostEnvironment;
_localizer = localizer;
_mediator = mediator; _mediator = mediator;
_mapper = mapper; _mapper = mapper;
_userInfo = userInfo; _userInfo = userInfo;
@@ -994,10 +1017,10 @@ namespace IRaCIS.Core.API.Controllers
if (!realFileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase)) if (!realFileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase))
{ {
// 请用提供格式的模板excel上传需要处理的数据 // 请用提供格式的模板excel上传需要处理的数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_TemplateUploadData")); throw new BusinessValidationFailedException(_localizer["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 }); await _inspectionFileRepository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId });
@@ -1015,7 +1038,7 @@ namespace IRaCIS.Core.API.Controllers
if (excelList.Any(t => string.IsNullOrWhiteSpace(t.TrialSiteCode) || string.IsNullOrWhiteSpace(t.FirstName) || string.IsNullOrWhiteSpace(t.LastName) || string.IsNullOrWhiteSpace(t.Email) || string.IsNullOrWhiteSpace(t.UserTypeStr))) if (excelList.Any(t => string.IsNullOrWhiteSpace(t.TrialSiteCode) || string.IsNullOrWhiteSpace(t.FirstName) || string.IsNullOrWhiteSpace(t.LastName) || string.IsNullOrWhiteSpace(t.Email) || string.IsNullOrWhiteSpace(t.UserTypeStr)))
{ {
//请确保Excel中 每一行的 中心编号,姓名,邮箱,用户类型数据记录完整再进行上传 //请确保Excel中 每一行的 中心编号,姓名,邮箱,用户类型数据记录完整再进行上传
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_EnsureCompleteData")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_EnsureCompleteData"]);
} }
var siteCodeList = excelList.Select(t => t.TrialSiteCode.Trim().ToUpper()).Distinct().ToList(); var siteCodeList = excelList.Select(t => t.TrialSiteCode.Trim().ToUpper()).Distinct().ToList();
@@ -1023,35 +1046,35 @@ namespace IRaCIS.Core.API.Controllers
if (_trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode.ToUpper())).Count() != siteCodeList.Count) if (_trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode.ToUpper())).Count() != siteCodeList.Count)
{ {
//在项目中未找到该Excel中部分或全部中心 //在项目中未找到该Excel中部分或全部中心
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidCenters")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidCenters"]);
} }
if (excelList.GroupBy(t => new { t.TrialSiteCode, t.UserTypeStr, t.Email }).Any(g => g.Count() > 1)) if (excelList.GroupBy(t => new { t.TrialSiteCode, t.UserTypeStr, t.Email }).Any(g => g.Count() > 1))
{ {
// 同一邮箱,同一用户类型,只能生成一个账户,请核查Excel数据 // 同一邮箱,同一用户类型,只能生成一个账户,请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_CheckDuplicateAccounts")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_CheckDuplicateAccounts"]);
} }
if (excelList.Any(t => !t.Email.Contains("@"))) if (excelList.Any(t => !t.Email.Contains("@")))
{ {
//有邮箱不符合邮箱格式,请核查Excel数据 //有邮箱不符合邮箱格式,请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidEmail")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidEmail"]);
} }
var generateUserTypeList = new List<string>() { "CRC", "CRA" }; var generateUserTypeList = new List<string>() { "CRC", "CRA" };
if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper()))) if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper())))
{ {
//用户类型仅能为 CRC,SR,CRA 请核查Excel数据 //用户类型仅能为 CRC,SR,CRA 请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidUserType")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidUserType"]);
} }
if (excelList.Count == 0) if (excelList.Count == 0)
{ {
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_NoValiddata")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_NoValiddata"]);
} }
//处理好 用户类型 和用户类型枚举 //处理好 用户类型 和用户类型枚举
var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList(); var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList();
var siteList = _trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode)).Select(t => new { t.TrialSiteCode, t.SiteId }).ToList(); var siteList = _trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode)).Select(t => new { t.TrialSiteCode, TrialSiteId= t.Id }).ToList();
foreach (var item in excelList) foreach (var item in excelList)
{ {
@@ -1072,7 +1095,7 @@ namespace IRaCIS.Core.API.Controllers
} }
item.SiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.ToUpper() == item.TrialSiteCode.ToUpper()).SiteId; item.TrialSiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.ToUpper() == item.TrialSiteCode.ToUpper()).TrialSiteId;
} }
+8 -9
View File
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<SignAssembly>false</SignAssembly> <SignAssembly>false</SignAssembly>
<UserSecretsId>354572d4-9e15-4099-807c-63a2d29ff9f2</UserSecretsId> <UserSecretsId>354572d4-9e15-4099-807c-63a2d29ff9f2</UserSecretsId>
<LangVersion>default</LangVersion> <LangVersion>default</LangVersion>
@@ -63,25 +63,24 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="aliyun-net-sdk-sts" Version="3.1.2" /> <PackageReference Include="aliyun-net-sdk-sts" Version="3.1.2" />
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" /> <PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" /> <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="EasyCaching.Interceptor.Castle" Version="1.9.2" /> <PackageReference Include="EasyCaching.Interceptor.Castle" Version="1.9.2" />
<PackageReference Include="EasyCaching.Serialization.MessagePack" Version="1.9.2"> <PackageReference Include="EasyCaching.Serialization.MessagePack" Version="1.9.2">
<TreatAsUsed>true</TreatAsUsed> <TreatAsUsed>true</TreatAsUsed>
</PackageReference> </PackageReference>
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.6" /> <PackageReference Include="Hangfire.AspNetCore" Version="1.8.12" />
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" /> <PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
<PackageReference Include="Hangfire.SqlServer" Version="1.8.6" /> <PackageReference Include="Hangfire.SqlServer" Version="1.8.12" />
<PackageReference Include="Invio.Extensions.Authentication.JwtBearer" Version="2.0.1" /> <PackageReference Include="Invio.Extensions.Authentication.JwtBearer" Version="2.0.1" />
<PackageReference Include="LogDashboard" Version="1.4.8" /> <PackageReference Include="LogDashboard" Version="1.4.8" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.10" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.5" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.0" /> <PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.0.3" /> <PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.0.3" />
<PackageReference Include="Serilog.Sinks.Email" Version="2.4.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.5.0" /> <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.6.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
+41 -25
View File
@@ -4,6 +4,34 @@
<name>IRaCIS.Core.API</name> <name>IRaCIS.Core.API</name>
</assembly> </assembly>
<members> <members>
<member name="M:EasyCaching.Demo.Interceptors.Controllers.ErrorController.Error(System.Int32)">
<summary>
主要处理 前端404等错误 全局业务异常已统一处理了,非业务错误会来到这里
</summary>
<param name="code"></param>
<returns></returns>
</member>
<member name="T:IRaCIS.Api.Controllers.ExtraController">
<summary>
医生基本信息 、工作信息 专业信息、审核状态
</summary>
</member>
<member name="M:IRaCIS.Api.Controllers.ExtraController.GetDoctorDetail(IRaCIS.Application.Interfaces.IAttachmentService,IRaCIS.Application.Interfaces.IDoctorService,IRaCIS.Application.Interfaces.IEducationService,IRaCIS.Application.Interfaces.ITrialExperienceService,IRaCIS.Application.Interfaces.IResearchPublicationService,IRaCIS.Application.Interfaces.IVacationService,System.Guid)">
<summary>
获取医生详情
</summary>
<param name="attachmentService"></param>
<param name="_doctorService"></param>
<param name="_educationService"></param>
<param name="_trialExperienceService"></param>
<param name="_researchPublicationService"></param>
<param name="_vacationService"></param>
<param name="doctorId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,EasyCaching.Core.IEasyCachingProvider,IRaCIS.Application.Services.IUserService,IRaCIS.Core.Application.Auth.ITokenService,IRaCIS.Core.Application.Contracts.IReadingImageTaskService,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},IRaCIS.Application.Services.IMailVerificationService)">
<summary> 系统用户登录接口[New] </summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateTrialInspection(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Application.Contracts.TrialCommand})"> <member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateTrialInspection(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Application.Contracts.TrialCommand})">
<summary> 添加实验项目-返回新增Id[AUTH]</summary> <summary> 添加实验项目-返回新增Id[AUTH]</summary>
<returns>新记录Id</returns> <returns>新记录Id</returns>
@@ -180,6 +208,12 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.ResetAndAsyncCriterion(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.ResetAndAsyncCriterionInDto})">
<summary>
重置并同步项目阅片标准
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.CRCRequestToQC(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Contracts.CRCRequestToQCCommand})"> <member name="M:IRaCIS.Core.API.Controllers.InspectionController.CRCRequestToQC(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Contracts.CRCRequestToQCCommand})">
<summary> <summary>
CRC RequestToQC 批量提交 CRC RequestToQC 批量提交
@@ -337,6 +371,11 @@
IPLimit限流 启动服务 IPLimit限流 启动服务
</summary> </summary>
</member> </member>
<member name="T:IRaCIS.Core.API.JSONTimeZoneConverter">
<summary>
序列化,反序列化的时候,处理时间 时区转换
</summary>
</member>
<member name="M:IRaCIS.Core.API.NullToEmptyStringResolver.CreateProperties(System.Type,Newtonsoft.Json.MemberSerialization)"> <member name="M:IRaCIS.Core.API.NullToEmptyStringResolver.CreateProperties(System.Type,Newtonsoft.Json.MemberSerialization)">
<summary> <summary>
创建属性 创建属性
@@ -345,27 +384,6 @@
<param name="memberSerialization">序列化成员</param> <param name="memberSerialization">序列化成员</param>
<returns></returns> <returns></returns>
</member> </member>
<member name="T:IRaCIS.Api.Controllers.ExtraController">
<summary>
医生基本信息 、工作信息 专业信息、审核状态
</summary>
</member>
<member name="M:IRaCIS.Api.Controllers.ExtraController.GetDoctorDetail(IRaCIS.Application.Interfaces.IAttachmentService,IRaCIS.Application.Interfaces.IDoctorService,IRaCIS.Application.Interfaces.IEducationService,IRaCIS.Application.Interfaces.ITrialExperienceService,IRaCIS.Application.Interfaces.IResearchPublicationService,IRaCIS.Application.Interfaces.IVacationService,System.Guid)">
<summary>
获取医生详情
</summary>
<param name="attachmentService"></param>
<param name="_doctorService"></param>
<param name="_educationService"></param>
<param name="_trialExperienceService"></param>
<param name="_researchPublicationService"></param>
<param name="_vacationService"></param>
<param name="doctorId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,EasyCaching.Core.IEasyCachingProvider,IRaCIS.Application.Services.IUserService,IRaCIS.Core.Application.Auth.ITokenService,Microsoft.Extensions.Configuration.IConfiguration)">
<summary> 系统用户登录接口[New] </summary>
</member>
<member name="M:IRaCIS.WX.CoreApi.Auth.AuthMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext)"> <member name="M:IRaCIS.WX.CoreApi.Auth.AuthMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext)">
<summary> <summary>
为了前端 一段时间无操作,需要重新登陆 为了前端 一段时间无操作,需要重新登陆
@@ -373,12 +391,10 @@
<param name="httpContext"></param> <param name="httpContext"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:EasyCaching.Demo.Interceptors.Controllers.ErrorController.Error(System.Int32)"> <member name="T:TimeZoneAdjustmentMiddleware">
<summary> <summary>
主要处理 前端404等错误 全局业务异常已统一处理了,非业务错误会来到这里 废弃,没用
</summary> </summary>
<param name="code"></param>
<returns></returns>
</member> </member>
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService"> <member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
<summary> <summary>
@@ -0,0 +1,118 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
/// <summary>
/// 废弃,没用
/// </summary>
public class TimeZoneAdjustmentMiddleware
{
private readonly RequestDelegate _next;
public TimeZoneAdjustmentMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (string.IsNullOrEmpty(context.Request.ContentType))
{
// 请求没有内容体,可能是一个没有请求体的请求,比如 GET 请求
await _next(context);
return;
}
var timeZoneId = "Asia/Shanghai"; // 客户端默认时区
var timeZoneIdHeaderValue = context.Request.Headers["TimeZoneId"];
if (!string.IsNullOrEmpty(timeZoneIdHeaderValue))
{
timeZoneId = timeZoneIdHeaderValue;
}
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
// 处理 JSON 请求体中的时间字段
if (context.Request.ContentType.StartsWith("application/json"))
{
var requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync();
// 使用 JSON.NET 或 System.Text.Json 解析 JSON 请求体
// 假设请求体中有一个名为 "dateTime" 的时间字段
dynamic jsonData = JsonConvert.DeserializeObject(requestBody);
if (jsonData.dateTime != null)
{
if (DateTime.TryParse((string)jsonData.dateTime, out DateTime dateTime))
{
// 将 JSON 请求体中的时间字段转换为服务器时区的时间
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
jsonData.dateTime = serverTime;
}
}
// 将修改后的 JSON 请求体重新写入请求流中
var jsonBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jsonData));
context.Request.Body = new MemoryStream(jsonBytes);
context.Request.ContentLength = jsonBytes.Length;
}
// 处理 URL 表单参数
var modifiedQuery = new Dictionary<string, StringValues>();
foreach (var key in context.Request.Query.Keys)
{
if (DateTime.TryParse(context.Request.Query[key], out DateTime dateTime))
{
// 将 URL 表单参数中的时间转换为服务器时区的时间
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
modifiedQuery[key] = new StringValues(serverTime.ToString());
}
else
{
modifiedQuery[key] = context.Request.Query[key];
}
}
context.Request.Query = new QueryCollection(modifiedQuery);
// 处理Form请求体中的参数
if (context.Request.HasFormContentType)
{
var modifiedForm = new Dictionary<string, StringValues>();
foreach (var key in context.Request.Form.Keys)
{
if (DateTime.TryParse(context.Request.Form[key], out DateTime dateTime))
{
// 将请求体中的时间转换为服务器时区的时间
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
modifiedForm[key] = new StringValues(serverTime.ToString());
}
else
{
modifiedForm[key] = context.Request.Form[key];
}
}
var newFormCollection = new FormCollection(modifiedForm);
// 将新的表单集合设置回请求对象
context.Request.Form = newFormCollection;
}
await _next(context);
}
}
+17 -19
View File
@@ -24,8 +24,10 @@ using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.HttpOverrides;
using IRaCIS.Application.Services.BackGroundJob; using IRaCIS.Application.Services.BackGroundJob;
using LogDashboard; using LogDashboard;
using OfficeOpenXml.Utils; using FellowOakDicom.Network;
using IRaCIS.Core.Application.Service.ImageAndDoc;
using IP2Region.Net.Abstractions;
using IP2Region.Net.XDB;
#region #region
@@ -74,16 +76,10 @@ if (urlsIndex > -1)
NewId.SetProcessIdProvider(new CurrentProcessIdProvider()); NewId.SetProcessIdProvider(new CurrentProcessIdProvider());
builder.Configuration.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{enviromentName}.json", false, true);
builder.Host builder.Host
.ConfigureAppConfiguration((hostContext, config) =>
{
//Console.WriteLine(hostContext.HostingEnvironment.EnvironmentName);
config.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{enviromentName}.json", false, true);
})
.UseServiceProviderFactory(new AutofacServiceProviderFactory()) .UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(containerBuilder => .ConfigureContainer<ContainerBuilder>(containerBuilder =>
{ {
@@ -115,7 +111,7 @@ builder.Services.AddControllers(options =>
} }
}) })
.AddNewtonsoftJsonSetup(); // NewtonsoftJson 序列化 处理 .AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化 处理
builder.Services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig")); builder.Services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig"));
builder.Services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig")); builder.Services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
@@ -165,7 +161,7 @@ builder.Services.AddSignalR();
builder.Services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>(); builder.Services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
builder.Services.AddSingleton<ISearcher>(new Searcher(CachePolicy.Content, Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, "ip2region.xdb")));
#region #region
@@ -247,15 +243,11 @@ app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseAuthentication(); app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers();
app.UseEndpoints(endpoints => app.MapHub<UploadHub>("/UploadHub");
{ app.MapHealthChecks("/health");
endpoints.MapControllers();
endpoints.MapHub<UploadHub>("/UploadHub");
endpoints.MapHealthChecks("/health");
});
// Serilog // Serilog
SerilogExtension.AddSerilogSetup(enviromentName, app.Services); SerilogExtension.AddSerilogSetup(enviromentName, app.Services);
@@ -266,6 +258,7 @@ var hangfireJobService = app.Services.GetRequiredService<IIRaCISHangfireJob>();
await hangfireJobService.InitHangfireJobTaskAsync(); await hangfireJobService.InitHangfireJobTaskAsync();
#endregion #endregion
try try
@@ -301,6 +294,11 @@ try
//Log.Logger.Warning($"ContentRootPath——GetParent{Directory.GetParent(env.ContentRootPath).Parent.FullName}"); //Log.Logger.Warning($"ContentRootPath——GetParent{Directory.GetParent(env.ContentRootPath).Parent.FullName}");
//Log.Logger.Warning($"ContentRootPath——xx{Path.GetDirectoryName(Path.GetDirectoryName(env.ContentRootPath))}"); //Log.Logger.Warning($"ContentRootPath——xx{Path.GetDirectoryName(Path.GetDirectoryName(env.ContentRootPath))}");
var server = DicomServerFactory.Create<CStoreSCPService>(11112,userState: app.Services);
app.Run(); app.Run();
} }
+10 -2
View File
@@ -30,7 +30,7 @@
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Event_IRC" "ASPNETCORE_ENVIRONMENT": "Event_IRC"
}, },
"applicationUrl": "http://localhost:6101" "applicationUrl": "http://localhost:6100"
}, },
"Docker": { "Docker": {
"commandName": "Docker", "commandName": "Docker",
@@ -52,7 +52,15 @@
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Prod_IRC" "ASPNETCORE_ENVIRONMENT": "Prod_IRC"
}, },
"applicationUrl": "http://localhost:6300" "applicationUrl": "http://localhost:6100"
},
"IRaCIS.US_IRC": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "US_IRC"
},
"applicationUrl": "http://localhost:6100"
} }
} }
@@ -19,7 +19,7 @@ namespace IRaCIS.Core.API
app.UseSerilogRequestLogging(opts 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; 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 Microsoft.AspNetCore.Http;
using Serilog; using Serilog;
using System; using System;
@@ -20,7 +21,7 @@ namespace IRaCIS.Core.API
diagnosticContext.Set("Host", request.Host); diagnosticContext.Set("Host", request.Host);
//这种获取的Ip不准 配置服务才行 //这种获取的Ip不准 配置服务才行
diagnosticContext.Set("RequestIP", httpContext.Connection.RemoteIpAddress.ToString()); //diagnosticContext.Set("RequestIP", httpContext.Connection.RemoteIpAddress.ToString());
//这种方式可以,但是serilog提供了 就不用了 //这种方式可以,但是serilog提供了 就不用了
//diagnosticContext.Set("TestIP", httpContext.GetUserIp()); //diagnosticContext.Set("TestIP", httpContext.GetUserIp());
@@ -41,9 +42,9 @@ namespace IRaCIS.Core.API
// Set the content-type of the Response at this point // Set the content-type of the Response at this point
diagnosticContext.Set("ContentType", httpContext.Response.ContentType); 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 // Retrieve the IEndpointFeature selected for the request
var endpoint = httpContext.GetEndpoint(); var endpoint = httpContext.GetEndpoint();
@@ -16,7 +16,7 @@ namespace IRaCIS.Core.API
public IStringLocalizer _localizer; public IStringLocalizer _localizer;
public ApiResponseHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, public ApiResponseHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
IStringLocalizer localizer, IStringLocalizer localizer,
ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder)
{ {
_localizer = localizer; _localizer = localizer;
@@ -49,8 +49,11 @@ namespace IRaCIS.Core.API
triggerOptions.AddTrigger<TableQuestionRowTrigger>(); triggerOptions.AddTrigger<TableQuestionRowTrigger>();
//triggerOptions.AddTrigger<AddlTrialUserTrigger>(); //triggerOptions.AddTrigger<AddlTrialUserTrigger>();
triggerOptions.AddTrigger<VisitTaskIsFrontTaskNeedSignButNotSignTrigger>(); triggerOptions.AddTrigger<VisitTaskIsFrontTaskNeedSignButNotSignTrigger>();
triggerOptions.AddTrigger<VisitTaskIbeforeTrigger>();
triggerOptions.AddTrigger<UserLogTrigger>();
@@ -1,46 +0,0 @@
using IRaCIS.Core.Domain.Share;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
namespace IRaCIS.Core.API
{
public class JSONCustomDateConverter : DateTimeConverterBase
{
private TimeZoneInfo _timeZoneInfo;
private string _dateFormat;
private IUserInfo _userInfo;
public JSONCustomDateConverter(string dateFormat, TimeZoneInfo timeZoneInfo, IUserInfo userInfo)
{
_dateFormat = dateFormat;
_timeZoneInfo = timeZoneInfo;
_userInfo = userInfo;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var timeZoneId = _userInfo.TimeZoneId;
var needConvertUtcDateTime = Convert.ToDateTime(value);
var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
var dateTimeOffset = new DateTimeOffset(needConvertUtcDateTime);
var time = TimeZoneInfo.ConvertTimeFromUtc(needConvertUtcDateTime, tz).ToString(_dateFormat);
writer.WriteValue(time);
writer.Flush();
}
}
}
@@ -0,0 +1,103 @@
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using StackExchange.Redis;
using System;
using System.Globalization;
namespace IRaCIS.Core.API
{
/// <summary>
/// 序列化,反序列化的时候,处理时间 时区转换
/// </summary>
public class JSONTimeZoneConverter : DateTimeConverterBase
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly TimeZoneInfo _clientTimeZone;
public JSONTimeZoneConverter(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
//默认是UTC
//var timeZoneId = "Etc/UTC";
var timeZoneId = "Asia/Shanghai";
var timeZoneIdHeader = _httpContextAccessor?.HttpContext?.Request?.Headers["TimeZoneId"];
if (timeZoneIdHeader is not null && !string.IsNullOrEmpty(timeZoneIdHeader.Value))
{
timeZoneId = timeZoneIdHeader.Value;
}
_clientTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
}
public override bool CanConvert(Type objectType)
{
// 仅支持 DateTime 类型的转换
return objectType == typeof(DateTime)|| objectType == typeof(DateTime?);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null)
{
return null;
}
DateTime dateTime;
if (reader.ValueType == typeof(DateTime) || reader.ValueType == typeof(DateTime?))
{
DateTime? nullableDateTime = reader.Value as DateTime?;
if (nullableDateTime != null && nullableDateTime.HasValue)
{
dateTime = nullableDateTime.Value;
}
else
{
return null;
}
}
else
{
if (DateTime.TryParse((string)reader.Value, out dateTime) == false)
{
return null;
}
}
// 将客户端时间转换为服务器时区的时间
var serverZoneTime = TimeZoneInfo.ConvertTime(dateTime, _clientTimeZone, TimeZoneInfo.Local);
return serverZoneTime;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
DateTime? nullableDateTime = value as DateTime?;
if (nullableDateTime != null && nullableDateTime.HasValue)
{
//第一个参数默认使用系统本地时区 也就是应用服务器的时区
DateTime clientZoneTime = TimeZoneInfo.ConvertTime(nullableDateTime.Value, _clientTimeZone);
writer.WriteValue(clientZoneTime);
}
else
{
writer.WriteNull();
}
}
}
}
@@ -1,4 +1,6 @@
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
using IRaCIS.Core.Application.Helper;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
@@ -8,8 +10,12 @@ namespace IRaCIS.Core.API
{ {
public static class NewtonsoftJsonSetup public static class NewtonsoftJsonSetup
{ {
public static void AddNewtonsoftJsonSetup(this IMvcBuilder builder) public static void AddNewtonsoftJsonSetup(this IMvcBuilder builder, IServiceCollection services)
{ {
services.AddHttpContextAccessor();
services.AddScoped<JSONTimeZoneConverter>();
services.AddScoped<CustomStringConverter>();
services.AddScoped<IOSSService,OSSService>();
builder.AddNewtonsoftJson(options => builder.AddNewtonsoftJson(options =>
{ {
@@ -23,8 +29,15 @@ namespace IRaCIS.Core.API
// 设置时间格式 // 设置时间格式
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
//options.SerializerSettings.Converters.Add(new JSONCustomDateConverter()) ; //options.SerializerSettings.Converters.Add(new JSONCustomDateConverter()) ;
options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService<JSONTimeZoneConverter>());
//options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService<CustomStringConverter>());
//IsoDateTimeConverter //IsoDateTimeConverter
//options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; //options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
@@ -0,0 +1,65 @@
using IRaCIS.Core.Application.Helper;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System;
using System.Linq;
using System.Text.RegularExpressions;
namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson
{
public class CustomStringConverter : JsonConverter<string>
{
//private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IOSSService _oSSService;
// 构造函数
public CustomStringConverter(/*IHttpContextAccessor httpContextAccessor*/ IOSSService oSSService)
{
//_httpContextAccessor = httpContextAccessor;
_oSSService = oSSService;
}
public override string ReadJson(JsonReader reader, Type objectType, string existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.String)
{
return (string)reader.Value;
}
return null;
}
public override void WriteJson(JsonWriter writer, string value, JsonSerializer serializer)
{
if (value != null)
{
// 在这里对字符串进行处理,例如转换大小写、去除空格等
// 这里只是一个示例,您可以根据实际需求进行更改
// 获取当前正在序列化的属性名
string propertyName = writer.Path.Split('.').Last();
Regex guidRegex = new Regex(@"[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}");
if (propertyName.IndexOf("Path") > -1 && value.IndexOf('.')>-1 && guidRegex.IsMatch(value))
{
var tt= _oSSService.GetSignedUrl(value);
writer.WriteValue(tt);
}
else
{
// 将处理后的字符串写入到 JsonWriter 中
writer.WriteValue(value);
}
}
else
{
writer.WriteNull();
}
}
}
}
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Serilog; using Serilog;
using Serilog.Events; using Serilog.Events;
using Serilog.Sinks.Email; //using Serilog.Sinks.Email;
using System; using System;
using System.Net; using System.Net;
@@ -19,31 +19,33 @@ namespace IRaCIS.Core.API
// Filter out ASP.NET Core infrastructre logs that are Information and below 日志太多了 一个请求 记录好几条 // Filter out ASP.NET Core infrastructre logs that are Information and below 日志太多了 一个请求 记录好几条
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning) .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
.MinimumLevel.Override("Hangfire", LogEventLevel.Warning) .MinimumLevel.Override("Hangfire", LogEventLevel.Warning)
.MinimumLevel.Override("System.Net.Http.HttpClient.HttpReports", LogEventLevel.Warning) .MinimumLevel.Override("System.Net.Http.HttpClient.HttpReports", LogEventLevel.Warning)
.Enrich.WithClientIp() .Enrich.WithClientIp()
.Enrich.FromLogContext() .Enrich.FromLogContext()
.Filter.ByExcluding(logEvent =>logEvent.Properties.ContainsKey("RequestPath") && logEvent.Properties["RequestPath"].ToString().Contains("/health"))
//控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型 //控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning, .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, .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会默认创建一些列。 //.WriteTo.MSSqlServer("Data Source=DESKTOP-4TU9A6M;Initial Catalog=CoreFrame;User ID=sa;Password=123456", "logs", autoCreateSqlTable: true, restrictedToMinimumLevel: LogEventLevel.Information)//从左至右四个参数分别是数据库连接字符串、表名、如果表不存在是否创建、最低等级。Serilog会默认创建一些列。
if (environment == "Production") //if (environment == "Production")
{ //{
config.WriteTo.Email(new EmailConnectionInfo() // config.WriteTo.Email(new EmailConnectionInfo()
{ // {
EmailSubject = "系统警告,请速速查看!",//邮件标题 // EmailSubject = "系统警告,请速速查看!",//邮件标题
FromEmail = "test@extimaging.com",//发件人邮箱 // FromEmail = "test@extimaging.com",//发件人邮箱
MailServer = "smtp.qiye.aliyun.com",//smtp服务器地址 // MailServer = "smtp.qiye.aliyun.com",//smtp服务器地址
NetworkCredentials = new NetworkCredential("test@extimaging.com", "SHzyyl2021"),//两个参数分别是发件人邮箱与客户端授权码 // NetworkCredentials = new NetworkCredential("test@extimaging.com", "SHzyyl2021"),//两个参数分别是发件人邮箱与客户端授权码
Port = 465,//端口号 // Port = 465,//端口号
ToEmail = "872297557@qq.com"//收件人 // ToEmail = "872297557@qq.com"//收件人
}, restrictedToMinimumLevel: LogEventLevel.Error, // }, 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})"); // 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 用户名 用户类型 //扩展方法 获取上下文的ip 用户名 用户类型
Log.Logger = config.Enrich.WithHttpContextInfo(serviceProvider).CreateLogger(); Log.Logger = config.Enrich.WithHttpContextInfo(serviceProvider).CreateLogger();
+7 -3
View File
@@ -41,8 +41,8 @@
"OpenLoginLimit": true, "OpenLoginLimit": true,
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30 "LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60
}, },
"SystemEmailSendConfig": { "SystemEmailSendConfig": {
"Port": 465, "Port": 465,
@@ -50,7 +50,11 @@
"FromEmail": "uat@extimaging.com", "FromEmail": "uat@extimaging.com",
"FromName": "UAT_IRC", "FromName": "UAT_IRC",
"AuthorizationCode": "SHzyyl2021", "AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.event.extimaging.com/login" "SiteUrl": "http://irc.event.extimaging.com/login",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗"
} }
+14 -7
View File
@@ -7,8 +7,10 @@
} }
}, },
"ConnectionStrings": { "ConnectionStrings": {
"RemoteNew": "Server=101.132.193.237,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true", //"RemoteNew": "Server=101.132.193.237,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=101.132.193.237,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true" //"Hangfire": "Server=101.132.193.237,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
}, },
"ObjectStoreService": { "ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS", "ObjectStoreUse": "AliyunOSS",
@@ -34,13 +36,16 @@
"BasicSystemConfig": { "BasicSystemConfig": {
"OpenUserComplexPassword": true, "OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true, "OpenSignDocumentBeforeWork": true,
"OpenLoginLimit": true, "OpenLoginLimit": true,
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60,
"OpenLoginMFA": false
"LoginFailLockMinutes": 30
}, },
"SystemEmailSendConfig": { "SystemEmailSendConfig": {
@@ -49,8 +54,10 @@
"FromEmail": "IRC@extimaging.com", "FromEmail": "IRC@extimaging.com",
"FromName": "IRC", "FromName": "IRC",
"AuthorizationCode": "ExtImg@2022", "AuthorizationCode": "ExtImg@2022",
"SiteUrl": "http://irc.extimaging.com/login" "SiteUrl": "http://irc.extimaging.com/login",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗"
} }
} }
+30 -12
View File
@@ -7,8 +7,8 @@
} }
}, },
"ConnectionStrings": { "ConnectionStrings": {
"RemoteNew": "Server=123.56.94.154,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", "RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=123.56.94.154,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" "Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
}, },
@@ -18,7 +18,7 @@
"AliyunOSS": { "AliyunOSS": {
"regionId": "cn-shanghai", "regionId": "cn-shanghai",
"endpoint": "https://oss-cn-shanghai.aliyuncs.com", "endPoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
"bucketName": "zy-irc-test-store", "bucketName": "zy-irc-test-store",
@@ -26,14 +26,23 @@
"viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", "viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai" "region": "oss-cn-shanghai"
}, },
"MinIO": { "MinIO": {
"endpoint": "http://192.168.3.68", "endPoint": "hir-oss.test.extimaging.com",
"port": "8001", "port": "443",
"useSSL": false, "useSSL": true,
"accessKey": "IDFkwEpWej0b4DtiuThL", "accessKey": "fbStsVYCIPKHQneeqMwD",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h", "secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"bucketName": "test" "bucketName": "irc-test",
"viewEndpoint": "https://hir-oss.test.extimaging.com/irc-test"
},
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": true,
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
"secretKey": "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",
"bucketName": "ei-irc-test-store",
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
} }
}, },
@@ -49,7 +58,11 @@
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 1 "LoginFailLockMinutes": 1,
"AutoLoginOutMinutes": 1,
"OpenLoginMFA": false
}, },
"SystemEmailSendConfig": { "SystemEmailSendConfig": {
@@ -59,7 +72,12 @@
"FromName": "Test_IRC", "FromName": "Test_IRC",
"AuthorizationCode": "SHzyyl2021", "AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.test.extimaging.com/login" "SiteUrl": "http://irc.test.extimaging.com/login",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗"
} }
} }
-37
View File
@@ -1,37 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=47.90.161.85,1433\\MSSQLSERVER;Database=IRaCIS_Demo_US;User ID=sa;Password=zhanying2021;TrustServerCertificate=true",
"Hangfire": "Server=47.90.161.85,1433\\MSSQLSERVER;Database=Hangfire.IRaCIS_Demo_US;User ID=sa;Password=zhanying2021;TrustServerCertificate=true"
},
"BasicSystemConfig": {
"OpenUserComplexPassword": false,
"OpenSignDocumentBeforeWork": false,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "test@extimaging.com",
"FromName": "Test_IRC",
"AuthorizationCode": "SHzyyl2021"
}
}
+79
View File
@@ -0,0 +1,79 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=us-mssql-service,1433;Database=Prod_US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=us-mssql-service,1433;Database=Prod_US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
//"RemoteNew": "Server=44.218.11.19,1435;Database=Prod_US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
//"Hangfire": "Server=44.218.11.19,1435;Database=Prod_US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"ObjectStoreService": {
"ObjectStoreUse": "AWS",
"AliyunOSS": {
"regionId": "cn-shanghai",
"endPoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
"bucketName": "zy-irc-test-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
},
"MinIO": {
"endPoint": "192.168.3.68",
"port": "8001",
"useSSL": false,
"accessKey": "IDFkwEpWej0b4DtiuThL",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
"bucketName": "test",
"viewEndpoint": "http://192.168.3.68:8001/test/"
},
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": true,
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
"secretKey": "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",
"bucketName": "ei-irc-test-store",
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
}
},
"BasicSystemConfig": {
"OpenUserComplexPassword": false,
"OpenSignDocumentBeforeWork": false,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "test@extimaging.com",
"FromName": "Test_IRC",
"AuthorizationCode": "SHzyyl2021",
"CompanyName": "Elevate Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Elevate Imaging",
"CompanyShortNameCN": "展影医疗"
}
}
+19 -8
View File
@@ -26,12 +26,17 @@
}, },
"MinIO": { "MinIO": {
"endpoint": "http://192.168.3.68", "endPoint": "hir-oss.uat.extimaging.com",
"port": "8001", //"port": "80",
"useSSL": false, //"useSSL": false,
"accessKey": "IDFkwEpWej0b4DtiuThL", //"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h", "port": "443",
"bucketName": "test" "useSSL": true,
"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
"bucketName": "irc-uat"
} }
}, },
@@ -44,7 +49,9 @@
"OpenLoginLimit": true, "OpenLoginLimit": true,
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30 "LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60,
"OpenLoginMFA": false
}, },
"SystemEmailSendConfig": { "SystemEmailSendConfig": {
@@ -53,7 +60,11 @@
"FromEmail": "uat@extimaging.com", "FromEmail": "uat@extimaging.com",
"FromName": "UAT_IRC", "FromName": "UAT_IRC",
"AuthorizationCode": "SHzyyl2021", "AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.uat.extimaging.com/login" "SiteUrl": "http://irc.uat.extimaging.com/login",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗"
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"JwtSetting": { "JwtSetting": {
"SecurityKey": "SecurityKey_SHzyyl@2021", "SecurityKey": "ShangHaiZhanYing_SecurityKey_SHzyyl@2021",
"Issuer": "Extimaging", "Issuer": "Extimaging",
"Audience": "EICS", "Audience": "EICS",
"TokenExpireDays": "7" "TokenExpireDays": "7"
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好: 尊敬的 {0} ,您好:
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
展影医疗为您添加了账户,账户信息如下: {company abbreviation}为您添加了账户,账户信息如下:
</div> </div>
<span style="color: #00D1B2"></span> <span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'> <div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
@@ -23,7 +23,7 @@
</div> </div>
<div> <div>
首次登陆前,请通过该链接修改您的账户信息: 首次登陆前,请通过该链接修改您的账户信息:
<a href='{3}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'> <a href='{3}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
初始化账号信息 初始化账号信息
</a> </a>
</div> </div>
@@ -31,8 +31,8 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <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 style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,28 +11,28 @@
Dear {0} , Dear {0} ,
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Extimaging has added an account for you. The account information is as follows: {company abbreviation} has created an account for you. The account information is as follows:
</div> </div>
<span style="color: #00D1B2"></span> <span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'> <div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
<div> <div>
User name: {1} User ID: {1}
</div> </div>
<div> <div>
Role: {2} Role: {2}
</div> </div>
<div> <div>
Before logging in for the first time, please modify your account information by this link Before logging in for the first time, please modify the account information through this link
<a href='{3}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'> <a href='{3}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
Initialize the account information Initialize account information
</a> </a>
</div> </div>
</div> </div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best Regards</div> <div>Best regards,</div>
<div style="font-size: 14px;">Extensive Imaging</div> <div style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好: 尊敬的 {0} ,您好:
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
展影医疗将您的账户密码已重置,账户信息如下: {company abbreviation}将您的账户密码已重置,账户信息如下:
</div> </div>
<span style="color: #00D1B2"></span> <span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'> <div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
@@ -28,8 +28,8 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <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 style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,12 +11,12 @@
Dear {0} , Dear {0} ,
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Extimaging has reset your account password, and the account information is as follows: {company abbreviation} has reset your account password, and the account information is as follows:
</div> </div>
<span style="color: #00D1B2"></span> <span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'> <div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
<div> <div>
User name: {1} User ID: {1}
</div> </div>
<div> <div>
Role: {2} Role: {2}
@@ -28,8 +28,8 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best Regards</div> <div>Best regards,</div>
<div style="font-size: 14px;">Extensive Imaging</div> <div style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -18,8 +18,8 @@
</div> </div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <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 style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,15 +11,15 @@
Dear Dear
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Thank you for using Extensive Imaging Cloud System. Thank you for using {company abbreviation} Cloud System.
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{0}。 {0}。
</div> </div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best Regards</div> <div>Best regards,</div>
<div style="font-size: 14px;">Extensive Imaging</div> <div style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好: 尊敬的 {0} ,您好:
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
展影医疗作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目阅片相关工作。 {company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目阅片相关工作。
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
该项目采用电子化工作流,系统及您的账号信息如下: 该项目采用电子化工作流,系统及您的账号信息如下:
@@ -35,15 +35,15 @@
</div> </div>
<div> <div>
系统登录地址: 系统登录地址:
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'> <a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
点击跳转 点击跳转
</a> </a>
</div> </div>
</div> </div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <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 style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,10 +11,10 @@
Dear {0}, Dear {0},
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
As the service provider of {1} trialProtocol ID is {2}, Extensive Imaging invites you to participate in the independent assessment work of this trial. {company abbreviation} invites you to participate in the IRC work of a trial ({1} , {2}).
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
This project adopts electronic workflow. The system and your account information are as follows Your account information is as follows
</div> </div>
<span style="color: #00D1B2"></span> <span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'> <div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
@@ -25,23 +25,26 @@
Protocol ID: {2} Protocol ID: {2}
</div> </div>
<div> <div>
Study name: {1} Study Name: {1}
</div> </div>
<div> <div>
User name: {4} User ID: {4}
</div> </div>
<div> <div>
Role: {5} Role: {5}
</div> </div>
<div> <div>
Login URL: {6} Login URL:
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
Click to login
</a>
</div> </div>
</div> </div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best Regards</div> <div>Best regards,</div>
<div style="font-size: 14px;">Extensive Imaging</div> <div style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好: 尊敬的 {0} ,您好:
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
展影医疗作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC阅片相关工作,欢迎您提供指导和建议,非常感谢! {company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC阅片相关工作,欢迎您提供指导和建议,非常感谢!
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
该项目采用电子化工作流,系统及您的账号信息如下: 该项目采用电子化工作流,系统及您的账号信息如下:
@@ -35,7 +35,7 @@
</div> </div>
<div> <div>
首次登陆前,请通过该链接修改您的账户信息: 首次登陆前,请通过该链接修改您的账户信息:
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'> <a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
初始化账号信息 初始化账号信息
</a> </a>
</div> </div>
@@ -43,8 +43,8 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <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 style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,10 +11,10 @@
Dear {0}, Dear {0},
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Hello, as the IRC supplier of [ {1} (Protocol ID is {2}) ] projectExtiming sincerely invites you to participate in the IRC related work of this project. Your guidance and suggestions are welcome. {company abbreviation} invites you to participate in the IRC work of a trial ({1}, {2}).
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
This project adopts electronic workflow. The system and your account information are as follows Your account information is as follows
</div> </div>
<span style="color: #00D1B2"></span> <span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'> <div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
@@ -25,26 +25,26 @@
Protocol ID: {2} Protocol ID: {2}
</div> </div>
<div> <div>
Study name: {1} Study Name: {1}
</div> </div>
<div> <div>
User name: {4} User ID: {4}
</div> </div>
<div> <div>
Role: {5} Role: {5}
</div> </div>
<div> <div>
Before logging in for the first time, please modify your account information by this link Before logging in for the first time, please modify the account information through this link
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'> <a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
Initialize the account information Initialize account information
</a> </a>
</div> </div>
</div> </div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best Regards</div> <div>Best regards,</div>
<div style="font-size: 14px;">Extensive Imaging</div> <div style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好: 尊敬的 {0} ,您好:
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
好, 您填写的中心调研表被驳回,详细信息如下: 您填写的中心调研表被驳回,详细信息如下:
</div> </div>
<span style="color: #00D1B2"></span> <span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'> <div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
@@ -40,8 +40,8 @@
</a> </a>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <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 style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,7 +11,7 @@
Dear {0} , Dear {0} ,
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Hello, the center survey form you filled in has been rejected. The details are as follows The site survey form you filled in has been rejected. The details are as follows
</div> </div>
<span style="color: #00D1B2"></span> <span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'> <div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
@@ -22,7 +22,7 @@
Protocol ID: {2} Protocol ID: {2}
</div> </div>
<div> <div>
Study name: {3} Study Name: {3}
</div> </div>
<div> <div>
Site ID: {4} Site ID: {4}
@@ -40,8 +40,8 @@
</a> </a>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best Regards</div> <div>Best regards,</div>
<div style="font-size: 14px;">Extensive Imaging</div> <div style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好: 尊敬的 {0} ,您好:
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
展影医疗作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目相关工作,欢迎您提供指导和建议,非常感谢! {company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目相关工作,欢迎您提供指导和建议,非常感谢!
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
该项目采用电子化工作流,系统及您的账号信息如下: 该项目采用电子化工作流,系统及您的账号信息如下:
@@ -35,7 +35,7 @@
</div> </div>
<div> <div>
系统登录地址: 系统登录地址:
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'> <a href='{6}' style='margin-left:5px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
点击跳转 点击跳转
</a> </a>
</div> </div>
@@ -43,8 +43,8 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <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 style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,10 +11,10 @@
Dear {0}, Dear {0},
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
As the service provider of {1} trial (Protocol ID is {2}), Extensive Imaging invites you to participate in related work of this trial. {company abbreviation} invites you to participate in the IRC work of a trial ({1}, {2}).
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
This project adopts electronic workflow. The system and your account information are as follows Your account information is as follows
</div> </div>
<span style="color: #00D1B2"></span> <span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'> <div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
@@ -25,23 +25,26 @@
Protocol ID: {2} Protocol ID: {2}
</div> </div>
<div> <div>
Study name: {1} Study Name: {1}
</div> </div>
<div> <div>
User name: {4} User ID: {4}
</div> </div>
<div> <div>
Role: {5} Role: {5}
</div> </div>
<div> <div>
Login URL: {6} Login URL:
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
Click to login
</a>
</div> </div>
</div> </div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best Regards</div> <div>Best regards,</div>
<div style="font-size: 14px;">Extensive Imaging</div> <div style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好: 尊敬的 {0} ,您好:
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
展影医疗作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢! {company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢!
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
该项目采用电子化工作流,系统及您的账号信息如下: 该项目采用电子化工作流,系统及您的账号信息如下:
@@ -35,7 +35,7 @@
</div> </div>
<div> <div>
首次登陆前,请通过该链接修改您的账户信息: 首次登陆前,请通过该链接修改您的账户信息:
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'> <a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
初始化账号信息 初始化账号信息
</a> </a>
</div> </div>
@@ -43,8 +43,8 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <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 style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -11,10 +11,10 @@
Dear {0}, Dear {0},
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Hello, as the IRC supplier of [ {1} (Protocol ID is {2}) ] projectExtiming sincerely invites you to participate in the IRC related work of this project. Your guidance and suggestions are welcome. {company abbreviation} invites you to participate in the IRC work of a trial ({1}, {2}).
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
This project adopts electronic workflow. The system and your account information are as follows Your account information is as follows
</div> </div>
<span style="color: #00D1B2"></span> <span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'> <div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
@@ -25,26 +25,26 @@
Protocol ID: {2} Protocol ID: {2}
</div> </div>
<div> <div>
Study name: {1} Study Name: {1}
</div> </div>
<div> <div>
User name: {4} User ID: {4}
</div> </div>
<div> <div>
Role: {5} Role: {5}
</div> </div>
<div> <div>
Before logging in for the first time, please modify your account information by this link Before logging in for the first time, please modify the account information through this link
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'> <a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
Initialize the account information Initialize the account information
</a> </a>
</div> </div>
</div> </div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best Regards</div> <div>Best regards,</div>
<div style="font-size: 14px;">Extensive Imaging</div> <div style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -8,7 +8,7 @@
<div style='padding-left: 40px;background: #f6f6f6'> <div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'> <div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'> <div style='line-height: 40px;font-size: 18px'>
Hello {0}, {0}您好,
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
感谢您使用展影云平台。 感谢您使用展影云平台。
@@ -21,7 +21,7 @@
</div> </div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!</div> <div>祝您顺利!</div>
<div style="font-size: 14px;">上海展影医疗科技有限公司</div> <div style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -8,21 +8,21 @@
<div style='padding-left: 40px;background: #f6f6f6'> <div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'> <div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'> <div style='line-height: 40px;font-size: 18px'>
Hello {0}, Dear {0},
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Thank you for using Extensive Imagings cloud system! {1}
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{1}, and the verification code is <span style="font-weight:bold">{2}</span>. The verification code is <span style="font-weight:bold">{2}</span>.
</div> </div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'> <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Please enter this verification code within 3 minutes for subsequent operations. This code will expire in 3 minutes.
</div> </div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'> <div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best Regards</div> <div>Best regards,</div>
<div style="font-size: 14px;">Extensive Imaging</div> <div style="font-size: 14px;">{company}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -8,6 +8,7 @@ using IRaCIS.Core.Infrastructure;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using SharpCompress.Common;
namespace IRaCIS.Application.Services.BackGroundJob namespace IRaCIS.Application.Services.BackGroundJob
{ {
@@ -24,6 +25,8 @@ namespace IRaCIS.Application.Services.BackGroundJob
{ {
public static string JsonFileFolder = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources); public static string JsonFileFolder = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources);
public static FileSystemWatcher FileSystemWatcher_US { get; set; }
public static FileSystemWatcher FileSystemWatcher_CN { get; set; }
private readonly IRepository<Trial> _trialRepository; private readonly IRepository<Trial> _trialRepository;
private readonly IEasyCachingProvider _provider; private readonly IEasyCachingProvider _provider;
private readonly ILogger<IRaCISCHangfireJob> _logger; private readonly ILogger<IRaCISCHangfireJob> _logger;
@@ -124,29 +127,43 @@ namespace IRaCIS.Application.Services.BackGroundJob
//监测Json文件变更 实时刷新数据 //监测Json文件变更 实时刷新数据
WatchJsonFile(usJsonPath);
WatchJsonFile(cnJsonPath);
} if (!File.Exists(usJsonPath)|| !File.Exists(cnJsonPath))
public void WatchJsonFile(string filePath)
{
if (!File.Exists(filePath))
{ {
throw new BusinessValidationFailedException(StaticData.International("IRaCISCHangfireJob_FileNotFound")); throw new BusinessValidationFailedException(StaticData.International("IRaCISCHangfireJob_FileNotFound"));
} }
FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(filePath), Path.GetFileName(filePath)); FileSystemWatcher_US = new FileSystemWatcher
watcher.Changed += (sender, e) => LoadJsonFile(filePath); {
watcher.EnableRaisingEvents = true; Path = Path.GetDirectoryName(usJsonPath)!,
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size,
Filter = Path.GetFileName(usJsonPath),
EnableRaisingEvents = true,
};
// 添加文件更改事件的处理程序
FileSystemWatcher_US.Changed += (sender, e) => LoadJsonFile(usJsonPath);
FileSystemWatcher_CN = new FileSystemWatcher
{
Path = Path.GetDirectoryName(cnJsonPath)!,
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size,
Filter = Path.GetFileName(cnJsonPath),
EnableRaisingEvents = true,
};
FileSystemWatcher_CN.Changed += (sender, e) => LoadJsonFile(cnJsonPath);
} }
private void LoadJsonFile(string filePath) private void LoadJsonFile(string filePath)
{ {
Console.WriteLine("刷新json内存数据");
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath); IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath,false,true);
IConfigurationRoot enConfiguration = builder.Build(); IConfigurationRoot enConfiguration = builder.Build();
@@ -35,6 +35,8 @@ public class LimitUserRequestAuthorization : IAsyncAuthorizationFilter
public async Task OnAuthorizationAsync(AuthorizationFilterContext context) public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{ {
var minutes = _verifyConfig.CurrentValue.AutoLoginOutMinutes;
if (_verifyConfig.CurrentValue.OpenLoginLimit) if (_verifyConfig.CurrentValue.OpenLoginLimit)
{ {
if (context.ActionDescriptor.EndpointMetadata.Any(item => item is IAllowAnonymous)) if (context.ActionDescriptor.EndpointMetadata.Any(item => item is IAllowAnonymous))
@@ -58,22 +60,45 @@ public class LimitUserRequestAuthorization : IAsyncAuthorizationFilter
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["LimitUser_AuthTokenMissing"])); context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["LimitUser_AuthTokenMissing"]));
} }
//2、在这里取缓存 进行比较 看是否有其他人进行了登陆,如果其他人登陆了,就把之前用户挤掉 //2、在这里取缓存 进行比较 看是否有其他人进行了登陆,如果其他人登陆了,就把之前用户挤掉
var cacheUserToken = (await _provider.GetAsync<string>(_userInfo.Id.ToString())).Value; var cacheUserToken = (await _provider.GetAsync<string>(_userInfo.Id.ToString())).Value;
//缓存中没有取到Token //缓存中没有取到Token
if (string.IsNullOrWhiteSpace(cacheUserToken)) if (string.IsNullOrWhiteSpace(cacheUserToken))
{ {
cacheUserToken = _userInfo.UserToken;
//设置当前用户最新Token //设置当前用户最新Token
await _provider.SetAsync(_userInfo.Id.ToString(), _userInfo.UserToken, TimeSpan.FromDays(7)); await _provider.SetAsync(_userInfo.Id.ToString(), _userInfo.UserToken, TimeSpan.FromDays(7));
cacheUserToken = _userInfo.UserToken; //重启应用程序,所有人续期,不一下子踢出所有人
await _provider.SetAsync($"{_userInfo.Id.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes));
} }
//是同一个人 //是同一个人
else if (cacheUserToken == _userInfo.UserToken) else if (cacheUserToken == _userInfo.UserToken)
{ {
var cacheTime = (await _provider.GetAsync<string>($"{_userInfo.Id.ToString()}_Online")).Value;
//过期了 需要自动退出
if (string.IsNullOrEmpty(cacheTime))
{
context.HttpContext.Response.ContentType = "application/json";
context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["LimitUser_AccountAuto_LoginOut"], ApiResponseCodeEnum.AutoLoginOut));
}
else
{
await _provider.SetAsync($"{_userInfo.Id.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes));
}
} }
else else
@@ -32,7 +32,9 @@ namespace IRaCIS.Core.Application.Filter
if (context.Exception.GetType() == typeof(BusinessValidationFailedException)) 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)) else if(context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException))
{ {
@@ -5,7 +5,6 @@ using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces; using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using Magicodes.ExporterAndImporter.Excel;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs; using MiniExcelLibs;
@@ -14,7 +13,6 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NPOI.HSSF.UserModel; using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel; using NPOI.XSSF.UserModel;
using SkiaSharp;
using System.Collections; using System.Collections;
using System.IO; using System.IO;
@@ -342,7 +340,7 @@ public static class ExcelExportHelper
IgnoreTemplateParameterMissing = true, IgnoreTemplateParameterMissing = true,
}; };
await MiniExcel.SaveAsByTemplateAsync(memoryStream, tplPath, translateData, config); await MiniExcel.SaveAsByTemplateAsync(memoryStream, templateStream.ToArray(), translateData, config);
memoryStream.Seek(0, SeekOrigin.Begin); memoryStream.Seek(0, SeekOrigin.Begin);
@@ -515,18 +515,18 @@ public static class FileStoreHelper
// 获取 入组确认 PD 进展发送邮件Word|PDF 存放路径 // 获取 入组确认 PD 进展发送邮件Word|PDF 存放路径
public static (string PhysicalPath, string RelativePath, string FileRealName) GetSubjectEnrollConfirmOrPDEmailPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteId, Guid subjectId,bool isChangeToPdfFormat=false) public static (string PhysicalPath, string RelativePath, string FileRealName) GetSubjectEnrollConfirmOrPDEmailPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid trialSiteId, Guid subjectId,bool isChangeToPdfFormat=false)
{ {
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString()); string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), trialSiteId.ToString(), subjectId.ToString());
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName, isChangeToPdfFormat); var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName, isChangeToPdfFormat);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{trustedFileNameForFileStorage}"; var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{trialSiteId}/{subjectId}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
@@ -541,7 +541,7 @@ public static class FileStoreHelper
return Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder); return Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder);
} }
public static (string PhysicalPath, string RelativePath) GetDicomInstanceFilePath(IWebHostEnvironment _hostEnvironment, Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId, Guid studyId, Guid instanceId) public static (string PhysicalPath, string RelativePath) GetDicomInstanceFilePath(IWebHostEnvironment _hostEnvironment, Guid trialId, Guid subjectId, Guid subjectVisitId, Guid studyId, Guid instanceId)
{ {
#region #region
//var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); //var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
@@ -552,7 +552,7 @@ public static class FileStoreHelper
//加入访视层级 和Data //加入访视层级 和Data
var path = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), var path = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(),
siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder, studyId.ToString()); subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder, studyId.ToString());
if (!Directory.Exists(path)) if (!Directory.Exists(path))
{ {
@@ -561,7 +561,7 @@ public static class FileStoreHelper
var physicalPath = Path.Combine(path, instanceId.ToString() ); var physicalPath = Path.Combine(path, instanceId.ToString() );
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.DicomFolder}/{studyId}/{instanceId}"; var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.DicomFolder}/{studyId}/{instanceId}";
//var physicalPath = Path.Combine(path, instanceId.ToString() + ".dcm"); //var physicalPath = Path.Combine(path, instanceId.ToString() + ".dcm");
+262 -53
View File
@@ -3,6 +3,8 @@ using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Minio.DataModel.Args;
using Minio;
using NPOI.HPSF; using NPOI.HPSF;
using SharpCompress.Common; using SharpCompress.Common;
using System; using System;
@@ -16,14 +18,20 @@ using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Helper namespace IRaCIS.Core.Application.Helper
{ {
public class MinIOOptions public class MinIOOptions : AWSOptions
{ {
public string endpoint { get; set; } public int port { get; set; }
public string port { get; set; }
}
public class AWSOptions
{
public string endPoint { get; set; }
public bool useSSL { get; set; } public bool useSSL { get; set; }
public string accessKey { get; set; } public string accessKey { get; set; }
public string secretKey { get; set; } public string secretKey { get; set; }
public string bucketName { get; set; } public string bucketName { get; set; }
public string viewEndpoint { get; set; }
} }
public class AliyunOSSOptions public class AliyunOSSOptions
@@ -48,6 +56,8 @@ namespace IRaCIS.Core.Application.Helper
public AliyunOSSOptions AliyunOSS { get; set; } public AliyunOSSOptions AliyunOSS { get; set; }
public MinIOOptions MinIO { get; set; } public MinIOOptions MinIO { get; set; }
public AWSOptions AWS { get; set; }
} }
public class ObjectStoreDTO public class ObjectStoreDTO
@@ -58,6 +68,8 @@ namespace IRaCIS.Core.Application.Helper
public MinIOOptions MinIO { get; set; } public MinIOOptions MinIO { get; set; }
public AWSOptions AWS { get; set; }
} }
public class AliyunOSSTempToken public class AliyunOSSTempToken
@@ -81,78 +93,112 @@ namespace IRaCIS.Core.Application.Helper
AWS = 2, AWS = 2,
} }
public interface IOSSService public interface IOSSService
{ {
public string UploadToOSS(Stream fileStream, string oosFolderPath, string fileRealName); public Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true);
public string UploadToOSS(string localFilePath, string oosFolderPath); public Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true);
public void DownLoadFromOSS(string ossRelativePath, string localFilePath); public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath);
public AliyunOSSOptions _OSSConfig { get; set; } public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
public Task<string> GetSignedUrl(string ossRelativePath);
public OssClient _ossClient { get; set; }
} }
public class OSSService : IOSSService public class OSSService : IOSSService
{ {
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
public AliyunOSSOptions _OSSConfig { get; set; }
public OssClient _ossClient { get; set; }
public OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options) public OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options)
{ {
var ossOptions = options.CurrentValue; ObjectStoreServiceOptions = options.CurrentValue;
_OSSConfig = ossOptions.AliyunOSS;
_ossClient = new OssClient(_OSSConfig.endPoint, _OSSConfig.accessKeyId, _OSSConfig.accessKeySecret);
} }
/// <summary> /// <summary>
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder /// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
/// </summary> /// </summary>
/// <param name="fileStream"></param> /// <param name="fileStream"></param>
/// <param name="oosFolderPath"></param> /// <param name="oosFolderPath"></param>
/// <param name="fileRealName"></param> /// <param name="fileRealName"></param>
/// <param name="isFileNameAddGuid"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception> public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true)
public string UploadToOSS(Stream fileStream, string oosFolderPath,string fileRealName)
{ {
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}";
//var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}";
//var ossRelativePath = oosFolderPath + "/" + fileRealName;
var ossRelativePath = oosFolderPath + "/" + fileRealName; using (var memoryStream = new MemoryStream())
try
{ {
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> /// <summary>
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder /// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
/// </summary> /// </summary>
@@ -160,38 +206,126 @@ namespace IRaCIS.Core.Application.Helper
/// <param name="oosFolderPath"></param> /// <param name="oosFolderPath"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception> /// <exception cref="BusinessValidationFailedException"></exception>
public string UploadToOSS(string localFilePath, string oosFolderPath) public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true)
{ {
var localFileName = Path.GetFileName(localFilePath); var localFileName = Path.GetFileName(localFilePath);
var ossRelativePath = oosFolderPath + "/" + localFileName; var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}";
try //var ossRelativePath = oosFolderPath + "/" + localFileName;
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 try
{ {
var result = _ossClient.GetObject(_OSSConfig.bucketName, ossRelativePath);
// 将下载的文件流保存到本地文件
using (var fs = File.OpenWrite(localFilePath)) if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{ {
result.Content.CopyTo(fs); var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
fs.Close();
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) catch (Exception ex)
@@ -201,11 +335,86 @@ namespace IRaCIS.Core.Application.Helper
} }
} }
public async Task<string> GetSignedUrl(string ossRelativePath)
{
ossRelativePath = ossRelativePath.TrimStart('/');
try
{
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
// 生成签名URL。
var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get)
{
// 设置签名URL过期时间,默认值为3600秒。
Expiration = DateTime.Now.AddHours(1),
};
var uri = _ossClient.GeneratePresignedUri(req);
return uri.PathAndQuery;
}
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 reqParams = new Dictionary<string, string>(StringComparer.Ordinal)
// {
// { "response-content-type", "application/json" }
// };
var args = new PresignedGetObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithExpiry(3600)
/*.WithHeaders(reqParams)*/;
var presignedUrl = await minioClient.PresignedGetObjectAsync(args);
Uri uri = new Uri(presignedUrl);
string relativePath = uri.PathAndQuery;
return relativePath;
}
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();
return string.Empty;
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
}
catch (Exception ex)
{
throw new BusinessValidationFailedException("oss授权url失败!" + ex.Message);
}
}
} }
@@ -40,11 +40,11 @@ public static class SendEmailHelper
} }
} }
catch (Exception ) catch (Exception ex)
{ {
//---邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员 //---邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员
throw new Exception(StaticData.International("SendEmail_SendFail")); throw new Exception(StaticData.International("SendEmail_SendFail"),new Exception(ex.Message));
} }
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<LangVersion>default</LangVersion> <LangVersion>default</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@@ -64,45 +64,44 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" /> <PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
<PackageReference Include="FreeSpire.Doc" Version="11.6.0" /> <PackageReference Include="FreeSpire.Doc" Version="12.2.0" />
<PackageReference Include="Hangfire.Core" Version="1.8.6" /> <PackageReference Include="Hangfire.Core" Version="1.8.12" />
<PackageReference Include="BeetleX.BNR" Version="1.0.1" /> <PackageReference Include="BeetleX.BNR" Version="1.0.1" />
<PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.1.0" /> <PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
<PackageReference Include="EasyCaching.Redis" Version="1.9.2" /> <PackageReference Include="EasyCaching.Redis" Version="1.9.2" />
<PackageReference Include="EasyCaching.InMemory" Version="1.9.2" /> <PackageReference Include="EasyCaching.InMemory" Version="1.9.2" />
<PackageReference Include="ExcelDataReader" Version="3.6.0" /> <PackageReference Include="ExcelDataReader" Version="3.6.0" />
<PackageReference Include="ExcelDataReader.DataSet" Version="3.6.0" /> <PackageReference Include="ExcelDataReader.DataSet" Version="3.6.0" />
<PackageReference Include="DistributedLock.Redis" Version="1.0.2" /> <PackageReference Include="DistributedLock.Redis" Version="1.0.3" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.3" /> <PackageReference Include="DistributedLock.SqlServer" Version="1.0.4" />
<PackageReference Include="fo-dicom" Version="5.1.1" /> <PackageReference Include="fo-dicom" Version="5.1.2" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.0" /> <PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.2" />
<PackageReference Include="fo-dicom.Codecs" Version="5.11.0" /> <PackageReference Include="fo-dicom.Codecs" Version="5.12.0" />
<PackageReference Include="Magicodes.IE.Core" Version="2.7.4.5" /> <PackageReference Include="IP2Region.Net" Version="2.0.2" />
<PackageReference Include="Magicodes.IE.Csv" Version="2.7.4.5"> <PackageReference Include="MailKit" Version="4.2.0" />
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="Magicodes.IE.Excel" Version="2.7.4.5">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="Magicodes.IE.Excel.AspNetCore" Version="2.7.4.5" />
<PackageReference Include="MailKit" Version="4.3.0" />
<PackageReference Include="MediatR" Version="12.2.0" /> <PackageReference Include="MediatR" Version="12.2.0" />
<PackageReference Include="MimeKit" Version="4.3.0" /> <PackageReference Include="MimeKit" Version="4.2.0" />
<PackageReference Include="MiniExcel" Version="1.31.2" /> <PackageReference Include="MiniExcel" Version="1.32.0" />
<PackageReference Include="Minio" Version="6.0.1" /> <PackageReference Include="Minio" Version="6.0.2" />
<PackageReference Include="MiniWord" Version="0.7.0" /> <PackageReference Include="MiniWord" Version="0.8.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.0.0"> <PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
<TreatAsUsed>true</TreatAsUsed> <TreatAsUsed>true</TreatAsUsed>
</PackageReference> </PackageReference>
<PackageReference Include="NPOI" Version="2.6.2" /> <PackageReference Include="NPOI" Version="2.7.0" />
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.1" /> <PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.0" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.12" /> <PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
<PackageReference Include="WinSCP" Version="6.1.2" /> <PackageReference Include="WinSCP" Version="6.3.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\IRaCIS.Core.Infra.EFCore\IRaCIS.Core.Infra.EFCore.csproj" /> <ProjectReference Include="..\IRaCIS.Core.Infra.EFCore\IRaCIS.Core.Infra.EFCore.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Update="Resources\ip2region.xdb">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project> </Project>
File diff suppressed because it is too large Load Diff
Binary file not shown.
@@ -1,37 +0,0 @@
using IRaCIS.Core.Domain.Share;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service.ViewModel
{
public class AllocationVisitViewModel
{
public Guid SubjectVisitId { get; set; }
public Guid SubjectId { get; set; }
public string BlindName { get; set; } = string.Empty;
public decimal VisitNum { get; set; }
public Guid SiteId { get; set; }
public String TrialSiteCode { get; set; } = String.Empty;
public string SubjectCode { get; set; } = String.Empty;
public string VisitName { get; set; } = string.Empty;
public DateTime? CheckPassedTime { get; set; }
public bool IsUrgent { get; set; }
public ReadingCategory ReadingCategoryEnum { get; set; }
}
}
@@ -24,7 +24,9 @@ namespace IRaCIS.Core.Application.ViewModel
public int? GeneratedSubjectCount { get; set; } public int? GeneratedSubjectCount { get; set; }
public int? MatchSubejctCount { get; set; }
public int? CanGeneratedSubejctCount => MatchSubejctCount - GeneratedSubjectCount;
} }
@@ -34,6 +36,13 @@ namespace IRaCIS.Core.Application.ViewModel
} }
public class SubjectGeneratedTask
{
public Guid SubjectId { get; set; }
public bool IsHaveGeneratedTask { get; set; }
}
public class ConsistentQuery : PageInput public class ConsistentQuery : PageInput
{ {
[NotDefault] [NotDefault]
@@ -46,6 +55,15 @@ namespace IRaCIS.Core.Application.ViewModel
} }
public class GroupConsistentSimpleQuery
{
[NotDefault]
public Guid TrialId { get; set; }
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
}
public class GroupConsistentQuery : PageInput public class GroupConsistentQuery : PageInput
{ {
[NotDefault] [NotDefault]
@@ -56,13 +74,21 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid TrialReadingCriterionId { get; set; } public Guid TrialReadingCriterionId { get; set; }
} }
public class ConsistentConfirmGenerateCommand public class SelfConsistentSimpleQuery
{ {
[NotDefault]
public Guid TaskConsistentRuleId { get; set; } public Guid TaskConsistentRuleId { get; set; }
[NotDefault] [NotDefault]
public Guid DoctorUserId { get; set; } public Guid DoctorUserId { get; set; }
}
public class ConsistentConfirmGenerateCommand: SelfConsistentSimpleQuery
{
public List<Guid> SubejctIdList { get; set; } public List<Guid> SubejctIdList { get; set; }
public bool IsAutoAllocateGenerateTask { get; set; }
} }
@@ -70,7 +96,13 @@ namespace IRaCIS.Core.Application.ViewModel
{ {
[NotDefault] [NotDefault]
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
public List<Guid> SubejctIdList { get; set; } public List<Guid> SubejctIdList { get; set; }
public bool IsAutoAllocateGenerateTask { get; set; }
} }
public class DoctorSelfConsistentSubjectView: ConsistentCommonView public class DoctorSelfConsistentSubjectView: ConsistentCommonView
@@ -86,7 +118,7 @@ namespace IRaCIS.Core.Application.ViewModel
public class ConsistentCommonView public class ConsistentCommonView
{ {
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; } public Guid TrialSiteId { get; set; }
public String TrialSiteCode { get; set; } public String TrialSiteCode { get; set; }
public string SubjectCode { get; set; } public string SubjectCode { get; set; }
@@ -105,6 +137,8 @@ namespace IRaCIS.Core.Application.ViewModel
public List<VisitTaskGroupSimpleDTO> SubjectTaskVisitList => VisitTaskList.GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Select(g => g.First()).OrderBy(t=>t.VisitTaskNum).ToList(); public List<VisitTaskGroupSimpleDTO> SubjectTaskVisitList => VisitTaskList.GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Select(g => g.First()).OrderBy(t=>t.VisitTaskNum).ToList();
public List<VisitTaskGroupSimpleDTO> VisitTaskList { get; set; } = new List<VisitTaskGroupSimpleDTO>(); public List<VisitTaskGroupSimpleDTO> VisitTaskList { get; set; } = new List<VisitTaskGroupSimpleDTO>();
public List<UserSimpleInfo> DoctorUserList { get; set; }=new List<UserSimpleInfo>();
} }
public class VisitTaskGroupSimpleDTO public class VisitTaskGroupSimpleDTO
@@ -166,31 +200,12 @@ namespace IRaCIS.Core.Application.ViewModel
} }
//public class DoctorConsistentRuleSubjectView
//{
// public Guid TrialId => VisitTaskList.Select(t => t.TrialId).First();
// public Guid SiteId => VisitTaskList.Select(t => t.SiteId).First();
// public String TrialSiteCode => VisitTaskList.Select(t => t.TrialSiteCode).First();
// public string SubjectCode => VisitTaskList.Select(t => t.SubjectCode).First();
// public Guid SubjectId { get; set; }
// public bool IsHaveGeneratedTask { get; set; }
// public int? ValidTaskCount { get; set; }
// public int? ValidVisitCount => VisitTaskList.Select(t => t.TaskName).Distinct().Count();
// public List<VisitTaskSimpleView> VisitTaskList { get; set; }
// //public List<UserSimpleInfo> HistoryDoctorUserList => VisitTaskList.SelectMany(t => t.RelationDoctorUserList).DistinctBy(t=>t.UserId).ToList();
//}
public class InfluenceTaskInfo public class InfluenceTaskInfo
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; } public Guid TrialSiteId { get; set; }
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
@@ -233,7 +248,7 @@ namespace IRaCIS.Core.Application.ViewModel
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; } public Guid TrialSiteId { get; set; }
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
@@ -287,6 +302,17 @@ namespace IRaCIS.Core.Application.ViewModel
} }
public class UpdateTrialSiteCodeCommand
{
public Guid TrialId { get; set; }
public string VirtualSiteCode { get; set; }
}
public class UpdateTrialSiteCodeCommandView: UpdateTrialSiteCodeCommand
{
public DateTime Creatime { get; set; }
}
///<summary> TaskConsistentRuleAddOrEdit 列表查询参数模型</summary> ///<summary> TaskConsistentRuleAddOrEdit 列表查询参数模型</summary>
public class TaskConsistentRuleAddOrEdit public class TaskConsistentRuleAddOrEdit
@@ -15,7 +15,6 @@ namespace IRaCIS.Core.Application.ViewModel
{ {
public Guid VisitTaskId { get; set; } public Guid VisitTaskId { get; set; }
public string MedicalNo { get; set; } = string.Empty;
public int AuditState { get; set; } public int AuditState { get; set; }
public DateTime? AuditSignTime { get; set; } public DateTime? AuditSignTime { get; set; }
@@ -54,7 +53,6 @@ namespace IRaCIS.Core.Application.ViewModel
//开始读片时间 //开始读片时间
public DateTime? FirstReadingTime { get; set; } public DateTime? FirstReadingTime { get; set; }
public string MedicalNo { get; set; } = string.Empty;
//读片时间差 //读片时间差
public TimeSpan? ReadingDurationTimeSpan { get; set; } public TimeSpan? ReadingDurationTimeSpan { get; set; }
@@ -71,7 +69,7 @@ namespace IRaCIS.Core.Application.ViewModel
{ {
if (!ReadingDurationTimeSpan.HasValue) if (!ReadingDurationTimeSpan.HasValue)
return ""; return "";
else return string.Format("{0}d {1}h {2}min", (SignTime - FirstReadingTime)?.Days, (SignTime - FirstReadingTime)?.Hours, (SignTime - FirstReadingTime)?.Minutes) else return string.Format("{0}h:{1}m:{2}s", (SignTime - FirstReadingTime)?.Hours, (SignTime - FirstReadingTime)?.Minutes, (SignTime - FirstReadingTime)?.Seconds)
/*string.Format("{0}分钟", (ReadingDurationTimeSpan)?.TotalMinutes)*/; /*string.Format("{0}分钟", (ReadingDurationTimeSpan)?.TotalMinutes)*/;
} }
} }
@@ -95,19 +93,27 @@ namespace IRaCIS.Core.Application.ViewModel
public class TaskMedicalReviewQuery : PageInput public class TaskMedicalReviewQuery : PageInput
{ {
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid? SiteId { get; set; } public Guid? TrialSiteId { get; set; }
/// <summary> /// <summary>
/// 传了Id 就不查询这条数据 /// 传了Id
/// </summary> /// </summary>
public Guid? Id { get; set; } public Guid? Id { get; set; }
public Guid? SubjectId { get; set; } public Guid? SubjectId { get; set; }
public Guid? MedicalManagerUserId { get; set; }
public bool IsGetBeRead { get; set; } = false; public DateTime? BeginSignTime { get; set; }
public AuditAdvice? AuditAdviceEnum { get; set; }
public string SubjectCode { get; set; } = String.Empty; public DateTime? EndSignTime { get; set; }
public bool IsGetBeRead { get; set; } = false;
public bool IsGetNextMedicalReviewTask { get; set; } = false;
public string SubjectCode { get; set; } = String.Empty;
public string TrialSiteCode { get; set; } = String.Empty; public string TrialSiteCode { get; set; } = String.Empty;
public string TaskName { get; set; } = String.Empty; public string TaskName { get; set; } = String.Empty;
@@ -126,6 +132,20 @@ namespace IRaCIS.Core.Application.ViewModel
public ReadingTaskState? ReadingTaskState { get; set; } public ReadingTaskState? ReadingTaskState { get; set; }
public Guid? TrialReadingCriterionId { get; set; } public Guid? TrialReadingCriterionId { get; set; }
public MedicalReviewDoctorUserIdea? DoctorUserIdeaEnum { get; set; }
public Arm? ArmEnum { get; set; }
public DateTime? BeginAuditSignTime { get; set; }
public DateTime? EndAuditSignTime { get; set; }
public bool? IsEffect { get; set; }
public bool? IsHaveQuestion { get; set; }
public DateTime? BeginAllocateDate { get; set; }
public DateTime? EndAllocateDate { get; set; }
} }
@@ -54,10 +54,16 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid UpdateUserId { get; set; } public Guid UpdateUserId { get; set; }
public Guid SiteId { get; set; } public Guid TrialSiteId { get; set; }
public string BlindTrialSiteCode { get; set; }
public String TrialSiteCode { get; set; } = String.Empty; public String TrialSiteCode { get; set; } = String.Empty;
public string SubjectCode { 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; } public bool IsPMSetBack { get; set; }
#region #region
@@ -86,7 +92,7 @@ namespace IRaCIS.Core.Application.ViewModel
/// <summary> /// <summary>
/// 任务展示访视 读片任务显示是否顺序 /// 任务展示访视 读片任务显示是否顺序
/// </summary> /// </summary>
public bool IsReadingTaskViewInOrder { get; set; } = true; public ReadingOrder IsReadingTaskViewInOrder { get; set; }
/// <summary> /// <summary>
@@ -150,7 +156,18 @@ namespace IRaCIS.Core.Application.ViewModel
public bool IsCanEditUrgentState { get; set; } public bool IsCanEditUrgentState { get; set; }
public DateTime? FirstReadingTime { get;set; }
public string ReadingDuration
{
get
{
if (!SignTime.HasValue)
return "";
else return string.Format("{0}h:{1}m:{2}s", (SignTime - FirstReadingTime)?.Hours, (SignTime - FirstReadingTime)?.Minutes, (SignTime - FirstReadingTime)?.Seconds)
/*string.Format("{0}分钟", (ReadingDurationTimeSpan)?.TotalMinutes)*/;
}
}
} }
public class UserSimpleInfo public class UserSimpleInfo
@@ -299,13 +316,14 @@ namespace IRaCIS.Core.Application.ViewModel
} }
} }
public int UrgentCount { get; set; }
// public int UrgentCount => UnReadCanReadTaskList.Count(t => t.IsUrgent);
public int UrgentCount => UnReadCanReadTaskList.Count(t => t.IsUrgent); public List<IRUnreadTaskView> UnReadCanReadTaskList { get; set; } = new List<IRUnreadTaskView>();
// public List<IRUnreadTaskView> UnReadCanReadTaskList => UnReadTaskList.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)).ToList();
public List<IRUnreadTaskView> UnReadCanReadTaskList => UnReadTaskList.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)).ToList(); public List<IRUnreadTaskView> UnReadTaskList { get; set; } = new List<IRUnreadTaskView>();
public List<IRUnreadTaskView> UnReadTaskList { get; set; } = new List<IRUnreadTaskView>();
} }
public class IRUnreadTaskView public class IRUnreadTaskView
@@ -352,16 +370,16 @@ namespace IRaCIS.Core.Application.ViewModel
} }
public class GetOrderReadingIQueryableInDto public class GetReadingIQueryableInDto:PageInput
{ {
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid TrialReadingCriterionId { get; set; } public Guid? SubjectId { get; set; }
public Guid TrialReadingCriterionId { get; set; }
public string? SubjectCode { get; set; } = null; public string? SubjectCode { get; set; } = null;
public PageInput? Page { get; set; } = null;
} }
public class VisitTaskQuery : PageInput public class VisitTaskQuery : PageInput
@@ -369,7 +387,8 @@ namespace IRaCIS.Core.Application.ViewModel
[NotDefault] [NotDefault]
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid? SiteId { get; set; }
public Guid? TrialSiteId { get; set; }
public Guid? SubjectId { get; set; } public Guid? SubjectId { get; set; }
@@ -391,6 +410,15 @@ namespace IRaCIS.Core.Application.ViewModel
public DateTime? EndAllocateDate { get; set; } public DateTime? EndAllocateDate { get; set; }
public DateTime? BeginSignTime { get; set; }
public DateTime? EndSignTime { get; set; }
public DateTime? BeginRequestReReadingTime { get; set; }
public DateTime? EndRequestReReadingTime { get; set; }
public Guid? RootReReadingTaskId { get; set; } public Guid? RootReReadingTaskId { get; set; }
public string? TaskCode { get; set; } public string? TaskCode { get; set; }
@@ -412,6 +440,10 @@ namespace IRaCIS.Core.Application.ViewModel
public RequestReReadingResult? RequestReReadingResultEnum { get; set; } public RequestReReadingResult? RequestReReadingResultEnum { get; set; }
public bool? IsEffect { get; set; }
public string? RequestReReadingReason { get; set; }
} }
@@ -467,7 +499,7 @@ namespace IRaCIS.Core.Application.ViewModel
[NotDefault] [NotDefault]
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid? SiteId { get; set; } public Guid? TrialSiteId { get; set; }
public Guid? SubjectId { get; set; } public Guid? SubjectId { get; set; }
@@ -489,7 +521,7 @@ namespace IRaCIS.Core.Application.ViewModel
[NotDefault] [NotDefault]
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid? SiteId { get; set; } public Guid? TrialSiteId { get; set; }
public Guid? SubjectId { get; set; } public Guid? SubjectId { get; set; }
@@ -498,6 +530,9 @@ namespace IRaCIS.Core.Application.ViewModel
public string SubjectCode { get; set; } = String.Empty; public string SubjectCode { get; set; } = String.Empty;
public int? SubjectAllocateState { get; set; }
public List<Arm> ArmList { get; set; }=new List<Arm>() { };
[NotDefault] [NotDefault]
public Guid TrialReadingCriterionId { get; set; } public Guid TrialReadingCriterionId { get; set; }
@@ -529,7 +564,7 @@ namespace IRaCIS.Core.Application.ViewModel
public class SubjectAssignStat public class SubjectAssignStat
{ {
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; } public Guid TrialSiteId { get; set; }
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
@@ -609,7 +644,7 @@ namespace IRaCIS.Core.Application.ViewModel
public class SubjectAssignView public class SubjectAssignView
{ {
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; } public Guid TrialSiteId { get; set; }
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
@@ -16,6 +16,6 @@ namespace IRaCIS.Core.Application.Service
Task<IResponseOutput> ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService); Task<IResponseOutput> ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService);
Task<(int, List<IRUnReadSubjectView>)> GetOrderReadingIQueryable(GetOrderReadingIQueryableInDto inDto); Task<PageOutput<IRUnReadSubjectView>> GetSubjectReadingIQueryable(GetReadingIQueryableInDto inDto);
} }
} }
@@ -116,9 +116,9 @@ namespace IRaCIS.Core.Application.Service
// return ResponseOutput.Ok(); // return ResponseOutput.Ok();
//} //}
public async Task<List<SubjectCancelDoctorView>> GetSubjectCancelDoctorHistoryList(Guid subjectId) public async Task<List<SubjectCancelDoctorView>> GetSubjectCancelDoctorHistoryList(Guid subjectId,Guid trialReadingCriterionId)
{ {
var list = await _subjectCanceDoctorRepository.Where(t => t.SubjectId == subjectId).ProjectTo<SubjectCancelDoctorView>(_mapper.ConfigurationProvider).ToListAsync(); var list = await _subjectCanceDoctorRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId==trialReadingCriterionId).ProjectTo<SubjectCancelDoctorView>(_mapper.ConfigurationProvider).ToListAsync();
return list; return list;
} }
@@ -16,6 +16,9 @@ using System.Linq;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using Medallion.Threading; using Medallion.Threading;
using IRaCIS.Core.Infrastructure.Extention;
using System;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace IRaCIS.Core.Application.Service namespace IRaCIS.Core.Application.Service
{ {
@@ -32,9 +35,16 @@ namespace IRaCIS.Core.Application.Service
private readonly IRepository<Subject> _subjectRepository; private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<Enroll> _enrollRepository; private readonly IRepository<Enroll> _enrollRepository;
private readonly IDistributedLockProvider _distributedLockProvider; private readonly IDistributedLockProvider _distributedLockProvider;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<TrialSite> _trialSiteRepository;
private readonly IRepository<TrialVirtualSiteCodeUpdate> _trialVirtualSiteCodeUpdateRepository;
private readonly IVisitTaskHelpeService _visitTaskCommonService;
public TaskConsistentRuleService(IRepository<VisitTask> visitTaskRepository, IRepository<Enroll> enrollRepository, IRepository<TaskConsistentRule> taskConsistentRuleRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<Subject> subjectRepository, IDistributedLockProvider distributedLockProvider) public TaskConsistentRuleService(IRepository<VisitTask> visitTaskRepository, IRepository<Enroll> enrollRepository, IRepository<TaskConsistentRule> taskConsistentRuleRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<Subject> subjectRepository, IDistributedLockProvider distributedLockProvider,
IRepository<Trial> trialRepository, IRepository<TrialSite> trialSiteRepository, IRepository<TrialVirtualSiteCodeUpdate> trialVirtualSiteCodeUpdateRepository, IVisitTaskHelpeService visitTaskCommonService)
{ {
_taskConsistentRuleRepository = taskConsistentRuleRepository; _taskConsistentRuleRepository = taskConsistentRuleRepository;
_visitTaskRepository = visitTaskRepository; _visitTaskRepository = visitTaskRepository;
@@ -42,6 +52,14 @@ namespace IRaCIS.Core.Application.Service
_subjectRepository = subjectRepository; _subjectRepository = subjectRepository;
_enrollRepository = enrollRepository; _enrollRepository = enrollRepository;
_distributedLockProvider = distributedLockProvider; _distributedLockProvider = distributedLockProvider;
_trialRepository = trialRepository;
_trialSiteRepository = trialSiteRepository;
_trialVirtualSiteCodeUpdateRepository = trialVirtualSiteCodeUpdateRepository;
_visitTaskCommonService = visitTaskCommonService;
} }
/// <summary> /// <summary>
@@ -54,7 +72,7 @@ namespace IRaCIS.Core.Application.Service
{ {
await _visitTaskRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.Id), u => new VisitTask() { TaskState = TaskState.NotEffect },true); await _visitTaskRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.Id), u => new VisitTask() { TaskState = TaskState.Adbandon }, true);
await _visitTaskRepository.SaveChangesAsync(); await _visitTaskRepository.SaveChangesAsync();
@@ -69,14 +87,14 @@ namespace IRaCIS.Core.Application.Service
/// <param name="queryVisitTask"></param> /// <param name="queryVisitTask"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<PageOutput<AnalysisTaskView>> GetAnalysisTaskList(VisitTaskQuery queryVisitTask) public async Task<IResponseOutput<PageOutput<AnalysisTaskView>>> GetAnalysisTaskList(VisitTaskQuery queryVisitTask )
{ {
var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId) var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
.Where(t => t.IsAnalysisCreate) .Where(t => t.IsAnalysisCreate)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
@@ -86,19 +104,22 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState)
.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) .WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum) .WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum)
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate == false)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => /*(t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) ||*/ (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) /*&& t.IsAnalysisCreate == false*/))
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName))
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => ((t.Subject.Code.Contains(queryVisitTask.SubjectCode)||t.Subject.MedicalNo.Contains(queryVisitTask.SubjectCode)) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate))
.WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime >= queryVisitTask.BeginAllocateDate)
.WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime <= queryVisitTask.EndAllocateDate)
.WhereIf(queryVisitTask.BeginSignTime != null, t => t.SignTime >= queryVisitTask.BeginSignTime)
.WhereIf(queryVisitTask.EndSignTime != null, t => t.SignTime <= queryVisitTask.EndSignTime)
.ProjectTo<AnalysisTaskView>(_mapper.ConfigurationProvider); .ProjectTo<AnalysisTaskView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) };
var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);
//var trialTaskConfig = _repository.Where<Trial>(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialTaskConfigView>(_mapper.ConfigurationProvider).FirstOrDefault(); var trialTaskConfig = _repository.Where<Trial>(t => t.Id == queryVisitTask.TrialId).Select(t => new { IsHaveDoubleReadCriterion=t.TrialReadingCriterionList.Any(t=>t.IsSigned && t.IsConfirm && t.ReadingType==ReadingMethod.Double), t.VitrualSiteCode }).FirstOrDefault();
return pageList;
return ResponseOutput.Ok(pageList, trialTaskConfig);
} }
@@ -123,13 +144,12 @@ namespace IRaCIS.Core.Application.Service
/// 确认生成自身一致性分析任务 /// 确认生成自身一致性分析任务
/// </summary> /// </summary>
/// <param name="inCommand"></param> /// <param name="inCommand"></param>
/// <param name="_visitTaskCommonService"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
[UnitOfWork] [UnitOfWork]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] //[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> ConfirmGenerateSelfConsistentTask(ConsistentConfirmGenerateCommand inCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) public async Task<IResponseOutput> ConfirmGenerateSelfConsistentTask(ConsistentConfirmGenerateCommand inCommand)
{ {
@@ -137,6 +157,25 @@ namespace IRaCIS.Core.Application.Service
var doctorUserId = inCommand.DoctorUserId; var doctorUserId = inCommand.DoctorUserId;
var trialReadingCriterionId = filterObj.TrialReadingCriterionId; var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
//随机分配
if (inCommand.IsAutoAllocateGenerateTask)
{
var subjectList = (await GetSelfConsistentRuleMatchSubjectIdListAsync(new SelfConsistentSimpleQuery() { TaskConsistentRuleId = inCommand.TaskConsistentRuleId, DoctorUserId = inCommand.DoctorUserId })).ToList();
if (subjectList.Any(t => t.IsHaveGeneratedTask))
{
//已手动分配,不允许自动分配
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate"]);
}
if (subjectList.Count<2 * filterObj.PlanSubjectCount)
{
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate1"]);
}
inCommand.SubejctIdList = GetRandomSubjectIdList(subjectList.Select(t => t.SubjectId).ToList(), filterObj.PlanSubjectCount);
}
var list = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, doctorUserId, inCommand.SubejctIdList).ToListAsync(); var list = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, doctorUserId, inCommand.SubejctIdList).ToListAsync();
//var (group, query) = GetIQueryableDoctorSelfConsistentRuleSubjectView(filterObj, inCommand.SubejctIdList); //var (group, query) = GetIQueryableDoctorSelfConsistentRuleSubjectView(filterObj, inCommand.SubejctIdList);
@@ -155,9 +194,9 @@ namespace IRaCIS.Core.Application.Service
var blindSubjectCode = string.Empty; var blindSubjectCode = string.Empty;
var subjectTask = _visitTaskRepository.Where(t => t.SubjectId == subject.SubjectId && t.TrialReadingCriterionId==trialReadingCriterionId && t.IsSelfAnalysis == true).OrderByDescending(t => t.BlindSubjectCode).FirstOrDefault(); var subjectTask = _visitTaskRepository.Where(t => t.SubjectId == subject.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == true).OrderByDescending(t => t.BlindSubjectCode).FirstOrDefault();
if (subjectTask!=null && subjectTask.BlindSubjectCode != String.Empty) if (subjectTask != null && subjectTask.BlindSubjectCode != String.Empty)
{ {
blindSubjectCode = subjectTask.BlindSubjectCode; blindSubjectCode = subjectTask.BlindSubjectCode;
} }
@@ -165,11 +204,11 @@ namespace IRaCIS.Core.Application.Service
{ {
var maxCodeStr = _visitTaskRepository.Where(t => t.TrialId == subject.TrialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == true).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault(); var maxCodeStr = _visitTaskRepository.Where(t => t.TrialId == subject.TrialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == true).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault();
if ( !string.IsNullOrEmpty(maxCodeStr)) if (!string.IsNullOrEmpty(maxCodeStr))
{ {
int.TryParse(maxCodeStr.Substring(maxCodeStr.Length - filterObj.BlindSubjectNumberOfPlaces), out maxCodeInt); int.TryParse(maxCodeStr.Substring(maxCodeStr.Length - filterObj.BlindSubjectNumberOfPlaces), out maxCodeInt);
} }
blindSubjectCode = filterObj.BlindTrialSiteCode + (maxCodeInt + 1).ToString($"D{filterObj.BlindSubjectNumberOfPlaces}"); blindSubjectCode = filterObj.BlindTrialSiteCode + (maxCodeInt + 1).ToString($"D{filterObj.BlindSubjectNumberOfPlaces}");
} }
@@ -190,7 +229,7 @@ namespace IRaCIS.Core.Application.Service
{ {
var lastTask = (subject.VisitTaskList.Take(filterObj.PlanVisitCount).Last()).Clone(); var lastTask = (subject.VisitTaskList.Take(filterObj.PlanVisitCount).Last()).Clone();
var existGlobal = _visitTaskRepository.Where(t => t.SubjectId == lastTask.SubjectId &&t.TrialReadingCriterionId==trialReadingCriterionId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum == lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).ProjectTo<VisitTaskSimpleDTO>(_mapper.ConfigurationProvider).FirstOrDefault(); var existGlobal = _visitTaskRepository.Where(t => t.SubjectId == lastTask.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum == lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).ProjectTo<VisitTaskSimpleDTO>(_mapper.ConfigurationProvider).FirstOrDefault();
if (existGlobal == null) if (existGlobal == null)
@@ -203,7 +242,7 @@ namespace IRaCIS.Core.Application.Service
ReadingCategory = ReadingCategory.Global, ReadingCategory = ReadingCategory.Global,
TaskName = lastTask.TaskName + "_Global", TaskName = lastTask.TaskName + "_Global",
TaskBlindName = lastTask.TaskBlindName + "_Global", TaskBlindName = lastTask.TaskBlindName + "_Global",
TrialReadingCriterionId=trialReadingCriterionId, TrialReadingCriterionId = trialReadingCriterionId,
}; };
} }
@@ -245,16 +284,17 @@ namespace IRaCIS.Core.Application.Service
/// <param name="inQuery"></param> /// <param name="inQuery"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<PageOutput<DoctorGroupConsistentSubjectView>> GetGroupConsistentRuleSubjectList(GroupConsistentQuery inQuery) public async Task<IResponseOutput<PageOutput<DoctorGroupConsistentSubjectView>> > GetGroupConsistentRuleSubjectList(GroupConsistentQuery inQuery)
{ {
var trialId = inQuery.TrialId; var trialId = inQuery.TrialId;
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.TrialReadingCriterionId==inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == false); var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == false);
if (filterObj == null) if (filterObj == null)
{ {
return new PageOutput<DoctorGroupConsistentSubjectView>(); object tt = null;
return ResponseOutput.Ok(new PageOutput<DoctorGroupConsistentSubjectView>(), new { Rule = tt, IsAllowAutoAllocate = false }) ;
} }
var query = await GetGroupConsistentQueryAsync(filterObj); var query = await GetGroupConsistentQueryAsync(filterObj);
@@ -262,7 +302,13 @@ namespace IRaCIS.Core.Application.Service
var pagedList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(DoctorSelfConsistentSubjectView.SubjectCode) : inQuery.SortField, inQuery.Asc); var pagedList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(DoctorSelfConsistentSubjectView.SubjectCode) : inQuery.SortField, inQuery.Asc);
return pagedList; var rule = await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == false && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo<TaskConsistentRuleBasic>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
var list = await GetGroupConsistentRuleMatchSubjectIdListAsync(new GroupConsistentSimpleQuery() { TrialId = inQuery.TrialId, TrialReadingCriterionId = inQuery.TrialReadingCriterionId });
var isAllowAutoAllocate = !list.Any(t => t.IsHaveGeneratedTask) && list.Count() > 2*(rule?.PlanSubjectCount??0);
return ResponseOutput.Ok(pagedList, new {Rule=rule, IsAllowAutoAllocate = isAllowAutoAllocate });
} }
@@ -271,26 +317,46 @@ namespace IRaCIS.Core.Application.Service
/// 确认生成组间一致性分析任务 /// 确认生成组间一致性分析任务
/// </summary> /// </summary>
/// <param name="inCommand"></param> /// <param name="inCommand"></param>
/// <param name="_visitTaskCommonService"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
[UnitOfWork] [UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> ConfirmGenerateGroupConsistentTask(GroupConsistentConfirmGenrateCommand inCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) public async Task<IResponseOutput> ConfirmGenerateGroupConsistentTask(GroupConsistentConfirmGenrateCommand inCommand)
{ {
var trialId = inCommand.TrialId; var trialId = inCommand.TrialId;
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.IsSelfAnalysis == false); var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.TrialReadingCriterionId == inCommand.TrialReadingCriterionId && t.IsSelfAnalysis == false);
var trialReadingCriterionId = filterObj.TrialReadingCriterionId; var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
//随机分配
if (inCommand.IsAutoAllocateGenerateTask)
{
var subjectSelectList = (await GetGroupConsistentRuleMatchSubjectIdListAsync(new GroupConsistentSimpleQuery() { TrialId = inCommand.TrialId, TrialReadingCriterionId = inCommand.TrialReadingCriterionId })).ToList();
if (subjectSelectList.Any(t => t.IsHaveGeneratedTask))
{
//已手动分配过,不允许自动分配
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate"]);
}
if (subjectSelectList.Count< 2 * filterObj.PlanSubjectCount)
{
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate1"]);
}
inCommand.SubejctIdList = GetRandomSubjectIdList(subjectSelectList.Select(t => t.SubjectId).ToList(), filterObj.PlanSubjectCount);
}
var query = await GetGroupConsistentQueryAsync(filterObj, inCommand.SubejctIdList); var query = await GetGroupConsistentQueryAsync(filterObj, inCommand.SubejctIdList);
var subjectList = query.ToList(); var subjectList = query.ToList();
var doctorUserIdQuery = from enroll in _repository.Where<Enroll>(t => t.TrialId == trialId).Where(t => t.EnrollReadingCategoryList.Where(t=>t.TrialReadingCriterionId==trialReadingCriterionId).Any(c => c.ReadingCategory == ReadingCategory.Global || c.ReadingCategory == ReadingCategory.Visit)) var doctorUserIdQuery = from enroll in _repository.Where<Enroll>(t => t.TrialId == trialId).Where(t => t.EnrollReadingCategoryList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(c => c.ReadingCategory == ReadingCategory.Global || c.ReadingCategory == ReadingCategory.Visit))
.Where(t => t.EnrollReadingCriteriaList.Any(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsJoinAnalysis == true))
join user in _repository.Where<User>() on enroll.DoctorId equals user.DoctorId join user in _repository.Where<User>() on enroll.DoctorId equals user.DoctorId
select user.Id; select user.Id;
@@ -310,7 +376,7 @@ namespace IRaCIS.Core.Application.Service
var blindSubjectCode = string.Empty; var blindSubjectCode = string.Empty;
var subjectTask = _visitTaskRepository.Where(t => t.SubjectId == subject.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis==false).OrderByDescending(t => t.BlindSubjectCode).FirstOrDefault(); var subjectTask = _visitTaskRepository.Where(t => t.SubjectId == subject.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == false).OrderByDescending(t => t.BlindSubjectCode).FirstOrDefault();
if (subjectTask != null && subjectTask.BlindSubjectCode != String.Empty) if (subjectTask != null && subjectTask.BlindSubjectCode != String.Empty)
{ {
blindSubjectCode = subjectTask.BlindSubjectCode; blindSubjectCode = subjectTask.BlindSubjectCode;
@@ -371,10 +437,10 @@ namespace IRaCIS.Core.Application.Service
TrialReadingCriterionId = task.TrialReadingCriterionId, TrialReadingCriterionId = task.TrialReadingCriterionId,
BlindSubjectCode=blindSubjectCode, BlindSubjectCode = blindSubjectCode,
BlindTrialSiteCode=filterObj.BlindTrialSiteCode BlindTrialSiteCode = filterObj.BlindTrialSiteCode
}); });
} }
@@ -460,7 +526,7 @@ namespace IRaCIS.Core.Application.Service
#region Subejct #region Subejct
Expression<Func<VisitTask, bool>> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && u.TrialReadingCriterionId== trialReadingCriterionId && Expression<Func<VisitTask, bool>> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && u.TrialReadingCriterionId == trialReadingCriterionId &&
u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject) && u.DoctorUserId == doctorUserId; u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject) && u.DoctorUserId == doctorUserId;
@@ -494,16 +560,16 @@ namespace IRaCIS.Core.Application.Service
var query = subjectQuery.Select(t => new DoctorSelfConsistentSubjectView() var query = subjectQuery.Select(t => new DoctorSelfConsistentSubjectView()
{ {
TrialId = t.TrialId, TrialId = t.TrialId,
SiteId = t.SiteId, TrialSiteId = t.TrialSiteId,
SubjectCode = t.Code, SubjectCode = t.Code,
TrialSiteCode = t.TrialSite.TrialSiteCode, TrialSiteCode = t.TrialSite.TrialSiteCode,
SubjectId = t.Id, SubjectId = t.Id,
IsReReadingOrBackInfluenceAnalysis=t.IsReReadingOrBackInfluenceAnalysis, IsReReadingOrBackInfluenceAnalysis = t.IsReReadingOrBackInfluenceAnalysis,
BlindSubjectCode = t.SubjectVisitTaskList.Where(t => t.IsAnalysisCreate && t.TrialReadingCriterionId == trialReadingCriterionId).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault(), BlindSubjectCode = t.SubjectVisitTaskList.Where(t => t.IsAnalysisCreate && t.TrialReadingCriterionId == trialReadingCriterionId).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault(),
IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.DoctorUserId == doctorUserId && c.IsSelfAnalysis == true && c.TrialReadingCriterionId==trialReadingCriterionId), IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.DoctorUserId == doctorUserId && c.IsSelfAnalysis == true && c.TrialReadingCriterionId == trialReadingCriterionId),
ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).Count(), ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).Count(),
@@ -526,7 +592,7 @@ namespace IRaCIS.Core.Application.Service
TrialReadingCriterionId=c.TrialReadingCriterionId, TrialReadingCriterionId = c.TrialReadingCriterionId,
IsClinicalDataSign = c.IsClinicalDataSign, IsClinicalDataSign = c.IsClinicalDataSign,
IsNeedClinicalDataSign = c.IsNeedClinicalDataSign, IsNeedClinicalDataSign = c.IsNeedClinicalDataSign,
@@ -564,7 +630,12 @@ namespace IRaCIS.Core.Application.Service
/// <summary>
/// 组间一致性分析 满足条件的subject 筛选
/// </summary>
/// <param name="filterObj"></param>
/// <param name="subejctIdList"></param>
/// <returns></returns>
private async Task<IQueryable<DoctorGroupConsistentSubjectView>> GetGroupConsistentQueryAsync(TaskConsistentRule filterObj, List<Guid>? subejctIdList = null) private async Task<IQueryable<DoctorGroupConsistentSubjectView>> GetGroupConsistentQueryAsync(TaskConsistentRule filterObj, List<Guid>? subejctIdList = null)
{ {
@@ -575,7 +646,7 @@ namespace IRaCIS.Core.Application.Service
Expression<Func<VisitTask, bool>> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && u.TrialReadingCriterionId == trialReadingCriterionId Expression<Func<VisitTask, bool>> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && u.TrialReadingCriterionId == trialReadingCriterionId
&& (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject); && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject);
@@ -616,14 +687,21 @@ namespace IRaCIS.Core.Application.Service
var query = subjectQuery.Select(t => new DoctorGroupConsistentSubjectView() var query = subjectQuery.Select(t => new DoctorGroupConsistentSubjectView()
{ {
TrialId = t.TrialId, TrialId = t.TrialId,
SiteId = t.SiteId, TrialSiteId = t.TrialSiteId,
SubjectCode = t.Code, SubjectCode = t.Code,
TrialSiteCode = t.TrialSite.TrialSiteCode, TrialSiteCode = t.TrialSite.TrialSiteCode,
SubjectId = t.Id, SubjectId = t.Id,
IsReReadingOrBackInfluenceAnalysis = t.IsReReadingOrBackInfluenceAnalysis, IsReReadingOrBackInfluenceAnalysis = t.IsReReadingOrBackInfluenceAnalysis,
IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.IsSelfAnalysis == false && c.TrialReadingCriterionId==trialReadingCriterionId), IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.IsSelfAnalysis == false && c.TrialReadingCriterionId == trialReadingCriterionId),
DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed).Select(t => new UserSimpleInfo()
{
UserId = t.Id,
FullName = t.DoctorUser.FullName,
UserCode = t.DoctorUser.UserCode,
UserName = t.DoctorUser.UserName
}).ToList(),
ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count(), ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count(),
@@ -663,7 +741,7 @@ namespace IRaCIS.Core.Application.Service
[HttpPost] [HttpPost]
public async Task<TaskConsistentRuleBasic?> GetConsistentRule(TaskConsistentRuleQuery inQuery) public async Task<TaskConsistentRuleBasic?> GetConsistentRule(TaskConsistentRuleQuery inQuery)
{ {
return await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == inQuery.IsSelfAnalysis && t.TrialReadingCriterionId==inQuery.TrialReadingCriterionId).ProjectTo<TaskConsistentRuleBasic>(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); return await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == inQuery.IsSelfAnalysis && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo<TaskConsistentRuleBasic>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
} }
/// <summary> /// <summary>
@@ -672,13 +750,23 @@ namespace IRaCIS.Core.Application.Service
/// <param name="inQuery"></param> /// <param name="inQuery"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<List<TaskConsistentRuleView>> GetSelfConsistentDoctorStatList(TaskConsistentRuleQuery inQuery) public async Task<IResponseOutput<List<TaskConsistentRuleView>>> GetSelfConsistentDoctorStatList(TaskConsistentRuleQuery inQuery)
{ {
var trialId = inQuery.TrialId; var trialId = inQuery.TrialId;
var taskConsistentRuleQueryable = from enroll in _repository.Where<Enroll>(t => t.TrialId == trialId && t.EnrollStatus==EnrollStatus.ConfirmIntoGroup) Expression<Func<VisitTask, bool>> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject);
join user in _repository.Where<User>() on enroll.DoctorId equals user.DoctorId
join taskConsistentRule in _repository.Where<TaskConsistentRule>(t => t.TrialId == trialId &&t.TrialReadingCriterionId==inQuery.TrialReadingCriterionId && t.IsSelfAnalysis) on enroll.TrialId equals taskConsistentRule.TrialId //&& u.TrialReadingCriterionId == trialReadingCriterionId &&u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && u.DoctorUserId == doctorUserId;
Expression<Func<VisitTask, bool>> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit);
var taskConsistentRuleQueryable = from enroll in _repository.Where<Enroll>(t => t.TrialId == trialId && t.EnrollStatus == EnrollStatus.ConfirmIntoGroup
&& t.EnrollReadingCriteriaList.Any(c => c.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && c.IsJoinAnalysis))
join user in _repository.Where<User>() on enroll.DoctorUserId equals user.Id
join taskConsistentRule in _repository.Where<TaskConsistentRule>(t => t.TrialId == trialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis) on enroll.TrialId equals taskConsistentRule.TrialId
select new TaskConsistentRuleView() select new TaskConsistentRuleView()
{ {
Id = taskConsistentRule.Id, Id = taskConsistentRule.Id,
@@ -697,7 +785,20 @@ namespace IRaCIS.Core.Application.Service
IsHaveReadingPeriod = taskConsistentRule.IsHaveReadingPeriod, IsHaveReadingPeriod = taskConsistentRule.IsHaveReadingPeriod,
PlanVisitCount = taskConsistentRule.PlanVisitCount, PlanVisitCount = taskConsistentRule.PlanVisitCount,
GeneratedSubjectCount = taskConsistentRule.Trial.VisitTaskList.Where(t => t.IsAnalysisCreate && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == true && t.DoctorUserId == user.Id).Select(t => t.SubjectId).Distinct().Count(), GeneratedSubjectCount = taskConsistentRule.TrialReadingCriterion.VisitTaskList.Where(t => t.IsAnalysisCreate && t.IsSelfAnalysis == true && t.DoctorUserId == user.Id).Select(t => t.SubjectId).Distinct().Count(),
MatchSubejctCount = taskConsistentRule.Trial.SubjectList.AsQueryable()
.Where(t => taskConsistentRule.IsHaveReadingPeriod == false ? t.SubjectVisitTaskList.AsQueryable()
.Where(visitTaskFilter).Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.Id)
.Count() >= taskConsistentRule.PlanVisitCount :
t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter)
.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.Id)
.Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(taskConsistentRule.PlanVisitCount + 1).Any(t => t.ReadingCategory == ReadingCategory.Global))
.Count(),
AnalysisDoctorUser = new UserSimpleInfo() AnalysisDoctorUser = new UserSimpleInfo()
{ {
@@ -724,10 +825,48 @@ namespace IRaCIS.Core.Application.Service
//var taskConsistentRuleQueryable = _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId) //var taskConsistentRuleQueryable = _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId)
// .ProjectTo<TaskConsistentRuleView>(_mapper.ConfigurationProvider); // .ProjectTo<TaskConsistentRuleView>(_mapper.ConfigurationProvider);
return await taskConsistentRuleQueryable.ToListAsync(); var list= await taskConsistentRuleQueryable.ToListAsync();
var rule= await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == true && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo<TaskConsistentRuleBasic>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
return ResponseOutput.Ok(list, rule);
} }
[HttpPost]
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> UpdateTrialVirtualSiteCode(UpdateTrialSiteCodeCommand inCommand)
{
if (_trialSiteRepository.Where(t => t.TrialId == inCommand.TrialId, false, true).Any(t => t.TrialSiteCode == inCommand.VirtualSiteCode))
{
return ResponseOutput.NotOk(_localizer["TaskConsistent_SiteCodeExists"]);
}
var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == inCommand.TrialId);
var oldCode = trial.VitrualSiteCode;
trial.VitrualSiteCode = inCommand.VirtualSiteCode;
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trial.Id, u => new VisitTask() { BlindTrialSiteCode = inCommand.VirtualSiteCode });
await _taskConsistentRuleRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trial.Id, u => new TaskConsistentRule() { BlindTrialSiteCode = inCommand.VirtualSiteCode });
await _visitTaskRepository.ExecuteUpdateAsync(t => t.TrialId == trial.Id, s => s.SetProperty(e => e.BlindSubjectCode, u => u.BlindSubjectCode.Replace(oldCode, inCommand.VirtualSiteCode)));
await _trialVirtualSiteCodeUpdateRepository.AddAsync(new TrialVirtualSiteCodeUpdate() { VirturalSiteCode = inCommand.VirtualSiteCode, TrialId = inCommand.TrialId });
await _trialRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
public async Task<List<UpdateTrialSiteCodeCommandView>> GetUpdateVirtualSiteCodeList(Guid trialId)
{
var list = await _trialVirtualSiteCodeUpdateRepository.Where(t => t.TrialId == trialId).Select(t => new UpdateTrialSiteCodeCommandView() { TrialId = trialId, VirtualSiteCode = t.VirturalSiteCode, Creatime = t.CreateTime }).OrderByDescending(t=>t.Creatime).ToListAsync();
return list;
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
@@ -737,7 +876,7 @@ namespace IRaCIS.Core.Application.Service
var verifyExp1 = new EntityVerifyExp<TaskConsistentRule>() var verifyExp1 = new EntityVerifyExp<TaskConsistentRule>()
{ {
VerifyExp = t => t.TrialId == addOrEditTaskConsistentRule.TrialId && t.IsSelfAnalysis == addOrEditTaskConsistentRule.IsSelfAnalysis && t.TrialReadingCriterionId==addOrEditTaskConsistentRule.TrialReadingCriterionId, VerifyExp = t => t.TrialId == addOrEditTaskConsistentRule.TrialId && t.IsSelfAnalysis == addOrEditTaskConsistentRule.IsSelfAnalysis && t.TrialReadingCriterionId == addOrEditTaskConsistentRule.TrialReadingCriterionId,
//"已有该项目配置,不允许继续增加" //"已有该项目配置,不允许继续增加"
VerifyMsg = _localizer["TaskConsistent_TaskGenerated"] VerifyMsg = _localizer["TaskConsistent_TaskGenerated"]
}; };
@@ -748,6 +887,22 @@ namespace IRaCIS.Core.Application.Service
return ResponseOutput.NotOk(_localizer["TaskConsistent_MedicalAuditTaskExists"]); return ResponseOutput.NotOk(_localizer["TaskConsistent_MedicalAuditTaskExists"]);
} }
if (_trialSiteRepository.Where(t => t.TrialId == addOrEditTaskConsistentRule.TrialId, false, true).Any(t => t.TrialSiteCode == addOrEditTaskConsistentRule.BlindTrialSiteCode))
{
return ResponseOutput.NotOk(_localizer["TaskConsistent_SiteCodeExists"]);
}
var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == addOrEditTaskConsistentRule.TrialId);
if (string.IsNullOrEmpty(trial.VitrualSiteCode))
{
await _trialVirtualSiteCodeUpdateRepository.AddAsync(new TrialVirtualSiteCodeUpdate() { VirturalSiteCode = addOrEditTaskConsistentRule.BlindTrialSiteCode, TrialId = addOrEditTaskConsistentRule.TrialId });
}
trial.VitrualSiteCode = addOrEditTaskConsistentRule.BlindTrialSiteCode;
var entity = await _taskConsistentRuleRepository.InsertOrUpdateAsync(addOrEditTaskConsistentRule, true, verifyExp1); var entity = await _taskConsistentRuleRepository.InsertOrUpdateAsync(addOrEditTaskConsistentRule, true, verifyExp1);
return ResponseOutput.Ok(entity.Id.ToString()); return ResponseOutput.Ok(entity.Id.ToString());
@@ -762,7 +917,7 @@ namespace IRaCIS.Core.Application.Service
var config = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == taskConsistentRuleId); var config = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == taskConsistentRuleId);
if (await _visitTaskRepository.AnyAsync(t => t.IsAnalysisCreate && t.TrialId == config.TrialId && t.IsSelfAnalysis == config.IsSelfAnalysis && t.TrialReadingCriterionId==config.TrialReadingCriterionId)) if (await _visitTaskRepository.AnyAsync(t => t.IsAnalysisCreate && t.TrialId == config.TrialId && t.IsSelfAnalysis == config.IsSelfAnalysis && t.TrialReadingCriterionId == config.TrialReadingCriterionId))
{ {
//"该标准已产生一致性分析任务,不允许删除" //"该标准已产生一致性分析任务,不允许删除"
throw new BusinessValidationFailedException(_localizer["TaskConsistent_SignedTaskCannotBeInvalidated"]); throw new BusinessValidationFailedException(_localizer["TaskConsistent_SignedTaskCannotBeInvalidated"]);
@@ -775,8 +930,65 @@ namespace IRaCIS.Core.Application.Service
} }
/// <summary>
/// 获取自身一致性分析 符合条件的subject 数组
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
public async Task<List<SubjectGeneratedTask>> GetSelfConsistentRuleMatchSubjectIdListAsync(SelfConsistentSimpleQuery inQuery)
{
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == inQuery.TaskConsistentRuleId);
var subjectList = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, inQuery.DoctorUserId).Select(t => new SubjectGeneratedTask() { SubjectId = t.SubjectId, IsHaveGeneratedTask = t.IsHaveGeneratedTask }).ToListAsync();
return subjectList;
}
/// <summary>
/// 获取组件一致性分析符合条件的subject 数组
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
public async Task<List<SubjectGeneratedTask>> GetGroupConsistentRuleMatchSubjectIdListAsync(GroupConsistentSimpleQuery inQuery)
{
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == inQuery.TrialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == false);
var subjectList = await (await GetGroupConsistentQueryAsync(filterObj)).Select(t => new SubjectGeneratedTask() { SubjectId = t.SubjectId, IsHaveGeneratedTask = t.IsHaveGeneratedTask }).ToListAsync();
return subjectList;
}
/// <summary>
/// 随机算法,选择指定数量的 subject
/// </summary>
/// <param name="matchSubjectIdList"></param>
/// <param name="countToSelect"></param>
/// <returns></returns>
public List<Guid> GetRandomSubjectIdList(List<Guid> matchSubjectIdList, int countToSelect)
{
// 使用 Fisher-Yates 随机置换算法来选择指定数量的 GUID
Random random = new Random();
for (int i = 0; i < countToSelect; i++)
{
// 生成一个随机索引
int randomIndex = random.Next(i, matchSubjectIdList.Count);
// 将选中的元素与当前元素交换位置
Guid temp = matchSubjectIdList[randomIndex];
matchSubjectIdList[randomIndex] = matchSubjectIdList[i];
matchSubjectIdList[i] = temp;
}
return matchSubjectIdList.Take(countToSelect).ToList();
// 使用洗牌算法来随机选择指定数量的GUID
//Random random = new Random();
//return matchSubjectIdList.OrderBy(g => random.Next()).Take(countToSelect).ToList();
}
} }
} }
@@ -67,11 +67,11 @@ namespace IRaCIS.Core.Application.Service
public async Task<IResponseOutput> DeleteTaskMedicalReviewRule(Guid taskMedicalReviewRuleId) public async Task<IResponseOutput> DeleteTaskMedicalReviewRule(Guid taskMedicalReviewRuleId)
{ {
if(await _taskMedicalReviewRuleRepository.Where(t=>t.Id== taskMedicalReviewRuleId).AnyAsync(t => t.TaskMedicalReviewList.Any())) //if(await _taskMedicalReviewRuleRepository.Where(t=>t.Id== taskMedicalReviewRuleId).AnyAsync(t => t.TaskMedicalReviewList.Any()))
{ //{
//"已产生医学审核任务" // //"已产生医学审核任务"
return ResponseOutput.NotOk(_localizer["TaskMedicalRule_TaskStarted"]); // return ResponseOutput.NotOk(_localizer["TaskMedicalRule_TaskStarted"]);
} //}
var success = await _taskMedicalReviewRuleRepository.DeleteFromQueryAsync(t => t.Id == taskMedicalReviewRuleId,true); var success = await _taskMedicalReviewRuleRepository.DeleteFromQueryAsync(t => t.Id == taskMedicalReviewRuleId,true);
@@ -11,6 +11,7 @@ using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using Microsoft.Extensions.Logging;
namespace IRaCIS.Core.Application.Service namespace IRaCIS.Core.Application.Service
{ {
@@ -54,21 +55,39 @@ namespace IRaCIS.Core.Application.Service
{ {
var taskMedicalReviewQueryable = _taskMedicalReviewRepository.Where(t => t.VisitTask.TrialId == inQuery.TrialId) var taskMedicalReviewQueryable = _taskMedicalReviewRepository.Where(t => t.VisitTask.TrialId == inQuery.TrialId)
.WhereIf(inQuery.SiteId != null, t => t.VisitTask.Subject.SiteId == inQuery.SiteId)
.WhereIf(inQuery.IsEffect == true, t => t.VisitTask.TaskState == TaskState.Effect || t.VisitTask.TaskState == TaskState.Freeze)
.WhereIf(inQuery.IsEffect == false, t => t.VisitTask.TaskState == TaskState.Adbandon || t.VisitTask.TaskState == TaskState.HaveReturned)
.WhereIf(inQuery.TrialSiteId != null, t => t.VisitTask.Subject.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId) .WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode)) .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode) || t.VisitTask.Subject.MedicalNo.Contains(inQuery.SubjectCode))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName)) .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName))
.WhereIf(inQuery.IsUrgent != null, t => t.VisitTask.IsUrgent == inQuery.IsUrgent) .WhereIf(inQuery.IsUrgent != null, t => t.VisitTask.IsUrgent == inQuery.IsUrgent)
.WhereIf(inQuery.DoctorUserId != null, t => t.VisitTask.DoctorUserId == inQuery.DoctorUserId) .WhereIf(inQuery.DoctorUserId != null, t => t.VisitTask.DoctorUserId == inQuery.DoctorUserId)
.WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.VisitTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode) && t.VisitTask.IsAnalysisCreate) || (t.VisitTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode) && t.VisitTask.IsAnalysisCreate == false)) .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.VisitTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode) && t.VisitTask.IsAnalysisCreate) || (t.VisitTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode) && t.VisitTask.IsAnalysisCreate == false))
.WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory) .WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory)
.WhereIf(inQuery.TaskState != null, t => t.VisitTask.TaskState == inQuery.TaskState) .WhereIf(inQuery.TaskState != null, t => t.VisitTask.TaskState == inQuery.TaskState)
.WhereIf(inQuery.ArmEnum != null, t => t.VisitTask.ArmEnum == inQuery.ArmEnum)
.WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState) .WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState)
.WhereIf(inQuery.MedicalManagerUserId != null, t => t.MedicalManagerUserId == inQuery.MedicalManagerUserId)
.WhereIf(inQuery.BeginSignTime != null, t => t.VisitTask.SignTime > inQuery.BeginSignTime)
.WhereIf(inQuery.EndSignTime != null, t => t.VisitTask.SignTime < inQuery.EndSignTime)
.WhereIf(inQuery.AuditAdviceEnum != null, t => t.AuditAdviceEnum == inQuery.AuditAdviceEnum)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) .WhereIf(inQuery.DoctorUserIdeaEnum != null, t => t.DoctorUserIdeaEnum == inQuery.DoctorUserIdeaEnum)
.ProjectTo<TaskMedicalReviewView>(_mapper.ConfigurationProvider); .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid)
.WhereIf(inQuery.IsHaveQuestion != null, t => t.IsHaveQuestion == inQuery.IsHaveQuestion)
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime >= inQuery.BeginAllocateDate)
.WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime <= inQuery.EndAllocateDate)
.WhereIf(inQuery.BeginAuditSignTime != null, t => t.AuditSignTime >= inQuery.BeginAuditSignTime)
.WhereIf(inQuery.EndAuditSignTime != null, t => t.AuditSignTime <= inQuery.EndAuditSignTime)
.ProjectTo<TaskMedicalReviewView>(_mapper.ConfigurationProvider);
var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(TaskMedicalReviewView.Id) : inQuery.SortField, inQuery.Asc); var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.AuditState), nameof(TaskMedicalReviewView.SubjectId), nameof(TaskMedicalReviewView.ArmEnum) , nameof(TaskMedicalReviewView.VisitTaskNum) };
var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
return pageList; return pageList;
} }
@@ -85,22 +104,25 @@ namespace IRaCIS.Core.Application.Service
var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId) var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId)
.Where(t => t.IsAnalysisCreate == false && (t.TaskState == TaskState.Effect||t.TaskState==TaskState.Freeze) && t.ReadingTaskState == ReadingTaskState.HaveSigned) .Where(t => t.IsAnalysisCreate == false && (t.TaskState == TaskState.Effect||t.TaskState==TaskState.Freeze) && t.ReadingTaskState == ReadingTaskState.HaveSigned)
.WhereIf(inQuery.SiteId != null, t => t.Subject.SiteId == inQuery.SiteId) .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId)
.WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent)
.WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId)
.WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory)
.WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState) .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState)
.WhereIf(inQuery.IsGeneratedJudge != null, t => t.JudgeVisitTaskId != null) .WhereIf(inQuery.IsGeneratedJudge != null, t => t.JudgeVisitTaskId != null)
.WhereIf(inQuery.IsGlobalHaveUpdate != null, t => t.IsGlobalHaveUpdate == inQuery.IsGlobalHaveUpdate) .WhereIf(inQuery.IsGlobalHaveUpdate != null, t => t.IsGlobalHaveUpdate == inQuery.IsGlobalHaveUpdate)
.WhereIf(inQuery.ArmEnum != null, t => t.ArmEnum == inQuery.ArmEnum)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName))
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.Subject.Code.Contains(inQuery.SubjectCode)) .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.Subject.Code.Contains(inQuery.SubjectCode))
.WhereIf(inQuery.BeginSignTime != null, t => t.SignTime > inQuery.BeginSignTime)
.WhereIf(inQuery.EndSignTime != null, t => t.SignTime < inQuery.EndSignTime)
.ProjectTo<GenerateMedicalReviewTaskView>(_mapper.ConfigurationProvider); .ProjectTo<GenerateMedicalReviewTaskView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.IsUrgent) + " desc", nameof(TaskMedicalReviewView.SubjectId) }; var defalutSortArray = new string[] { nameof(GenerateMedicalReviewTaskView.IsUrgent) + " desc", nameof(GenerateMedicalReviewTaskView.SubjectId) };
var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
@@ -136,45 +158,53 @@ namespace IRaCIS.Core.Application.Service
[HttpPost] [HttpPost]
public async Task<TaskMedicalReviewView> GetNextMedicalReviewTask(GetNextMedicalReviewTaskInDto inDto) public async Task<TaskMedicalReviewView> GetNextMedicalReviewTask(GetNextMedicalReviewTaskInDto inDto)
{ {
var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.MedicalReviewId).Include(x=>x.VisitTask).FirstNotNullAsync(); var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.MedicalReviewId).Include(x => x.VisitTask).FirstNotNullAsync();
var subjectReview = (await GetMIMMedicalReviewTaskList(new TaskMedicalReviewQuery()
{
TrialId = medicalReview.TrialId,
IsGetBeRead = true,
Id=inDto.MedicalReviewId,
SubjectId= medicalReview.VisitTask.SubjectId,
TrialReadingCriterionId = medicalReview.VisitTask.TrialReadingCriterionId,
PageIndex=1,
PageSize=1,
})).Data;
if (subjectReview.CurrentPageData.Count == 1)
{
return subjectReview.CurrentPageData[0];
}
var data = (await GetMIMMedicalReviewTaskList(new TaskMedicalReviewQuery() var data = (await GetMIMMedicalReviewTaskList(new TaskMedicalReviewQuery()
{ {
TrialId = medicalReview.TrialId, TrialId = medicalReview.TrialId,
IsGetBeRead = true,
Id = inDto.MedicalReviewId, Id = inDto.MedicalReviewId,
TrialReadingCriterionId = medicalReview.VisitTask.TrialReadingCriterionId, TrialReadingCriterionId = medicalReview.VisitTask.TrialReadingCriterionId,
IsGetNextMedicalReviewTask = true,
PageIndex = 1, PageIndex = 1,
PageSize = 1, PageSize = 99999,
})).Data; })).Data;
if (data.CurrentPageData.Count == 1)
if (data.CurrentPageData.Count > 0)
{ {
return data.CurrentPageData[0];
var index = data.CurrentPageData.ToList().FindIndex(x => x.Id == inDto.MedicalReviewId);
var result = new TaskMedicalReviewView() { };
if (index+1 == data.CurrentPageData.Count()) // 最后一个
{
throw new BusinessValidationFailedException(_localizer["MedicalReview_Finish"]);
}
else if (index == -1 || data.CurrentPageData.Count == 1) // 第一个或者只有一个
{
if (data.CurrentPageData[0].Id == inDto.MedicalReviewId)
{
throw new BusinessValidationFailedException(_localizer["MedicalReview_Finish"]);
}
result = data.CurrentPageData[0];
}
else
{
result = data.CurrentPageData.Skip(index + 1).Take(1).First();
}
return result;
} }
else else
{ {
throw new BusinessValidationFailedException(_localizer["MedicalReview_Finish"]); throw new BusinessValidationFailedException(_localizer["MedicalReview_Finish"]);
} }
} }
@@ -190,22 +220,47 @@ namespace IRaCIS.Core.Application.Service
{ {
var taskMedicalReviewQueryable = _taskMedicalReviewRepository.Where(t => t.VisitTask.TrialId == inQuery.TrialId && t.MedicalManagerUserId == _userInfo.Id&&t.VisitTask.TrialReadingCriterionId==inQuery.TrialReadingCriterionId) var taskMedicalReviewQueryable = _taskMedicalReviewRepository.Where(t => t.VisitTask.TrialId == inQuery.TrialId && t.MedicalManagerUserId == _userInfo.Id&&t.VisitTask.TrialReadingCriterionId==inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId)
.WhereIf(inQuery.SiteId != null, t => t.VisitTask.Subject.SiteId == inQuery.SiteId) .WhereIf(inQuery.IsGetNextMedicalReviewTask,
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode)) x=>(
.WhereIf(inQuery.Id != null, t => t.Id != inQuery.Id) !x.IsInvalid&& x.AuditState== MedicalReviewAuditState.Auditing &
( x.ReadingMedicalReviewDialogList.Count()!=0&&
x.ReadingMedicalReviewDialogList.Count()>0&&
x.ReadingMedicalReviewDialogList.OrderByDescending(x=>x.CreateTime).FirstOrDefault().UserTypeEnumInt==(int)UserTypeEnum.IndependentReviewer)
) // 审核中最新回复为IR的
|| (!x.IsInvalid&& x.AuditState==MedicalReviewAuditState.WaitAudit)
||x.Id == inQuery.Id // 这里必须找传入id 因为要找到这条的索引 获取下一条
)
.WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId)
.WhereIf(inQuery.TrialSiteId != null, t => t.VisitTask.Subject.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.IsUrgent != null, t => t.VisitTask.IsUrgent == inQuery.IsUrgent) .WhereIf(inQuery.IsUrgent != null, t => t.VisitTask.IsUrgent == inQuery.IsUrgent)
.WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState) .WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState)
.WhereIf(inQuery.TaskState != null, t => t.VisitTask.TaskState == inQuery.TaskState) .WhereIf(inQuery.DoctorUserIdeaEnum != null, t => t.DoctorUserIdeaEnum == inQuery.DoctorUserIdeaEnum)
.WhereIf(inQuery.TaskState != null, t => t.VisitTask.TaskState == inQuery.TaskState)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode) || t.VisitTask.Subject.MedicalNo.Contains(inQuery.SubjectCode))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName))
.WhereIf(inQuery.DoctorUserId != null, t => t.VisitTask.DoctorUserId == inQuery.DoctorUserId) .WhereIf(inQuery.DoctorUserId != null, t => t.VisitTask.DoctorUserId == inQuery.DoctorUserId)
.WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory) .WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory)
.WhereIf(inQuery.ReadingTaskState != null, t => t.VisitTask.ReadingTaskState == inQuery.ReadingTaskState) .WhereIf(inQuery.ReadingTaskState != null, t => t.VisitTask.ReadingTaskState == inQuery.ReadingTaskState)
.WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid) .WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid)
.WhereIf(inQuery.IsGetBeRead,x=>!x.IsInvalid&&x.AuditState!= MedicalReviewAuditState.HaveSigned) .WhereIf(inQuery.IsGetBeRead,x=>!x.IsInvalid&&x.AuditState!= MedicalReviewAuditState.HaveSigned)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.BeginAuditSignTime != null, t => t.AuditSignTime >= inQuery.BeginAuditSignTime)
.WhereIf(inQuery.EndAuditSignTime != null, t => t.AuditSignTime <= inQuery.EndAuditSignTime)
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime >= inQuery.BeginAllocateDate)
.WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime <= inQuery.EndAllocateDate)
.WhereIf(inQuery.ArmEnum != null, t => t.VisitTask.ArmEnum == inQuery.ArmEnum)
.WhereIf(inQuery.MedicalManagerUserId != null, t => t.MedicalManagerUserId == inQuery.MedicalManagerUserId)
.WhereIf(inQuery.BeginSignTime != null, t => t.VisitTask.SignTime > inQuery.BeginSignTime)
.WhereIf(inQuery.EndSignTime != null, t => t.VisitTask.SignTime < inQuery.EndSignTime)
.WhereIf(inQuery.AuditAdviceEnum != null, t => t.AuditAdviceEnum == inQuery.AuditAdviceEnum)
.WhereIf(inQuery.IsHaveQuestion != null, t => t.IsHaveQuestion == inQuery.IsHaveQuestion)
.ProjectTo<TaskMedicalReviewView>(_mapper.ConfigurationProvider); .ProjectTo<TaskMedicalReviewView>(_mapper.ConfigurationProvider);
var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(TaskMedicalReviewView.Id) : inQuery.SortField, inQuery.Asc);
var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.AuditState), nameof(TaskMedicalReviewView.SubjectId), nameof(TaskMedicalReviewView.ArmEnum), nameof(TaskMedicalReviewView.VisitTaskNum) };
var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
return ResponseOutput.Ok(pageList, new return ResponseOutput.Ok(pageList, new
{ {
@@ -40,6 +40,7 @@ namespace IRaCIS.Core.Application.Service
private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository; private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;
private readonly IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository; private readonly IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository;
private readonly IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository; private readonly IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository;
private readonly IRepository<ReadingOncologyTaskInfo> _readingOncologyTaskInfoRepository;
private readonly IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository; private readonly IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository;
private readonly IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository; private readonly IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository;
private readonly IMapper _mapper; private readonly IMapper _mapper;
@@ -60,6 +61,7 @@ namespace IRaCIS.Core.Application.Service
IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository, IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository,
IRepository<ReadingTableAnswerRowInfo> readingTableAnswerRowInfoRepository, IRepository<ReadingTableAnswerRowInfo> readingTableAnswerRowInfoRepository,
IRepository<ReadingTableQuestionAnswer> readingTableQuestionAnswerRepository, IRepository<ReadingTableQuestionAnswer> readingTableQuestionAnswerRepository,
IRepository<ReadingOncologyTaskInfo> ReadingOncologyTaskInfoRepository,
IRepository<ReadingTableQuestionTrial> readingTableQuestionTrialRepository, IRepository<ReadingTableQuestionTrial> readingTableQuestionTrialRepository,
IRepository<ReadingQuestionTrial> readingQuestionTrialRepository, IRepository<ReadingQuestionTrial> readingQuestionTrialRepository,
IRepository<ReadingJudgeInfo> readingJudgeInfoRepository, IRepository<ReadingJudgeInfo> readingJudgeInfoRepository,
@@ -76,6 +78,7 @@ namespace IRaCIS.Core.Application.Service
this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository; this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
this._readingTableAnswerRowInfoRepository = readingTableAnswerRowInfoRepository; this._readingTableAnswerRowInfoRepository = readingTableAnswerRowInfoRepository;
this._readingTableQuestionAnswerRepository = readingTableQuestionAnswerRepository; this._readingTableQuestionAnswerRepository = readingTableQuestionAnswerRepository;
_readingOncologyTaskInfoRepository = ReadingOncologyTaskInfoRepository;
this._readingTableQuestionTrialRepository = readingTableQuestionTrialRepository; this._readingTableQuestionTrialRepository = readingTableQuestionTrialRepository;
this._readingQuestionTrialRepository = readingQuestionTrialRepository; this._readingQuestionTrialRepository = readingQuestionTrialRepository;
_provider = provider; _provider = provider;
@@ -152,6 +155,8 @@ namespace IRaCIS.Core.Application.Service
await _visitTaskRepository.SaveChangesAsync(); await _visitTaskRepository.SaveChangesAsync();
} }
//基于标准签名 产生任务 (或者手动选择某些访视生成该标准的任务) //基于标准签名 产生任务 (或者手动选择某些访视生成该标准的任务)
public async Task BaseCritrionGenerateVisitTask(Guid trialId, Guid confirmedTrialReadingCriterionId, bool? isManualSelectVisit = null, List<Guid>? subjectVisitIdList = null) public async Task BaseCritrionGenerateVisitTask(Guid trialId, Guid confirmedTrialReadingCriterionId, bool? isManualSelectVisit = null, List<Guid>? subjectVisitIdList = null)
{ {
@@ -194,26 +199,29 @@ namespace IRaCIS.Core.Application.Service
foreach (var subjectVisit in subjectGroup.SubjectVisitList) foreach (var subjectVisit in subjectGroup.SubjectVisitList)
{ {
var blindTaskName = string.Empty;
var isNeedClinicalDataSign = IsNeedClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionConfig.TrialReadingCriterionId, clinicalDataConfirmList); var isNeedClinicalDataSign = IsNeedClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionConfig.TrialReadingCriterionId, clinicalDataConfirmList);
var isClinicalDataSign = IsClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionConfig.TrialReadingCriterionId, clinicalDataConfirmList, subjectVisit.Id, trialId); var isClinicalDataSign = IsClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionConfig.TrialReadingCriterionId, clinicalDataConfirmList, subjectVisit.Id, trialId);
if (visitNumList.IndexOf(subjectVisit.VisitNum) == 0) var blindTaskName = string.Empty;
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
blindTaskName = visitBlindConfig.BlindBaseLineName; if (visitNumList.IndexOf(subjectVisit.VisitNum) == 0 && subjectVisit.VisitNum==0)
}
else
{
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder)
{ {
blindTaskName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(subjectVisit.VisitNum); blindTaskName = visitBlindConfig.BlindBaseLineName;
} }
else else
{ {
blindTaskName = visitBlindConfig.BlindFollowUpPrefix; blindTaskName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(subjectVisit.VisitNum);
} }
} }
else
{
blindTaskName ="Timepoint";
}
//每个访视 根据项目配置生成任务 双审生成两个 //每个访视 根据项目配置生成任务 双审生成两个
@@ -389,13 +397,14 @@ namespace IRaCIS.Core.Application.Service
} }
await _visitTaskRepository.SaveChangesAsync();
} }
} }
await _visitTaskRepository.SaveChangesAsync();
} }
@@ -460,11 +469,11 @@ namespace IRaCIS.Core.Application.Service
.Where(t => t.TrialId == trialId && t.IsSign && t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count(); .Where(t => t.TrialId == trialId && t.IsSign && t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count();
var readModule = _readModuleRepository.Where(t => t.Id == readingId).FirstOrDefault(); var readModule = _readModuleRepository.Where(t => t.Id == readingId).FirstOrDefault();
//CRC 阅片期自定义结构化录入是否签名 //CRC 阅片期自定义结构化录入是否签名
bool crcReadModuleSign = true; bool crcReadModuleSign = true;
//访视 //访视
if (readingCategory == ReadingCategory.Visit) if (readingCategory == ReadingCategory.Visit)
@@ -505,7 +514,7 @@ namespace IRaCIS.Core.Application.Service
// 肿瘤学 // 肿瘤学
else if (readingCategory == ReadingCategory.Oncology) else if (readingCategory == ReadingCategory.Oncology)
{ {
needSignCount= trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCriterionId) && t.ClinicalDataLevel == ClinicalLevel.OncologyRead && t.UploadRole == UploadRole.PM).Count(); needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCriterionId) && t.ClinicalDataLevel == ClinicalLevel.OncologyRead && t.UploadRole == UploadRole.PM).Count();
if (readModule != null) if (readModule != null)
{ {
// 不存在需要CRC上传的临床数据 或者 PM已确认 // 不存在需要CRC上传的临床数据 或者 PM已确认
@@ -523,7 +532,7 @@ namespace IRaCIS.Core.Application.Service
} }
//可能仅仅CRC 基线 没有PM //可能仅仅CRC 基线 没有PM
if (needSignCount == haveSignedCount && crcReadModuleSign ) if (needSignCount == haveSignedCount && crcReadModuleSign)
{ {
isClinicalDataSign = true; isClinicalDataSign = true;
@@ -657,28 +666,29 @@ namespace IRaCIS.Core.Application.Service
var assignConfigList = await _subjectUserRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.OrignalSubjectUserId == null && t.IsConfirmed).Select(u => new { u.DoctorUserId, u.ArmEnum }).ToListAsync(); var assignConfigList = await _subjectUserRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.OrignalSubjectUserId == null && t.IsConfirmed).Select(u => new { u.DoctorUserId, u.ArmEnum }).ToListAsync();
var blindTaskName = string.Empty;
var isNeedClinicalDataSign = IsNeedClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionConfig.TrialReadingCriterionId, clinicalDataConfirmList); var isNeedClinicalDataSign = IsNeedClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionConfig.TrialReadingCriterionId, clinicalDataConfirmList);
var isClinicalDataSign = IsClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionConfig.TrialReadingCriterionId, clinicalDataConfirmList, subjectVisit.Id, trialId); var isClinicalDataSign = IsClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionConfig.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) var blindTaskName = string.Empty;
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
blindTaskName = visitBlindConfig.BlindBaseLineName; if (visitNumList.IndexOf(subjectVisit.VisitNum) == 0 && subjectVisit.VisitNum == 0)
}
else
{
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder)
{ {
blindTaskName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(subjectVisit.VisitNum); blindTaskName = visitBlindConfig.BlindBaseLineName;
} }
else else
{ {
blindTaskName = visitBlindConfig.BlindFollowUpPrefix; blindTaskName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(subjectVisit.VisitNum);
} }
} }
else
{
blindTaskName = "Timepoint";
}
//每个访视 根据项目配置生成任务 双审生成两个 //每个访视 根据项目配置生成任务 双审生成两个
@@ -689,7 +699,7 @@ namespace IRaCIS.Core.Application.Service
var existCurrentVisitTaskList = _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId var existCurrentVisitTaskList = _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId
&& t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect
&& t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.SourceSubjectVisitId == subjectVisit.Id).ToList(); /* && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null*/ && t.SourceSubjectVisitId == subjectVisit.Id).ToList();
VisitTask? task1 = null; VisitTask? task1 = null;
VisitTask? task2 = null; VisitTask? task2 = null;
@@ -719,7 +729,8 @@ namespace IRaCIS.Core.Application.Service
TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId,
IsNeedClinicalDataSign = isNeedClinicalDataSign, IsNeedClinicalDataSign = isNeedClinicalDataSign,
IsClinicalDataSign = isClinicalDataSign IsClinicalDataSign = isClinicalDataSign,
IsFrontTaskNeedSignButNotSign = isFrontTaskNeedSignButNotSign
}); });
} }
@@ -746,7 +757,8 @@ namespace IRaCIS.Core.Application.Service
TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId,
IsNeedClinicalDataSign = isNeedClinicalDataSign, IsNeedClinicalDataSign = isNeedClinicalDataSign,
IsClinicalDataSign = isClinicalDataSign IsClinicalDataSign = isClinicalDataSign,
IsFrontTaskNeedSignButNotSign = isFrontTaskNeedSignButNotSign
}); });
} }
@@ -778,7 +790,7 @@ namespace IRaCIS.Core.Application.Service
#region 访 (PM 退 PM ) #region 访 (PM 退 PM )
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
//之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的) //之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的)
@@ -1068,7 +1080,8 @@ namespace IRaCIS.Core.Application.Service
TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId,
IsNeedClinicalDataSign = isNeedClinicalDataSign, IsNeedClinicalDataSign = isNeedClinicalDataSign,
IsClinicalDataSign = isClinicalDataSign IsClinicalDataSign = isClinicalDataSign,
IsFrontTaskNeedSignButNotSign = isFrontTaskNeedSignButNotSign
}); });
@@ -1107,7 +1120,7 @@ namespace IRaCIS.Core.Application.Service
#region /退访 #region /退访
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
//之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的) //之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的)
var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
@@ -1602,17 +1615,18 @@ namespace IRaCIS.Core.Application.Service
var oncologySubjectUser = await _subjectUserRepository.Where(x => x.SubjectId == item.SubjectId && x.ArmEnum == Arm.TumorArm && x.IsConfirmed && x.TrialReadingCriterionId == originalTaskInfo.TrialReadingCriterionId).FirstOrDefaultAsync(); var oncologySubjectUser = await _subjectUserRepository.Where(x => x.SubjectId == item.SubjectId && x.ArmEnum == Arm.TumorArm && x.IsConfirmed && x.TrialReadingCriterionId == originalTaskInfo.TrialReadingCriterionId).FirstOrDefaultAsync();
item.VisitNum = await _readModuleRepository.Where(x => x.Id == item.ReadModuleId).Select(x => x.SubjectVisit.VisitNum).FirstOrDefaultAsync(); item.VisitNum = await _readModuleRepository.Where(x => x.Id == item.ReadModuleId).Select(x => x.SubjectVisit.VisitNum).FirstOrDefaultAsync();
var id = NewId.NextGuid();
var singleTask = await _visitTaskRepository.AddAsync(new VisitTask() var singleTask = await _visitTaskRepository.AddAsync(new VisitTask()
{ {
Id = id,
TrialId = trialId, TrialId = trialId,
SubjectId = item.SubjectId, SubjectId = item.SubjectId,
IsUrgent = originalTaskInfo.IsUrgent, IsUrgent = originalTaskInfo.IsUrgent,
TaskName = item.ReadingName, TaskName = item.ReadingName,
//IsConvertedTask = originalTaskInfo.IsConvertedTask, //IsConvertedTask = originalTaskInfo.IsConvertedTask,
// 原任务是全局任务 加0.03 就好 // 这里可能是
VisitTaskNum = originalTaskInfo.VisitTaskNum + 0.03m, VisitTaskNum = originalTaskInfo.VisitTaskNum - ReadingCommon.TaskNumDic[originalTaskInfo.ReadingCategory] + ReadingCommon.TaskNumDic[ReadingCategory.Oncology],
ArmEnum = Arm.TumorArm, //特殊 ArmEnum = Arm.TumorArm, //特殊
Code = currentMaxCodeInt + 1, Code = currentMaxCodeInt + 1,
SouceReadModuleId = item.ReadModuleId, SouceReadModuleId = item.ReadModuleId,
@@ -1637,6 +1651,22 @@ namespace IRaCIS.Core.Application.Service
currentMaxCodeInt = currentMaxCodeInt + 1; currentMaxCodeInt = currentMaxCodeInt + 1;
// 生成肿瘤学需要 肿瘤学阅片结果中基线,统一显示为NA
// 找到基线任务ID
var baseLineTaskId = await _visitTaskRepository.Where(x => x.TaskState == TaskState.Effect
&& x.ArmEnum == originalTaskInfo.ArmEnum && x.VisitTaskNum == 0
&& x.SubjectId == originalTaskInfo.SubjectId
&& x.ReadingTaskState == ReadingTaskState.HaveSigned && x.TrialReadingCriterionId == originalTaskInfo.TrialReadingCriterionId).Select(x => x.Id).FirstNotNullAsync();
await _readingOncologyTaskInfoRepository.AddAsync(new ReadingOncologyTaskInfo()
{
EvaluationResult = "-1",
EvaluationReason = string.Empty,
OncologyTaskId = id,
VisitTaskId = baseLineTaskId,
SubjectId = originalTaskInfo.SubjectId,
TrialId = originalTaskInfo.TrialId
});
_provider.Set<int>($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); _provider.Set<int>($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30));
} }
break; break;
@@ -22,6 +22,8 @@ using DocumentFormat.OpenXml.Bibliography;
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto;
using IRaCIS.Core.Domain.Share.Reading; using IRaCIS.Core.Domain.Share.Reading;
using MassTransit; using MassTransit;
using System.Reactive.Subjects;
using Subject = IRaCIS.Core.Domain.Models.Subject;
namespace IRaCIS.Core.Application.Service.Allocation namespace IRaCIS.Core.Application.Service.Allocation
{ {
@@ -105,7 +107,23 @@ namespace IRaCIS.Core.Application.Service.Allocation
var list = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId && t.IsConfirm) var list = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId && t.IsConfirm)
.OrderBy(t => t.ShowOrder) .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,
IsArbitrationReading = t.IsArbitrationReading,
IsGlobalReading = t.IsGlobalReading,
IsOncologyReading = t.IsOncologyReading,
ImageDownloadEnum = t.ImageDownloadEnum,
ImageUploadEnum = t.ImageUploadEnum,
IsReadingTaskViewInOrder = t.IsReadingTaskViewInOrder
})
.ToListAsync(); .ToListAsync();
//if (list.Count == 0) //if (list.Count == 0)
@@ -128,16 +146,24 @@ namespace IRaCIS.Core.Application.Service.Allocation
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<(PageOutput<SubjectAssignStat>, object?)> GetSubjectAssignAndTaskStatList(SubjectAssignStatQuery querySubjectAssign) public async Task<IResponseOutput<PageOutput<SubjectAssignStat>>> GetSubjectAssignAndTaskStatList(SubjectAssignStatQuery querySubjectAssign)
{ {
var isAddtinoarlCriterion = await _trialReadingCriterionRepository.AnyAsync(t => t.Id == querySubjectAssign.TrialReadingCriterionId && t.IsAutoCreate == false); var isAddtinoarlCriterion = await _trialReadingCriterionRepository.AnyAsync(t => t.Id == querySubjectAssign.TrialReadingCriterionId && t.IsAutoCreate == false);
var subjectQuery = _subjectRepository.Where(t => t.TrialId == querySubjectAssign.TrialId && t.SubjectVisitTaskList.Any()) var subjectQuery = _subjectRepository.Where(t => t.TrialId == querySubjectAssign.TrialId && t.SubjectVisitTaskList.Any())
.WhereIf(querySubjectAssign.SiteId != null, t => t.SiteId == querySubjectAssign.SiteId) .WhereIf(querySubjectAssign.TrialSiteId != null, t => t.TrialSiteId == querySubjectAssign.TrialSiteId)
.WhereIf(querySubjectAssign.SubjectId != null, t => t.Id == querySubjectAssign.SubjectId) .WhereIf(querySubjectAssign.SubjectId != null, t => t.Id == querySubjectAssign.SubjectId)
.WhereIf(querySubjectAssign.DoctorUserId != null, t => t.SubjectDoctorList.Any(t => t.DoctorUserId == querySubjectAssign.DoctorUserId && t.TrialReadingCriterionId == querySubjectAssign.TrialReadingCriterionId)) .WhereIf(querySubjectAssign.DoctorUserId != null, t => t.SubjectDoctorList.Any(t => t.DoctorUserId == querySubjectAssign.DoctorUserId && t.TrialReadingCriterionId == querySubjectAssign.TrialReadingCriterionId))
.WhereIf(!string.IsNullOrEmpty(querySubjectAssign.SubjectCode), t => t.Code.Contains(querySubjectAssign.SubjectCode)) .WhereIf(!string.IsNullOrEmpty(querySubjectAssign.SubjectCode), t => t.Code.Contains(querySubjectAssign.SubjectCode))
//未分配
.WhereIf(querySubjectAssign.SubjectAllocateState == 0, t => !t.SubjectDoctorList.Any(t => t.AssignTime != null && t.TrialReadingCriterionId == querySubjectAssign.TrialReadingCriterionId))
//已分配
.WhereIf(querySubjectAssign.SubjectAllocateState == 1, t => t.SubjectDoctorList.Any(t => t.AssignTime != null && t.TrialReadingCriterionId == querySubjectAssign.TrialReadingCriterionId))
.WhereIf(querySubjectAssign.ArmList.Count > 0, t => !querySubjectAssign.ArmList.Except(t.SubjectDoctorList.Where(t => t.AssignTime != null && t.TrialReadingCriterionId == querySubjectAssign.TrialReadingCriterionId).Select(c => c.ArmEnum)).Any())
.WhereIf(isAddtinoarlCriterion, t => t.SubjectCriteriaEvaluationList.Where(t => t.TrialReadingCriterionId == querySubjectAssign.TrialReadingCriterionId).Any(t => t.IsJoinEvaluation)) .WhereIf(isAddtinoarlCriterion, t => t.SubjectCriteriaEvaluationList.Where(t => t.TrialReadingCriterionId == querySubjectAssign.TrialReadingCriterionId).Any(t => t.IsJoinEvaluation))
@@ -150,7 +176,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == querySubjectAssign.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading, x.IsGlobalReading }).FirstOrDefaultAsync()).IfNullThrowException(); var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == querySubjectAssign.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading, x.IsGlobalReading }).FirstOrDefaultAsync()).IfNullThrowException();
return (pageList, criterionConfig); return ResponseOutput.Ok(pageList, criterionConfig);
} }
/// <summary> /// <summary>
@@ -284,7 +310,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
var subjectId = cancelCommand.CancelList.First().SubjectId; var subjectId = cancelCommand.CancelList.First().SubjectId;
await _repository.AddAsync(new SubjectCanceDoctor() { SubjectId = subjectId, Note = cancelCommand.Note }); await _repository.AddAsync(new SubjectCanceDoctor() { SubjectId = subjectId, Note = cancelCommand.Note, TrialReadingCriterionId = cancelCommand.TrialReadingCriterionId });
await _visitTaskRepository.SaveChangesAsync(); await _visitTaskRepository.SaveChangesAsync();
@@ -399,7 +425,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
.WhereIf(querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) .WhereIf(querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any())
.WhereIf(querySubjectAssign.IsJudgeDoctor, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) .WhereIf(querySubjectAssign.IsJudgeDoctor, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any())
.WhereIf(querySubjectAssign.SiteId != null, t => t.SiteId == querySubjectAssign.SiteId) .WhereIf(querySubjectAssign.TrialSiteId != null, t => t.TrialSiteId == querySubjectAssign.TrialSiteId)
.WhereIf(querySubjectAssign.SubjectId != null, t => t.Id == querySubjectAssign.SubjectId) .WhereIf(querySubjectAssign.SubjectId != null, t => t.Id == querySubjectAssign.SubjectId)
.WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == true && querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) .WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == true && querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any())
@@ -662,7 +688,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
.WhereIf(queryVisitTask.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge) .WhereIf(queryVisitTask.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge)
.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -702,7 +728,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory) .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -734,13 +760,16 @@ namespace IRaCIS.Core.Application.Service.Allocation
/// <param name="queryVisitTask"></param> /// <param name="queryVisitTask"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<(PageOutput<ReadingTaskView>, object?)> GetReadingTaskList(VisitTaskQuery queryVisitTask) public async Task<IResponseOutput<PageOutput<ReadingTaskView>>> GetReadingTaskList(VisitTaskQuery queryVisitTask)
{ {
var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false) var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false)
//.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null) //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null)
.WhereIf(queryVisitTask.IsEffect == true, t => t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze)
.WhereIf(queryVisitTask.IsEffect == false, t => t.TaskState == TaskState.Adbandon || t.TaskState == TaskState.HaveReturned)
.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -757,7 +786,9 @@ namespace IRaCIS.Core.Application.Service.Allocation
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName))
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate))
.WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
.WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate)
.WhereIf(queryVisitTask.BeginSignTime != null, t => t.SignTime > queryVisitTask.BeginSignTime)
.WhereIf(queryVisitTask.EndSignTime != null, t => t.SignTime < queryVisitTask.EndSignTime)
.ProjectTo<ReadingTaskView>(_mapper.ConfigurationProvider); .ProjectTo<ReadingTaskView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) };
@@ -766,7 +797,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialUrgentConfig>(_mapper.ConfigurationProvider).FirstOrDefault(); var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialUrgentConfig>(_mapper.ConfigurationProvider).FirstOrDefault();
return (pageList, trialTaskConfig); return ResponseOutput.Ok(pageList, trialTaskConfig);
} }
@@ -784,26 +815,33 @@ namespace IRaCIS.Core.Application.Service.Allocation
.Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/) .Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/)
.WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId) .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId)
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!))
.WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState) .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState)
.WhereIf(queryVisitTask.RequestReReadingType != null, t => t.RequestReReadingType == queryVisitTask.RequestReReadingType) .WhereIf(queryVisitTask.RequestReReadingType != null, t => t.RequestReReadingType == queryVisitTask.RequestReReadingType)
.WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId)
.WhereIf(queryVisitTask.ArmEnum != null, t => t.OriginalReReadingTask.ArmEnum == queryVisitTask.ArmEnum)
.WhereIf(queryVisitTask.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState) .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState)
.WhereIf(queryVisitTask.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == queryVisitTask.ReadingCategory) .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.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == queryVisitTask.RequestReReadingResultEnum)
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false))
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName))
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => ((t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode) || t.OriginalReReadingTask.Subject.MedicalNo.Contains(queryVisitTask.SubjectCode)) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate))
.WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate)
.WhereIf(queryVisitTask.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1))
.WhereIf(queryVisitTask.BeginRequestReReadingTime != null, t => t.RequestReReadingTime >= queryVisitTask.BeginRequestReReadingTime)
.WhereIf(queryVisitTask.EndRequestReReadingTime != null, t => t.RequestReReadingTime <= queryVisitTask.EndRequestReReadingTime!.Value.AddDays(1))
.ProjectTo<ReReadingTaskView>(_mapper.ConfigurationProvider); .ProjectTo<ReReadingTaskView>(_mapper.ConfigurationProvider);
//var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) };
@@ -835,12 +873,13 @@ namespace IRaCIS.Core.Application.Service.Allocation
.Where(t => t.RequestReReadingType == RequestReReadingType.DocotorApply) .Where(t => t.RequestReReadingType == RequestReReadingType.DocotorApply)
.Where(t => t.OriginalReReadingTask.DoctorUserId == _userInfo.Id) .Where(t => t.OriginalReReadingTask.DoctorUserId == _userInfo.Id)
.Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId) .Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId)
.WhereIf(queryVisitTask.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == queryVisitTask.RequestReReadingResultEnum)
.WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId) .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId)
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!))
.WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == queryVisitTask.ReadingCategory)
.WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState) .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState)
.WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -875,7 +914,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
.WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId) .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId)
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!))
.WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -907,74 +946,54 @@ namespace IRaCIS.Core.Application.Service.Allocation
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<(PageOutput<IRUnReadSubjectView>, object)> GetIRUnReadSubjectTaskList(IRUnReadSubjectQuery iRUnReadSubjectQuery) public async Task<IResponseOutput<PageOutput<IRUnReadSubjectView>>> GetIRUnReadSubjectTaskList(IRUnReadSubjectQuery inQuery)
{ {
var trialId = iRUnReadSubjectQuery.TrialId; var trialId = inQuery.TrialId;
var subjectCode = inQuery.SubjectCode;
var trialReadingCriterionId = iRUnReadSubjectQuery.TrialReadingCriterionId; var trialReadingCriterionId = inQuery.TrialReadingCriterionId;
var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == iRUnReadSubjectQuery.TrialReadingCriterionId).FirstNotNullAsync(); var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).FirstNotNullAsync();
var readingTool = criterionConfig.ReadingTool; var readingTool = criterionConfig.ReadingTool;
var isReadingTaskViewInOrder = criterionConfig.IsReadingTaskViewInOrder; var isReadingTaskViewInOrder = criterionConfig.IsReadingTaskViewInOrder;
#region Subject
if (isReadingTaskViewInOrder) var result = new PageOutput<IRUnReadSubjectView>()
{ {
PageSize = inQuery.PageSize,
PageIndex = inQuery.PageIndex,
TotalCount = 0,
CurrentPageData = null,
};
IRUnReadOutDto iRUnReadOut = new IRUnReadOutDto();
var visitTaskListInfo = await GetOrderReadingIQueryable(new GetOrderReadingIQueryableInDto() //subject 级别 有序 无序查询
if (isReadingTaskViewInOrder == ReadingOrder.InOrder || isReadingTaskViewInOrder == ReadingOrder.SubjectRandom)
{
result = await GetSubjectReadingIQueryable(new GetReadingIQueryableInDto()
{ {
TrialId = trialId, TrialId = trialId,
TrialReadingCriterionId = trialReadingCriterionId, TrialReadingCriterionId = trialReadingCriterionId,
SubjectCode = iRUnReadSubjectQuery.SubjectCode, SubjectCode = inQuery.SubjectCode,
Page = new PageInput()
{
PageIndex = iRUnReadSubjectQuery.PageIndex,
PageSize = iRUnReadSubjectQuery.PageSize,
Asc = iRUnReadSubjectQuery.Asc,
SortField = iRUnReadSubjectQuery.SortField,
}
PageIndex = inQuery.PageIndex,
PageSize = inQuery.PageSize,
Asc = inQuery.Asc,
SortField = inQuery.SortField,
}); });
var totalCount = visitTaskListInfo.Item1;
var currentPageData = visitTaskListInfo.Item2;
var result = new PageOutput<IRUnReadSubjectView>()
{
PageSize = iRUnReadSubjectQuery.PageSize,
PageIndex = iRUnReadSubjectQuery.PageIndex,
TotalCount = totalCount,
CurrentPageData = currentPageData,
};
// 封装的方法有问题
//var result = await visitQuery.ToPagedListAsync(iRUnReadSubjectQuery.PageIndex, iRUnReadSubjectQuery.PageSize, String.IsNullOrEmpty(iRUnReadSubjectQuery.SortField) ? nameof(IRUnReadSubjectView.SubjectId) : iRUnReadSubjectQuery.SortField, iRUnReadSubjectQuery.Asc);
return (result, new
{
RandomReadInfo = new IRUnReadOutDto(),
IsReadingTaskViewInOrder = isReadingTaskViewInOrder,
ReadingTool = readingTool,
IseCRFShowInDicomReading = criterionConfig.IseCRFShowInDicomReading,
IsReadingShowSubjectInfo = criterionConfig.IsReadingShowSubjectInfo,
IsReadingShowPreviousResults = criterionConfig.IsReadingShowPreviousResults,
DigitPlaces = criterionConfig.DigitPlaces,
CriterionType = criterionConfig.CriterionType,
});
} }
//随机阅片
else else
{ {
var taskQuery = _visitTaskRepository.Where(x => x.TrialId == iRUnReadSubjectQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == trialReadingCriterionId) var taskQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == trialReadingCriterionId)
// .Where(x=>x.Subject.ClinicalDataList.Any(c => c.IsSign && (c.ReadingId == x.SouceReadModuleId || c.ReadingId == x.SourceSubjectVisitId))) // .Where(x=>x.Subject.ClinicalDataList.Any(c => c.IsSign && (c.ReadingId == x.SouceReadModuleId || c.ReadingId == x.SourceSubjectVisitId)))
.Where(x => !x.Subject.IsDeleted).Where(x => (x.IsNeedClinicalDataSign && x.IsClinicalDataSign) || !x.IsNeedClinicalDataSign); .Where(x => !x.Subject.IsDeleted).Where(x => (x.IsNeedClinicalDataSign && x.IsClinicalDataSign) || !x.IsNeedClinicalDataSign);
IRUnReadOutDto iRUnReadOut = new IRUnReadOutDto() iRUnReadOut = new IRUnReadOutDto()
{ {
FinishJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(), FinishJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(),
FinishTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(), FinishTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(),
@@ -982,12 +1001,57 @@ namespace IRaCIS.Core.Application.Service.Allocation
UnReadJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(), UnReadJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(),
UnReadTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(), UnReadTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(),
}; };
}
return ResponseOutput.Ok(result, new
{
IsReadingTaskViewInOrder = isReadingTaskViewInOrder,
RandomReadInfo = iRUnReadOut,
ReadingTool = readingTool,
IseCRFShowInDicomReading = criterionConfig.IseCRFShowInDicomReading,
IsReadingShowSubjectInfo = criterionConfig.IsReadingShowSubjectInfo,
IsReadingShowPreviousResults = criterionConfig.IsReadingShowPreviousResults,
DigitPlaces = criterionConfig.DigitPlaces,
CriterionType = criterionConfig.CriterionType,
});
}
var visitGroupQuery = taskQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }); /// <summary>
/// 获取subject有序 或者无序阅片IQuery对象
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
public async Task<PageOutput<IRUnReadSubjectView>> GetSubjectReadingIQueryable(GetReadingIQueryableInDto inQuery)
{
var trialReadingCriterionId = inQuery.TrialReadingCriterionId;
var subjectCode = inQuery.SubjectCode;
var trialId = inQuery.TrialId;
var subjectId = inQuery.SubjectId;
var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId);
if (critrion.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{
var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect)
.WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId)
//前序 不存在 未生成任务的访视
.WhereIf(critrion.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum))
// 前序 不存在 未一致性核查未通过的
.Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum >= sv.VisitNum))
//.WhereIf(critrion.IsAutoCreate == false, t => t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(t => t.IsGeneratedTask == false) ?
//t.VisitTaskNum <= t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsGeneratedTask == false).Min(t => t.SubjectVisit.VisitNum) : true)
//.Where(t => t.Subject.SubjectVisitList.Any(t => t.CheckState != CheckStateEnum.CVPassed) ? t.VisitTaskNum <= t.Subject.SubjectVisitList.Where(t => t.CheckState != CheckStateEnum.CVPassed).Min(t => t.VisitNum) : true)
//满足前序访视不存在 需要签署但是未签署 sql 相当复杂 同时想查询所有未读的统计数字 就无法统计 byzhouhang
//但是加字段 IsFrontTaskNeedSignButNotSign 那么签名临床数据的时候,要对该subject 该标准的有效的任务 这个字段需要在签名的时候维护 采取这种方式 统计数字灵活
//.Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum))
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate));
var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode });
var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView() var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView()
{ {
@@ -1006,6 +1070,32 @@ namespace IRaCIS.Core.Application.Service.Allocation
).Count(), ).Count(),
UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned)
.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
.OrderBy(x => x.VisitTaskNum)
.Select(u => new IRUnreadTaskView()
{
Id = u.Id,
IsUrgent = u.IsUrgent,
VisitNum = u.VisitTaskNum,
TaskBlindName = u.TaskBlindName,
VisistId = u.SourceSubjectVisitId,
SuggesteFinishedTime = u.SuggesteFinishedTime,
ReadingCategory = u.ReadingCategory,
IsAnalysisCreate = u.IsAnalysisCreate,
ArmEnum = u.ArmEnum,
TrialReadingCriterionId = u.TrialReadingCriterionId,
IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
IsClinicalDataSign = u.IsClinicalDataSign,
IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign
})
.ToList(),
UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned)
.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
.Where(x => x.IsUrgent).Count(),
//已读任务量 //已读任务量
HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(), HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(),
@@ -1030,141 +1120,122 @@ namespace IRaCIS.Core.Application.Service.Allocation
IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign
}) })
.ToList(), .ToList(),
}).Where(x => x.UnReadCanReadTaskCount > 0); }).Where(x => x.UnReadCanReadTaskCount > 0)/*.OrderBy(x => x.UnReadCanReadTaskCount)*/;
// 有序阅片需要找到最小需要
var totalCount = await visitGroupQuery.CountAsync(); // 不这样写会有问题
var currentPageData = await visitTaskQuery.ToListAsync(); var count = visitQuery.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }).Count();
var result = new PageOutput<IRUnReadSubjectView>() var result = new List<IRUnReadSubjectView>();
{
PageSize = iRUnReadSubjectQuery.PageSize,
PageIndex = iRUnReadSubjectQuery.PageIndex,
TotalCount = totalCount,
CurrentPageData = currentPageData,
};
return (result, new var propName = string.IsNullOrWhiteSpace(inQuery!.SortField) ? nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) : inQuery.SortField;
{
IsReadingTaskViewInOrder = isReadingTaskViewInOrder,
RandomReadInfo = iRUnReadOut,
ReadingTool = readingTool,
IseCRFShowInDicomReading = criterionConfig.IseCRFShowInDicomReading,
IsReadingShowSubjectInfo = criterionConfig.IsReadingShowSubjectInfo,
IsReadingShowPreviousResults = criterionConfig.IsReadingShowPreviousResults,
DigitPlaces = criterionConfig.DigitPlaces,
CriterionType = criterionConfig.CriterionType,
});
} var visitTaskOrderQuery = inQuery.Asc ? visitTaskQuery.OrderBy(propName) : visitTaskQuery.OrderBy(propName + " desc");
#endregion
}
/// <summary>
/// 获取有序阅片IQuery对象
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<(int, List<IRUnReadSubjectView>)> GetOrderReadingIQueryable(GetOrderReadingIQueryableInDto inDto)
{
var trialReadingCriterionId = inDto.TrialReadingCriterionId;
//Expression<Func<VisitTask, bool>> visitTaskLambda = x => x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId;
var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId);
var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.DoctorUserId == _userInfo.Id
&& x.TaskState == TaskState.Effect /*&& x.TrialReadingCriterionId== inDto.TrialReadingCriterionId*/)
//前序 不存在 未生成任务的访视
.WhereIf(critrion.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum))
// 前序 不存在 未一致性核查未通过的
.Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum))
//.WhereIf(critrion.IsAutoCreate == false, t => t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(t => t.IsGeneratedTask == false) ?
//t.VisitTaskNum <= t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsGeneratedTask == false).Min(t => t.SubjectVisit.VisitNum) : true)
//.Where(t => t.Subject.SubjectVisitList.Any(t => t.CheckState != CheckStateEnum.CVPassed) ? t.VisitTaskNum <= t.Subject.SubjectVisitList.Where(t => t.CheckState != CheckStateEnum.CVPassed).Min(t => t.VisitNum) : true)
//满足前序访视不存在 需要签署但是未签署 sql 相当复杂 同时想查询所有未读的统计数字 就无法统计 byzhouhang
//但是加字段 IsFrontTaskNeedSignButNotSign 那么签名临床数据的时候,要对该subject 该标准的有效的任务 这个字段需要在签名的时候维护 采取这种方式 统计数字灵活
//.Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum))
.WhereIf(!string.IsNullOrEmpty(inDto.SubjectCode), t => (t.Subject.Code.Contains(inDto.SubjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inDto.SubjectCode!) && t.IsAnalysisCreate));
var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode });
var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView()
{
SubjectId = x.Key.SubjectId,
SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode,
SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime),
//未读任务量
UnReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(),
//未读 里可读任务量
UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)
//不能对包含聚合或子查询的表达式执行聚合函数
//&& !x.Any(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.IsNeedClinicalDataSign == true && t.IsClinicalDataSign == false && t.VisitTaskNum<y.VisitTaskNum )
).Count(),
//已读任务量
HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(),
ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed),
//查出所有未读的 未读的可读的 在这个列表基础上 过滤下 y.IsFrontTaskNeedSignButNotSign==false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true) 这样容易排错 确认这三个字段是否维护有误
UnReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).OrderBy(x => x.VisitTaskNum)
.Select(u => new IRUnreadTaskView()
{
Id = u.Id,
IsUrgent = u.IsUrgent,
VisitNum = u.VisitTaskNum,
TaskBlindName = u.TaskBlindName,
VisistId = u.SourceSubjectVisitId,
SuggesteFinishedTime = u.SuggesteFinishedTime,
ReadingCategory = u.ReadingCategory,
IsAnalysisCreate = u.IsAnalysisCreate,
ArmEnum = u.ArmEnum,
TrialReadingCriterionId = u.TrialReadingCriterionId,
IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
IsClinicalDataSign = u.IsClinicalDataSign,
IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign
})
.ToList(),
}).Where(x => x.UnReadCanReadTaskCount > 0)/*.OrderBy(x => x.UnReadCanReadTaskCount)*/;
// 有序阅片需要找到最小需要
// 不这样写会有问题
var count = visitQuery.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }).Count();
var result = new List<IRUnReadSubjectView>();
var propName = string.IsNullOrWhiteSpace(inDto.Page!.SortField) ? "UnReadCanReadTaskCount" : inDto.Page.SortField;
var visitTaskOrderQuery = inDto.Page.Asc ? visitTaskQuery.OrderBy(propName) : visitTaskQuery.OrderBy(propName + " desc");
if (inDto.Page != null)
{
result = await visitTaskOrderQuery result = await visitTaskOrderQuery
.Skip((inDto.Page.PageIndex - 1) * inDto.Page.PageSize) .Skip((inQuery.PageIndex - 1) * inQuery.PageSize)
.Take(inDto.Page.PageSize).ToListAsync(); .Take(inQuery.PageSize).ToListAsync();
return new PageOutput<IRUnReadSubjectView>()
{
PageSize = inQuery.PageSize,
PageIndex = inQuery.PageIndex,
TotalCount = count,
CurrentPageData = result,
};
} }
else else
{ {
result = await visitTaskOrderQuery.ToListAsync();
if (subjectId != null)
{
//找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务
var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
&& t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskBlindName == "Timepoint" && t.ReadingCategory == ReadingCategory.Visit
&& (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze), true).ToListAsync();
if (needDealTaskList.Count > 0)
{
//已完成的访视任务数量(包含重阅的)
var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
&& t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit);
//已经处理过的任务名称的数量
var haveDealedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
&& t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint");
//随机赋值编号 比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个
List<int> availableNumbers = Enumerable.Range(haveDealedTaskCount + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList();
Random rng = new Random();
foreach (var visitTask in needDealTaskList)
{
int randomIndex = rng.Next(availableNumbers.Count);
visitTask.TaskBlindName = $"Timepoint Ran {availableNumbers[randomIndex]}";
availableNumbers.RemoveAt(randomIndex);
}
await _visitTaskRepository.SaveChangesAsync();
}
}
var visitQuery = _visitTaskRepository.Where(x => x.TrialId == trialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect)
.WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId)
.WhereIf(!string.IsNullOrEmpty(subjectCode), t => (t.Subject.Code.Contains(subjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(subjectCode!) && t.IsAnalysisCreate));
var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode });
var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView()
{
SubjectId = x.Key.SubjectId,
SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode,
SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime),
//未读任务量
UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(),
UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Where(x => x.IsUrgent).Count(),
//已读任务量
HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(),
ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed),
UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned)
.OrderBy(x => x.VisitTaskNum)
.Select(u => new IRUnreadTaskView()
{
Id = u.Id,
IsUrgent = u.IsUrgent,
VisitNum = u.VisitTaskNum,
TaskBlindName = u.TaskBlindName,
VisistId = u.SourceSubjectVisitId,
SuggesteFinishedTime = u.SuggesteFinishedTime,
ReadingCategory = u.ReadingCategory,
IsAnalysisCreate = u.IsAnalysisCreate,
ArmEnum = u.ArmEnum,
TrialReadingCriterionId = u.TrialReadingCriterionId,
IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
IsClinicalDataSign = u.IsClinicalDataSign,
IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign
})
.ToList()
}).Where(x => x.UnReadCanReadTaskCount > 0);
var pageList = await visitTaskQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) : inQuery.SortField, inQuery.Asc);
return pageList;
} }
return (count, result);
} }
@@ -1182,7 +1253,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
.Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState == ReadingTaskState.HaveSigned)//该医生 已经签名的数据 .Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState == ReadingTaskState.HaveSigned)//该医生 已经签名的数据
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory) .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
@@ -1214,14 +1285,14 @@ namespace IRaCIS.Core.Application.Service.Allocation
var baseLineTaskList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id var baseLineTaskList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id
&& t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.SourceSubjectVisit.IsBaseLine == true).ToListAsync(); && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.SourceSubjectVisit.IsBaseLine == true).ToListAsync();
var judegeList= await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id var judegeList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id
&& t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned).ToListAsync(); && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned).ToListAsync();
foreach (var item in judegeList) foreach (var item in judegeList)
{ {
if (!baseLineTaskList.Any(t => t.SubjectId == item.SubjectId)) if (!baseLineTaskList.Any(t => t.SubjectId == item.SubjectId))
{ {
baseLineTaskList.Add(item); baseLineTaskList.Add(item);
} }
} }
@@ -1325,7 +1396,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
// 有序 一个受试者访视重阅未处理完,不能申请其他的 // 有序 一个受试者访视重阅未处理完,不能申请其他的
if (criterionConfig.IsReadingTaskViewInOrder) if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect
&& t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId
@@ -1346,7 +1417,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed;
// 有序 // 有序
if (criterionConfig.IsReadingTaskViewInOrder) if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
// 针对同一个subject 不同阅片人 针对同一个访视申请重阅,是允许的,所以同一阅片人,针对同一suject 有访视申请重阅还未处理,不允许申请重阅 // 针对同一个subject 不同阅片人 针对同一个访视申请重阅,是允许的,所以同一阅片人,针对同一suject 有访视申请重阅还未处理,不允许申请重阅
if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect
@@ -1612,7 +1683,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
} }
//有序阅片 //有序阅片
if (criterionConfig.IsReadingTaskViewInOrder) if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
@@ -1721,7 +1792,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
//有序阅片 //有序阅片
if (criterionConfig.IsReadingTaskViewInOrder) if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
#region IR 访 #region IR 访
@@ -2129,8 +2200,8 @@ namespace IRaCIS.Core.Application.Service.Allocation
foreach (var item in readingTableAnswerRowInfoList) foreach (var item in readingTableAnswerRowInfoList)
{ {
var originalVisitTaskId= item.VisitTaskId; var originalVisitTaskId = item.VisitTaskId;
var originalFristAddTaskId= item.FristAddTaskId; var originalFristAddTaskId = item.FristAddTaskId;
item.Id = NewId.NextSequentialGuid(); item.Id = NewId.NextSequentialGuid();
item.VisitTaskId = newTask.Id; item.VisitTaskId = newTask.Id;
@@ -2234,7 +2305,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
//有序 //有序
if (criterionConfig.IsReadingTaskViewInOrder) if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
//Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated; //Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated;
@@ -2253,7 +2324,13 @@ namespace IRaCIS.Core.Application.Service.Allocation
#region #region
var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault();
//pm退回的时候,影响的任务里不一定有该任务id 双重 分配了一个人,退回的时候,选择的是未分配的
//var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault();
var origenalTask = await _visitTaskRepository.FindAsync(task.Id);
foreach (var influenceTask in influenceTaskList) foreach (var influenceTask in influenceTaskList)
{ {
@@ -2312,7 +2389,9 @@ namespace IRaCIS.Core.Application.Service.Allocation
await SetMedicalReviewInvalidAsync(currentVisitList); 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) foreach (var influenceTask in currentVisitList)
{ {
@@ -2558,7 +2637,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
//当前任务及其之后的所有访视任务、全局任务、裁判任务、肿瘤学阅片任务 //当前任务及其之后的所有访视任务、全局任务、裁判任务、肿瘤学阅片任务
//有序 //有序
if (criterionConfig.IsReadingTaskViewInOrder) if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
switch (filterObj.ReadingCategory) switch (filterObj.ReadingCategory)
@@ -2667,7 +2746,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
//throw new BusinessValidationFailedException("仅允许PM 同意 IR 申请的任务"); //throw new BusinessValidationFailedException("仅允许PM 同意 IR 申请的任务");
} }
//PM 影响所有阅片人 仅仅针对访视 SPM CPM //PM 影响所有阅片人 仅仅针对访视 SPM CPM
else if (((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM) && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.ProjectManager) && filterObj.IsAnalysisCreate == false && filterObj.ReadingCategory == ReadingCategory.Visit) else if (((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM) && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.ProjectManager) && filterObj.IsAnalysisCreate == false && filterObj.ReadingCategory == ReadingCategory.Visit)
|| (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && applyId == null)) || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && applyId == null))
@@ -2677,7 +2756,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
//有序 //有序
if (criterionConfig.IsReadingTaskViewInOrder) if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
switch (filterObj.ReadingCategory) switch (filterObj.ReadingCategory)
{ {
@@ -2736,7 +2815,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
if (filterObj.ReadingCategory == ReadingCategory.Visit && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager) if (filterObj.ReadingCategory == ReadingCategory.Visit && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager)
{ {
//有序 //有序
if (criterionConfig.IsReadingTaskViewInOrder) if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
// 当前任务及其之后的所有访视任务 两个阅片人的 // 当前任务及其之后的所有访视任务 两个阅片人的
@@ -74,7 +74,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<TaskAllocationRule, TaskAllocationRuleDTO>() CreateMap<TaskAllocationRule, TaskAllocationRuleDTO>()
.ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.Enroll.DoctorUser)) .ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.Enroll.DoctorUser))
.ForMember(o => o.CriterionReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Select(t => new TrialCriterionReadingCategory() { EnrollId = t.EnrollId, ReadingCategory = t.ReadingCategory, TrialReadingCriterionId = t.TrialReadingCriterionId }))) .ForMember(o => o.CriterionReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Select(t => new TrialCriterionReadingCategory() { EnrollId = t.EnrollId, ReadingCategory = t.ReadingCategory, TrialReadingCriterionId = t.TrialReadingCriterionId })))
.ForMember(o => o.TrialReadingCriterionList, t => t.MapFrom(u => u.Trial.ReadingQuestionCriterionTrialList.Where(t => t.IsConfirm))) .ForMember(o => o.TrialReadingCriterionList, t => t.MapFrom(u => u.Trial.TrialReadingCriterionList.Where(t => t.IsConfirm)))
.ForMember(o => o.ReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Where(t=>t.TrialReadingCriterionId== trialReadingCriterionId).OrderBy(t => t.ReadingCategory).Select(t => t.ReadingCategory).ToList())) .ForMember(o => o.ReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Where(t=>t.TrialReadingCriterionId== trialReadingCriterionId).OrderBy(t => t.ReadingCategory).Select(t => t.ReadingCategory).ToList()))
; ;
@@ -124,9 +124,11 @@ namespace IRaCIS.Core.Application.Service
CreateMap<VisitTask, VisitTaskView>().IncludeBase<VisitTask, VisitTaskViewBasic>() CreateMap<VisitTask, VisitTaskView>().IncludeBase<VisitTask, VisitTaskViewBasic>()
.ForMember(o => o.SiteId, t => t.MapFrom(u => u.Subject.SiteId)) .ForMember(o => o.TrialSiteId, t => t.MapFrom(u => u.Subject.TrialSiteId))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode)) .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.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.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName)) .ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName)) .ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
@@ -167,7 +169,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<VisitTask, IRHaveReadView>().IncludeBase<VisitTask, VisitTaskViewBasic>() CreateMap<VisitTask, IRHaveReadView>().IncludeBase<VisitTask, VisitTaskViewBasic>()
.ForMember(o => o.SiteId, t => t.MapFrom(u => u.Subject.SiteId)) .ForMember(o => o.TrialSiteId, t => t.MapFrom(u => u.Subject.TrialSiteId))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode)) .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.SubjectCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code));
@@ -223,17 +225,19 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.Id, t => t.MapFrom(u => u.Id)) .ForMember(o => o.Id, t => t.MapFrom(u => u.Id))
.ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.VisitTask.Subject.MedicalNo)) .ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.VisitTask.Subject.MedicalNo))
.ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.VisitTask.DoctorUser)) .ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.VisitTask.DoctorUser))
.ForMember(o => o.MedicalManagerUser, t => t.MapFrom(u => u.MedicalManagerUser)); .ForMember(o => o.MedicalManagerUser, t => t.MapFrom(u => u.MedicalManagerUser))
.ForMember(o => o.AllocateTime, t => t.MapFrom(u => u.AllocateTime))
;
CreateMap<VisitTask, TaskMedicalReviewView>() CreateMap<VisitTask, TaskMedicalReviewView>()
.ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName)) .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.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.SubjectCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindSubjectCode :*/ u.Subject.Code));
CreateMap<VisitTask, GenerateMedicalReviewTaskView>() CreateMap<VisitTask, GenerateMedicalReviewTaskView>()
.ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName)) .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.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.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.GeneratedMedicalReviewCount, t => t.MapFrom(u => u.TaskMedicalReviewList.Count()))
.ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.Subject.MedicalNo)) .ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.Subject.MedicalNo))
.ForMember(o => o.IsGeneratedJudge, t => t.MapFrom(u => u.JudgeVisitTaskId != null)) .ForMember(o => o.IsGeneratedJudge, t => t.MapFrom(u => u.JudgeVisitTaskId != null))
@@ -257,27 +261,27 @@ namespace IRaCIS.Core.Application.Service
CreateMap<TaskMedicalReviewRule, TaskMedicalReviewRuleView>() //CreateMap<TaskMedicalReviewRule, TaskMedicalReviewRuleView>()
.ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.DoctorUser)) // .ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.DoctorUser))
.ForMember(o => o.ActualVisitTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect // .ForMember(o => o.ActualVisitTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect
&& t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId }))) // && t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.ActualJudgeTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && // .ForMember(o => o.ActualJudgeTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect &&
t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId }))) // t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.ActualGlobalTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Global && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && // .ForMember(o => o.ActualGlobalTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Global && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect &&
t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId }))) // t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.ActualTumorTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Oncology && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && // .ForMember(o => o.ActualTumorTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Oncology && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect &&
t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId }))) // t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.GeneratedGlobalTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Global && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId }))) // .ForMember(o => o.GeneratedGlobalTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Global && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.GeneratedJudgeTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Judge && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId }))) // .ForMember(o => o.GeneratedJudgeTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Judge && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.GeneratedTumorTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Oncology && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId }))) // .ForMember(o => o.GeneratedTumorTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Oncology && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.GeneratedVisitTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Visit && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId }))); // .ForMember(o => o.GeneratedVisitTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Visit && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })));
CreateMap<TaskMedicalReviewRuleAddOrEdit, TaskMedicalReviewRule>(); CreateMap<TaskMedicalReviewRuleAddOrEdit, TaskMedicalReviewRule>();
@@ -91,7 +91,9 @@ namespace IRaCIS.Application.Contracts
public class GetBasicDataAllSelectInDto public class GetBasicDataAllSelectInDto
{ {
public Guid? TrialReadingCriterionId { get; set; } public Guid? TrialReadingCriterionId { get; set; }
}
public Guid? SystemReadingCriterionId { get; set; }
}
public class GetTrialCriterionDictionaryListInDto public class GetTrialCriterionDictionaryListInDto
@@ -42,6 +42,8 @@ namespace IRaCIS.Core.Application.ViewModel
public string Value { get; set; } = string.Empty; public string Value { get; set; } = string.Empty;
public string ValueCN { get; set; } = string.Empty; public string ValueCN { get; set; } = string.Empty;
public string FrontType { get; set; } = string.Empty;
public int InternationalizationType { get; set; } 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 Description { get; set; } = string.Empty;
public string Code { get; set; } = string.Empty; public string Code { get; set; } = string.Empty;
public string Value { 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 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
{
} }
} }
@@ -23,7 +23,7 @@ namespace IRaCIS.Application.Services
private readonly IRepository<SystemCriterionDictionaryCode> _systemCriterionDictionaryCodeRepository; private readonly IRepository<SystemCriterionDictionaryCode> _systemCriterionDictionaryCodeRepository;
private readonly IRepository<TrialCriterionDictionaryCode> _trialCriterionDictionaryCodeRepository; private readonly IRepository<TrialCriterionDictionaryCode> _trialCriterionDictionaryCodeRepository;
private readonly IRepository<ReadingTrialCriterionDictionary> _readingTrialCriterionDictionaryRepository; private readonly IRepository<ReadingTrialCriterionDictionary> _readingTrialCriterionDictionaryRepository;
private readonly IRepository<ReadingSystemCriterionDictionary> _readingSystemCriterionDictionaryRepository;
private readonly IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository; private readonly IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository;
private readonly IRepository<ReadingQuestionCriterionSystem> _readingQuestionCriterionSystem; private readonly IRepository<ReadingQuestionCriterionSystem> _readingQuestionCriterionSystem;
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrial; private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrial;
@@ -34,6 +34,7 @@ namespace IRaCIS.Application.Services
IRepository<SystemCriterionDictionaryCode> systemCriterionDictionaryCodeRepository, IRepository<SystemCriterionDictionaryCode> systemCriterionDictionaryCodeRepository,
IRepository<TrialCriterionDictionaryCode> trialCriterionDictionaryCodeRepository, IRepository<TrialCriterionDictionaryCode> trialCriterionDictionaryCodeRepository,
IRepository<ReadingTrialCriterionDictionary> readingTrialCriterionDictionaryRepository, IRepository<ReadingTrialCriterionDictionary> readingTrialCriterionDictionaryRepository,
IRepository<ReadingSystemCriterionDictionary> readingSystemCriterionDictionaryRepository,
IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository, IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository,
IRepository<ReadingQuestionCriterionSystem> readingQuestionCriterionSystem, IRepository<ReadingQuestionCriterionSystem> readingQuestionCriterionSystem,
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrial IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrial
@@ -49,6 +50,7 @@ namespace IRaCIS.Application.Services
this._systemCriterionDictionaryCodeRepository = systemCriterionDictionaryCodeRepository; this._systemCriterionDictionaryCodeRepository = systemCriterionDictionaryCodeRepository;
this._trialCriterionDictionaryCodeRepository = trialCriterionDictionaryCodeRepository; this._trialCriterionDictionaryCodeRepository = trialCriterionDictionaryCodeRepository;
this._readingTrialCriterionDictionaryRepository = readingTrialCriterionDictionaryRepository; this._readingTrialCriterionDictionaryRepository = readingTrialCriterionDictionaryRepository;
this._readingSystemCriterionDictionaryRepository = readingSystemCriterionDictionaryRepository;
this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository; this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository;
this._readingQuestionCriterionSystem = readingQuestionCriterionSystem; this._readingQuestionCriterionSystem = readingQuestionCriterionSystem;
this._readingQuestionCriterionTrial = readingQuestionCriterionTrial; this._readingQuestionCriterionTrial = readingQuestionCriterionTrial;
@@ -85,6 +87,18 @@ namespace IRaCIS.Application.Services
return ResponseOutput.Ok(entity.Id.ToString()); return ResponseOutput.Ok(entity.Id.ToString());
} }
/// <summary>
/// 获取所有字典的Key
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<List<string>> GetAllDictionaryKey()
{
var result =await _dicRepository.Where(t => t.ParentId == null).OrderBy(x=>x.Code).Select(x => x.Code).ToListAsync();
return result;
}
/// <summary> /// <summary>
/// 添加字典 的同时 一起添加子项 --New /// 添加字典 的同时 一起添加子项 --New
@@ -462,11 +476,11 @@ namespace IRaCIS.Application.Services
var result = searchList.GroupBy(t => t.ParentCode).ToDictionary(g => g.Key, g => g.OrderBy(t => t.ShowOrder).ToList()); var result = searchList.GroupBy(t => t.ParentCode).ToDictionary(g => g.Key, g => g.OrderBy(t => t.ShowOrder).ToList());
if (inDto.TrialReadingCriterionId == null) if (inDto.TrialReadingCriterionId == null && inDto.SystemReadingCriterionId == null)
{ {
return result; return result;
} }
else else if (inDto.TrialReadingCriterionId != null)
{ {
var trialCriterionType = await _readingQuestionCriterionTrial.Where(x => x.Id == inDto.TrialReadingCriterionId).Select(x => x.CriterionType).FirstOrDefaultAsync(); var trialCriterionType = await _readingQuestionCriterionTrial.Where(x => x.Id == inDto.TrialReadingCriterionId).Select(x => x.CriterionType).FirstOrDefaultAsync();
if (trialCriterionType == CriterionType.SelfDefine) if (trialCriterionType == CriterionType.SelfDefine)
@@ -520,8 +534,52 @@ namespace IRaCIS.Application.Services
return result; return result;
} }
else
{
List<string> selectCode = await _systemCriterionDictionaryCodeRepository.Where(x => x.SystemCriterionId == inDto.SystemReadingCriterionId).Select(x => x.Code).ToListAsync();
var criterionCode = await _dicRepository.Where(x => x.ConfigDictionary.Code == "Reading_eCRF_Criterion").Select(x => x.Code).ToListAsync();
foreach (var item in criterionCode)
{
if (result.ContainsKey(item))
{
result[item] = new List<BasicDicSelect>();
}
}
var criterionDictionList = await _readingSystemCriterionDictionaryRepository.Where(x => x.CriterionId == inDto.SystemReadingCriterionId).Select(x => new BasicDicSelect()
{
ChildGroup = x.Dictionary.ChildGroup,
Code = x.Dictionary.Code,
Description = x.Dictionary.Description,
DataTypeEnum = x.Dictionary.DataTypeEnum,
ParentChildCodeEnum = x.Dictionary.Parent.ChildCodeEnum,
ShowOrder = x.Dictionary.ShowOrder,
ParentCode = x.ParentCode,
Id = x.DictionaryId,
CrterionDictionaryGroup = x.CrterionDictionaryGroup,
ParentId = x.Dictionary.ParentId,
Value = x.Dictionary.Value,
ValueCN = x.Dictionary.ValueCN
}).ToListAsync();
criterionDictionList = criterionDictionList.Where(x => selectCode.Contains(x.ParentCode)).ToList();
var criterionDic = criterionDictionList.GroupBy(x => x.ParentCode).ToDictionary(g => g.Key, g => g.OrderBy(t => t.ShowOrder).ToList());
foreach (var item in criterionDic)
{
result[item.Key] = item.Value;
}
return result;
}
} }
#region #region
@@ -3,6 +3,7 @@ using DocumentFormat.OpenXml.Presentation;
using DocumentFormat.OpenXml.Spreadsheet; using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces; using IRaCIS.Application.Interfaces;
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Application.Service.Reading.Dto;
@@ -59,7 +60,7 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = await _trialUseRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters() var list = await _trialUseRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters()
.WhereIf(param.UserTypeId != null, t => t.User.UserTypeId == param.UserTypeId) .WhereIf(param.UserTypeId != null, t => t.User.UserTypeId == param.UserTypeId)
.WhereIf(!string.IsNullOrWhiteSpace(param.UserName), t => t.User.UserName.Contains(param.UserName)) .WhereIf(!string.IsNullOrWhiteSpace(param.UserName), t => t.User.UserName.Contains(param.UserName))
@@ -70,8 +71,10 @@ namespace IRaCIS.Core.Application.Service.Common
t => (t.User.FullName).Contains(param.UserRealName)) t => (t.User.FullName).Contains(param.UserRealName))
.ProjectTo<TrialMaintenanceDTO>(_mapper.ConfigurationProvider).ToListAsync(); .ProjectTo<TrialMaintenanceDTO>(_mapper.ConfigurationProvider).ToListAsync();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialUserList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialMaintenanceDTO)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialUserList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialMaintenanceDTO));
@@ -90,7 +93,7 @@ namespace IRaCIS.Core.Application.Service.Common
[HttpPost] [HttpPost]
[AllowAnonymous] [AllowAnonymous]
public async Task<IActionResult> TrialSiteUserListExport(SiteCRCExportQueryDTO param, public async Task<IActionResult> TrialSiteUserListExport(SiteCRCExportQueryDTO param,
[FromServices] IRepository<CommonDocument> _commonDocumentRepository, [FromServices] IRepository<CommonDocument> _commonDocumentRepository,
[FromServices] IDictionaryService _dictionaryService, [FromServices] IDictionaryService _dictionaryService,
[FromServices] IRepository<Trial> _trialRepository, [FromServices] IRepository<Trial> _trialRepository,
[FromServices] IRepository<TrialSiteUser> _trialSiteUserRepository [FromServices] IRepository<TrialSiteUser> _trialSiteUserRepository
@@ -100,21 +103,26 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = await _trialSiteUserRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters() var list = await _trialSiteUserRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters()
.WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted) .WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted)
.WhereIf(!string.IsNullOrWhiteSpace(param.SiteName), t => t.Site.SiteName.Contains(param.SiteName)) .WhereIf(!string.IsNullOrWhiteSpace(param.SiteName), t => t.TrialSite.TrialSiteName.Contains(param.SiteName) || t.TrialSite.TrialSiteAliasName.Contains(param.SiteName))
.WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteAliasName), .WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteAliasName),
t => t.TrialSite.TrialSiteAliasName.Contains(param.TrialSiteAliasName)) t => t.TrialSite.TrialSiteAliasName.Contains(param.TrialSiteAliasName))
.WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteCode), .WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteCode),
t => t.TrialSite.TrialSiteCode.Contains(param.TrialSiteCode)) t => t.TrialSite.TrialSiteCode.Contains(param.TrialSiteCode))
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator,
t => t.UserId == _userInfo.Id) t => t.UserId == _userInfo.Id)
.WhereIf(!string.IsNullOrWhiteSpace(param.UserKeyInfo), t => (t.User.FullName).Contains(param.UserKeyInfo) .WhereIf(!string.IsNullOrWhiteSpace(param.UserKeyInfo), t => (t.User.FullName).Contains(param.UserKeyInfo)
|| t.User.UserName.Contains(param.UserKeyInfo) || t.User.EMail.Contains(param.UserKeyInfo)) || t.User.UserName.Contains(param.UserKeyInfo) || t.User.EMail.Contains(param.UserKeyInfo))
.ProjectTo<SiteUserExportDTO>(_mapper.ConfigurationProvider).ToListAsync(); .ProjectTo<SiteUserExportDTO>(_mapper.ConfigurationProvider).ToListAsync();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteUserList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SiteUserExportDTO)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteUserList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SiteUserExportDTO));
} }
@@ -145,9 +153,9 @@ namespace IRaCIS.Core.Application.Service.Common
var groupSelectIdQuery = var groupSelectIdQuery =
_trialSiteSurveyRepository.Where(t => t.TrialId == queryParam.TrialId) _trialSiteSurveyRepository.Where(t => t.TrialId == queryParam.TrialId)
.WhereIf(queryParam.SiteId != null, t => t.SiteId == queryParam.SiteId) .WhereIf(queryParam.TrialSiteId != null, t => t.TrialSiteId == queryParam.TrialSiteId)
.WhereIf(!string.IsNullOrEmpty(queryParam.FormWriterKeyInfo), t => (t.UserName).Contains(queryParam.FormWriterKeyInfo) || t.Email.Contains(queryParam.FormWriterKeyInfo) || t.Phone.Contains(queryParam.FormWriterKeyInfo)) .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) .GroupBy(t => t.TrialSiteId)
.Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First()); .Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First());
@@ -161,13 +169,14 @@ namespace IRaCIS.Core.Application.Service.Common
.WhereIf(!string.IsNullOrEmpty(queryParam.OrganizationName), t => t.OrganizationName.Contains(queryParam.OrganizationName)) .WhereIf(!string.IsNullOrEmpty(queryParam.OrganizationName), t => t.OrganizationName.Contains(queryParam.OrganizationName))
.ProjectTo<TrialSiteUserSummaryDto>(_mapper.ConfigurationProvider); .ProjectTo<TrialSiteUserSummaryDto>(_mapper.ConfigurationProvider);
data.List = await query.ToListAsync(); var list = await query.ToListAsync();
data.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
var exportInfo = data; var exportInfo = data;
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteUserSummary_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialSiteUserSummaryDto)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteUserSummary_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialSiteUserSummaryDto));
} }
@@ -213,7 +222,7 @@ namespace IRaCIS.Core.Application.Service.Common
var list = await _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId) var list = await _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId)
.Where(t => t.Subject.FinalSubjectVisitId != null ? t.VisitNum <= t.Subject.FinalSubjectVisit.VisitNum : true) .Where(t => t.Subject.FinalSubjectVisitId != null ? t.VisitNum <= t.Subject.FinalSubjectVisit.VisitNum : true)
.WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId) .WhereIf(visitSearchDTO.TrialSiteId != null, t => t.TrialSiteId == visitSearchDTO.TrialSiteId)
.WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId) .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId)
.WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => t.Subject.Code.Contains(visitSearchDTO.SubjectInfo)) .WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => t.Subject.Code.Contains(visitSearchDTO.SubjectInfo))
@@ -230,8 +239,9 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == visitSearchDTO.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == visitSearchDTO.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialCRCUploadImageList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CRCVisitExportDTO)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialCRCUploadImageList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CRCVisitExportDTO));
@@ -265,7 +275,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.WhereIf(challengeQuery.ChallengeState != null, t => t.SubjectVisit.ChallengeState == challengeQuery.ChallengeState) //.WhereIf(challengeQuery.ChallengeState != null, t => t.SubjectVisit.ChallengeState == challengeQuery.ChallengeState)
.WhereIf(challengeQuery.ReuploadEnum != null, t => t.ReuploadEnum == challengeQuery.ReuploadEnum) .WhereIf(challengeQuery.ReuploadEnum != null, t => t.ReuploadEnum == challengeQuery.ReuploadEnum)
.WhereIf(challengeQuery.IsClosed != null, t => t.IsClosed == challengeQuery.IsClosed) .WhereIf(challengeQuery.IsClosed != null, t => t.IsClosed == challengeQuery.IsClosed)
.WhereIf(challengeQuery.SiteId != null, t => t.SubjectVisit.SiteId == challengeQuery.SiteId) .WhereIf(challengeQuery.TrialSiteId != null, t => t.SubjectVisit.TrialSiteId == challengeQuery.TrialSiteId)
.WhereIf(challengeQuery.SubjectId != null, t => t.SubjectVisit.SubjectId == challengeQuery.SubjectId) .WhereIf(challengeQuery.SubjectId != null, t => t.SubjectVisit.SubjectId == challengeQuery.SubjectId)
.WhereIf(challengeQuery.CreateUserId != null, t => t.CreateUserId == challengeQuery.CreateUserId) .WhereIf(challengeQuery.CreateUserId != null, t => t.CreateUserId == challengeQuery.CreateUserId)
.WhereIf(!string.IsNullOrEmpty(challengeQuery.SubjectCode), t => t.SubjectVisit.Subject.Code.Contains(challengeQuery.SubjectCode)) .WhereIf(!string.IsNullOrEmpty(challengeQuery.SubjectCode), t => t.SubjectVisit.Subject.Code.Contains(challengeQuery.SubjectCode))
@@ -280,8 +290,9 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == challengeQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == challengeQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialQCImageChanllengeList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCChanllengeExportDto)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialQCImageChanllengeList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCChanllengeExportDto));
} }
@@ -307,7 +318,7 @@ namespace IRaCIS.Core.Application.Service.Common
.WhereIf(!string.IsNullOrWhiteSpace(param.Name), t => t.ShortName.Contains(param.Name)) .WhereIf(!string.IsNullOrWhiteSpace(param.Name), t => t.ShortName.Contains(param.Name))
.WhereIf(!string.IsNullOrWhiteSpace(param.Sex), t => t.Sex.Contains(param.Sex)) .WhereIf(!string.IsNullOrWhiteSpace(param.Sex), t => t.Sex.Contains(param.Sex))
.WhereIf(param.Status != null, t => t.Status == param.Status) .WhereIf(param.Status != null, t => t.Status == param.Status)
.WhereIf(param.SiteId != null, t => t.SiteId == param.SiteId) .WhereIf(param.TrialSiteId != null, t => t.TrialSiteId == param.TrialSiteId)
// CRC 只负责他管理site的受试者 // CRC 只负责他管理site的受试者
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.ProjectTo<SubjectExportDTO>(_mapper.ConfigurationProvider).ToListAsync(); .ProjectTo<SubjectExportDTO>(_mapper.ConfigurationProvider).ToListAsync();
@@ -317,8 +328,9 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectExportDTO)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectExportDTO));
@@ -425,8 +437,9 @@ namespace IRaCIS.Core.Application.Service.Common
exportInfo.CriterionName = await _repository.Where<ReadingQuestionCriterionTrial>(u => u.TrialId == dto.TrialId && u.IsConfirm && u.Id == dto.TrialReadingCriterionId).Select(t => t.CriterionName).FirstOrDefaultAsync(); exportInfo.CriterionName = await _repository.Where<ReadingQuestionCriterionTrial>(u => u.TrialId == dto.TrialId && u.IsConfirm && u.Id == dto.TrialReadingCriterionId).Select(t => t.CriterionName).FirstOrDefaultAsync();
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(StaticData.Export.TrialSubjectProgressList_Export, exportInfo, /*"", */_commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectProgressDto)); var (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(StaticData.Export.TrialSubjectProgressList_Export, exportInfo, /*"", */_commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectProgressDto));
@@ -491,7 +504,7 @@ namespace IRaCIS.Core.Application.Service.Common
} }
var memoryStream2 = new MemoryStream(); var memoryStream2 = new MemoryStream();
wb.Write(memoryStream2,true); wb.Write(memoryStream2, true);
memoryStream2.Seek(0, SeekOrigin.Begin); memoryStream2.Seek(0, SeekOrigin.Begin);
return new FileStreamResult(memoryStream2, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") return new FileStreamResult(memoryStream2, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
@@ -519,16 +532,16 @@ namespace IRaCIS.Core.Application.Service.Common
var svExpression = QCCommon.GetStudyMonitorSubjectVisitFilter(studyQuery.VisitPlanArray); var svExpression = QCCommon.GetStudyMonitorSubjectVisitFilter(studyQuery.VisitPlanArray);
var StudyMonitorQuery = _repository.Where<StudyMonitor>(t => t.TrialId == studyQuery.TrialId) var StudyMonitorQuery = _repository.Where<StudyMonitor>(t => t.TrialId == studyQuery.TrialId)
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.Subject.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression) .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression)
.WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo))
.WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId) .WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId)
.WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId) .WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId)
.WhereIf(studyQuery.SiteId != null, t => t.SiteId == studyQuery.SiteId) .WhereIf(studyQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == studyQuery.TrialSiteId)
.Select(t => new UnionStudyMonitorExportDto() .Select(t => new UnionStudyMonitorExportDto()
{ {
TrialSiteCode = t.TrialSite.TrialSiteCode, TrialSiteCode = t.Subject.TrialSite.TrialSiteCode,
TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, TrialSiteAliasName = t.Subject.TrialSite.TrialSiteAliasName,
SubjectCode = t.Subject.Code, SubjectCode = t.Subject.Code,
@@ -565,8 +578,9 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == studyQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == studyQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialStudyUploadMonitor_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(UnionStudyMonitorExportDto)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialStudyUploadMonitor_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(UnionStudyMonitorExportDto));
@@ -601,8 +615,9 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectReadingPeriodList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReadPeriodExportDto)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectReadingPeriodList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReadPeriodExportDto));
@@ -627,7 +642,7 @@ namespace IRaCIS.Core.Application.Service.Common
var svExpression = QCCommon.GetDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray); var svExpression = QCCommon.GetDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray);
var dicomStudyQuery = _repository.Where<DicomStudy>(t => t.TrialId == studyQuery.TrialId) var dicomStudyQuery = _repository.Where<DicomStudy>(t => t.TrialId == studyQuery.TrialId)
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.Subject.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression) .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression)
.WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo))
.Where(x => x.SubjectVisit.AuditState == AuditStateEnum.QCPassed) .Where(x => x.SubjectVisit.AuditState == AuditStateEnum.QCPassed)
@@ -641,9 +656,9 @@ namespace IRaCIS.Core.Application.Service.Common
StudyCode = t.StudyCode, StudyCode = t.StudyCode,
StudyTime = t.StudyTime, StudyTime = t.StudyTime,
TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, TrialSiteAliasName = t.Subject.TrialSite.TrialSiteAliasName,
TrialSiteCode = t.TrialSite.TrialSiteCode, TrialSiteCode = t.Subject.TrialSite.TrialSiteCode,
CheckState = t.SubjectVisit.CheckState, CheckState = t.SubjectVisit.CheckState,
//Uploader = t.Uploader.UserName, //Uploader = t.Uploader.UserName,
@@ -655,7 +670,7 @@ namespace IRaCIS.Core.Application.Service.Common
var nodeDicomStudyQuery = _repository.Where<NoneDicomStudy>(t => t.TrialId == studyQuery.TrialId) var nodeDicomStudyQuery = _repository.Where<NoneDicomStudy>(t => t.TrialId == studyQuery.TrialId)
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.Subject.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression2) .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression2)
.WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo))
.Where(x => x.SubjectVisit.AuditState == AuditStateEnum.QCPassed) .Where(x => x.SubjectVisit.AuditState == AuditStateEnum.QCPassed)
@@ -670,9 +685,9 @@ namespace IRaCIS.Core.Application.Service.Common
StudyCode = t.StudyCode, StudyCode = t.StudyCode,
StudyTime = t.ImageDate, StudyTime = t.ImageDate,
TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, TrialSiteAliasName = t.Subject.TrialSite.TrialSiteAliasName,
TrialSiteCode = t.TrialSite.TrialSiteCode, TrialSiteCode = t.Subject.TrialSite.TrialSiteCode,
CheckState = t.SubjectVisit.CheckState, CheckState = t.SubjectVisit.CheckState,
@@ -690,8 +705,9 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == studyQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == studyQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialStudyList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(UnionStudyExportDTO)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialStudyList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(UnionStudyExportDTO));
} }
@@ -719,7 +735,7 @@ namespace IRaCIS.Core.Application.Service.Common
var list = await _subjectVisitRepository.Where(x => x.TrialId == checkQuery.TrialId) var list = await _subjectVisitRepository.Where(x => x.TrialId == checkQuery.TrialId)
.Where(x => x.AuditState == AuditStateEnum.QCPassed) //一致性核查中的,或者还没一致性核查的 .Where(x => x.AuditState == AuditStateEnum.QCPassed) //一致性核查中的,或者还没一致性核查的
.WhereIf(checkQuery.CheckState != null, t => t.CheckState == checkQuery.CheckState) .WhereIf(checkQuery.CheckState != null, t => t.CheckState == checkQuery.CheckState)
.WhereIf(checkQuery.SiteId != null, t => t.SiteId == checkQuery.SiteId) .WhereIf(checkQuery.TrialSiteId != null, t => t.TrialSiteId == checkQuery.TrialSiteId)
.WhereIf(!string.IsNullOrEmpty(checkQuery.SubjectInfo), t => t.Subject.Code.Contains(checkQuery.SubjectInfo)) .WhereIf(!string.IsNullOrEmpty(checkQuery.SubjectInfo), t => t.Subject.Code.Contains(checkQuery.SubjectInfo))
.WhereIf(checkQuery.VisitPlanArray != null && checkQuery.VisitPlanArray?.Length > 0, svExpression) .WhereIf(checkQuery.VisitPlanArray != null && checkQuery.VisitPlanArray?.Length > 0, svExpression)
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))//CRC 过滤负责的site .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))//CRC 过滤负责的site
@@ -729,8 +745,9 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == checkQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == checkQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectVisitCheckList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(PMKCheckEXportDTO)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectVisitCheckList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(PMKCheckEXportDTO));
} }
@@ -756,7 +773,8 @@ namespace IRaCIS.Core.Application.Service.Common
//.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null) //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null)
.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum)
.WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -780,8 +798,9 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialReadingTaskList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReadingTaskExportDto)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialReadingTaskList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReadingTaskExportDto));
} }
@@ -808,7 +827,7 @@ namespace IRaCIS.Core.Application.Service.Common
var list = await _repository.Where<VisitTaskReReading>(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/) var list = await _repository.Where<VisitTaskReReading>(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/)
.WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId) .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId)
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!))
.WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState) .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState)
.WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId)
@@ -831,8 +850,9 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialReReadingTaskList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReReadingTaskExportDto)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialReReadingTaskList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReReadingTaskExportDto));
} }
@@ -855,7 +875,7 @@ namespace IRaCIS.Core.Application.Service.Common
{ {
var list = await _repository.Where<TaskMedicalReview>(t => t.VisitTask.TrialId == inQuery.TrialId) var list = await _repository.Where<TaskMedicalReview>(t => t.VisitTask.TrialId == inQuery.TrialId)
.WhereIf(inQuery.SiteId != null, t => t.VisitTask.Subject.SiteId == inQuery.SiteId) .WhereIf(inQuery.TrialSiteId != null, t => t.VisitTask.Subject.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId) .WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode)) .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName)) .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName))
@@ -865,7 +885,7 @@ namespace IRaCIS.Core.Application.Service.Common
.WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory) .WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory)
.WhereIf(inQuery.ReadingTaskState != null, t => t.VisitTask.ReadingTaskState == inQuery.ReadingTaskState) .WhereIf(inQuery.ReadingTaskState != null, t => t.VisitTask.ReadingTaskState == inQuery.ReadingTaskState)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.ProjectTo<TaskMedicalReviewExportDto>(_mapper.ConfigurationProvider).ToListAsync(); .ProjectTo<TaskMedicalReviewExportDto>(_mapper.ConfigurationProvider).ToListAsync();
list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList();
@@ -873,8 +893,9 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialMedicalReviewList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TaskMedicalReviewExportDto)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialMedicalReviewList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TaskMedicalReviewExportDto));
} }
@@ -915,7 +936,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) //.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -941,7 +962,7 @@ namespace IRaCIS.Core.Application.Service.Common
foreach (var item in list) foreach (var item in list)
{ {
//找到一致性分析的结果 //找到一致性分析的结果
var selfAnalysisTask = allList.Where(t => t.IsSelfAnalysis == true && t.SubjectCode == item.SubjectCode && t.VisitTaskNum == item.VisitTaskNum && t.TaskName == t.TaskName).FirstOrDefault(); var selfAnalysisTask = allList.Where(t => t.IsSelfAnalysis == true && t.SubjectCode == item.SubjectCode && t.VisitTaskNum == item.VisitTaskNum && t.TaskName == t.TaskName && t.UserName == item.UserName).FirstOrDefault();
//因为基线的评估结果是 是否存在疾病 而 其他访视的结果是 整体肿瘤评估结果 是用不同的枚举翻译的 所以这里手动翻译 不把翻译逻辑耦合到通用的翻译代码里面 在此特殊处理 //因为基线的评估结果是 是否存在疾病 而 其他访视的结果是 整体肿瘤评估结果 是用不同的枚举翻译的 所以这里手动翻译 不把翻译逻辑耦合到通用的翻译代码里面 在此特殊处理
@@ -957,8 +978,9 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.CriterionName = await _repository.Where<ReadingQuestionCriterionTrial>(u => u.TrialId == queryVisitTask.TrialId && u.IsConfirm && u.Id == queryVisitTask.TrialReadingCriterionId).Select(t => t.CriterionName).FirstOrDefaultAsync(); exportInfo.CriterionName = await _repository.Where<ReadingQuestionCriterionTrial>(u => u.TrialId == queryVisitTask.TrialId && u.IsConfirm && u.Id == queryVisitTask.TrialReadingCriterionId).Select(t => t.CriterionName).FirstOrDefaultAsync();
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSelfAnalysisList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SelftAnalysisExport)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSelfAnalysisList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SelftAnalysisExport));
} }
@@ -998,7 +1020,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) //.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -1014,7 +1036,7 @@ namespace IRaCIS.Core.Application.Service.Common
.ProjectTo<GroupAnalysisExport>(_mapper.ConfigurationProvider).ToListAsync(); .ProjectTo<GroupAnalysisExport>(_mapper.ConfigurationProvider).ToListAsync();
//找到原任务(非组间一致性分析的)
var list = allList.Where(t => t.IsSelfAnalysis == null).OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); var list = allList.Where(t => t.IsSelfAnalysis == null).OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList();
@@ -1060,8 +1082,9 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.CriterionName = await _repository.Where<ReadingQuestionCriterionTrial>(u => u.TrialId == queryVisitTask.TrialId && u.IsConfirm && u.Id == queryVisitTask.TrialReadingCriterionId).Select(t => t.CriterionName).FirstOrDefaultAsync(); exportInfo.CriterionName = await _repository.Where<ReadingQuestionCriterionTrial>(u => u.TrialId == queryVisitTask.TrialId && u.IsConfirm && u.Id == queryVisitTask.TrialReadingCriterionId).Select(t => t.CriterionName).FirstOrDefaultAsync();
exportInfo.List = newList; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(newList, _userInfo.TimeZoneId); ;
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialGroupAnalysisList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(GroupAnalysisExport)); return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialGroupAnalysisList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(GroupAnalysisExport));
} }
@@ -1128,30 +1151,41 @@ namespace IRaCIS.Core.Application.Service.Common
{ {
//处理裁判标记 //处理裁判标记
var resultList = list.Where(t => t.ReadingCategory != ReadingCategory.Judge).ToList();
if (arbitrationRule == ArbitrationRule.Visit)
{ {
var resultList = list.Where(t => t.ReadingCategory != ReadingCategory.Judge).ToList();
if (arbitrationRule == ArbitrationRule.Visit) foreach (var item in resultList)
{ {
item.IsGenerateJudge = list.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode
foreach (var item in resultList) && (t.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Judge]) == item.VisitTaskNum)?.JudgeArmEnum == item.ArmEnum ? true : false;
{
item.IsGenerateJudge = list.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode
&& (t.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Judge]) == item.VisitTaskNum)?.JudgeArmEnum == item.ArmEnum ? true : false;
}
}
if (arbitrationRule == ArbitrationRule.Reading)
{
foreach (var item in resultList)
{
item.IsGenerateJudge = list.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode && t.VisitTaskNum>item.VisitTaskNum
).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault()?.JudgeArmEnum == item.ArmEnum ? true : false;
}
} }
return resultList;
} }
if (arbitrationRule == ArbitrationRule.Reading)
{
foreach (var item in resultList)
{
item.IsGenerateJudge = list.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode && t.VisitTaskNum > item.VisitTaskNum
).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault()?.JudgeArmEnum == item.ArmEnum ? true : false;
}
}
//如果没有产生裁判,默认选择R1
//找到没有裁判的访视任务
var notJudgeList = resultList.GroupBy(t => new { t.SubjectCode, t.VisitTaskNum }).Where(g => g.All(t => t.IsGenerateJudge == false)).Select(g => new { g.Key.SubjectCode, g.Key.VisitTaskNum }).ToList();
foreach (var item in resultList)
{
if (notJudgeList.Any(t => t.SubjectCode == item.SubjectCode && t.VisitTaskNum == item.VisitTaskNum) && item.ArmEnum == Arm.DoubleReadingArm1)
{
item.IsGenerateJudge = true;
}
}
return resultList;
} }
@@ -1190,7 +1224,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) //.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -1205,7 +1239,7 @@ namespace IRaCIS.Core.Application.Service.Common
.WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1))
.ProjectTo<OverallTumorEvaluationExport>(_mapper.ConfigurationProvider, new { criterionType = criterion.CriterionType }).ToListAsync(); .ProjectTo<OverallTumorEvaluationExport>(_mapper.ConfigurationProvider, new { criterionType = criterion.CriterionType }).ToListAsync();
list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.ArmEnum).ThenBy(t => t.VisitTaskNum).ToList();
var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.CriterionName = criterion.CriterionName; exportInfo.CriterionName = criterion.CriterionName;
@@ -1213,8 +1247,9 @@ namespace IRaCIS.Core.Application.Service.Common
//处理裁判标记 //处理裁判标记
list = DealJudgeMark(criterion.ArbitrationRule, list); list = DealJudgeMark(criterion.ArbitrationRule, list);
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.OverallTumorEvaluation_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(OverallTumorEvaluationExport), criterion.CriterionType); return await ExcelExportHelper.DataExportAsync(StaticData.Export.OverallTumorEvaluation_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(OverallTumorEvaluationExport), criterion.CriterionType);
@@ -1246,7 +1281,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) //.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -1267,13 +1302,14 @@ namespace IRaCIS.Core.Application.Service.Common
{ {
var list = await query.ProjectTo<RECIST1Point1EvaluationOfTumorEfficacyExport>(_mapper.ConfigurationProvider, new { criterionType = criterion.CriterionType }).ToListAsync(); var list = await query.ProjectTo<RECIST1Point1EvaluationOfTumorEfficacyExport>(_mapper.ConfigurationProvider, new { criterionType = criterion.CriterionType }).ToListAsync();
list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.ArmEnum).ThenBy(t => t.VisitTaskNum).ToList();
//处理裁判标记 //处理裁判标记
list = DealJudgeMark(criterion.ArbitrationRule, list); list = DealJudgeMark(criterion.ArbitrationRule, list);
exportInfo.List = list; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.RECIST1Point1EvaluationOfTumorEfficacy_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(RECIST1Point1EvaluationOfTumorEfficacyExport), criterion.CriterionType); return await ExcelExportHelper.DataExportAsync(StaticData.Export.RECIST1Point1EvaluationOfTumorEfficacy_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(RECIST1Point1EvaluationOfTumorEfficacyExport), criterion.CriterionType);
@@ -1305,7 +1341,7 @@ namespace IRaCIS.Core.Application.Service.Common
{ {
//每次查询必须是单标准的 //每次查询必须是单标准的
var criterion = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionName,t.ArbitrationRule }).FirstOrDefaultAsync(); var criterion = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionName, t.ArbitrationRule }).FirstOrDefaultAsync();
var query = _repository.Where<VisitTask>(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned) var query = _repository.Where<VisitTask>(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned)
@@ -1314,7 +1350,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) //.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -1335,7 +1371,7 @@ namespace IRaCIS.Core.Application.Service.Common
{ {
var list = await query.ProjectTo<RECIST1Point1DetailedOfEvaluatedLesionExport>(_mapper.ConfigurationProvider, new { criterionType = criterion.CriterionType, isEn_Us = _userInfo.IsEn_Us }).ToListAsync(); var list = await query.ProjectTo<RECIST1Point1DetailedOfEvaluatedLesionExport>(_mapper.ConfigurationProvider, new { criterionType = criterion.CriterionType, isEn_Us = _userInfo.IsEn_Us }).ToListAsync();
list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.ArmEnum).ThenBy(t => t.VisitTaskNum).ToList();
var exportList = list.SelectMany(c => var exportList = list.SelectMany(c =>
{ {
@@ -1345,6 +1381,7 @@ namespace IRaCIS.Core.Application.Service.Common
var clone = c.Clone(); var clone = c.Clone();
clone.LessionCode = u.LessionCode; clone.LessionCode = u.LessionCode;
clone.LessionType = u.LessionType; clone.LessionType = u.LessionType;
clone.BeforeTranslateLessionTypeValue = u.LessionType;
clone.IsLymph = u.IsLymph; clone.IsLymph = u.IsLymph;
@@ -1363,8 +1400,9 @@ namespace IRaCIS.Core.Application.Service.Common
//处理裁判标记 //处理裁判标记
list = DealJudgeMark(criterion.ArbitrationRule, list); list = DealJudgeMark(criterion.ArbitrationRule, list);
exportInfo.List = exportList; exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(exportList, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.RECIST1Point1DetailedOfEvaluatedLesion_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(RECIST1Point1DetailedOfEvaluatedLesionExport), criterion.CriterionType); return await ExcelExportHelper.DataExportAsync(StaticData.Export.RECIST1Point1DetailedOfEvaluatedLesion_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(RECIST1Point1DetailedOfEvaluatedLesionExport), criterion.CriterionType);
@@ -1396,8 +1434,10 @@ namespace IRaCIS.Core.Application.Service.Common
//处理裁判标记 //处理裁判标记
list = DealJudgeMark(criterion.ArbitrationRule, list); list = DealJudgeMark(criterion.ArbitrationRule, list);
exportInfo.List = exportList;
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(exportList, _userInfo.TimeZoneId); ;
exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.PCWG3Point1DetailedOfEvaluatedLesion_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(PCWG3DetailedOfEvaluatedLesionExport), criterion.CriterionType); return await ExcelExportHelper.DataExportAsync(StaticData.Export.PCWG3Point1DetailedOfEvaluatedLesion_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(PCWG3DetailedOfEvaluatedLesionExport), criterion.CriterionType);
@@ -10,6 +10,8 @@ using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using EasyCaching.Core;
using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.Application.Service namespace IRaCIS.Core.Application.Service
{ {
@@ -19,28 +21,77 @@ namespace IRaCIS.Core.Application.Service
[ApiExplorerSettings(GroupName = "Common")] [ApiExplorerSettings(GroupName = "Common")]
public class InternationalizationService : BaseService, IInternationalizationService public class InternationalizationService : BaseService, IInternationalizationService
{ {
private readonly IEasyCachingProvider _provider;
private readonly IRepository<Internationalization> _internationalizationRepository; private readonly IRepository<Internationalization> _internationalizationRepository;
public InternationalizationService(IRepository<Internationalization> internationalizationRepository) public InternationalizationService(IRepository<Internationalization> internationalizationRepository, IEasyCachingProvider provider)
{ {
_internationalizationRepository = internationalizationRepository; _internationalizationRepository = internationalizationRepository;
_provider = provider;
} }
/// <summary>
/// 前端国际化内容接口
/// </summary>
/// <returns></returns>
[AllowAnonymous] [AllowAnonymous]
[HttpGet]
public async Task<List<InternationalizationSimpleDto>> GetFrontInternationalizationList() 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)
//{
// return cacheList;
//}
//else
{ {
Code = t.Code, var list = await _internationalizationRepository.Where(t => t.InternationalizationType == 0).Select(t => new InternationalizationSimpleDto()
Value = t.Value, {
ValueCN = t.ValueCN Code = t.Code,
}).ToListAsync(); 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] [HttpPost]
@@ -63,6 +114,11 @@ namespace IRaCIS.Core.Application.Service
return pageList; return pageList;
} }
/// <summary>
/// 后端之前批量添加接口
/// </summary>
/// <param name="batchAdd"></param>
/// <returns></returns>
[HttpPost] [HttpPost]
public async Task<IResponseOutput> BatchAddInternationalization(BatchAddInternationalization batchAdd) public async Task<IResponseOutput> BatchAddInternationalization(BatchAddInternationalization batchAdd)
{ {
@@ -87,29 +143,50 @@ namespace IRaCIS.Core.Application.Service
await _internationalizationRepository.SaveChangesAsync(); await _internationalizationRepository.SaveChangesAsync();
//清理缓存
_provider.Set<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front, new List<InternationalizationSimpleDto>(), TimeSpan.FromDays(1));
return ResponseOutput.Ok(); return ResponseOutput.Ok();
} }
/// <summary>
/// 前后端添加的时候,区分了,前端判断重复多了多了一个路由 路由+标识唯一
/// </summary>
/// <param name="addOrEditInternationalization"></param>
/// <returns></returns>
public async Task<IResponseOutput> AddOrUpdateInternationalization(InternationalizationAddOrEdit addOrEditInternationalization) public async Task<IResponseOutput> AddOrUpdateInternationalization(InternationalizationAddOrEdit addOrEditInternationalization)
{ {
var internationalizationType = addOrEditInternationalization.InternationalizationType;
//后端验证标识重复与否
var verifyExp1 = new EntityVerifyExp<Internationalization>() var verifyExp1 = new EntityVerifyExp<Internationalization>()
{ {
VerifyExp = t => t.Code == addOrEditInternationalization.Code && t.InternationalizationType == addOrEditInternationalization.InternationalizationType, VerifyExp = t => t.Code == addOrEditInternationalization.Code && t.InternationalizationType == addOrEditInternationalization.InternationalizationType,
VerifyMsg = $"该类型已有{addOrEditInternationalization.Code}名称的国际化标识", VerifyMsg = $"该类型已有{addOrEditInternationalization.Code}名称的国际化标识",
IsVerify = true IsVerify = true /*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) if (addOrEditInternationalization.InternationalizationType == 1)
{ {
await InternationalizationHelper.AddOrUpdateJsonKeyValueAsync(entity.Code, addOrEditInternationalization.Value, addOrEditInternationalization.ValueCN); await InternationalizationHelper.AddOrUpdateJsonKeyValueAsync(entity.Code, addOrEditInternationalization.Value, addOrEditInternationalization.ValueCN);
} }
else
{
//清理缓存
_provider.Set<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front, new List<InternationalizationSimpleDto>(), TimeSpan.FromDays(1));
}
return ResponseOutput.Ok(entity.Id.ToString()); return ResponseOutput.Ok(entity.Id.ToString());
} }
@@ -119,6 +196,9 @@ namespace IRaCIS.Core.Application.Service
public async Task<IResponseOutput> DeleteInternationalization(Guid internationalizationId) public async Task<IResponseOutput> DeleteInternationalization(Guid internationalizationId)
{ {
var success = await _internationalizationRepository.DeleteFromQueryAsync(t => t.Id == internationalizationId, true); 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(); return ResponseOutput.Ok();
} }
@@ -8,6 +8,7 @@ using AutoMapper;
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Medallion.Threading; using Medallion.Threading;
using System.Text.RegularExpressions;
namespace IRaCIS.Application.Services namespace IRaCIS.Application.Services
{ {
@@ -20,6 +21,8 @@ namespace IRaCIS.Application.Services
Task SiteSurveyRejectEmail(MimeMessage messageToSend); Task SiteSurveyRejectEmail(MimeMessage messageToSend);
Task SenMFAVerifyEmail(Guid userId, string userName, string emailAddress, int verificationCode, UserMFAType mfaType = UserMFAType.Login);
Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode); Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode);
Task AnolymousSendEmailForResetAccount(string emailAddress, int verificationCode); Task AnolymousSendEmailForResetAccount(string emailAddress, int verificationCode);
@@ -58,7 +61,7 @@ namespace IRaCIS.Application.Services
public MailVerificationService(IRepository<VerificationCode> verificationCodeRepository, public MailVerificationService(IRepository<VerificationCode> verificationCodeRepository,
IRepository<SystemBasicData> systemBasicDatarepository, IRepository<SystemBasicData> systemBasicDatarepository,
IRepository<User> userRepository, IRepository<User> userRepository,
ITokenService tokenService, ITokenService tokenService,
@@ -70,9 +73,6 @@ namespace IRaCIS.Application.Services
_systemEmailConfig = systemEmailConfig.CurrentValue; _systemEmailConfig = systemEmailConfig.CurrentValue;
_verificationCodeRepository = verificationCodeRepository; _verificationCodeRepository = verificationCodeRepository;
_systemBasicDatarepository = systemBasicDatarepository; _systemBasicDatarepository = systemBasicDatarepository;
_tokenService = tokenService; _tokenService = tokenService;
_userRepository = userRepository; _userRepository = userRepository;
_trialRepository = trialRepository; _trialRepository = trialRepository;
@@ -80,6 +80,77 @@ namespace IRaCIS.Application.Services
_userTypeRepository = userTypeRepository; _userTypeRepository = userTypeRepository;
_doctorTypeRepository = doctorTypeRepository; _doctorTypeRepository = doctorTypeRepository;
_distributedLockProvider = distributedLockProvider; _distributedLockProvider = distributedLockProvider;
}
private string ReplaceCompanyName(string needDealtxt)
{
var str= needDealtxt.Replace("{company}", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyName : _systemEmailConfig.CompanyNameCN)
.Replace("{company abbreviation}", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN);
return str;
}
//MFA
public async Task SenMFAVerifyEmail(Guid userId, string userName, string emailAddress, int verificationCode, UserMFAType mfaType = UserMFAType.Login)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(userName, emailAddress));
//主题
//---[来自{0}] 关于MFA邮箱验证的提醒
messageToSend.Subject = _localizer[mfaType == UserMFAType.Login? "Mail_EmailMFALoginTopic":"Mail_EmailMFAUnlockTopic", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN];
var builder = new BodyBuilder();
var pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
//+ "UserOptCommon.html";
+ (_userInfo.IsEn_Us ? "UserOptCommon_US.html" : "UserOptCommon.html");
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
userName,
_localizer[mfaType == UserMFAType.Login ? "Mail_EmailMFALoginEmail": "Mail_EmailMFAUnlockEmail"],
verificationCode
);
}
messageToSend.Body = builder.ToMessageBody();
EventHandler<MessageSentEventArgs> sucessHandle = (sender, args) =>
{
// args.Response
var code = verificationCode.ToString();
_ = _verificationCodeRepository.AddAsync(new VerificationCode()
{
CodeType = 0,
HasSend = true,
Code = code,
UserId = userId,
ExpirationTime = DateTime.Now.AddMinutes(3)
}).Result;
_ = _verificationCodeRepository.SaveChangesAsync().Result;
};
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle);
} }
//重置邮箱 //重置邮箱
@@ -95,7 +166,7 @@ namespace IRaCIS.Application.Services
messageToSend.To.Add(new MailboxAddress(userName, emailAddress)); messageToSend.To.Add(new MailboxAddress(userName, emailAddress));
//主题 //主题
//---[来自展影IRC] 关于重置邮箱的提醒 //---[来自展影IRC] 关于重置邮箱的提醒
messageToSend.Subject = _localizer["Mail_EmailResetReminder"]; messageToSend.Subject = _localizer["Mail_EmailResetReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN];
var builder = new BodyBuilder(); var builder = new BodyBuilder();
@@ -112,11 +183,12 @@ namespace IRaCIS.Application.Services
var templateInfo = SourceReader.ReadToEnd(); var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(templateInfo, builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
userName,
//---尊敬的 //---尊敬的
_localizer["Mail_Dear", userName], //_localizer["Mail_Dear", userName],
//---您正在进行邮箱重置操作 //---您正在进行邮箱重置操作
_localizer["Mail_ResettingEmail"], _localizer["Mail_ResettingEmail"],
verificationCode verificationCode
); );
@@ -161,7 +233,7 @@ namespace IRaCIS.Application.Services
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress)); messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
//主题 //主题
//---[来自展影IRC] 关于重置密码的提醒 //---[来自展影IRC] 关于重置密码的提醒
messageToSend.Subject = _localizer["Mail_IRCResettingPassword"]; messageToSend.Subject = _localizer["Mail_IRCResettingPassword", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN];
@@ -179,7 +251,7 @@ namespace IRaCIS.Application.Services
var templateInfo = SourceReader.ReadToEnd(); var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(templateInfo, builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
"", "",
//---您正在进行邮箱重置密码操作 //---您正在进行邮箱重置密码操作
_localizer["Mail_ResettingPassword"], _localizer["Mail_ResettingPassword"],
@@ -229,7 +301,7 @@ namespace IRaCIS.Application.Services
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress)); messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
//主题 //主题
//---[来自展影IRC]的提醒 //---[来自展影IRC]的提醒
messageToSend.Subject = _localizer["Mail_ImagingIRCReminder"]; messageToSend.Subject = _localizer["Mail_ImagingIRCReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN];
@@ -247,9 +319,10 @@ namespace IRaCIS.Application.Services
var templateInfo = SourceReader.ReadToEnd(); var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(templateInfo, builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
"Sir or Madam",
//---您正在参与展影医疗IRC项目 //---您正在参与展影医疗IRC项目
_localizer["Mail_IRCProject"], _localizer["Mail_IRCProject", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN],
verificationCode verificationCode
); );
} }
@@ -294,7 +367,7 @@ namespace IRaCIS.Application.Services
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress)); messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
//主题 //主题
//$"[来自展影IRC] [{researchProgramNo}] 关于中心调研的提醒"; //$"[来自展影IRC] [{researchProgramNo}] 关于中心调研的提醒";
messageToSend.Subject = _localizer["Mail_ProjectParticipationReminder", researchProgramNo]; messageToSend.Subject = _localizer["Mail_ProjectParticipationReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN, researchProgramNo];
@@ -313,10 +386,10 @@ namespace IRaCIS.Application.Services
var templateInfo = SourceReader.ReadToEnd(); var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(templateInfo, builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
"", "Sir or Madam",
//---您正在参与展影医疗IRC项目中心调研工作 //---您正在参与展影医疗IRC项目中心调研工作
_localizer["Mail_CenterResearchReminder"], _localizer["Mail_CenterResearchReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN],
verificationCode verificationCode
); );
} }
@@ -374,7 +447,7 @@ namespace IRaCIS.Application.Services
messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail)); messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail));
//主题 //主题
//---[来自展影IRC] 关于创建账户的提醒 //---[来自展影IRC] 关于创建账户的提醒
messageToSend.Subject = _localizer["Mail_AccountCreationReminder"]; messageToSend.Subject = _localizer["Mail_AccountCreationReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN];
@@ -402,7 +475,7 @@ namespace IRaCIS.Application.Services
var templateInfo = SourceReader.ReadToEnd(); var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(templateInfo, builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
sysUserInfo.FullName, sysUserInfo.FullName,
sysUserInfo.UserName, sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName, sysUserInfo.UserTypeRole.UserTypeShortName,
@@ -430,7 +503,7 @@ namespace IRaCIS.Application.Services
messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail)); messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail));
//主题 //主题
//---[来自展影IRC] 关于重置账户密码的提醒 //---[来自展影IRC] 关于重置账户密码的提醒
messageToSend.Subject = _localizer["Mail_AccountPasswordResetReminder"]; messageToSend.Subject = _localizer["Mail_AccountPasswordResetReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN];
@@ -449,7 +522,7 @@ namespace IRaCIS.Application.Services
var templateInfo = SourceReader.ReadToEnd(); var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(templateInfo, builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
sysUserInfo.FullName, sysUserInfo.FullName,
sysUserInfo.UserName, sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName, sysUserInfo.UserTypeRole.UserTypeShortName,
@@ -480,7 +553,7 @@ namespace IRaCIS.Application.Services
messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail)); messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail));
//主题 //主题
// $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信"; // $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信";
messageToSend.Subject = _localizer["Mail_InvitationEmail", trialInfo.ResearchProgramNo]; messageToSend.Subject = _localizer["Mail_InvitationEmail", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN, trialInfo.ResearchProgramNo];
@@ -511,7 +584,7 @@ namespace IRaCIS.Application.Services
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}"; var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
builder.HtmlBody = string.Format(templateInfo, builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
sysUserInfo.FullName, sysUserInfo.FullName,
trialInfo.ExperimentName, trialInfo.ExperimentName,
trialInfo.ResearchProgramNo, trialInfo.ResearchProgramNo,
@@ -544,7 +617,7 @@ namespace IRaCIS.Application.Services
messageToSend.To.Add(new MailboxAddress(String.Empty, sysUserInfo.EMail)); messageToSend.To.Add(new MailboxAddress(String.Empty, sysUserInfo.EMail));
//主题 //主题
// $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信"; // $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信";
messageToSend.Subject = _localizer["Mail_InvitationEmail", trialInfo.ResearchProgramNo]; messageToSend.Subject = _localizer["Mail_InvitationEmail", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN,trialInfo.ResearchProgramNo];
var builder = new BodyBuilder(); var builder = new BodyBuilder();
@@ -573,7 +646,7 @@ namespace IRaCIS.Application.Services
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}"; var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
builder.HtmlBody = string.Format(templateInfo, builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
sysUserInfo.FullName, sysUserInfo.FullName,
trialInfo.ExperimentName, trialInfo.ExperimentName,
trialInfo.ResearchProgramNo, trialInfo.ResearchProgramNo,
@@ -659,7 +732,7 @@ namespace IRaCIS.Application.Services
messageToSend.To.Add(new MailboxAddress(doctor.FullName, doctor.EMail)); messageToSend.To.Add(new MailboxAddress(doctor.FullName, doctor.EMail));
//主题 //主题
// $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信"; // $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信";
messageToSend.Subject = _localizer["Mail_InvitationEmail", trialInfo.ResearchProgramNo]; messageToSend.Subject = _localizer["Mail_InvitationEmail", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN, trialInfo.ResearchProgramNo];
var builder = new BodyBuilder(); var builder = new BodyBuilder();
@@ -695,7 +768,7 @@ namespace IRaCIS.Application.Services
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}"; var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
builder.HtmlBody = string.Format(templateInfo, builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo),
sysUserInfo.FullName, sysUserInfo.FullName,
trialInfo.ExperimentName, trialInfo.ExperimentName,
trialInfo.ResearchProgramNo, trialInfo.ResearchProgramNo,
@@ -69,6 +69,9 @@ namespace IRaCIS.Core.Application.Service
CreateMap<Internationalization, InternationalizationView>(); CreateMap<Internationalization, InternationalizationView>();
CreateMap<Internationalization, InternationalizationAddOrEdit>().ReverseMap(); CreateMap<Internationalization, InternationalizationAddOrEdit>().ReverseMap();
CreateMap<Internationalization, BatchInternationalizationDto>().ReverseMap();
CreateMap<BatchAddInternationalizationDto, InternationalizationAddOrEdit>(); CreateMap<BatchAddInternationalizationDto, InternationalizationAddOrEdit>();
@@ -182,6 +182,9 @@ namespace IRaCIS.Application.Contracts
public string OptUserName { get; set; } = string.Empty; public string OptUserName { get; set; } = string.Empty;
public DateTime? OptTime { get; set; } public DateTime? OptTime { get; set; }
public string? OptTimeStr => OptTime?.ToString("yyyy-MM-dd HH:mm:ss"); public string? OptTimeStr => OptTime?.ToString("yyyy-MM-dd HH:mm:ss");
public string DoctorUserName { get; set; }
} }
public class DoctorOptDTO public class DoctorOptDTO
@@ -79,7 +79,7 @@ namespace IRaCIS.Application.Services
return ResponseOutput.NotOk(_localizer["Doctor_DupEmail"], new DoctorBasicInfoCommand()); return ResponseOutput.NotOk(_localizer["Doctor_DupEmail"], new DoctorBasicInfoCommand());
} }
doctor.Code = (await _doctorRepository.MaxAsync(t => t.Code)) + 1; doctor.Code = await _doctorRepository.Select(t => t.Code).DefaultIfEmpty().MaxAsync() + 1;
doctor.ReviewerCode = AppSettings.GetCodeStr(doctor.Code, nameof(Doctor)); doctor.ReviewerCode = AppSettings.GetCodeStr(doctor.Code, nameof(Doctor));
@@ -432,11 +432,11 @@ namespace IRaCIS.Application.Services
//判断 合作协议、正式简历 是否有。如果没有,显示提示信息,并且不能保存 //判断 合作协议、正式简历 是否有。如果没有,显示提示信息,并且不能保存
var attachmentList = await _attachmentRepository.Where(u => u.DoctorId == auditResumeParam.Id) var attachmentList = await _attachmentRepository.Where(u => u.DoctorId == auditResumeParam.Id)
.Select(u => u.Type).ToListAsync(); .Select(u => u.Type).ToListAsync();
if (auditResumeParam.ResumeStatus == ResumeStatusEnum.Pass && ((!attachmentList.Contains("Resume")) || (!attachmentList.Contains("Consultant Agreement")))) //if (auditResumeParam.ResumeStatus == ResumeStatusEnum.Pass && ((!attachmentList.Contains("Resume")) || (!attachmentList.Contains("Consultant Agreement"))))
{ //{
//---Resume & Consultant Agreement must be upload // //---Resume & Consultant Agreement must be upload
return ResponseOutput.NotOk(_localizer["Doctor_RequiredDocumentsError"]); // return ResponseOutput.NotOk(_localizer["Doctor_RequiredDocumentsError"]);
} //}
var success = await _doctorRepository.BatchUpdateNoTrackingAsync(o => o.Id == auditResumeParam.Id, u => new Doctor() var success = await _doctorRepository.BatchUpdateNoTrackingAsync(o => o.Id == auditResumeParam.Id, u => new Doctor()
{ {
CooperateStatus = auditResumeParam.CooperateStatus, CooperateStatus = auditResumeParam.CooperateStatus,
@@ -147,12 +147,12 @@ namespace IRaCIS.Application.Services
var successs = await _repository.BatchUpdateAsync<Doctor>(o => o.Id == updateGCPExperienceParam.Id, u => new Doctor() var successs = await _repository.BatchUpdateAsync<Doctor>(o => o.Id == updateGCPExperienceParam.Id, u => new Doctor()
{ {
GCP = updateGCPExperienceParam.GCP, GCP = updateGCPExperienceParam.GCP,
GCPId = updateGCPExperienceParam.GCP==0&&updateGCPExperienceParam.GCPId==null?Guid.Empty: updateGCPExperienceParam.GCPId!.Value GCPId = (updateGCPExperienceParam.GCP==0||updateGCPExperienceParam.GCPId==null)?Guid.Empty: updateGCPExperienceParam.GCPId!.Value
}); });
if (updateGCPExperienceParam.GCP == 0 && updateGCPExperienceParam.GCPId != null) if (updateGCPExperienceParam.GCP == 0 )
{ {
await _repository.BatchDeleteAsync<Attachment>(a => a.Id == updateGCPExperienceParam.GCPId); await _repository.BatchDeleteAsync<Attachment>(a => a.DoctorId == updateGCPExperienceParam.Id && a.Type=="GCP");
} }
return ResponseOutput.Result(successs, updateGCPExperienceParam.GCPId.ToString()); return ResponseOutput.Result(successs, updateGCPExperienceParam.GCPId.ToString());
@@ -60,7 +60,8 @@ namespace IRaCIS.Core.Application.Service
CreateMap<AddOrUpdateDicDTO, Dictionary>().ReverseMap(); CreateMap<AddOrUpdateDicDTO, Dictionary>().ReverseMap();
//医生列表、项目显示列表模型转换 //医生列表、项目显示列表模型转换
CreateMap<DoctorDTO, SelectionReviewerDTO>(); CreateMap<DoctorDTO, SelectionReviewerDTO>()
;
CreateMap<User, UserBasicInfo>() CreateMap<User, UserBasicInfo>()
.ForMember(d => d.UserTypeShortName, u => u.MapFrom(t => t.UserTypeRole.UserTypeShortName)) .ForMember(d => d.UserTypeShortName, u => u.MapFrom(t => t.UserTypeRole.UserTypeShortName))
@@ -80,7 +81,8 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.UserName, u => u.MapFrom(doctor => doctor.LastName + " / " + doctor.FirstName)); .ForMember(d => d.UserName, u => u.MapFrom(doctor => doctor.LastName + " / " + doctor.FirstName));
#region #region
CreateMap<Doctor, SelectionReviewerDTO>(); CreateMap<Doctor, SelectionReviewerDTO>()
.ForMember(d => d.DoctorUserName, u => u.MapFrom(t => t.User.UserName));
CreateMap<Doctor, DoctorDTO>().IncludeMembers(t => t.Hospital).Include<Doctor, SelectionReviewerDTO>() CreateMap<Doctor, DoctorDTO>().IncludeMembers(t => t.Hospital).Include<Doctor, SelectionReviewerDTO>()
.ForMember(d => d.AccountUserName, u => u.MapFrom(s => s.EnrollList.Where(t=>t.DoctorUserId!=null).Select(c=>c.DoctorUser.UserName).FirstOrDefault())) .ForMember(d => d.AccountUserName, u => u.MapFrom(s => s.EnrollList.Where(t=>t.DoctorUserId!=null).Select(c=>c.DoctorUser.UserName).FirstOrDefault()))
.ForMember(d => d.Department, u => u.MapFrom(s => s.Department.Value)) .ForMember(d => d.Department, u => u.MapFrom(s => s.Department.Value))
@@ -121,6 +123,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<Doctor, SpecialtyDTO>() CreateMap<Doctor, SpecialtyDTO>()
.ForMember(o => o.Speciality, t => t.MapFrom(u => u.Speciality.Value)) .ForMember(o => o.Speciality, t => t.MapFrom(u => u.Speciality.Value))
.ForMember(o => o.SpecialityCN, t => t.MapFrom(u => u.Speciality.ValueCN))
.ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder))); .ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)));
CreateMap<SpecialtyCommand, Doctor>(); CreateMap<SpecialtyCommand, Doctor>();
@@ -35,14 +35,25 @@ namespace IRaCIS.Core.Application.Contracts
} }
public class TrialSignDocView:UnionDocumentWithConfirmInfoView
{
public string TrialCode { get; set; }
public string ResearchProgramNo { get; set; }
public string ExperimentName { get; set; }
}
public class UnionDocumentWithConfirmInfoView: UnionDocumentView public class UnionDocumentWithConfirmInfoView: UnionDocumentView
{ {
public DateTime? ConfirmTime { get; set; } public DateTime? ConfirmTime { get; set; }
public Guid? ConfirmUserId { get; set; } public Guid? ConfirmUserId { get; set; }
public bool IsConfirmed => ConfirmTime is not null; public bool IsConfirmed => ConfirmTime != null;
public string UserName { get; set; } = string.Empty; public string UserName { get; set; } = string.Empty;
@@ -101,18 +112,34 @@ namespace IRaCIS.Core.Application.Contracts
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
public bool IsSigned { get; set; }
} }
public class GetNextUnSignDocumentInDto public class GetNextUnSignDocumentInDto
{ {
[NotDefault] public Guid? TrialId { get; set; }
public Guid TrialId { get; set; }
public bool Asc { get; set; } = true; public bool Asc { get; set; } = true;
public string SortField { get; set; } = ""; public string SortField { get; set; } = "";
} }
public class TrialDocQuery : PageInput
{
public Guid? TrialId { get; set; }
public Guid? FileTypeId { get; set; }
public string TrialCode { get; set;} = string.Empty;
public string Name { get; set; } = string.Empty;
public bool IsSigned { get; set; }
}
public class TrialUserDocUnionQuery: PageInput public class TrialUserDocUnionQuery: PageInput
{ {
[NotDefault] [NotDefault]
@@ -144,7 +171,11 @@ namespace IRaCIS.Core.Application.Contracts
public Guid? UserTypeId { get; set; } public Guid? UserTypeId { get; set; }
public Guid? UserId { get; set; } public Guid? UserId { get; set; }
}
public bool? IsConfirmed { get; set; }
public bool? IsDeleted { get; set; }
}
///<summary> SystemDocumentAddOrEdit 列表查询参数模型</summary> ///<summary> SystemDocumentAddOrEdit 列表查询参数模型</summary>
public class SystemDocumentAddOrEdit public class SystemDocumentAddOrEdit
@@ -33,8 +33,10 @@ namespace IRaCIS.Core.Application.Contracts
///<summary>TrialDocumentQuery 列表查询参数模型</summary> ///<summary>TrialDocumentQuery 列表查询参数模型</summary>
public class TrialDocumentQuery : PageInput public class TrialDocumentQuery : PageInput
{ {
public bool? IsDeleted { get; set; }
public Guid? FileTypeId { get; set; }
public Guid? FileTypeId { get; set; } public Guid? UserTypeId { get; set; }
public string Name { get; set; } = String.Empty; public string Name { get; set; } = String.Empty;
@@ -108,6 +108,9 @@ namespace IRaCIS.Core.Application.ViewModel
public bool IsDistinguishCriteria { get; set; } public bool IsDistinguishCriteria { get; set; }
public string SortField { get; set; } = string.Empty;
public bool Asc { get; set; }
} }
@@ -75,7 +75,7 @@ namespace IRaCIS.Core.Application.Service
var taskInfo = await _repository.Where<VisitTask>(t => t.Id == visitTaskId).Select(t => new var taskInfo = await _repository.Where<VisitTask>(t => t.Id == visitTaskId).Select(t => new
{ {
t.Subject.SiteId, t.Subject.TrialSiteId,
t.Trial.ResearchProgramNo, t.Trial.ResearchProgramNo,
t.Subject.TrialSite.TrialSiteCode, t.Subject.TrialSite.TrialSiteCode,
SubjectCode = t.Subject.Code, SubjectCode = t.Subject.Code,
@@ -102,7 +102,7 @@ namespace IRaCIS.Core.Application.Service
return (topicStr, htmlBodyStr, isEn_us, null); return (topicStr, htmlBodyStr, isEn_us, null);
}; };
await SendTrialEmailAsync(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc, taskInfo.SiteId); await SendTrialEmailAsync(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc, taskInfo.TrialSiteId);
} }
else else
{ {
@@ -117,7 +117,7 @@ namespace IRaCIS.Core.Application.Service
return (topicStr, htmlBodyStr, isEn_us, null); return (topicStr, htmlBodyStr, isEn_us, null);
}; };
await SendTrialEmailAsync(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc, taskInfo.SiteId); await SendTrialEmailAsync(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc, taskInfo.TrialSiteId);
} }
@@ -283,9 +283,9 @@ namespace IRaCIS.Core.Application.Service
public async Task SendTrialEmailAsync(Guid trialId, EmailBusinessScenario businessScenario, Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc, Guid? siteId = null, Guid? trialReadingCriterionId = null, Func<TrialEmailNoticeConfig, SMTPEmailConfig, SMTPEmailConfig> emailAttachFunc=null) public async Task SendTrialEmailAsync(Guid trialId, EmailBusinessScenario businessScenario, Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc, Guid? trialSiteId = null, Guid? trialReadingCriterionId = null, Func<TrialEmailNoticeConfig, SMTPEmailConfig, SMTPEmailConfig> emailAttachFunc=null)
{ {
var (trialEmailConfig, sendEmailConfig) = await BuildEmailConfig(trialId, businessScenario, topicAndHtmlFunc, siteId, trialReadingCriterionId); var (trialEmailConfig, sendEmailConfig) = await BuildEmailConfig(trialId, businessScenario, topicAndHtmlFunc, trialSiteId, trialReadingCriterionId);
if (sendEmailConfig != null) if (sendEmailConfig != null)
{ {
@@ -295,14 +295,14 @@ namespace IRaCIS.Core.Application.Service
} }
public async Task<(TrialEmailNoticeConfig?, SMTPEmailConfig?)> BuildEmailConfig(Guid trialId, EmailBusinessScenario businessScenario, Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc, Guid? siteId = null, Guid? trialReadingCriterionId = null) public async Task<(TrialEmailNoticeConfig?, SMTPEmailConfig?)> BuildEmailConfig(Guid trialId, EmailBusinessScenario businessScenario, Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc, Guid? trialSiteId = null, Guid? trialReadingCriterionId = null)
{ {
//找到配置 //找到配置
var trialEmailConfig = await _trialEmailNoticeConfigRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.BusinessScenarioEnum == businessScenario, ignoreQueryFilters: true) var trialEmailConfig = await _trialEmailNoticeConfigRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.BusinessScenarioEnum == businessScenario, ignoreQueryFilters: true)
.Include(t => t.TrialEmailNoticeUserList).Include(t => t.TrialEmailBlackUserList).FirstOrDefaultAsync(); .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); return (null,null);
} }
@@ -333,13 +333,13 @@ namespace IRaCIS.Core.Application.Service
.ToList(); .ToList();
//收件人 有CRC CRA , CRC CRA的账户要按照中心发送 //收件人 有CRC CRA , CRC CRA的账户要按照中心发送
if (siteId == null && toUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA) && onlyToUserId == null) if (trialSiteId == null && toUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA) && onlyToUserId == null)
{ {
throw new BusinessValidationFailedException("当前场景收件人包含CRC CRA,但是没有siteId,请联系后端开发"); throw new BusinessValidationFailedException("当前场景收件人包含CRC CRA,但是没有siteId,请联系后端开发");
} }
if (siteId != null && toUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA)) if (trialSiteId != null && toUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA))
{ {
var curentSiteUserIdList = _repository.Where<TrialSiteUser>(t => t.TrialId == trialId && t.SiteId == siteId).Select(t => t.UserId).ToList(); var curentSiteUserIdList = _repository.Where<TrialSiteUser>(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId).Select(t => t.UserId).ToList();
toUserList = toUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList(); toUserList = toUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList();
} }
@@ -351,9 +351,9 @@ namespace IRaCIS.Core.Application.Service
var copyUserList = allUserList.Where(t => copyUserTypeEnumList.Contains(t.UserTypeEnum)) var copyUserList = allUserList.Where(t => copyUserTypeEnumList.Contains(t.UserTypeEnum))
.Where(t => !blackUserIdList.Contains(t.UserId)).ToList(); .Where(t => !blackUserIdList.Contains(t.UserId)).ToList();
if (siteId != null && copyUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA)) if (trialSiteId != null && copyUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA))
{ {
var curentSiteUserIdList = _repository.Where<TrialSiteUser>(t => t.TrialId == trialId && t.SiteId == siteId).Select(t => t.UserId).ToList(); var curentSiteUserIdList = _repository.Where<TrialSiteUser>(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId).Select(t => t.UserId).ToList();
copyUserList = copyUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList(); copyUserList = copyUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList();
} }
@@ -25,7 +25,10 @@ namespace IRaCIS.Core.Application.Contracts
Task<IResponseOutput> DeleteSystemDocumentAsync(Guid systemDocumentId); Task<IResponseOutput> DeleteSystemDocumentAsync(Guid systemDocumentId);
Task<PageOutput<UnionDocumentWithConfirmInfoView>> getWaitSignSysDocList(SystemDocumentQuery querySystemDocument);
}
}
} }
@@ -23,6 +23,7 @@ namespace IRaCIS.Core.Application.Services
private readonly IRepository<SystemDocConfirmedUser> _systemDocConfirmedUserRepository; private readonly IRepository<SystemDocConfirmedUser> _systemDocConfirmedUserRepository;
public SystemDocumentService( IRepository<SystemDocument> systemDocumentRepository, public SystemDocumentService( IRepository<SystemDocument> systemDocumentRepository,
IRepository<SystemDocNeedConfirmedUserType> systemDocNeedConfirmedUserTypeRepository, IRepository<SystemDocNeedConfirmedUserType> systemDocNeedConfirmedUserTypeRepository,
IRepository<SystemDocConfirmedUser> systemDocConfirmedUserRepository) IRepository<SystemDocConfirmedUser> systemDocConfirmedUserRepository)
{ {
@@ -183,7 +184,9 @@ namespace IRaCIS.Core.Application.Services
UserTypeShortName = user.UserTypeRole.UserTypeShortName UserTypeShortName = user.UserTypeRole.UserTypeShortName
}; };
return await query.Where(t=>t.ConfirmTime==null).ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc); return await query.WhereIf(querySystemDocument.IsSigned==true,t=>t.ConfirmTime!=null)
.WhereIf(querySystemDocument.IsSigned == false, t => t.ConfirmTime == null)
.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);
@@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using System.Linq;
namespace IRaCIS.Core.Application.Services namespace IRaCIS.Core.Application.Services
{ {
@@ -25,7 +26,8 @@ namespace IRaCIS.Core.Application.Services
private readonly IRepository<TrialDocument> _trialDocumentRepository; private readonly IRepository<TrialDocument> _trialDocumentRepository;
private readonly IRepository<TrialDocConfirmedUser> _trialDocUserTypeConfirmedUserRepository; private readonly IRepository<TrialDocConfirmedUser> _trialDocUserTypeConfirmedUserRepository;
private readonly IRepository<Trial> _trialRepository; private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<SystemDocConfirmedUser> _systemDocConfirmedUserRepository; private readonly ISystemDocumentService _systemDocumentService;
private readonly IRepository<SystemDocConfirmedUser> _systemDocConfirmedUserRepository;
private readonly IRepository<SystemDocument> _systemDocumentRepository; private readonly IRepository<SystemDocument> _systemDocumentRepository;
private readonly IRepository<TrialCriterionAdditionalAssessmentType> _trialCriterionAdditionalAssessmentTypeRepository; private readonly IRepository<TrialCriterionAdditionalAssessmentType> _trialCriterionAdditionalAssessmentTypeRepository;
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository; private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository;
@@ -34,7 +36,8 @@ namespace IRaCIS.Core.Application.Services
public TrialDocumentService(IRepository<TrialDocument> trialDocumentRepository, public TrialDocumentService(IRepository<TrialDocument> trialDocumentRepository,
IRepository<TrialDocConfirmedUser> trialDocUserTypeConfirmedUserRepository, IRepository<TrialDocConfirmedUser> trialDocUserTypeConfirmedUserRepository,
IRepository<Trial> trialRepository, IRepository<Trial> trialRepository,
IRepository<SystemDocConfirmedUser> systemDocConfirmedUserRepository, ISystemDocumentService systemDocumentService,
IRepository<SystemDocConfirmedUser> systemDocConfirmedUserRepository,
IRepository<TrialCriterionAdditionalAssessmentType> trialCriterionAdditionalAssessmentTypeRepository, IRepository<TrialCriterionAdditionalAssessmentType> trialCriterionAdditionalAssessmentTypeRepository,
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository
, IRepository<SystemDocument> systemDocumentRepository) , IRepository<SystemDocument> systemDocumentRepository)
@@ -42,7 +45,8 @@ namespace IRaCIS.Core.Application.Services
_trialDocumentRepository = trialDocumentRepository; _trialDocumentRepository = trialDocumentRepository;
this._trialDocUserTypeConfirmedUserRepository = trialDocUserTypeConfirmedUserRepository; this._trialDocUserTypeConfirmedUserRepository = trialDocUserTypeConfirmedUserRepository;
this._trialRepository = trialRepository; this._trialRepository = trialRepository;
this._systemDocConfirmedUserRepository = systemDocConfirmedUserRepository; this._systemDocumentService = systemDocumentService;
this._systemDocConfirmedUserRepository = systemDocConfirmedUserRepository;
_systemDocumentRepository = systemDocumentRepository; _systemDocumentRepository = systemDocumentRepository;
_readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository; _readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
_trialCriterionAdditionalAssessmentTypeRepository = trialCriterionAdditionalAssessmentTypeRepository; _trialCriterionAdditionalAssessmentTypeRepository = trialCriterionAdditionalAssessmentTypeRepository;
@@ -60,11 +64,61 @@ namespace IRaCIS.Core.Application.Services
var trialDocumentQueryable = _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == queryTrialDocument.TrialId) var trialDocumentQueryable = _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == queryTrialDocument.TrialId)
.WhereIf(!string.IsNullOrEmpty(queryTrialDocument.Name), t => t.Name.Contains(queryTrialDocument.Name)) .WhereIf(!string.IsNullOrEmpty(queryTrialDocument.Name), t => t.Name.Contains(queryTrialDocument.Name))
.WhereIf(queryTrialDocument.FileTypeId != null, t => t.FileTypeId == queryTrialDocument.FileTypeId) .WhereIf(queryTrialDocument.FileTypeId != null, t => t.FileTypeId == queryTrialDocument.FileTypeId)
.WhereIf(queryTrialDocument.UserTypeId != null, t => t.NeedConfirmedUserTypeList.Any(t=>t.NeedConfirmUserTypeId== queryTrialDocument.UserTypeId) )
.WhereIf(queryTrialDocument.IsDeleted != null, t => t.IsDeleted == queryTrialDocument.IsDeleted)
.ProjectTo<TrialDocumentView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken, isEn_Us = _userInfo.IsEn_Us }); .ProjectTo<TrialDocumentView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken, isEn_Us = _userInfo.IsEn_Us });
return await trialDocumentQueryable.ToPagedListAsync(queryTrialDocument.PageIndex, queryTrialDocument.PageSize, queryTrialDocument.SortField, queryTrialDocument.Asc); return await trialDocumentQueryable.ToPagedListAsync(queryTrialDocument.PageIndex, queryTrialDocument.PageSize, queryTrialDocument.SortField, queryTrialDocument.Asc);
} }
[HttpPost]
public async Task<PageOutput<TrialSignDocView>> GetTrialSignDocumentList(TrialDocQuery querySystemDocument)
{
var trialDocQueryable = from trialDoc in _trialDocumentRepository.AsQueryable(true)
.WhereIf(querySystemDocument.TrialId!=null,t=>t.TrialId==querySystemDocument.TrialId)
.Where(t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId) )
join trialUser in _repository.Where<TrialUser>(t=>t.UserId==_userInfo.Id) on trialDoc.TrialId equals trialUser.TrialId
join confirm in _repository.Where<TrialDocConfirmedUser>() on
new { trialUser.UserId, TrialDocumentId = trialDoc.Id } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
from confirm in cc.DefaultIfEmpty()
select new TrialSignDocView()
{
TrialCode=trialDoc.Trial.TrialCode,
ResearchProgramNo = trialDoc.Trial.ResearchProgramNo,
ExperimentName = trialDoc.Trial.ExperimentName,
Id = trialDoc.Id,
IsSystemDoc = false,
CreateTime = trialDoc.CreateTime,
FullFilePath = trialDoc.Path,
IsDeleted = trialDoc.IsDeleted,
Name = trialDoc.Name,
Path = trialDoc.Path,
FileTypeId = trialDoc.FileTypeId,
FileType = _userInfo.IsEn_Us ? trialDoc.FileType.Value : trialDoc.FileType.ValueCN,
UpdateTime = trialDoc.UpdateTime,
SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes,
//IsConfirmed = confirm.ConfirmTime != null,
ConfirmUserId = confirm.ConfirmUserId,
ConfirmTime = confirm.ConfirmTime,
RealName = trialUser.User.FullName,
UserName = trialUser.User.UserName,
UserTypeId = trialUser.User.UserTypeId,
UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName
};
trialDocQueryable = trialDocQueryable.WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name))
.WhereIf(querySystemDocument.FileTypeId != null, t => t.FileTypeId == querySystemDocument.FileTypeId)
.WhereIf(querySystemDocument.IsSigned == true, t => t.ConfirmTime != null)
.WhereIf(querySystemDocument.IsSigned == false, t => t.ConfirmTime == null);
return await trialDocQueryable.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);
}
/// <summary> /// <summary>
/// 获取下一个未签名的文件 /// 获取下一个未签名的文件
@@ -74,19 +128,37 @@ namespace IRaCIS.Core.Application.Services
[HttpPost] [HttpPost]
public async Task<UnionDocumentWithConfirmInfoView?> GetNextUnSignDocument(GetNextUnSignDocumentInDto inDto) public async Task<UnionDocumentWithConfirmInfoView?> GetNextUnSignDocument(GetNextUnSignDocumentInDto inDto)
{ {
var result = await this.GetUserDocumentList(new TrialUserDocUnionQuery() var result = new PageOutput<UnionDocumentWithConfirmInfoView>() { };
{
Asc = inDto.Asc,
IsSign = false,
SortField = inDto.SortField,
TrialId = inDto.TrialId,
PageIndex = 1,
PageSize = 1,
});
if (result.Data.CurrentPageData.Count > 0) if (inDto.TrialId != null)
{ {
return result.Data.CurrentPageData.First(); result = (await this.GetUserDocumentList(new TrialUserDocUnionQuery()
{
Asc = inDto.Asc,
IsSign = false,
SortField = inDto.SortField,
TrialId = inDto.TrialId.Value,
PageIndex = 1,
PageSize = 1,
})).Data;
}
else
{
result = await _systemDocumentService.getWaitSignSysDocList(new SystemDocumentQuery()
{
PageIndex=1,
IsSigned = false,
PageSize=1,
Asc=false,
SortField="UpdateTime",
});
}
if (result.CurrentPageData.Count > 0)
{
return result.CurrentPageData.First();
} }
else else
{ {
@@ -165,7 +237,7 @@ namespace IRaCIS.Core.Application.Services
var trialId = querySystemDocument.TrialId; var trialId = querySystemDocument.TrialId;
var trialInfo = await (_repository.Where<Trial>(t => t.Id == querySystemDocument.TrialId,ignoreQueryFilters:true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync()); var trialInfo = await (_repository.Where<Trial>(t => t.Id == querySystemDocument.TrialId, ignoreQueryFilters: true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync());
//系统文档查询 //系统文档查询
var systemDocumentQueryable = from needConfirmedUserType in _repository.Where<SystemDocNeedConfirmedUserType>(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId) var systemDocumentQueryable = from needConfirmedUserType in _repository.Where<SystemDocNeedConfirmedUserType>(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId)
@@ -193,6 +265,7 @@ namespace IRaCIS.Core.Application.Services
FullFilePath = needConfirmedUserType.SystemDocument.Path, FullFilePath = needConfirmedUserType.SystemDocument.Path,
//IsConfirmed = confirm.ConfirmTime != null,
ConfirmUserId = confirm.ConfirmUserId, ConfirmUserId = confirm.ConfirmUserId,
ConfirmTime = confirm.ConfirmTime, ConfirmTime = confirm.ConfirmTime,
RealName = trialUser.User.FullName, RealName = trialUser.User.FullName,
@@ -224,6 +297,7 @@ namespace IRaCIS.Core.Application.Services
UpdateTime = trialDoc.UpdateTime, UpdateTime = trialDoc.UpdateTime,
SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes, SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes,
//IsConfirmed = confirm.ConfirmTime != null,
ConfirmUserId = confirm.ConfirmUserId, ConfirmUserId = confirm.ConfirmUserId,
ConfirmTime = confirm.ConfirmTime, ConfirmTime = confirm.ConfirmTime,
RealName = trialUser.User.FullName, RealName = trialUser.User.FullName,
@@ -359,6 +433,7 @@ namespace IRaCIS.Core.Application.Services
FileTypeId = trialDocumentNeedConfirmedUserType.TrialDocument.FileTypeId, FileTypeId = trialDocumentNeedConfirmedUserType.TrialDocument.FileTypeId,
FileType = _userInfo.IsEn_Us ? trialDocumentNeedConfirmedUserType.TrialDocument.FileType.Value : trialDocumentNeedConfirmedUserType.TrialDocument.FileType.ValueCN, FileType = _userInfo.IsEn_Us ? trialDocumentNeedConfirmedUserType.TrialDocument.FileType.Value : trialDocumentNeedConfirmedUserType.TrialDocument.FileType.ValueCN,
UpdateTime = trialDocumentNeedConfirmedUserType.TrialDocument.UpdateTime, UpdateTime = trialDocumentNeedConfirmedUserType.TrialDocument.UpdateTime,
//IsConfirmed= confirm.ConfirmTime!=null,
@@ -394,7 +469,7 @@ namespace IRaCIS.Core.Application.Services
FileType = _userInfo.IsEn_Us ? needConfirmEdUserType.SystemDocument.FileType.Value : needConfirmEdUserType.SystemDocument.FileType.ValueCN, FileType = _userInfo.IsEn_Us ? needConfirmEdUserType.SystemDocument.FileType.Value : needConfirmEdUserType.SystemDocument.FileType.ValueCN,
FileTypeId = needConfirmEdUserType.SystemDocument.FileTypeId, FileTypeId = needConfirmEdUserType.SystemDocument.FileTypeId,
UpdateTime = needConfirmEdUserType.SystemDocument.UpdateTime, UpdateTime = needConfirmEdUserType.SystemDocument.UpdateTime,
//IsConfirmed = confirm.ConfirmTime != null,
ConfirmUserId = confirm.ConfirmUserId, ConfirmUserId = confirm.ConfirmUserId,
ConfirmTime = confirm.ConfirmTime, ConfirmTime = confirm.ConfirmTime,
@@ -409,6 +484,9 @@ namespace IRaCIS.Core.Application.Services
var unionQuery = trialDocQuery.Union(systemDocQuery) var unionQuery = trialDocQuery.Union(systemDocQuery)
.WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name)) .WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name))
.WhereIf(querySystemDocument.FileTypeId != null, t => t.FileTypeId == querySystemDocument.FileTypeId) .WhereIf(querySystemDocument.FileTypeId != null, t => t.FileTypeId == querySystemDocument.FileTypeId)
.WhereIf(querySystemDocument.IsConfirmed == true, t => t.ConfirmTime != null)
.WhereIf(querySystemDocument.IsConfirmed == false, t => t.ConfirmTime == null)
.WhereIf(querySystemDocument.IsDeleted != null, t => t.IsDeleted == querySystemDocument.IsDeleted)
.WhereIf(querySystemDocument.UserTypeId != null, t => t.UserTypeId == querySystemDocument.UserTypeId); .WhereIf(querySystemDocument.UserTypeId != null, t => t.UserTypeId == querySystemDocument.UserTypeId);
var result = await unionQuery.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc); var result = await unionQuery.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);
@@ -25,7 +25,8 @@ using Microsoft.AspNetCore.Http;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SharpCompress.Common; using SharpCompress.Common;
using SkiaSharp; using DocumentFormat.OpenXml.Bibliography;
using System.Linq.Dynamic.Core;
namespace IRaCIS.Core.Application.Service namespace IRaCIS.Core.Application.Service
{ {
@@ -235,7 +236,7 @@ namespace IRaCIS.Core.Application.Service
t.SourceSubjectVisitId, t.SourceSubjectVisitId,
t.SouceReadModuleId, t.SouceReadModuleId,
t.SubjectId, t.SubjectId,
t.Subject.SiteId, t.Subject.TrialSiteId,
t.DoctorUserId, t.DoctorUserId,
t.ReadingTaskState, t.ReadingTaskState,
@@ -316,13 +317,13 @@ namespace IRaCIS.Core.Application.Service
}; };
var (trialEmailConfig, sendEmailConfig) = await _emailSendService.BuildEmailConfig(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc, taskInfo.SiteId,taskInfo.TrialReadingCriterionId); var (trialEmailConfig, sendEmailConfig) = await _emailSendService.BuildEmailConfig(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc, taskInfo.TrialSiteId, taskInfo.TrialReadingCriterionId);
#endregion #endregion
//自动发送 //自动发送
if (sendEmailConfig != null && trialEmailConfig !=null) if (sendEmailConfig != null && trialEmailConfig != null)
{ {
#region #region
@@ -380,7 +381,7 @@ namespace IRaCIS.Core.Application.Service
//有序 //有序
if (taskInfo.IsReadingTaskViewInOrder) if (taskInfo.IsReadingTaskViewInOrder==ReadingOrder.InOrder)
{ {
@@ -658,7 +659,7 @@ namespace IRaCIS.Core.Application.Service
var path = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, _userInfo.IsEn_Us ? trialEmailConfig.AttachPath : trialEmailConfig.AttachCNPath); var path = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, _userInfo.IsEn_Us ? trialEmailConfig.AttachPath : trialEmailConfig.AttachCNPath);
var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetSubjectEnrollConfirmOrPDEmailPath(_hostEnvironment, Path.GetFileName(path), taskInfo.TrialId, taskInfo.SiteId, taskInfo.SubjectId, true); var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetSubjectEnrollConfirmOrPDEmailPath(_hostEnvironment, Path.GetFileName(path), taskInfo.TrialId, taskInfo.TrialSiteId, taskInfo.SubjectId, true);
if (emailStoreMode == EmailStoreSendMode.StoreLocalSend || emailStoreMode == EmailStoreSendMode.OnlyStoreLocalNotSentEmail) if (emailStoreMode == EmailStoreSendMode.StoreLocalSend || emailStoreMode == EmailStoreSendMode.OnlyStoreLocalNotSentEmail)
{ {
@@ -679,8 +680,8 @@ namespace IRaCIS.Core.Application.Service
} }
else else
{ {
var wordStoreServerPath = Path.Combine(Path.GetDirectoryName(serverFilePath), Path.GetFileNameWithoutExtension(serverFilePath)+".docx"); var wordStoreServerPath = Path.Combine(Path.GetDirectoryName(serverFilePath), Path.GetFileNameWithoutExtension(serverFilePath) + ".docx");
using (FileStream fileStream = new FileStream(wordStoreServerPath, FileMode.Create, FileAccess.Write)) using (FileStream fileStream = new FileStream(wordStoreServerPath, FileMode.Create, FileAccess.Write))
{ {
wordMemoryStream.WriteTo(fileStream); wordMemoryStream.WriteTo(fileStream);
@@ -718,7 +719,7 @@ namespace IRaCIS.Core.Application.Service
Document document = new Document(); Document document = new Document();
document.LoadFromStream(wordMemoryStream, FileFormat.Docx); document.LoadFromStream(wordMemoryStream, FileFormat.Docx);
document.SaveToStream(pdfMemoryStream, FileFormat.PDF); document.SaveToStream(pdfMemoryStream, FileFormat.PDF);
} }
else else
{ {
@@ -887,7 +888,7 @@ namespace IRaCIS.Core.Application.Service
{ TrialReadingCriterionId = t.Id, t.ReadingType, t.IsReadingTaskViewInOrder, t.CriterionType, t.ArbitrationRule }).FirstNotNullAsync(); { TrialReadingCriterionId = t.Id, t.ReadingType, t.IsReadingTaskViewInOrder, t.CriterionType, t.ArbitrationRule }).FirstNotNullAsync();
// 项目双重 // 项目双重
if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double && trialReadingCriterionConfig.IsReadingTaskViewInOrder) if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double && trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{ {
//仲裁在访视上面 //仲裁在访视上面
if (trialReadingCriterionConfig.ArbitrationRule == ArbitrationRule.Visit) if (trialReadingCriterionConfig.ArbitrationRule == ArbitrationRule.Visit)
@@ -1355,7 +1356,9 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(inQuery.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == inQuery.BusinessScenarioEnum) .WhereIf(inQuery.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == inQuery.BusinessScenarioEnum)
.ProjectTo<TrialEmailNoticeConfigView>(_mapper.ConfigurationProvider); .ProjectTo<TrialEmailNoticeConfigView>(_mapper.ConfigurationProvider);
return await trialEmailNoticeConfigQueryable.ToListAsync(); var sortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(TrialEmailNoticeConfigView.Code) : inQuery.SortField;
var orderQuery = inQuery.Asc ? trialEmailNoticeConfigQueryable.OrderBy(sortField) : trialEmailNoticeConfigQueryable.OrderBy(sortField + " desc");
return await orderQuery.ToListAsync();
} }
@@ -0,0 +1,175 @@
using FellowOakDicom.Network;
using FellowOakDicom;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using IRaCIS.Core.Application.Contracts.Dicom;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace IRaCIS.Core.Application.Service.ImageAndDoc
{
/// <summary>
/// 后台托管服务的方式运行
/// </summary>
//public class CStoreSCPHostedService : IHostedService
//{
// private readonly ILogger<CStoreSCPHostedService> _logger;
// private readonly IDicomServerFactory _dicomServerFactory;
// private IDicomServer? _server;
// public CStoreSCPHostedService(ILogger<CStoreSCPHostedService> logger, IDicomServerFactory dicomServerFactory)
// {
// _logger = logger ?? throw new ArgumentNullException(nameof(logger));
// _dicomServerFactory = dicomServerFactory ?? throw new ArgumentNullException(nameof(dicomServerFactory));
// }
// public async Task StartAsync(CancellationToken cancellationToken)
// {
// _logger.LogInformation("Starting DICOM server");
// _server = _dicomServerFactory.Create<CStoreSCPService>(104);
// _logger.LogInformation("DICOM server is running");
// }
// public Task StopAsync(CancellationToken cancellationToken)
// {
// if (_server != null)
// {
// _server.Stop();
// _server.Dispose();
// _server = null;
// }
// return Task.CompletedTask;
// }
//}
public class CStoreSCPService : DicomService, IDicomServiceProvider, IDicomCStoreProvider, IDicomCEchoProvider
{
private IServiceProvider _serviceProvider { get; set; }
private static readonly DicomTransferSyntax[] _acceptedTransferSyntaxes = new DicomTransferSyntax[]
{
DicomTransferSyntax.ExplicitVRLittleEndian,
DicomTransferSyntax.ExplicitVRBigEndian,
DicomTransferSyntax.ImplicitVRLittleEndian
};
private static readonly DicomTransferSyntax[] _acceptedImageTransferSyntaxes = new DicomTransferSyntax[]
{
// Lossless
DicomTransferSyntax.JPEGLSLossless,
DicomTransferSyntax.JPEG2000Lossless,
DicomTransferSyntax.JPEGProcess14SV1,
DicomTransferSyntax.JPEGProcess14,
DicomTransferSyntax.RLELossless,
// Lossy
DicomTransferSyntax.JPEGLSNearLossless,
DicomTransferSyntax.JPEG2000Lossy,
DicomTransferSyntax.JPEGProcess1,
DicomTransferSyntax.JPEGProcess2_4,
// Uncompressed
DicomTransferSyntax.ExplicitVRLittleEndian,
DicomTransferSyntax.ExplicitVRBigEndian,
DicomTransferSyntax.ImplicitVRLittleEndian
};
public CStoreSCPService(INetworkStream stream, Encoding fallbackEncoding, ILogger log, DicomServiceDependencies dependencies)
: base(stream, fallbackEncoding, log, dependencies)
{
var tt = base.UserState;
//_dicomArchiveService = dicomArchiveService;
}
public Task OnReceiveAssociationRequestAsync(DicomAssociation association)
{
_serviceProvider =(IServiceProvider) this.UserState;
if (association.CalledAE != "STORESCP")
{
return SendAssociationRejectAsync(
DicomRejectResult.Permanent,
DicomRejectSource.ServiceUser,
DicomRejectReason.CalledAENotRecognized);
}
foreach (var pc in association.PresentationContexts)
{
if (pc.AbstractSyntax == DicomUID.Verification)
{
pc.AcceptTransferSyntaxes(_acceptedTransferSyntaxes);
}
else if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None)
{
pc.AcceptTransferSyntaxes(_acceptedImageTransferSyntaxes);
}
}
return SendAssociationAcceptAsync(association);
}
public Task OnReceiveAssociationReleaseRequestAsync()
{
return SendAssociationReleaseResponseAsync();
}
public void OnReceiveAbort(DicomAbortSource source, DicomAbortReason reason)
{
/* nothing to do here */
}
public void OnConnectionClosed(Exception exception)
{
/* nothing to do here */
}
public async Task<DicomCStoreResponse> OnCStoreRequestAsync(DicomCStoreRequest request)
{
var tt= _serviceProvider.GetService<IDicomArchiveService>();
var studyUid = request.Dataset.GetSingleValue<string>(DicomTag.StudyInstanceUID).Trim();
var instUid = request.SOPInstanceUID.UID;
var path = Path.GetFullPath(@".\DICOM-Store");
path = Path.Combine(path, studyUid);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
path = Path.Combine(path, instUid) + ".dcm";
await request.File.SaveAsync(path);
return new DicomCStoreResponse(request, DicomStatus.Success);
}
public Task OnCStoreRequestExceptionAsync(string tempFileName, Exception e)
{
// let library handle logging and error response
return Task.CompletedTask;
}
public Task<DicomCEchoResponse> OnCEchoRequestAsync(DicomCEchoRequest request)
{
return Task.FromResult(new DicomCEchoResponse(request, DicomStatus.Success));
}
}
}
@@ -20,7 +20,6 @@ namespace IRaCIS.Core.Application.Contracts
public int SliceLocation { get; set; } public int SliceLocation { get; set; }
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; }
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
public Guid SubjectVisitId { get; set; } public Guid SubjectVisitId { get; set; }
@@ -30,14 +29,16 @@ namespace IRaCIS.Core.Application.Contracts
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }
public bool IsReading { get; set; } = true; public bool IsReading { get; set; } = true;
public string SliceThickness { get; set; } = String.Empty;
} }
public class DicomTrialSiteSubjectInfo public class DicomTrialSiteSubjectInfo
{ {
public string TrialSiteCode { get; set; } = string.Empty; public string TrialSiteCode { get; set; } = string.Empty;
public string SiteCode { get; set; } = string.Empty; public string TrialSiteAliasName { get; set; } = string.Empty;
public string SiteName { get; set; } = string.Empty;
public string SubjectCode { get; set; } = string.Empty; public string SubjectCode { get; set; } = string.Empty;
public int? SubjectAge { get; set; } public int? SubjectAge { get; set; }
public string SubjectSex { get; set; } = string.Empty; public string SubjectSex { get; set; } = string.Empty;
@@ -51,7 +52,7 @@ namespace IRaCIS.Core.Application.Contracts
public string VisitName { get; set; } = string.Empty; public string VisitName { get; set; } = string.Empty;
public string Sponsor { get; set; } = string.Empty; public string Sponsor { get; set; } = string.Empty;
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; } public Guid TrialSiteId { get; set; }
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
public Guid SubjectVisitId { get; set; } public Guid SubjectVisitId { get; set; }
@@ -1,8 +1,14 @@
namespace IRaCIS.Core.Application.Contracts.Dicom.DTO 
using Newtonsoft.Json;
namespace IRaCIS.Core.Application.Contracts.Dicom.DTO
{ {
public class DicomSeriesDTO public class DicomSeriesDTO
{ {
public bool IsDicom { get; set; } = true; public bool IsDicom { get; set; } = true;
public bool IsBeMark { get; set; } = false; public bool IsBeMark { get; set; } = false;
@@ -21,7 +27,7 @@
public string SliceThickness { get; set; } = String.Empty; public string SliceThickness { get; set; } = String.Empty;
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; }
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
public Guid SubjectVisitId { get; set; } public Guid SubjectVisitId { get; set; }
@@ -33,19 +39,41 @@
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }
public bool IsReading { get; set; } = true; public bool IsReading { get; set; } = true;
public List<Guid> InstanceList { get; set; } = new List<Guid>();
public List<string> InstancePathList { get; set; } = new List<string>(); public List<InstanceBasicInfo> InstanceInfoList { get; set; }=new List<InstanceBasicInfo>();
public bool IsExistMutiFrames => InstanceInfoList.Any(t => t.NumberOfFrames > 1);
public List<string> InstanceHtmlPathList { get; set; }
//存放在instance 上面 //存放在instance 上面
public string WindowCenter { get; set; } = string.Empty; public string? WindowCenter => InstanceInfoList.FirstOrDefault()?.WindowCenter;
public string WindowWidth { get; set; } = string.Empty; public string? WindowWidth => InstanceInfoList.FirstOrDefault()?.WindowWidth;
public string ImageResizePath { get; set; } public string ImageResizePath { get; set; }
} }
public class InstanceBasicInfo
{
public Guid Id { get; set; }
public string Path { get; set; }
public string HtmlPath { get; set; }
public int NumberOfFrames { get; set; }
public int InstanceNumber { get; set; }
[JsonIgnore]
public int ShowOrder { get; set; }
[JsonIgnore]
public decimal RowIndex { get; set; }
[JsonIgnore]
public string WindowCenter { get; set; }
[JsonIgnore]
public string WindowWidth { get; set; }
}
public class DicomSeriesWithLabelDTO : DicomSeriesDTO public class DicomSeriesWithLabelDTO : DicomSeriesDTO
{ {
public bool HasLabel { get; set; } = false; public bool HasLabel { get; set; } = false;
@@ -4,7 +4,7 @@
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; } public Guid TrialSiteId { get; set; }
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
public Guid SubjectVisitId { get; set; } public Guid SubjectVisitId { get; set; }
@@ -18,7 +18,7 @@
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; } public Guid TrialSiteId { get; set; }
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
public Guid SubjectVisitId { get; set; } public Guid SubjectVisitId { get; set; }
@@ -74,7 +74,7 @@
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; } public Guid TrialSiteId { get; set; }
//public string SubjectName { get; set; } //public string SubjectName { get; set; }
public string SubjectCode { get; set; } = string.Empty; public string SubjectCode { get; set; } = string.Empty;
@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace IRaCIS.Core.Application.Service.ImageAndDoc.DTO
{
public class SubjectImageUploadDTO
{
public Guid VisitTaskId { get; set; }
public Guid TrialSiteId { get; set; }
public Guid SubejctId { get; set; }
public string SubjectCode { get; set; }
public string TaskBlindName { get; set; }
public string TaskName { get; set; }
public bool IsImageFilter { get; set; }
public string CriterionModalitys { get; set; }
public Guid? SourceSubjectVisitId { get; set; }
public PackState PackState { get; set; }
public List<StudyBasicInfo> OrginalStudyList { get; set; }
public List<StudyBasicInfo> UploadStudyList { get; set; }
}
public class StudyBasicInfo
{
public Guid Id { get; set; }
public string StudyInstanceUid { get; set; }
public string StudyCode { get; set; }
public string ModalityForEdit { get; set; }
public string BodyPartExamined { get; set; }
public string BodyPartForEdit { get; set; }
public DateTime? StudyTime { get; set; }
public string Modalities { get; set; }
public string Description { get; set; }
public int SeriesCount { get; set; }
public int InstanceCount { get; set; }
public List<string> SopInstanceUidList { get; set; }
}
}
@@ -5,7 +5,6 @@ namespace IRaCIS.Core.Application.Contracts.Dicom.DTO
public class ImageShareCommand public class ImageShareCommand
{ {
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; }
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
public Guid? StudyId { get; set; } public Guid? StudyId { get; set; }
@@ -13,7 +13,7 @@ namespace IRaCIS.Core.Application.Contracts
{ {
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
public Guid SiteId { get; set; } public Guid TrialSiteId { get; set; }
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
@@ -42,6 +42,7 @@ namespace IRaCIS.Core.Application.Contracts
//[JsonIgnore] //[JsonIgnore]
//public int NoneDicomCode { get; set; } //public int NoneDicomCode { get; set; }
public string RecordPath { get; set; } = string.Empty;
public bool IsDicom { get; set; } public bool IsDicom { get; set; }
} }
@@ -90,25 +91,6 @@ namespace IRaCIS.Core.Application.Contracts
return $" {uploadTimeSpan?.Hours}:{uploadTimeSpan?.Minutes}:{uploadTimeSpan?.Seconds}.{uploadTimeSpan?.Milliseconds}"; return $" {uploadTimeSpan?.Hours}:{uploadTimeSpan?.Minutes}:{uploadTimeSpan?.Seconds}.{uploadTimeSpan?.Milliseconds}";
#region
//if (uploadTimeSpan.Seconds == 0 && uploadTimeSpan.Minutes==0 && uploadTimeSpan.Hours == 0)
//{
// return $"{uploadTimeSpan.Milliseconds}毫秒";
//}
//else if (uploadTimeSpan.Minutes == 0 && uploadTimeSpan.Hours == 0)
//{
// return $"{uploadTimeSpan.Seconds}秒";
//}
//else if (uploadTimeSpan.Hours == 0)
//{
// return $"{uploadTimeSpan.Minutes} 分钟 {uploadTimeSpan.Seconds} 秒";
//}
//else
//{
// return $" {uploadTimeSpan.Hours} 小时 {uploadTimeSpan.Minutes} 分钟 {uploadTimeSpan.Seconds} 秒 {uploadTimeSpan.Milliseconds}毫秒";
//}
#endregion
} }
} }
@@ -165,7 +147,7 @@ namespace IRaCIS.Core.Application.Contracts
public Guid? SubjectId { get; set; } public Guid? SubjectId { get; set; }
public Guid? SiteId { get; set; } public Guid? TrialSiteId { get; set; }
public Guid? SubjectVisitId { get; set; } public Guid? SubjectVisitId { get; set; }
public string SubjectInfo { get; set; } = String.Empty; public string SubjectInfo { get; set; } = String.Empty;
@@ -175,23 +157,28 @@ namespace IRaCIS.Core.Application.Contracts
public Guid? VisitTaskId { 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 public class PriArchiveTaskStudyCommand
{ {
//public string StudyInstanceUid { get; set; }
[NotDefault] [NotDefault]
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
[NotDefault]
public Guid SiteId { get; set; }
[NotDefault] [NotDefault]
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
[NotDefault] [NotDefault]
public Guid SubjectVisitId { get; set; } public Guid SubjectVisitId { get; set; }
public decimal FileSize { get; set; } public decimal FileSize { get; set; }
public bool IsDicomReUpload { get; set; } public bool IsDicomReUpload { get; set; }
@@ -200,32 +187,73 @@ namespace IRaCIS.Core.Application.Contracts
public int FileCount { get; set; } public int FileCount { get; set; }
} }
public class PreArchiveDicomStudyCommand
{
[NotDefault]
public Guid TrialId { get; set; }
[NotDefault]
public Guid TrialSiteId { get; set; }
[NotDefault]
public Guid SubjectId { get; set; }
[NotDefault]
public Guid SubjectVisitId { get; set; }
public decimal FileSize { get; set; }
public bool IsDicomReUpload { get; set; }
public int FileCount { get; set; }
}
public class TaskArchiveStudyCommand
{
[NotDefault]
public Guid TrialId { get; set; }
[NotDefault]
public Guid SubjectId { get; set; }
[NotDefault]
public Guid StudyMonitorId { get; set; }
public int FailedFileCount { get; set; }
public string RecordPath { get; set; } = string.Empty;
public AddOrUpdateStudyDto Study { get; set; }
}
public class NewArchiveStudyCommand public class NewArchiveStudyCommand
{ {
[NotDefault] [NotDefault]
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
[NotDefault] [NotDefault]
public Guid SiteId { get; set; } public Guid TrialSiteId { get; set; }
[NotDefault] [NotDefault]
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
[NotDefault] [NotDefault]
public Guid SubjectVisitId { get; set; } public Guid SubjectVisitId { get; set; }
[NotDefault] [NotDefault]
public Guid StudyMonitorId { get; set; } public Guid StudyMonitorId { get; set; }
public int FailedFileCount { get; set; } public int FailedFileCount { get; set; }
public AddOrUpdateStudyDto Study { get; set; } public string RecordPath { get; set; } = string.Empty;
} public AddOrUpdateStudyDto Study { get; set; }
}
public class AddOrUpdateStudyDto public class AddOrUpdateStudyDto
{ {
public string StudyId { get; set; } = string.Empty; public string StudyId { get; set; } = string.Empty;
//public int Code { get; set; } = 0; //public int Code { get; set; } = 0;
//public string StudyCode { get; set; } = string.Empty; //public string StudyCode { get; set; } = string.Empty;
@@ -280,7 +308,7 @@ namespace IRaCIS.Core.Application.Contracts
public string AcquisitionNumber { get; set; } = string.Empty; public string AcquisitionNumber { get; set; } = string.Empty;
public string TriggerTime { get; set; } = string.Empty; public string TriggerTime { get; set; } = string.Empty;
public string ImageResizePath { get; set; }=string.Empty; public string ImageResizePath { get; set; } = string.Empty;
public List<AddInstanceDto> InstanceList { get; set; } public List<AddInstanceDto> InstanceList { get; set; }
public Guid? VisitTaskId { get; set; } public Guid? VisitTaskId { get; set; }
@@ -9,6 +9,9 @@ using IRaCIS.Core.Infrastructure;
using Medallion.Threading; using Medallion.Threading;
using FellowOakDicom; using FellowOakDicom;
using FellowOakDicom.Imaging.Codec; using FellowOakDicom.Imaging.Codec;
using System.Data;
using IRaCIS.Core.Domain.Models;
using FellowOakDicom.Network;
namespace IRaCIS.Core.Application.Services namespace IRaCIS.Core.Application.Services
{ {
@@ -149,7 +152,7 @@ namespace IRaCIS.Core.Application.Services
} }
var (physicalPath, relativePath) = FileStoreHelper.GetDicomInstanceFilePath(_hostEnvironment, dicomStudy.TrialId, dicomStudy.SiteId, dicomStudy.SubjectId, dicomStudy.SubjectVisitId, dicomStudy.Id, dicomInstance.Id); var (physicalPath, relativePath) = FileStoreHelper.GetDicomInstanceFilePath(_hostEnvironment, dicomStudy.TrialId, dicomStudy.SubjectId, dicomStudy.SubjectVisitId, dicomStudy.Id, dicomInstance.Id);
dicomInstance.Path = relativePath; dicomInstance.Path = relativePath;
@@ -267,7 +270,6 @@ namespace IRaCIS.Core.Application.Services
TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty), TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty),
SiteId = addtionalInfo.SiteId,
TrialId = addtionalInfo.TrialId, TrialId = addtionalInfo.TrialId,
SubjectId = addtionalInfo.SubjectId, SubjectId = addtionalInfo.SubjectId,
SubjectVisitId = addtionalInfo.SubjectVisitId, SubjectVisitId = addtionalInfo.SubjectVisitId,
@@ -397,7 +399,6 @@ namespace IRaCIS.Core.Application.Services
AcquisitionNumber = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionNumber, string.Empty), AcquisitionNumber = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionNumber, string.Empty),
TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty), TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty),
SiteId = dicomStudy.SiteId,
TrialId = dicomStudy.TrialId, TrialId = dicomStudy.TrialId,
SubjectId = dicomStudy.SubjectId, SubjectId = dicomStudy.SubjectId,
SubjectVisitId = dicomStudy.SubjectVisitId, SubjectVisitId = dicomStudy.SubjectVisitId,
@@ -430,7 +431,6 @@ namespace IRaCIS.Core.Application.Services
StudyId = dicomStudy.Id, StudyId = dicomStudy.Id,
SeriesId = dicomSeries.Id, SeriesId = dicomSeries.Id,
SiteId = dicomStudy.SiteId,
TrialId = dicomStudy.TrialId, TrialId = dicomStudy.TrialId,
SubjectId = dicomStudy.SubjectId, SubjectId = dicomStudy.SubjectId,
SubjectVisitId = dicomStudy.SubjectVisitId, SubjectVisitId = dicomStudy.SubjectVisitId,
@@ -474,11 +474,202 @@ namespace IRaCIS.Core.Application.Services
} }
/// <summary>
/// 单个文件接收 归档
/// </summary>
/// <param name="dataset"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task ArchiveDicomFileAsync(DicomDataset dataset)
{
string studyInstanceUid = dataset.GetString(DicomTag.StudyInstanceUID);
string seriesInstanceUid = dataset.GetString(DicomTag.SeriesInstanceUID);
string sopInstanceUid = dataset.GetString(DicomTag.SOPInstanceUID);
Guid studyId = IdentifierHelper.CreateGuid(studyInstanceUid);
Guid seriesId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid);
Guid instanceId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, sopInstanceUid);
var isStudyNeedAdd = false;
var isSeriesNeedAdd = false;
var isInstanceNeedAdd = false;
var @lock = _distributedLockProvider.CreateLock($"StudyInstanceUid");
using (@lock.Acquire())
{
var findStudy = await _studyRepository.FirstOrDefaultAsync(t => t.Id == studyId);
var findSerice = await _seriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
var findInstance = await _instanceRepository.FirstOrDefaultAsync(t => t.Id == instanceId);
if (findStudy == null)
{
isStudyNeedAdd = true;
findStudy = new DicomStudy
{
Id = studyId,
StudyInstanceUid = studyInstanceUid,
StudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.StudyDate).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.StudyTime).TimeOfDay),
//Modalities = modality,
//ModalityForEdit = modalityForEdit,
Description = dataset.GetSingleValueOrDefault(DicomTag.StudyDescription, string.Empty),
InstitutionName = dataset.GetSingleValueOrDefault(DicomTag.InstitutionName, string.Empty),
PatientId = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty),
PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty),
PatientAge = dataset.GetSingleValueOrDefault(DicomTag.PatientAge, string.Empty),
PatientSex = dataset.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty),
BodyPartExamined = dataset.GetSingleValueOrDefault(DicomTag.BodyPartExamined, string.Empty),
StudyId = dataset.GetSingleValueOrDefault(DicomTag.StudyID, string.Empty),
AccessionNumber = dataset.GetSingleValueOrDefault(DicomTag.AccessionNumber, string.Empty),
//需要特殊处理
PatientBirthDate = dataset.GetSingleValueOrDefault(DicomTag.PatientBirthDate, string.Empty),
AcquisitionTime = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionTime, string.Empty),
AcquisitionNumber = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionNumber, string.Empty),
TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty),
TrialId = Guid.Empty,
SubjectId = Guid.Empty,
SubjectVisitId = Guid.Empty,
//IsDoubleReview = addtionalInfo.IsDoubleReview,
SeriesCount = 0,
InstanceCount = 0
};
//特殊逻辑
var modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty);
var dicModalityList = _dictionaryRepository.Where(t => t.Code == "Modality").SelectMany(t => t.ChildList.Select(c => c.Value)).ToList();
var modalityForEdit = dicModalityList.Contains(modality) ? modality : String.Empty;
if (modality == "MR")
{
modalityForEdit = "MRI";
}
if (modality == "PT")
{
modalityForEdit = "PET";
}
if (modality == "PT、CT")
{
modalityForEdit = "PET-CT";
}
findStudy.Modalities = modality;
findStudy.ModalityForEdit= modalityForEdit;
if (findStudy.PatientBirthDate.Length == 8)
{
findStudy.PatientBirthDate = $"{findStudy.PatientBirthDate[0]}{findStudy.PatientBirthDate[1]}{findStudy.PatientBirthDate[2]}{findStudy.PatientBirthDate[3]}-{findStudy.PatientBirthDate[4]}{findStudy.PatientBirthDate[5]}-{findStudy.PatientBirthDate[6]}{findStudy.PatientBirthDate[7]}";
}
}
if (findSerice == null)
{
isSeriesNeedAdd = true;
findSerice = new DicomSeries
{
Id = seriesId,
StudyId = findStudy.Id,
StudyInstanceUid = findStudy.StudyInstanceUid,
SeriesInstanceUid = seriesInstanceUid,
SeriesNumber = dataset.GetSingleValueOrDefault(DicomTag.SeriesNumber, 1),
//SeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, DateTime.Now).Add(dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, DateTime.Now).TimeOfDay),
//SeriesTime = DateTime.TryParse(dataset.GetSingleValue<string>(DicomTag.SeriesDate) + dataset.GetSingleValue<string>(DicomTag.SeriesTime), out DateTime dt) ? dt : null,
SeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.SeriesDate).Add(dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.SeriesTime).TimeOfDay),
Modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty),
Description = dataset.GetSingleValueOrDefault(DicomTag.SeriesDescription, string.Empty),
SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty),
ImagePositionPatient = dataset.GetSingleValueOrDefault(DicomTag.ImagePositionPatient, string.Empty),
ImageOrientationPatient = dataset.GetSingleValueOrDefault(DicomTag.ImageOrientationPatient, string.Empty),
BodyPartExamined = dataset.GetSingleValueOrDefault(DicomTag.BodyPartExamined, string.Empty),
SequenceName = dataset.GetSingleValueOrDefault(DicomTag.SequenceName, string.Empty),
ProtocolName = dataset.GetSingleValueOrDefault(DicomTag.ProtocolName, string.Empty),
ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
AcquisitionTime = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionTime, string.Empty),
AcquisitionNumber = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionNumber, string.Empty),
TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty),
TrialId = Guid.Empty,
SubjectId = Guid.Empty,
SubjectVisitId = Guid.Empty,
InstanceCount = 0
};
++findStudy.SeriesCount;
}
if (findInstance == null)
{
isInstanceNeedAdd = true;
findInstance = new DicomInstance
{
Id = instanceId,
StudyId = findStudy.Id,
SeriesId = findSerice.Id,
StudyInstanceUid = findStudy.StudyInstanceUid,
SeriesInstanceUid = findSerice.SeriesInstanceUid,
TrialId = Guid.Empty,
SubjectId = Guid.Empty,
SubjectVisitId = Guid.Empty,
SopInstanceUid = sopInstanceUid,
InstanceNumber = dataset.GetSingleValueOrDefault(DicomTag.InstanceNumber, 1),
InstanceTime = dataset.GetSingleValueOrDefault(DicomTag.ContentDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.ContentDate).Add(dataset.GetSingleValueOrDefault(DicomTag.ContentTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.ContentTime).TimeOfDay),
//InstanceTime = DateTime.TryParse(dataset.GetSingleValue<string>(DicomTag.ContentDate) + dataset.GetSingleValue<string>(DicomTag.ContentTime), out DateTime dt) ? dt : null,
//InstanceTime = dataset.GetSingleValueOrDefault(DicomTag.ContentDate,(DateTime?)null)?.Add(dataset.GetSingleValueOrDefault(DicomTag.ContentTime, TimeSpan.Zero)),
//dataset.GetSingleValueOrDefault(DicomTag.ContentDate,DateTime.Now);//, DicomTag.ContentTime)
CPIStatus = false,
ImageRows = dataset.GetSingleValueOrDefault(DicomTag.Rows, 0),
ImageColumns = dataset.GetSingleValueOrDefault(DicomTag.Columns, 0),
SliceLocation = dataset.GetSingleValueOrDefault(DicomTag.SliceLocation, 0),
SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty),
NumberOfFrames = dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 0),
PixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.PixelSpacing, string.Empty),
ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
FrameOfReferenceUID = dataset.GetSingleValueOrDefault(DicomTag.FrameOfReferenceUID, string.Empty),
WindowCenter = dataset.GetSingleValueOrDefault(DicomTag.WindowCenter, string.Empty),
WindowWidth = dataset.GetSingleValueOrDefault(DicomTag.WindowWidth, string.Empty),
};
++findStudy.InstanceCount;
++findSerice.InstanceCount;
}
if (isStudyNeedAdd)
{
await _studyRepository.AddAsync(findStudy);
}
if(isSeriesNeedAdd)
{
await _seriesRepository.AddAsync(findSerice);
}
if(isInstanceNeedAdd)
{
await _instanceRepository.AddAsync(findInstance);
}
await _studyRepository.SaveChangesAsync();
}
}
} }
} }
@@ -0,0 +1,688 @@
using EasyCaching.Core;
using FellowOakDicom;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit;
using MathNet.Numerics;
using Medallion.Threading;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service.ImageAndDoc
{
public interface IDownloadAndUploadService
{
Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isAnonymize = true);
}
[ApiExplorerSettings(GroupName = "Trial")]
public class DownloadAndUploadService : BaseService, IDownloadAndUploadService
{
private readonly IEasyCachingProvider _provider;
private readonly IRepository<SystemAnonymization> _systemAnonymizationRepository;
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IOSSService _oSSService;
private readonly IRepository<StudyMonitor> _studyMonitorRepository;
private readonly IDistributedLockProvider _distributedLockProvider;
public DownloadAndUploadService(IEasyCachingProvider provider, IRepository<SystemAnonymization> systemAnonymizationRepository, IRepository<SubjectVisit> subjectVisitRepository, IOSSService oSSService,
IRepository<StudyMonitor> studyMonitorRepository, IDistributedLockProvider distributedLockProvider, IRepository<VisitTask> visitTaskRepository)
{
_systemAnonymizationRepository = systemAnonymizationRepository;
_subjectVisitRepository = subjectVisitRepository;
_oSSService = oSSService;
_studyMonitorRepository = studyMonitorRepository;
_distributedLockProvider = distributedLockProvider;
_provider = provider;
_visitTaskRepository = visitTaskRepository;
}
/// <summary>
/// 受试者随机阅片,任务进行随机编号
/// 进入阅片任务前,随机挑选出该受试者的一个任务,然后给该任务一个编号,编号给的逻辑是:TimePoint Ran+ 已阅任务数量+1
/// 根据当前受试者该标准已阅任务数量(生效失效的任务都算,考虑重阅,最后编号不重复) 第一个就是TimePoint Ran1,后面依次随机挑选出来的阅片序号依次递增
/// </summary>
/// <param name="subjectId"></param>
/// <param name="trialReadingCriterionId"></param>
/// <returns></returns>
public async Task<IResponseOutput> SubejctRandomReadingTaskNameDeal(Guid subjectId, Guid trialReadingCriterionId)
{
//subject 随机阅片 才处理任务编号
if (_visitTaskRepository.Any(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom))
{
//找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务
var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
&& t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskBlindName == "Timepoint" && t.ReadingCategory == ReadingCategory.Visit
&& (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze), true).ToListAsync();
if (needDealTaskList.Count > 0)
{
//已完成的访视任务数量(包含重阅的)
var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
&& t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit);
//已经处理过的任务名称的数量
var haveDealedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
&& t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint");
//随机赋值编号 比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个
List<int> availableNumbers = Enumerable.Range(haveDealedTaskCount + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList();
Random rng = new Random();
foreach (var visitTask in needDealTaskList)
{
int randomIndex = rng.Next(availableNumbers.Count);
visitTask.TaskBlindName = $"Timepoint Ran {availableNumbers[randomIndex]}";
availableNumbers.RemoveAt(randomIndex);
}
await _visitTaskRepository.SaveChangesAsync();
}
}
return ResponseOutput.Ok();
}
/// <summary>
/// 获取该受试者任务上传列表(展示已上传情况)
/// </summary>
/// <param name="subjectId"></param>
/// <param name="trialReadingCriterionId"></param>
/// <returns></returns>
public async Task<IResponseOutput<List<SubjectImageUploadDTO>>> GetSubjectImageUploadList(Guid subjectId, Guid trialReadingCriterionId)
{
await SubejctRandomReadingTaskNameDeal(subjectId, trialReadingCriterionId);
var query = _repository.Where<VisitTask>(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.SourceSubjectVisitId != null
&& t.DoctorUserId == _userInfo.Id && t.TaskState==TaskState.Effect)
.Select(u => new SubjectImageUploadDTO()
{
VisitTaskId = u.Id,
SubejctId = u.SubjectId,
TrialSiteId = u.Subject.TrialSiteId,
IsImageFilter = u.TrialReadingCriterion.IsImageFilter,
CriterionModalitys = u.TrialReadingCriterion.CriterionModalitys,
SubjectCode = u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code,
TaskBlindName = u.TaskBlindName,
TaskName = u.TaskName,
SourceSubjectVisitId = u.SourceSubjectVisitId,
PackState = u.SourceSubjectVisit.PackState,
OrginalStudyList = u.SourceSubjectVisit.StudyList
.Where(t => u.TrialReadingCriterion.IsImageFilter ?("|"+u.TrialReadingCriterion.CriterionModalitys+"|").Contains("|"+t.ModalityForEdit+"|" ) : true)
.Select(t => new StudyBasicInfo()
{
Id = t.Id,
StudyInstanceUid = t.StudyInstanceUid,
ModalityForEdit = t.ModalityForEdit,
BodyPartExamined = t.BodyPartExamined,
BodyPartForEdit = t.BodyPartForEdit,
StudyCode = t.StudyCode,
StudyTime = t.StudyTime,
Description = t.Description,
InstanceCount = t.InstanceCount,
Modalities = t.Modalities,
SeriesCount = t.SeriesCount,
}).ToList(),
UploadStudyList = u.TaskStudyList.Select(t => new StudyBasicInfo()
{
Id = t.Id,
StudyInstanceUid = t.StudyInstanceUid,
ModalityForEdit = t.ModalityForEdit,
BodyPartExamined = t.BodyPartExamined,
BodyPartForEdit = t.BodyPartForEdit,
StudyCode = t.StudyCode,
StudyTime = t.StudyTime,
Description = t.Description,
InstanceCount = t.InstanceCount,
Modalities = t.Modalities,
SeriesCount = t.SeriesCount,
SopInstanceUidList = t.InstanceList.Select(t => t.SopInstanceUid).ToList(),
}).ToList()
})
;
var list = await query.ToListAsync();
return ResponseOutput.Ok(list);
}
private void SpecialArchiveStudyDeal(TaskStudy study)
{
#region
if (study.PatientBirthDate.Length == 8)
{
study.PatientBirthDate = $"{study.PatientBirthDate[0]}{study.PatientBirthDate[1]}{study.PatientBirthDate[2]}{study.PatientBirthDate[3]}-{study.PatientBirthDate[4]}{study.PatientBirthDate[5]}-{study.PatientBirthDate[6]}{study.PatientBirthDate[7]}";
}
var dicModalityList = _repository.Where<Dictionary>(t => t.Code == "Modality").SelectMany(t => t.ChildList.Select(c => c.Value)).ToList();
var modality = study.Modalities;
var modalityForEdit = dicModalityList.Contains(modality) ? modality : String.Empty;
if (modality == "MR")
{
modalityForEdit = "MRI";
}
if (modality == "PT")
{
modalityForEdit = "PET";
}
if (modality == "PT、CT")
{
modalityForEdit = "PET-CT";
}
study.ModalityForEdit = modalityForEdit;
#endregion
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> PreArchiveDicomStudy(PriArchiveTaskStudyCommand preArchiveStudyCommand)
{
var studyMonitor = new StudyMonitor()
{
TrialId = preArchiveStudyCommand.TrialId,
SubjectId = preArchiveStudyCommand.SubjectId,
SubjectVisitId = preArchiveStudyCommand.SubjectVisitId,
IsSuccess = false,
UploadStartTime = DateTime.Now,
IsDicom = true,
IP = _userInfo.IP,
IsDicomReUpload = preArchiveStudyCommand.IsDicomReUpload,
FileSize = preArchiveStudyCommand.FileSize,
FileCount = preArchiveStudyCommand.FileCount,
};
var addEntity = await _studyMonitorRepository.AddAsync(studyMonitor, true);
return ResponseOutput.Ok(addEntity.Id);
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> AddOrUpdateArchiveTaskStudy(TaskArchiveStudyCommand incommand)
{
#region subject 访
var queryStudy = _repository.Where<VisitTask>(t => t.SubjectId == incommand.SubjectId && t.SourceSubjectVisitId != null && t.DoctorUserId == _userInfo.Id).Select(u => new
{
VisitTaskId = u.Id,
SourceSubjectVisitId = u.SourceSubjectVisitId,
OrginalStudyList = u.SourceSubjectVisit.StudyList.Select(t => new StudyBasicInfo()
{
Id = t.Id,
StudyInstanceUid = t.StudyInstanceUid
}).ToList(),
});
var studyList = await queryStudy.ToListAsync();
var findOriginStudy = studyList.FirstOrDefault(c => c.OrginalStudyList.Any(t => t.StudyInstanceUid == incommand.Study.StudyInstanceUid));
if (findOriginStudy == null)
{
return ResponseOutput.NotOk("该检查不属于该受试者,请核查");
}
#endregion
var modalitys = string.Empty;
try
{
var trialId = incommand.TrialId;
var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId);
studyMonitor.UploadFinishedTime = DateTime.Now;
studyMonitor.ArchiveFinishedTime = DateTime.Now;
studyMonitor.FailedFileCount = incommand.FailedFileCount;
studyMonitor.IsSuccess = incommand.FailedFileCount == 0;
studyMonitor.RecordPath = incommand.RecordPath;
//上传
if (studyMonitor.IsDicomReUpload == false)
{
var study = _mapper.Map<TaskStudy>(incommand.Study);
var @lock = _distributedLockProvider.CreateLock($"StudyCode");
using (await @lock.AcquireAsync())
{
//查询数据库获取最大的Code 没有记录则为0
var dbStudyCodeIntMax = _repository.Where<TaskStudy>(s => s.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max();
//获取缓存中的值 并发的时候,需要记录,已被占用的值 这样其他线程在此占用的最大的值上递增
var cacheMaxCodeInt = _provider.Get<int>($"{trialId}_{StaticData.CacheKey.StudyMaxCode}").Value;
int currentNextCodeInt = cacheMaxCodeInt > dbStudyCodeIntMax ? cacheMaxCodeInt + 1 : dbStudyCodeIntMax + 1;
study.Code = currentNextCodeInt;
study.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy));
_provider.Set<int>($"{trialId}_{StaticData.CacheKey.StudyMaxCode}", study.Code, TimeSpan.FromMinutes(30));
}
study.Id = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString(), findOriginStudy.VisitTaskId.ToString());
study.TrialId = incommand.TrialId;
study.SubjectId = incommand.SubjectId;
study.VisitTaskId = findOriginStudy.VisitTaskId;
//study.SubjectVisitId = incommand.SubjectVisitId;
//特殊处理逻辑
study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Distinct());
SpecialArchiveStudyDeal(study);
modalitys = study.Modalities;
await _repository.AddAsync(study);
studyMonitor.StudyId = study.Id;
studyMonitor.StudyCode = study.StudyCode;
foreach (var seriesItem in incommand.Study.SeriesList)
{
var series = _mapper.Map<TaskSeries>(seriesItem);
series.Id = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, incommand.TrialId.ToString(), findOriginStudy.VisitTaskId.ToString());
series.StudyId = study.Id;
series.TrialId = incommand.TrialId;
series.SubjectId = incommand.SubjectId;
//series.SubjectVisitId = incommand.SubjectVisitId;
series.VisitTaskId = findOriginStudy.VisitTaskId;
//前端传递的数量不准,上传的时候,把失败的也加进来了,以实际数组的数字为准
series.InstanceCount = seriesItem.InstanceList.Count;
await _repository.AddAsync(series);
foreach (var instanceItem in seriesItem.InstanceList)
{
var isntance = _mapper.Map<TaskInstance>(instanceItem);
Guid instanceId = IdentifierHelper.CreateGuid(study.StudyInstanceUid, series.SeriesInstanceUid, isntance.SopInstanceUid, study.TrialId.ToString(), findOriginStudy.VisitTaskId.ToString());
isntance.Id = instanceId;
isntance.StudyId = study.Id;
isntance.SeriesId = series.Id;
isntance.TrialId = incommand.TrialId;
isntance.SubjectId = incommand.SubjectId;
//isntance.SubjectVisitId = incommand.SubjectVisitId;
isntance.VisitTaskId = findOriginStudy.VisitTaskId;
await _repository.AddAsync(isntance);
}
}
}
else
{
var studyId = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString(), findOriginStudy.VisitTaskId.ToString());
var study = await _repository.FirstOrDefaultAsync<TaskStudy>(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());
SpecialArchiveStudyDeal(study);
modalitys = study.Modalities;
// 少了整个序列
//某个序列下少了instance
foreach (var seriesItem in incommand.Study.SeriesList)
{
var seriesId = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, trialId.ToString(), findOriginStudy.VisitTaskId.ToString());
TaskSeries dicomSeries = await _repository.FirstOrDefaultAsync<TaskSeries>(t => t.Id == seriesId);
//判断重复
if (dicomSeries == null)
{
var series = _mapper.Map<TaskSeries>(seriesItem);
series.Id = seriesId;
series.StudyId = study.Id;
series.TrialId = incommand.TrialId;
series.SubjectId = incommand.SubjectId;
series.VisitTaskId = findOriginStudy.VisitTaskId;
//series.SubjectVisitId = incommand.SubjectVisitId;
dicomSeries = await _repository.AddAsync(series);
//新的序列 那么 检查的序列数量+1
study.SeriesCount += 1;
}
else
{
//该序列掉了instance
dicomSeries.InstanceCount += seriesItem.InstanceList.Count;
}
foreach (var instanceItem in seriesItem.InstanceList)
{
var insntance = _mapper.Map<TaskInstance>(instanceItem);
insntance.Id = IdentifierHelper.CreateGuid(insntance.StudyInstanceUid, insntance.SeriesInstanceUid, insntance.SopInstanceUid, trialId.ToString(), findOriginStudy.VisitTaskId.ToString());
insntance.StudyId = study.Id;
insntance.SeriesId = dicomSeries.Id;
insntance.TrialId = incommand.TrialId;
insntance.SubjectId = incommand.SubjectId;
insntance.VisitTaskId = findOriginStudy.VisitTaskId;
await _repository.AddAsync(insntance);
}
// 不管是新的序列 还是 该序列 掉了Instance 重传的时候 检查的instance 数量都会增加
study.InstanceCount += seriesItem.InstanceList.Count;
}
}
var @lock2 = _distributedLockProvider.CreateLock($"StudyCommit");
using (await @lock2.AcquireAsync())
{
await _repository.SaveChangesAsync();
}
}
catch (Exception ex)
{
return ResponseOutput.NotOk(ex.Message);
}
finally
{
_provider.Remove($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}");
}
return ResponseOutput.Ok(modalitys);
}
[HttpDelete]
public async Task<IResponseOutput> DeleteTaskStudy(Guid visitTaskId)
{
await _repository.BatchDeleteAsync<TaskStudy>(t => t.VisitTaskId == visitTaskId);
await _repository.BatchDeleteAsync<TaskSeries>(t => t.VisitTaskId == visitTaskId);
await _repository.BatchDeleteAsync<TaskInstance>(t => t.VisitTaskId == visitTaskId);
return ResponseOutput.Ok();
}
/// <summary>
/// 打包和匿名化影像 默认是匿名化打包,也可以不匿名化打包
/// </summary>
/// <param name="trialId"></param>
/// <param name="subjectVisitId"></param>
/// <param name="isAnonymize"></param>
/// <returns></returns>
public async Task<IResponseOutput> RequestPackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isAnonymize = true)
{
var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId);
if (subjectVisit.PackState == PackState.WaitPack)
{
HangfireJobHelper.NotImmediatelyOnceOnlyJob<IDownloadAndUploadService>(t => t.PackageAndAnonymizImage(trialId, subjectVisitId, isAnonymize), TimeSpan.FromSeconds(1));
subjectVisit.PackState = PackState.Packing;
await _subjectVisitRepository.SaveChangesAsync();
}
return ResponseOutput.Ok(subjectVisit.VisitImageZipPath);
}
/// <summary>
/// 后台任务调用,前端忽略该接口
/// </summary>
/// <param name="trialId"></param>
/// <param name="subjectVisitId"></param>
/// <param name="isAnonymize"></param>
/// <returns></returns>
public async Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isAnonymize = true)
{
var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId);
try
{
var addOrUpdateFixedFieldList = new List<SystemAnonymization>();
var ircFieldList = new List<SystemAnonymization>();
if (isAnonymize)
{
var systemAnonymizationList = _systemAnonymizationRepository.Where(t => t.IsEnable).ToList();
addOrUpdateFixedFieldList = systemAnonymizationList.Where(t => t.IsFixed).ToList();
ircFieldList = systemAnonymizationList.Where(t => t.IsFixed == false).ToList();
}
var subjectAndVisitInfo = _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => new { SubjectCode = t.Subject.Code, t.Trial.TrialCode, t.VisitNum }).FirstOrDefault();
var query = from sv in _subjectVisitRepository.Where(t => t.Id == subjectVisitId)
select new
{
SubjectCode = sv.Subject.Code,
VisitName = sv.VisitName,
StudyList = sv.StudyList.Select(u => new
{
u.PatientId,
u.StudyTime,
u.StudyCode,
SeriesList = u.SeriesList.Select(z => new
{
z.Modality,
InstancePathList = z.DicomInstanceList.Select(k => new
{
k.Path
})
})
})
};
var info = query.FirstOrDefault();
if (info != null)
{
// 创建一个临时文件夹来存放文件
string tempFolderPath = Path.Combine(Directory.GetCurrentDirectory(), $"DownloadTemp_{NewId.NextGuid()}");
Directory.CreateDirectory(tempFolderPath);
// 遍历查询结果
foreach (var studyInfo in info.StudyList)
{
// 遍历 Series
foreach (var seriesInfo in studyInfo.SeriesList)
{
string studyFolderPath = Path.Combine(tempFolderPath, $"{info.SubjectCode}_{info.VisitName}", $"{studyInfo.StudyCode}_{studyInfo.StudyTime?.ToString("yyyy-MM-dd")}_{seriesInfo.Modality}");
// 创建 影像 文件夹
Directory.CreateDirectory(studyFolderPath);
// 遍历 InstancePathList
foreach (var instanceInfo in seriesInfo.InstancePathList)
{
// 复制文件到相应的文件夹
string destinationPath = Path.Combine(studyFolderPath, Path.GetFileName(instanceInfo.Path));
//下载到当前目录
await _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath);
#region
if (isAnonymize)
{
//受试者随机阅片,需要匿名化检查时间
DicomFile dicomFile = await DicomFile.OpenAsync(destinationPath, Encoding.Default);
DicomDataset dataset = dicomFile.Dataset;
dataset.AddOrUpdate(DicomTag.StudyDate, string.Empty);
dataset.AddOrUpdate(DicomTag.StudyTime, string.Empty);
#region tag匿名化
//DicomFile dicomFile = await DicomFile.OpenAsync(destinationPath, Encoding.Default);
//DicomDataset dataset = dicomFile.Dataset;
//foreach (var item in addOrUpdateFixedFieldList)
//{
// var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16));
// dataset.AddOrUpdate(dicomTag, item.ReplaceValue);
//}
//foreach (var item in ircFieldList)
//{
// var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16));
// if (dicomTag == DicomTag.ClinicalTrialProtocolID)
// {
// dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialCode);
// }
// if (dicomTag == DicomTag.ClinicalTrialSiteID)
// {
// //dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialSiteCode);
// }
// if (dicomTag == DicomTag.ClinicalTrialSubjectID)
// {
// dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.SubjectCode);
// }
// if (dicomTag == DicomTag.ClinicalTrialTimePointID)
// {
// dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.VisitNum.ToString());
// }
// if (dicomTag == DicomTag.PatientID)
// {
// dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialCode + "_" + subjectAndVisitInfo.SubjectCode);
// }
//}
#endregion
}
#endregion
}
}
}
var zipPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy.zip");
ZipFile.CreateFromDirectory(tempFolderPath, zipPath);
//上传到Oss
var relativePath = await _oSSService.UploadToOSSAsync(zipPath, $"download_zip", false);
//subjectVisit.PackState = PackState.Packed;
//subjectVisit.VisitImageZipPath = relativePath;
//await _subjectVisitRepository.SaveChangesAsync();
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitImageZipPath = relativePath });
//清理文件夹
Directory.Delete(tempFolderPath, true);
File.Delete(zipPath);
}
}
catch (Exception ex)
{
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.WaitPack });
}
}
}
}
@@ -49,8 +49,8 @@ namespace IRaCIS.Core.Application.Services
#endregion #endregion
var studyIds = await _studyRepository.AsQueryable() var studyIds = await _studyRepository.AsQueryable()
.Where(t => t.TrialId == imageShareCommand.TrialId && t.SubjectId == imageShareCommand.SubjectId && .Where(t => t.TrialId == imageShareCommand.TrialId && t.SubjectId == imageShareCommand.SubjectId
t.SiteId == imageShareCommand.SiteId) )
.Select(u => u.Id).ToListAsync(); .Select(u => u.Id).ToListAsync();
if (!studyIds.Any()) if (!studyIds.Any())
@@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using System.Linq.Dynamic.Core;
namespace IRaCIS.Core.Application.Services namespace IRaCIS.Core.Application.Services
{ {
@@ -26,7 +27,7 @@ namespace IRaCIS.Core.Application.Services
[HttpGet("{seriesId:guid}")] [HttpGet("{seriesId:guid}")]
public async Task<IResponseOutput<List<DicomInstanceDTO>>> List(Guid seriesId) public async Task<IResponseOutput<List<DicomInstanceDTO>>> List(Guid seriesId)
{ {
var list = await _instanceRepository.Where(s => s.SeriesId == seriesId).OrderBy(s => s.InstanceNumber). var list = await _instanceRepository.Where(s => s.SeriesId == seriesId)/*.OrderBy(s => s.SliceLocation)*/.OrderBy(s => s.InstanceNumber).
ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime) ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
.ProjectTo<DicomInstanceDTO>(_mapper.ConfigurationProvider).ToListAsync(); .ProjectTo<DicomInstanceDTO>(_mapper.ConfigurationProvider).ToListAsync();
@@ -59,12 +60,6 @@ namespace IRaCIS.Core.Application.Services
path = (await _instanceRepository.Where(s => s.Id == instanceId).Select(t => t.Path).FirstOrDefaultAsync()).IfNullThrowException(); path = (await _instanceRepository.Where(s => s.Id == instanceId).Select(t => t.Path).FirstOrDefaultAsync()).IfNullThrowException();
//DicomInstance dicomInstance = await _instanceRepository.FirstOrDefaultAsync(s => s.Id == instanceId).IfNullThrowException();
//DicomStudy dicomStudy = await _studyRepository.FirstOrDefaultAsync(s => s.Id == dicomInstance.StudyId).IfNullThrowException();
//var (physicalPath, relativePath) = FileStoreHelper.GetDicomInstanceFilePath(_hostEnvironment, dicomStudy.TrialId, dicomStudy.SiteId, dicomStudy.SubjectId, dicomStudy.SubjectVisitId, dicomStudy.Id, dicomInstance.Id);
var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path); var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path);
using (var sw = ImageHelper.RenderPreviewJpeg(physicalPath)) using (var sw = ImageHelper.RenderPreviewJpeg(physicalPath))
@@ -85,16 +80,6 @@ namespace IRaCIS.Core.Application.Services
var filePath = string.Empty; var filePath = string.Empty;
var path = (await _instanceRepository.Where(s => s.Id == instanceId).Select(t=>t.Path).FirstOrDefaultAsync()).IfNullThrowException(); var path = (await _instanceRepository.Where(s => s.Id == instanceId).Select(t=>t.Path).FirstOrDefaultAsync()).IfNullThrowException();
//DicomStudy dicomStudy = await _studyRepository.FirstOrDefaultAsync(s => s.Id == dicomInstance.StudyId).IfNullThrowException();
////if (dicomInstance.Anonymize) //被匿名化
////{
//// filePath = _dicomFileStoreHelper.GetInstanceFilePath(dicomStudy, dicomInstance.SeriesId, dicomInstance.Id + ".Anonymize");
////}
////else
//var (physicalPath, relativePath) = FileStoreHelper.GetDicomInstanceFilePath(_hostEnvironment, dicomStudy.TrialId, dicomStudy.SiteId, dicomStudy.SubjectId, dicomStudy.SubjectVisitId, dicomStudy.Id, dicomInstance.Id);
var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path); var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path);
@@ -1,4 +1,6 @@
namespace IRaCIS.Core.Application.Contracts.Dicom using FellowOakDicom;
namespace IRaCIS.Core.Application.Contracts.Dicom
{ {
public interface IDicomArchiveService public interface IDicomArchiveService
{ {
@@ -18,7 +20,7 @@
////[EasyCachingAble(Expiration = 6000)] ////[EasyCachingAble(Expiration = 6000)]
//string GetSeriesPreview(Guid seriesId); //string GetSeriesPreview(Guid seriesId);
Task ArchiveDicomFileAsync(DicomDataset dicomDataset);
} }
} }
@@ -39,36 +39,23 @@ namespace IRaCIS.Core.Application.Services
ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime) ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime)
.ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync(); .ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();
var idList = await _instanceRepository.Where(s => s.StudyId == studyId).OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber) var instanceList = await _instanceRepository.Where(s => s.StudyId == studyId).OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber)
.ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime) .ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
.Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames,t.InstanceNumber }).ToListAsync();//.GroupBy(u => u.SeriesId); .Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames,t.InstanceNumber,t.HtmlPath }).ToListAsync();//.GroupBy(u => u.SeriesId);
foreach (var item in seriesList) foreach (var series in seriesList)
{ {
item.InstanceList = idList.Where(s => s.SeriesId == item.Id).Select(u => u.Id).ToList();
//处理多帧 series.InstanceInfoList = instanceList.Where(t => t.SeriesId == series.Id).OrderBy(t => t.InstanceNumber).Select(k =>
item.InstancePathList = idList.Where(s => s.SeriesId == item.Id).OrderBy(t => t.InstanceNumber) new InstanceBasicInfo()
.SelectMany(u => {
{ Id = k.Id,
NumberOfFrames = k.NumberOfFrames,
HtmlPath = k.HtmlPath,
Path = k.Path,
InstanceNumber = k.InstanceNumber,
if (u.NumberOfFrames > 1) }).ToList();
{
var pathList = new List<string>();
for (int i = 1; i <= u.NumberOfFrames; i++)
{
pathList.Add(u.Path + "?frame=" + (i - 1));
}
return pathList;
}
else
{
return new List<string> { u.Path };
}
})
.ToList();
} }
#region #region

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