Compare commits

...

208 Commits

Author SHA1 Message Date
he ff72c4aefc sheet页问题修改
continuous-integration/drone/push Build is running Details
2026-08-06 15:01:26 +08:00
he f94d1caa79 导入忽略空格 2026-08-06 15:01:15 +08:00
he 621fab16a0 匹配去掉空格 2026-08-06 15:01:10 +08:00
he 581ee62a5b Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is passing Details
2026-08-06 09:19:30 +08:00
he 8d9a824ac3 提示修改 2026-08-06 09:19:21 +08:00
he 4357185ac7 导入1和0 兼容 2 2026-08-06 09:19:19 +08:00
he 10793c6a93 导入1和0 兼容 2026-08-06 09:19:17 +08:00
he 37100008eb 导出靶段备注 2026-08-06 09:19:15 +08:00
he adc9b2635a 导出模版只导出靶段 2026-08-06 09:19:12 +08:00
he ffb8894608 导出修改 2026-08-06 09:19:04 +08:00
hang 62421988c4 增加日志详细信息:get请求参数,请求 OS Browser 信息
continuous-integration/drone/push Build is passing Details
2026-08-05 14:13:42 +08:00
hang 96650ced2d Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-08-04 15:08:15 +08:00
hang cdcd3154b4 中心调研这里增加额外的验证 2026-08-04 15:08:13 +08:00
he ef7f0ebc4a 重新发布
continuous-integration/drone/push Build is running Details
2026-08-04 14:32:19 +08:00
he c5eaf847cc 修改行数 2026-08-04 14:27:46 +08:00
he 739f610d4e 字典修改
continuous-integration/drone/push Build is passing Details
2026-08-04 14:15:13 +08:00
he 5c8ccdf434 导入修改
continuous-integration/drone/push Build is running Details
2026-08-04 14:10:22 +08:00
he e0b80b3316 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-08-04 13:32:54 +08:00
he d4bbe47b81 导出修改 2026-08-04 13:32:51 +08:00
hang dc16cc2018 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-08-04 11:38:57 +08:00
hang 2f930ddca3 ivus隐藏导表 2026-08-04 11:38:55 +08:00
he e346593ebb Revert "拷贝病灶"
continuous-integration/drone/push Build is running Details
This reverts commit 282e56e5fc.
2026-08-03 16:47:31 +08:00
he fab6c8c55a Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-08-03 16:43:50 +08:00
he 282e56e5fc 拷贝病灶 2026-08-03 16:43:46 +08:00
hang a600f11422 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10 2026-07-30 17:52:53 +08:00
hang 2db4a293ed 修复后处理增加数量bug 2026-07-30 17:52:44 +08:00
he 8641a11b53 查询修改
continuous-integration/drone/push Build is passing Details
2026-07-30 17:39:10 +08:00
he 980248d899 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is passing Details
2026-07-30 15:59:14 +08:00
he 372ee55241 稽查修改 2026-07-30 15:59:11 +08:00
hang 799c579121 质控 -ivus 空检查过滤
continuous-integration/drone/push Build is running Details
2026-07-29 15:08:06 +08:00
hang 4841a9ac1e Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-07-29 11:47:27 +08:00
hang 287dd5d0bf 导表拆分查询修改 2026-07-29 11:47:24 +08:00
he 32e23ca0a2 修改字典 加英文 2026-07-29 09:34:37 +08:00
he b7d7b8c815 字典修改
continuous-integration/drone/push Build is passing Details
2026-07-29 09:19:22 +08:00
he 96fd034c5a 必填修改
continuous-integration/drone/push Build is running Details
2026-07-28 14:32:21 +08:00
he 6118e0a4f8 重新发布
continuous-integration/drone/push Build is running Details
2026-07-27 14:06:40 +08:00
he c00d1fb89c 重新发布 2026-07-27 14:03:54 +08:00
he 900f4dfb64 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-07-27 13:53:14 +08:00
he 11f8c9ca56 获取单个问题 2026-07-27 13:53:11 +08:00
hang 026f63c730 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is passing Details
2026-07-27 13:43:00 +08:00
hang e322952ff4 IR下载增加字段记录 2026-07-27 13:42:59 +08:00
he e762da2bf5 IUVS和OCT修改
continuous-integration/drone/push Build is running Details
2026-07-27 13:39:28 +08:00
he 822a4331aa 合并 2026-07-27 11:00:19 +08:00
he 2b2ba2a551 配置文件修改 2026-07-27 10:57:29 +08:00
hang 317fbc2ea7 修改生产配置文件
continuous-integration/drone/push Build is running Details
2026-07-27 10:53:20 +08:00
he 0cd9d666c1 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-07-20 16:05:21 +08:00
he 187ea3b92f 配置文件修改 2026-07-20 16:05:18 +08:00
hang d2beb399dd 阅片任务相关 访视信息赋值
continuous-integration/drone/push Build is running Details
2026-07-17 11:08:13 +08:00
he 15623ab515 配置文件修改
continuous-integration/drone/push Build is pending Details
2026-07-16 14:24:03 +08:00
he f771a23c2a Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10 2026-07-16 14:23:04 +08:00
he f20b8708a3 参数修改 2026-07-16 14:23:02 +08:00
hang 536ed731ed 一致性核查绑定模板修改
continuous-integration/drone/push Build is running Details
2026-07-14 17:27:43 +08:00
he 5b10619460 消息通知
continuous-integration/drone/push Build is running Details
2026-07-14 17:12:38 +08:00
he 311ac85419 重复请求code改为-4 取消Get类型验证
continuous-integration/drone/push Build is running Details
2026-07-14 16:58:17 +08:00
he dba3351195 Prod Ray plus bucker 修改
continuous-integration/drone/push Build is passing Details
2026-07-14 13:27:38 +08:00
he 506d6504c7 添加睿佳生产环境配置
continuous-integration/drone/push Build is running Details
2026-07-14 11:35:53 +08:00
he 1eede7832b 配置修改
continuous-integration/drone/push Build is running Details
2026-07-14 11:02:24 +08:00
he 5ec79bb61b 邮箱配置修改
continuous-integration/drone/push Build is running Details
2026-07-14 11:00:31 +08:00
hang 548863845b 修改睿佳数据库配置文件
continuous-integration/drone/push Build is passing Details
2026-07-13 16:28:31 +08:00
hang 2f73376ff6 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-07-13 16:22:46 +08:00
hang 9a8ee3a6aa 增加睿佳部署配置文件 2026-07-13 16:22:45 +08:00
he 28e367eb88 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10 2026-07-10 18:05:16 +08:00
he 7d642b46c9 维护项目受试者名称 2026-07-10 18:05:14 +08:00
hang 2be6757e23 盲态名称修改
continuous-integration/drone/push Build is running Details
2026-07-10 14:26:35 +08:00
hang 4ca67212aa 双重阅片,盲态名称不一样
continuous-integration/drone/push Build is passing Details
2026-07-10 11:13:42 +08:00
hang 503f99ccbe 修改部署配置文件读取方式
continuous-integration/drone/push Build is running Details
2026-07-10 10:39:43 +08:00
hang 93410b4075 增加1s延时测试热更新
continuous-integration/drone/push Build is passing Details
2026-07-10 09:45:20 +08:00
hang a96945201f 盲态名称查询
continuous-integration/drone/push Build is passing Details
2026-07-09 16:27:05 +08:00
hang 35c495f8a8 搜索条件
continuous-integration/drone/push Build is running Details
2026-07-09 16:22:54 +08:00
hang 9abd8e2c54 医学反馈仓储查询修改
continuous-integration/drone/push Build is passing Details
2026-07-09 14:00:03 +08:00
hang b9a79f0658 修改随机阅片任务盲态名字
continuous-integration/drone/push Build is passing Details
2026-07-09 13:48:39 +08:00
hang 83111d3338 增加缓存类别
continuous-integration/drone/push Build is running Details
2026-07-09 09:53:34 +08:00
hang 92072d3640 中心调研退出后改加入逻辑修改
continuous-integration/drone/push Build is passing Details
2026-07-09 09:07:51 +08:00
hang fd0ea313c2 中心调研人员退出bug
continuous-integration/drone/push Build is running Details
2026-07-08 17:30:39 +08:00
hang 79a15a08cc Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is passing Details
2026-07-08 16:14:23 +08:00
hang 1af798fb04 修改重复影像bug 2026-07-08 16:14:22 +08:00
he c19eb5bab7 添加校验
continuous-integration/drone/push Build is running Details
2026-07-08 14:57:55 +08:00
he db693de576 备注添加
continuous-integration/drone/push Build is running Details
2026-07-08 14:55:34 +08:00
he 651fa35018 自定义复制 2026-07-08 14:52:46 +08:00
he 36f1e9e8dd Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is passing Details
2026-07-08 14:42:20 +08:00
he 7e454467d1 赋值分割 2026-07-08 14:42:20 +08:00
hang 978caf8e9c 修改拷贝影像bug
continuous-integration/drone/push Build is passing Details
2026-07-08 13:56:39 +08:00
hang 2bf4e5d8fd 修改变量名错误
continuous-integration/drone/push Build is passing Details
2026-07-08 10:42:21 +08:00
hang dfb0c5a61c 优化写法
continuous-integration/drone/push Build is passing Details
2026-07-08 10:00:18 +08:00
hang 9d54fac8c5 无序阅片没有拷贝后续表单
continuous-integration/drone/push Build is passing Details
2026-07-08 09:36:16 +08:00
hang 5842590f6d 修改拷贝影像
continuous-integration/drone/push Build is running Details
2026-07-08 09:35:18 +08:00
hang 06a60cac38 拷贝影像不跟拷贝表单绑定
continuous-integration/drone/push Build is running Details
2026-07-08 09:29:21 +08:00
hang dac5eb0d7d 修改稽查报错
continuous-integration/drone/push Build is passing Details
2026-07-07 17:10:16 +08:00
hang 923edf166b subject状态变更撤销修改
continuous-integration/drone/push Build is passing Details
2026-07-07 10:20:43 +08:00
hang a0776e5462 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-07-07 09:47:51 +08:00
hang 9ac6d3df70 IR申请重阅,拷贝dicom 非dicom 影像 2026-07-07 09:47:50 +08:00
he a8a3104019 任务Id修改 2026-07-07 09:32:17 +08:00
he 7cd476028a 受试者图表数据修改
continuous-integration/drone/push Build is running Details
2026-07-07 09:24:54 +08:00
he fe96ff5924 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is passing Details
2026-07-06 17:49:07 +08:00
he 890d349ee9 获取项目链接过期时间 返回研究方案号 2026-07-06 17:49:06 +08:00
hang 895eaa42c8 列表接口返回状态字段
continuous-integration/drone/push Build is running Details
2026-07-06 17:13:01 +08:00
hang 2e4457b56d Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is passing Details
2026-07-06 16:58:05 +08:00
hang b30638fa82 增加访视状态退回原因 2026-07-06 16:58:03 +08:00
he a3fac7bcb1 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-07-06 15:58:31 +08:00
he 7228bdd9e9 修改项目受试者名称 2026-07-06 15:58:30 +08:00
hang fa84171da4 写配置文件加锁
continuous-integration/drone/push Build is running Details
2026-07-06 11:31:35 +08:00
hang f4c3f685eb 区分标准判断逻辑bug
continuous-integration/drone/push Build is running Details
2026-07-03 18:09:17 +08:00
he db17d23360 功能修改
continuous-integration/drone/push Build is passing Details
2026-07-03 16:42:57 +08:00
he 76fe1e12d3 邮件内容修改
continuous-integration/drone/push Build is running Details
2026-07-03 16:25:19 +08:00
he d7f455c740 邮件名称替换
continuous-integration/drone/push Build is running Details
2026-07-03 14:24:01 +08:00
he d62d7172d0 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-07-03 11:05:23 +08:00
he 9bfdb2f06a 答案异常 与裁判异常 发邮件给PM 2026-07-03 11:05:22 +08:00
hang d6436b01d4 中心调研,仅仅上传文件,不用验证
continuous-integration/drone/push Build is passing Details
2026-07-02 15:38:17 +08:00
hang e848ee1972 修改密码设置状态
continuous-integration/drone/push Build is passing Details
2026-07-02 14:42:30 +08:00
hang 2716b462b1 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is passing Details
2026-07-01 17:31:47 +08:00
hang 10f3db1ec2 优化查询,增加字段 2026-07-01 17:31:46 +08:00
he 0848a441b1 阅片问题重复提示修改
continuous-integration/drone/push Build is passing Details
2026-07-01 15:59:55 +08:00
he 00c59958e6 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is passing Details
2026-07-01 14:38:04 +08:00
he 9cc438a647 邮件发送修改 2026-07-01 14:38:03 +08:00
hang 1053fdc8a8 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-07-01 11:33:11 +08:00
hang e1ee129f41 中心调研增加上传文件 2026-07-01 11:33:11 +08:00
he dae0cab261 修改编辑 重新发布
continuous-integration/drone/push Build is passing Details
2026-07-01 11:20:49 +08:00
he 5871d054d3 系统文档区分语言
continuous-integration/drone/push Build is passing Details
2026-07-01 09:25:24 +08:00
he a69e8969a4 请求时间修改
continuous-integration/drone/push Build is passing Details
2026-06-30 16:45:34 +08:00
he dd05e26feb 邮件修改
continuous-integration/drone/push Build is running Details
2026-06-30 15:33:55 +08:00
he 8cd8b7cf43 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-06-30 14:04:12 +08:00
he 1d90aba7cd 添加重复请求通知 2026-06-30 14:04:11 +08:00
hang 826aff3d36 中心调研增加字段
continuous-integration/drone/push Build is passing Details
2026-06-30 10:22:05 +08:00
he 718294f776 接口加锁
continuous-integration/drone/push Build is running Details
2026-06-30 09:10:07 +08:00
he 7a003eb490 添加任务名称
continuous-integration/drone/push Build is running Details
2026-06-30 09:09:21 +08:00
he bcceb5d42d 数据通知 2026-06-30 09:09:18 +08:00
he b1802d7d79 修改名称 2026-06-30 09:09:15 +08:00
he e14eeb4da3 异常提醒修改 2026-06-30 09:09:13 +08:00
he f726088cc9 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-06-29 15:55:51 +08:00
he 4082850b7a 只限制 changeDicomReadingQuestionAnswer 接口 以及微信通知 2026-06-29 15:55:51 +08:00
hang 641d61d242 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-06-29 15:43:01 +08:00
hang e2b67bb3f5 返回有序无序 2026-06-29 15:43:00 +08:00
he 1f3e1ceb37 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-06-29 15:35:34 +08:00
he 254e9508b6 任务答案数量验证 2026-06-29 15:35:33 +08:00
hang 631be6d7c7 返回重置密码字段
continuous-integration/drone/push Build is running Details
2026-06-29 15:11:51 +08:00
hang ca31e9a062 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-06-29 14:36:56 +08:00
hang 9fd7d9928a 非dicom 匿名图像 以及用户重置密码 2026-06-29 14:36:55 +08:00
he 9362b2fb23 Revert "临时去掉锁"
This reverts commit e045302d38.
2026-06-29 12:28:49 +08:00
he 1735a4621e 重新发布
continuous-integration/drone/push Build is running Details
2026-06-29 12:18:55 +08:00
he 6ff332367d Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is passing Details
2026-06-29 11:40:10 +08:00
he e045302d38 临时去掉锁 2026-06-29 11:40:09 +08:00
hang 88793cf011 修改过滤
continuous-integration/drone/push Build is running Details
2026-06-29 11:13:30 +08:00
hang a4181f819b 修改受试者状态退回,逻辑判断
continuous-integration/drone/push Build is running Details
2026-06-26 16:33:47 +08:00
hang 79aeb663c6 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-06-26 14:32:51 +08:00
hang 169301836a 修改标准相关邮件过滤 2026-06-26 14:32:50 +08:00
he 71bd67ba01 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-06-26 14:14:55 +08:00
he 3e94dc6518 生效通知改为单独发 2026-06-26 14:14:54 +08:00
hang 503322d57e pd 入组邮件筛选过滤修改
continuous-integration/drone/push Build is running Details
2026-06-26 13:03:50 +08:00
hang 0c9ffbf5e4 修改项目邮件查询列表
continuous-integration/drone/push Build is running Details
2026-06-26 11:45:17 +08:00
he fae7889995 演示用户不发送邮局
continuous-integration/drone/push Build is running Details
2026-06-25 13:48:13 +08:00
he 532e514060 培训过期改为每个人单独发送
continuous-integration/drone/push Build is running Details
2026-06-25 09:55:01 +08:00
he b3a5047ba8 验证重复请求加锁
continuous-integration/drone/push Build is running Details
2026-06-24 15:15:12 +08:00
he 810e6ccb19 禁用的用户不发邮件
continuous-integration/drone/push Build is running Details
2026-06-23 17:15:24 +08:00
he 352e719fae Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-06-23 10:42:55 +08:00
he d8e0c73f56 修改 试验参与者 2026-06-23 10:42:54 +08:00
hang 46374be4c0 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is passing Details
2026-06-22 15:28:27 +08:00
hang 020c5280b3 修改匿名化配置,更新缓存,同时增加代码自动替换excel 关键字 2026-06-22 15:28:25 +08:00
he 4beba23f99 发布
continuous-integration/drone/push Build is running Details
2026-06-18 17:55:05 +08:00
he 59f36cceb4 修改字段名 2026-06-18 17:50:40 +08:00
he d08b409f0e Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-06-18 13:10:44 +08:00
he 1612201101 重新发布 2026-06-18 13:10:43 +08:00
hang 924347361a 去重提交
continuous-integration/drone/push Build is running Details
2026-06-18 11:38:29 +08:00
he 061d212623 修改验证
continuous-integration/drone/push Build is running Details
2026-06-18 11:32:48 +08:00
he af937b3f53 验证不用加token
continuous-integration/drone/push Build is passing Details
2026-06-18 11:18:49 +08:00
he 1faa72c5ea 修改关键帧排序
continuous-integration/drone/push Build is running Details
2026-06-18 10:37:38 +08:00
he db53e5a60b 修改
continuous-integration/drone/push Build is passing Details
2026-06-17 17:37:09 +08:00
he 802e768bad Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-06-17 17:33:09 +08:00
he 67f17cffe0 添加LinkVerificationCode 2026-06-17 17:33:09 +08:00
hang 70160cb937 更新状态,不忽略null值
continuous-integration/drone/push Build is running Details
2026-06-17 17:17:01 +08:00
hang 6e22246555 中心接口增加参数
continuous-integration/drone/push Build is running Details
2026-06-16 17:16:57 +08:00
hang 7ed0258cfd 中心调研增加字段返回禁用的中心 2026-06-16 17:16:55 +08:00
he ddd06c8313 添加中心调研链接过期时间
continuous-integration/drone/push Build is running Details
2026-06-16 15:42:33 +08:00
he d33b84c245 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10
continuous-integration/drone/push Build is running Details
2026-06-16 13:50:08 +08:00
he 14cd5dd91c 替换字典中项目关键字 2026-06-16 13:50:07 +08:00
hang 2b29ebc29b 项目配置增加培训类型呢
continuous-integration/drone/push Build is passing Details
2026-06-16 13:32:15 +08:00
hang 84b65ee122 关键图里增加分割路径,支持下载
continuous-integration/drone/push Build is passing Details
2026-06-16 11:31:06 +08:00
hang c3e9024a57 受试者进展表导表排序变更
continuous-integration/drone/push Build is passing Details
2026-06-16 09:20:50 +08:00
hang d49b5663ba 阅片期查询bug
continuous-integration/drone/push Build is running Details
2026-06-15 14:27:47 +08:00
hang e1386da5ae CRC CRA退出,过滤重传审批列表
continuous-integration/drone/push Build is running Details
2026-06-15 11:10:00 +08:00
hang b9f9af06f4 屏蔽swager 报错接口 2026-06-11 09:44:44 +08:00
he 01a79e0612 新增接口 GetNoneDicomMarkList
continuous-integration/drone/push Build is passing Details
2026-06-10 15:12:07 +08:00
he 3e69d72597 添加标记名称字段
continuous-integration/drone/push Build is passing Details
2026-06-10 14:13:15 +08:00
he f69c7af9d6 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10 2026-06-09 16:33:19 +08:00
he ae03503d76 添加NumberOfFrames 2026-06-09 16:33:18 +08:00
hang 39eade67f0 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10 2026-06-09 16:32:55 +08:00
hang e6d7a0c0e0 返回默认值,如果没有任务 2026-06-09 16:32:53 +08:00
he 98103451e9 添加 SopInstanceUid
continuous-integration/drone/push Build is passing Details
2026-06-09 16:18:33 +08:00
he b64eed88cf 高亮修改
continuous-integration/drone/push Build is passing Details
2026-06-09 16:07:12 +08:00
he bafe61ae64 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10 2026-06-09 15:45:53 +08:00
he 0579c4aeda 功能添加 2026-06-09 15:45:52 +08:00
hang 7599e06b9d 重新触发测试
continuous-integration/drone/push Build is passing Details
2026-06-09 15:19:51 +08:00
hang 8e77d2e3ed 请求改为post 2026-06-09 15:05:46 +08:00
hang c2a129c56a Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10 2026-06-09 15:05:21 +08:00
hang 111d5509bc 医生阅片统计+受试者完成任务状态返回 2026-06-09 15:05:19 +08:00
he 7c9987f3de 获取标记信息
continuous-integration/drone/push Build is passing Details
2026-06-09 14:58:02 +08:00
hang f1471b6424 访视结束,状态回退
continuous-integration/drone/push Build is running Details
2026-06-08 11:35:26 +08:00
hang 935369c05c zip流方式下载影像
continuous-integration/drone/push Build is running Details
2026-06-05 11:27:27 +08:00
hang 2b03f382bd 术语替换-先完整准确匹配,匹配了就跳过,否则就关键字匹配替换
continuous-integration/drone/push Build is running Details
2026-06-04 16:28:17 +08:00
he 152a142d82 添加新增修改表格问题限制
continuous-integration/drone/push Build is failing Details
2026-06-04 14:41:26 +08:00
hang f55ce703b0 升级net10 自动打包分支修改
continuous-integration/drone/push Build is running Details
2026-06-04 14:12:09 +08:00
hang a08c8a0d64 升级除开收费包以外所有其他包 2026-06-04 13:45:31 +08:00
hang 76dd0c46ae 处理.net10编译错误 2026-06-04 13:19:38 +08:00
hang 1e8056f689 .net10 -合并编译错误 2026-06-04 13:19:17 +08:00
hang 388dac5f8d 删除无用包 2026-04-30 09:01:24 +08:00
hang ec0a4aeef9 降级automapper 2026-04-29 20:39:41 +08:00
hang 8bf0be9699 ClosedXML 替代 npoi 修改 2026-04-29 20:19:01 +08:00
hang 7707b339dc 打印运行时版本 2026-04-29 16:57:27 +08:00
hang 8eaa6606c4 升级.net10 2026-04-29 15:56:41 +08:00
155 changed files with 161781 additions and 2464 deletions

9
Directory.Build.props Normal file
View File

@ -0,0 +1,9 @@
<Project>
<PropertyGroup>
<!-- 在这里定义所有项目共享的属性 -->
<TargetFramework>net10.0</TargetFramework>
<!-- 如果需要Nullable等全局设置也可以加在这里 -->
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@ -1,37 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.11" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.5" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.8" />
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="11.0.0" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="AWSSDK.S3" Version="4.0.21" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.5.19" />
<PackageReference Include="AWSSDK.S3" Version="4.0.24" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.7" />
<PackageReference Include="DistributedLock.Core" Version="1.0.8" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.6" />
<PackageReference Include="fo-dicom" Version="5.2.1" />
<PackageReference Include="fo-dicom.Codecs" Version="5.16.1" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Minio" Version="6.0.4" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
<PackageReference Include="DistributedLock.Core" Version="1.0.9" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.7" />
<PackageReference Include="fo-dicom" Version="5.2.6" />
<PackageReference Include="fo-dicom.Codecs" Version="5.16.7" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.8" />
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Minio" Version="7.0.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="4.0.0">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.1.2" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.9.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="10.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.1" />
</ItemGroup>
<ItemGroup>

View File

@ -56,7 +56,7 @@ var _configuration = builder.Configuration;
builder.Services.AddHealthChecks();
//本地化
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddJsonLocalization(options => options.ResourcesPath = new[] { "Resources" });
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()

View File

@ -1,8 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
@ -10,17 +8,17 @@
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="11.0.0" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="AWSSDK.S3" Version="4.0.21" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.5.19" />
<PackageReference Include="AWSSDK.S3" Version="4.0.24" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.7" />
<PackageReference Include="DistributedLock.Core" Version="1.0.9" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.7" />
<PackageReference Include="fo-dicom" Version="5.2.6" />
<PackageReference Include="fo-dicom.Codecs" Version="5.16.7" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
<PackageReference Include="AutoMapper" Version="16.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.8" />
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Minio" Version="7.0.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
<PackageReference Include="My.Extensions.Localization.Json" Version="4.0.0">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
@ -28,7 +26,7 @@
<PackageReference Include="Serilog.Extensions.Hosting" Version="10.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.7" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.1" />
</ItemGroup>
<ItemGroup>

View File

@ -13,7 +13,6 @@ using IRaCIS.Core.SCP.Service;
using MassTransit;
using MassTransit.NewIdProviders;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.DependencyInjection;
using Panda.DynamicWebApi;
using Serilog;
using Serilog.Events;
@ -71,7 +70,7 @@ builder.Services.AddHostedService<FileSyncWorker>();
builder.Services.AddHealthChecks();
//本地化
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddJsonLocalization(options => options.ResourcesPath = new[] { "Resources" });
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()

View File

@ -0,0 +1,76 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
"SyncConfigList": [
{
"Domain": "irc.test.rayplus.net",
"Primary": "AliyunOSS",
"Target": "AWS",
"UploadRegion": "CN",
"TargetRegion": "US",
"IsOpenSync": false
},
{
"Domain": "lili.uat.extimaging.com",
"Primary": "AWS",
"Target": "AliyunOSS",
"UploadRegion": "US",
"TargetRegion": "CN",
"IsOpenSync": false
}
],
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
"BucketName": "rayplus-irc-test-store",
"ViewEndpoint": "https://rayplus-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
// AWS S3
"AWS": {
// AWS S3 Region
"Region": "us-east-1",
// AWS S3 访
"EndPoint": "s3.us-east-1.amazonaws.com",
// 使 SSL
"UseSSL": true,
// AWS S3 ARN
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
// AWS S3 访 ID
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
// AWS S3 访 Secret
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
// AWS S3 Bucket
"BucketName": "ei-med-s3-lili-uat-store",
// AWS S3 访
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
// AWS S3
"DurationSeconds": 7200
}
},
"ConnectionStrings": {
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_Rayplus;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_Rayplus_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"CalledAEList": [
"STORESCP"
],
"ServerPort": 11112
}
}

View File

@ -0,0 +1,76 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
"SyncConfigList": [
{
"Domain": "irc.test.rayplus.net",
"Primary": "AliyunOSS",
"Target": "AWS",
"UploadRegion": "CN",
"TargetRegion": "US",
"IsOpenSync": false
},
{
"Domain": "lili.uat.extimaging.com",
"Primary": "AWS",
"Target": "AliyunOSS",
"UploadRegion": "US",
"TargetRegion": "CN",
"IsOpenSync": false
}
],
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
"BucketName": "rayplus-irc-test-store",
"ViewEndpoint": "https://rayplus-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
// AWS S3
"AWS": {
// AWS S3 Region
"Region": "us-east-1",
// AWS S3 访
"EndPoint": "s3.us-east-1.amazonaws.com",
// 使 SSL
"UseSSL": true,
// AWS S3 ARN
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
// AWS S3 访 ID
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
// AWS S3 访 Secret
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
// AWS S3 Bucket
"BucketName": "ei-med-s3-lili-uat-store",
// AWS S3 访
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
// AWS S3
"DurationSeconds": 7200
}
},
"ConnectionStrings": {
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_Rayplus;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=106.14.89.110,1435;Database=Test_Rayplus_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"CalledAEList": [
"STORESCP"
],
"ServerPort": 11112
}
}

View File

@ -0,0 +1,76 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
"SyncConfigList": [
{
"Domain": "irc.uat.extimaging.com",
"Primary": "AliyunOSS",
"Target": "AWS",
"UploadRegion": "CN",
"TargetRegion": "US",
"IsOpenSync": true
},
{
"Domain": "lili.uat.extimaging.com",
"Primary": "AWS",
"Target": "AliyunOSS",
"UploadRegion": "US",
"TargetRegion": "CN",
"IsOpenSync": true
}
],
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
"BucketName": "zy-irc-test-store",
"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
// AWS S3
"AWS": {
// AWS S3 Region
"Region": "us-east-1",
// AWS S3 访
"EndPoint": "s3.us-east-1.amazonaws.com",
// 使 SSL
"UseSSL": true,
// AWS S3 ARN
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
// AWS S3 访 ID
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
// AWS S3 访 Secret
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
// AWS S3 Bucket
"BucketName": "ei-med-s3-lili-uat-store",
// AWS S3 访
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
// AWS S3
"DurationSeconds": 7200
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_HeAnShu;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server101.132.253.119,1435;Database=Uat_HeAnShu_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"CalledAEList": [
"STORESCP"
],
"ServerPort": 11112
}
}

View File

@ -0,0 +1,76 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
"SyncConfigList": [
{
"Domain": "irc.uat.rayplus.net",
"Primary": "AliyunOSS",
"Target": "AWS",
"UploadRegion": "CN",
"TargetRegion": "US",
"IsOpenSync": false
},
{
"Domain": "lili.uat.extimaging.com",
"Primary": "AWS",
"Target": "AliyunOSS",
"UploadRegion": "US",
"TargetRegion": "CN",
"IsOpenSync": false
}
],
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tFUCCmz5TwghZHsj45Y",
"AccessKeySecret": "8evrBy1fVfzJG25i67Jm0xqn9Xcw2T",
"RoleArn": "acs:ram::1078130221702011:role/uat-oss-access",
"BucketName": "rayplus-irc-uat-store",
"ViewEndpoint": "https://rayplus-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
// AWS S3
"AWS": {
// AWS S3 Region
"Region": "us-east-1",
// AWS S3 访
"EndPoint": "s3.us-east-1.amazonaws.com",
// 使 SSL
"UseSSL": true,
// AWS S3 ARN
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
// AWS S3 访 ID
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
// AWS S3 访 Secret
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
// AWS S3 Bucket
"BucketName": "ei-med-s3-lili-uat-store",
// AWS S3 访
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
// AWS S3
"DurationSeconds": 7200
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_Rayplus;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server101.132.253.119,1435;Database=Uat_Rayplus_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"CalledAEList": [
"STORESCP"
],
"ServerPort": 11112
}
}

View File

@ -1,43 +1,21 @@
using AlibabaCloud.SDK.Sts20150401;
using Amazon.Auth.AccessControlPolicy;
using Amazon.SecurityToken;
using AutoMapper;
using Azure.Core;
using IdentityModel.Client;
using IdentityModel.OidcClient;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit;
using MassTransit.Futures.Contracts;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Org.BouncyCastle.Tls;
using RestSharp;
using RestSharp.Authenticators;
using Serilog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using ZiggyCreatures.Caching.Fusion;
using AssumeRoleRequest = Amazon.SecurityToken.Model.AssumeRoleRequest;
using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO;
namespace IRaCIS.Api.Controllers
{

View File

@ -1,11 +1,9 @@
using AutoMapper;
using ExcelDataReader;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.BusinessFilter;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.Dicom;
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Application.Service;
@ -17,8 +15,6 @@ using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit.Mediator;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
@ -27,21 +23,15 @@ using Microsoft.AspNetCore.StaticFiles;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using MiniExcelLibs;
using Newtonsoft.Json;
using SharpCompress.Archives;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Path = System.IO.Path;
namespace IRaCIS.Core.API.Controllers
@ -132,7 +122,7 @@ namespace IRaCIS.Core.API.Controllers
//处理压缩文件
if (fileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".rar", StringComparison.OrdinalIgnoreCase))
{
var archive = ArchiveFactory.Open(section.Body);
var archive = ArchiveFactory.OpenArchive(section.Body);
foreach (var entry in archive.Entries)
{
@ -213,7 +203,7 @@ namespace IRaCIS.Core.API.Controllers
//处理压缩文件
if (fileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".rar", StringComparison.OrdinalIgnoreCase))
{
var archive = ArchiveFactory.Open(section.Body);
var archive = ArchiveFactory.OpenArchive(section.Body);
foreach (var entry in archive.Entries)
{

View File

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<SignAssembly>false</SignAssembly>
<UserSecretsId>354572d4-9e15-4099-807c-63a2d29ff9f2</UserSecretsId>
<LangVersion>default</LangVersion>
@ -10,6 +9,7 @@
<Company>上海展影医疗科技有限公司</Company>
<Product>IRC影像系统 (EICS)</Product>
<Copyright>上海展影医疗科技有限公司版权所有</Copyright>
<NoWarn>$(NoWarn);NU1903</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@ -69,22 +69,21 @@
<ItemGroup>
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.14" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.15">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="ConfigMapFileProvider" Version="2.0.1" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.20" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.23" />
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
<PackageReference Include="Hangfire.InMemory" Version="1.0.0" />
<PackageReference Include="Hangfire.SqlServer" Version="1.8.20" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
<PackageReference Include="Hangfire.SqlServer" Version="1.8.23" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.8" />
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.Email" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="10.2.1" />
</ItemGroup>
<ItemGroup>

View File

@ -378,6 +378,11 @@
LowerCamelCaseJsonAttribute 可以设置类小写返回给前端
</summary>
</member>
<member name="T:Program">
<summary>
Auto-generated public partial Program class for top-level statement apps.
</summary>
</member>
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
<summary>
对称可逆加密
@ -413,5 +418,49 @@
<param name="withPrivate"></param>
<returns></returns>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Type)">
<summary>
Generates a documentation comment ID for a type.
Example: T:Namespace.Outer+Inner`1 becomes T:Namespace.Outer.Inner`1
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Reflection.PropertyInfo)">
<summary>
Generates a documentation comment ID for a property.
Example: P:Namespace.ContainingType.PropertyName or for an indexer P:Namespace.ContainingType.Item(System.Int32)
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Type,System.String)">
<summary>
Generates a documentation comment ID for a property given its container type and property name.
Example: P:Namespace.ContainingType.PropertyName
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Reflection.MethodInfo)">
<summary>
Generates a documentation comment ID for a method (or constructor).
For example:
M:Namespace.ContainingType.MethodName(ParamType1,ParamType2)~ReturnType
M:Namespace.ContainingType.#ctor(ParamType)
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.GetTypeDocId(System.Type,System.Boolean,System.Boolean)">
<summary>
Generates a documentation ID string for a type.
This method handles nested types (replacing '+' with '.'),
generic types, arrays, pointers, by-ref types, and generic parameters.
The <paramref name="includeGenericArguments"/> flag controls whether
constructed generic type arguments are emitted, while <paramref name="omitGenericArity"/>
controls whether the generic arity marker (e.g. "`1") is appended.
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.NormalizeDocId(System.String)">
<summary>
Normalizes a documentation comment ID to match the compiler-style format.
Strips the return type suffix for ordinary methods but retains it for conversion operators.
</summary>
<param name="docId">The documentation comment ID to normalize.</param>
<returns>The normalized documentation comment ID.</returns>
</member>
</members>
</doc>

View File

@ -4,30 +4,16 @@ using IRaCIS.Core.API.HostService;
using IRaCIS.Core.Application.BusinessFilter;
using IRaCIS.Core.Application.BusinessFilter.LegacyController.Database.Api;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.MassTransit.Consumer;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.Service.BusinessFilter;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit;
using MassTransit.NewIdProviders;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Localization;
using Newtonsoft.Json;
using Serilog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using UAParser;
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
@ -95,6 +81,8 @@ builder.Services.AddSingleton<FileSyncQueue>();
builder.Services.AddHostedService<SyncFileRecoveryService>();
builder.Services.AddHostedService<FileSyncWorker>();
builder.Services.AddSingleton(_ => Parser.GetDefault());
//minimal api 异常处理
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
//builder.Services.AddProblemDetails();
@ -103,7 +91,7 @@ builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
builder.Services.AddHealthChecks();
builder.Services.AddSerilog();
//本地化
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddJsonLocalization(options => options.ResourcesPath = new[] { "Resources" });
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
builder.Services.AddControllers(options =>
@ -286,6 +274,7 @@ try
#region 运行环境 部署平台
Log.Logger.Warning($"当前环境:{enviromentName}");
Log.Logger.Warning($".NET 运行时版本:{Environment.Version}");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{

View File

@ -25,6 +25,24 @@
},
"applicationUrl": "http://0.0.0.0:6100"
},
"IRaCIS.Test_Rayplus": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Test_Rayplus",
"ASPNETCORE_OpenSwagger": "true"
},
"applicationUrl": "http://0.0.0.0:6100"
},
"IRaCIS.Uat_Rayplus": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Uat_Rayplus",
"ASPNETCORE_OpenSwagger": "true"
},
"applicationUrl": "http://0.0.0.0:6100"
},
"IRaCIS.Test_IRC_PGSQL": {
"commandName": "Project",
"launchBrowser": true,

View File

@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Serilog;
using System.Linq;
using UAParser;
namespace IRaCIS.Core.API
{
@ -17,11 +18,14 @@ namespace IRaCIS.Core.API
{
app.UseMiddleware<RequestResponseLoggingMiddleware>();
// 从 DI 容器中获取 Parser 实例
var uaParser = app.ApplicationServices.GetRequiredService<Parser>();
app.UseSerilogRequestLogging(opts
=>
{
opts.MessageTemplate = "{FullName} {UserType} {UserIp} {Host} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
opts.MessageTemplate = "{FullName} {UserType} {UserIp} {Host} {RequestMethod} {RequestPath}{QueryString} {RequestBody} {OS} {Browser} {DeviceType} responded {StatusCode} in {Elapsed:0.0000} ms";
opts.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
{
@ -33,10 +37,9 @@ namespace IRaCIS.Core.API
// Only set it if available. You're not sending sensitive data in a querystring right?!
if (request.QueryString.HasValue)
{
diagnosticContext.Set("QueryString", request.QueryString.Value);
}
diagnosticContext.Set("QueryString", request.QueryString.Value ?? "");
diagnosticContext.Set("FullName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.FullName)?.Value);
@ -52,6 +55,38 @@ namespace IRaCIS.Core.API
diagnosticContext.Set("UserIp", clientIp);
// ==================== 新增:解析 User-Agent ====================
try
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (!string.IsNullOrEmpty(userAgent))
{
var clientInfo = uaParser.Parse(userAgent);
diagnosticContext.Set("OS", clientInfo.OS.ToString());
diagnosticContext.Set("Browser", clientInfo.UA.ToString());
//diagnosticContext.Set("DeviceType", clientInfo.Device.ToString());
diagnosticContext.Set("DeviceType", userAgent.Contains("Mobile") ? "Mobile": "Desktop");
}
else
{
diagnosticContext.Set("OS", "Unknown");
diagnosticContext.Set("Browser", "Unknown");
diagnosticContext.Set("DeviceType", "Unknown");
}
}
catch (Exception ex)
{
// 解析失败时记录异常,但不要影响主流程
diagnosticContext.Set("OS", "ParseError");
diagnosticContext.Set("Browser", "ParseError");
diagnosticContext.Set("DeviceType", "ParseError");
}
// ==============================================================
#region 非必要不记录
//diagnosticContext.Set("Protocol", request.Protocol);
//diagnosticContext.Set("Scheme", request.Scheme);

View File

@ -1,15 +1,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi;
using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
namespace IRaCIS.Core.API;
@ -52,18 +44,21 @@ public static class SwaggerSetup
services.AddSwaggerGen(options =>
{
typeof(SwaggerVersion).GetFields(BindingFlags.Public | BindingFlags.Static).ToList()
.ForEach(field =>
{
var description = field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? field.Name;
options.SwaggerDoc(field.Name, new Microsoft.OpenApi.Models.OpenApiInfo
{
Version = field.Name,
Description = $"{field.Name} API",
Title = description // 使用Description作为Title
});
});
// 使用反射获取字段并动态创建 Swagger 文档
typeof(SwaggerVersion).GetFields(BindingFlags.Public | BindingFlags.Static)
.ToList()
.ForEach(field =>
{
var description = field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? field.Name;
options.SwaggerDoc(field.Name, new OpenApiInfo
{
Version = field.Name,
Description = $"{field.Name} API",
Title = description // 使用 Description 作为 Title
});
});
// 接口排序
options.OrderActionsBy(o => o.GroupName);

View File

@ -7,7 +7,7 @@
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.193.237,1433;Database=Prod_IRC_pidr_restore;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"RemoteNew": "Server=101.132.193.237,1433;Database=Prod_IRC_pidr_restore_new;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=101.132.193.237,1433;Database=irc_Hangfire_bak;User ID=sa;Password=xc@123456;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"
@ -94,7 +94,7 @@
"Imap": "imap.qiye.aliyun.com",
"ImapPort": 993,
"FromEmail": "irc@extimaging.com",
"FromName": "IRC Imaging System",
"FromName": "EIC Imaging System",
"AuthorizationCode": "ExtImg@2022",
"SiteUrl": "http://irc.extimaging.com/login",
@ -117,7 +117,7 @@
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"DuplicationWindowMs": 500,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]

View File

@ -7,10 +7,10 @@
}
},
"ConnectionStrings": {
"RemoteNew": "Server=10.10.10.49,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=10.10.10.49,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"
//"RemoteNew": "Server=10.10.10.49,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
//"Hangfire": "Server=10.10.10.49,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"
},
"WeComNoticeConfig": {
"IsOpenWeComNotice": true,
@ -94,7 +94,7 @@
"Imap": "imap.qiye.aliyun.com",
"ImapPort": 993,
"FromEmail": "irc@extimaging.com",
"FromName": "IRC Imaging System",
"FromName": "EIC Imaging System",
"AuthorizationCode": "ExtImg@2022",
"SiteUrl": "http://irc.extimaging.com/login",
@ -117,7 +117,7 @@
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"DuplicationWindowMs": 500,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]

View File

@ -0,0 +1,143 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_Rayplus;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_Rayplus_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
},
"WeComNoticeConfig": {
"IsOpenWeComNotice": true,
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
"APINoticeUserList": [ "u", "wait..." ],
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
"SyncConfigList": [
{
"Domain": "irc.uat.rayplus.net",
"Primary": "AliyunOSS",
"Target": "AWS",
"UploadRegion": "CN",
"TargetRegion": "US",
"IsOpenSync": false
},
{
"Domain": "lili.uat.extimaging.com",
"Primary": "AWS",
"Target": "AliyunOSS",
"UploadRegion": "US",
"TargetRegion": "CN",
"IsOpenSync": false
}
],
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
"BucketName": "rayplus-irc-store",
"ViewEndpoint": "https://rayplus-irc-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"MinIO": {
"endPoint": "hir-oss.uat.extimaging.com",
"port": "80",
"useSSL": false,
"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
//"port": "443",
//"useSSL": true,
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
"bucketName": "irc-uat"
},
"AWS": {
"Region": "us-east-1",
"EndPoint": "s3.us-east-1.amazonaws.com",
"UseSSL": true,
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
"SecretAccessKey": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
"DurationSeconds": 7200
}
},
"BasicSystemConfig": {
//
"QCRiskControl": true,
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 120,
"OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90,
// 1 Elevate 2 Extensive
"TemplateType": 2,
//MFA
"UserMFAVerifyMinutes": 1440
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"Imap": "imap.qiye.aliyun.com",
"ImapPort": 993,
"FromEmail": "irc@mail.rayplus.net",
"FromName": "RayPlus Imaging System",
"AuthorizationCode": "QWE1zxcv7632",
"SiteUrl": "https://irc.rayplus.net/login",
"PlatformName": "RayPlus",
"PlatformNameCN": "睿佳影像云平台",
"SystemShortName": "RayPlus",
"OrganizationName": "RayPlus",
"OrganizationNameCN": "RayPlus",
"CompanyName": "RayPlus",
"CompanyNameCN": "睿佳(武汉)软件科技有限公司",
"CompanyShortName": "RayPlus",
"CompanyShortNameCN": "睿佳",
"IsEnv_US": false,
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
"CronEmailDefaultCulture": "zh-CN"
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "47.117.165.18"
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]
}
}

View File

@ -1,32 +1,28 @@
{
//
"Logging": {
//
"LogLevel": {
//
"Default": "Information",
//
"Microsoft": "Warning",
// ASP.NET Core
"Microsoft.Hosting.Lifetime": "Information"
}
},
//
"ConnectionStrings": {
//
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
// Hangfire
"Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"WeComNoticeConfig": {
"IsOpenWeComNotice": true,
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
"APINoticeUserList": [ "u", "wait..." ],
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449",
"APINoticeUserList": [
"u",
"wait..."
],
"VueNoticeUserList": [
"wangxiaoshuang",
"6b7717a31647293621b97b96f74e6f3d"
]
},
//
"ObjectStoreService": {
// 使
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
@ -48,168 +44,88 @@
"IsOpenSync": true
}
],
//
"AliyunOSS": {
// OSS Region ID
"RegionId": "cn-shanghai",
// OSS 访
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
// OSS 访
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
// OSS 访 ID
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
// OSS 访 Secret
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
// OSS ARN
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
// OSS Bucket
"BucketName": "zy-irc-test-store",
// OSS 访
"ViewEndpoint": "https://zy-irc-test-dev-cache.oss-cn-shanghai.aliyuncs.com",
// OSS
"Region": "oss-cn-shanghai",
// OSS 访
"DurationSeconds": 7200,
// OSS
"PreviewEndpoint": "https://test-oss.test.extimaging.com"
},
// MinIO
"MinIO": {
// MinIO 访
"EndPoint": "hir-oss.test.extimaging.com",
// MinIO
"Port": "443",
// 使 SSL
"UseSSL": true,
// MinIO ARN
"AccessKey": "fbStsVYCIPKHQneeqMwD",
// MinIO 访
"SecretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
// MinIO BucketName
"BucketName": "irc-test",
// MinIO 访
"ViewEndpoint": "https://hir-oss.test.extimaging.com/irc-test"
},
// AWS S3
"AWS": {
// AWS S3 Region
"Region": "us-east-1",
// AWS S3 访
"EndPoint": "s3.us-east-1.amazonaws.com",
// 使 SSL
"UseSSL": true,
// AWS S3 ARN
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
// AWS S3 访 ID
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
// AWS S3 访 Secret
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
// AWS S3 Bucket
"BucketName": "ei-med-s3-lili-uat-store",
// AWS S3 访
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
// AWS S3
"DurationSeconds": 7200
}
},
//
"BasicSystemConfig": {
//
"QCRiskControl": true,
//
"OpenUserComplexPassword": false,
//
"OpenSignDocumentBeforeWork": false,
//
"OpenLoginLimit": false,
//
"LoginMaxFailCount": 5,
//
"LoginFailLockMinutes": 1,
//
"AutoLoginOutMinutes": 10,
// MFA
"OpenLoginMFA": false,
//
"ContinuousReadingTimeMin": 120,
//
"ReadingRestTimeMin": 10,
//
"IsNeedChangePassWord": true,
//
"ChangePassWordDays": 90,
// 1 ElevateLiLi 2 Extensive()
"TemplateType": 2,
//
"OpenTrialRelationDelete": true,
// PDF
"OpenTrialRelationDelete": false,
"ThirdPdfUrl": "http://106.14.89.110:30088/api/v1/convert/file/pdf",
//MFA
"UserMFAVerifyMinutes": 1440
},
//
"SystemEmailSendConfig": {
// SMTP
"Host": "smtp.qiye.aliyun.com",
// SMTP
"Port": 465,
"Imap": "imap.qiye.aliyun.com",
"ImapPort": 993,
//
"FromEmail": "test@extimaging.com",
//
"FromName": "Test IRC Imaging System",
// SMTP
"FromName": "Test EIC Imaging System",
"AuthorizationCode": "SHzyyl2021",
// 访
"SiteUrl": "http://irc.test.extimaging.com/login",
// - 使
"SystemShortName": "IRC",
// -
"OrganizationName": "ExtImaging",
//
"OrganizationNameCN": "ExtImaging",
"PlatformName": "EICS",
"PlatformNameCN": "展影云平台",
//
"CompanyName": "Extensive Imaging",
//
"CompanyNameCN": "上海展影医疗科技有限公司",
//
"CompanyShortName": "Extensive Imaging",
//
"CompanyShortNameCN": "展影医疗",
// 便lili irc
"IsEnv_US": false,
//
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
//
"CronEmailDefaultCulture": "zh-CN"
},
// PACS
"SystemPacsConfig": {
// PACS
"Port": "11113",
// PACSIP
"IP": "106.14.89.110"
},
//
"RequestDuplicationOptions": {
//
"IsEnabled": true,
//
"DuplicationWindowMs": 200,
//
"DuplicationWindowMs": 500,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]
"ExcludedPaths": []
}
}
}

View File

@ -97,7 +97,7 @@
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"DuplicationWindowMs": 500,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]

View File

@ -0,0 +1,143 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_Rayplus;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=106.14.89.110,1435;Database=Test_Rayplus_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"WeComNoticeConfig": {
"IsOpenWeComNotice": true,
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
"APINoticeUserList": [ "u", "wait..." ],
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
"SyncConfigList": [
{
"Domain": "irc.test.rayplus.net",
"Primary": "AliyunOSS",
"Target": "AWS",
"UploadRegion": "CN",
"TargetRegion": "US",
"IsOpenSync": false
},
{
"Domain": "lili.uat.extimaging.com",
"Primary": "AWS",
"Target": "AliyunOSS",
"UploadRegion": "US",
"TargetRegion": "CN",
"IsOpenSync": false
}
],
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
"BucketName": "rayplus-irc-test-store",
"ViewEndpoint": "https://rayplus-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"MinIO": {
"endPoint": "hir-oss.uat.extimaging.com",
"port": "80",
"useSSL": false,
"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
//"port": "443",
//"useSSL": true,
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
"bucketName": "irc-uat"
},
"AWS": {
"Region": "us-east-1",
"EndPoint": "s3.us-east-1.amazonaws.com",
"UseSSL": true,
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
"SecretAccessKey": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
"DurationSeconds": 7200
}
},
"BasicSystemConfig": {
//
"QCRiskControl": true,
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 120,
"OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90,
// 1 Elevate 2 Extensive
"TemplateType": 2,
//MFA
"UserMFAVerifyMinutes": 1440
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"Imap": "imap.qiye.aliyun.com",
"ImapPort": 993,
"FromEmail": "test_irc@mail.rayplus.net",
"FromName": "Test RayPlus Imaging System",
"AuthorizationCode": "QWE1zxcv7632",
"SiteUrl": "https://irc.test.rayplus.net/login",
"PlatformName": "RayPlus",
"PlatformNameCN": "睿佳影像云平台",
"SystemShortName": "RayPlus",
"OrganizationName": "RayPlus",
"OrganizationNameCN": "RayPlus",
"CompanyName": "RayPlus",
"CompanyNameCN": "睿佳(武汉)软件科技有限公司",
"CompanyShortName": "RayPlus",
"CompanyShortNameCN": "睿佳",
"IsEnv_US": false,
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
"CronEmailDefaultCulture": "zh-CN"
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "101.132.253.119"
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]
}
}

View File

@ -122,7 +122,7 @@
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"DuplicationWindowMs": 500,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]

View File

@ -102,7 +102,7 @@
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"DuplicationWindowMs": 500,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]

View File

@ -107,7 +107,7 @@
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"DuplicationWindowMs": 500,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]

View File

@ -0,0 +1,152 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_HeAnShu;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=101.132.253.119,1435;Database=Uat_HeAnShu_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"WeComNoticeConfig": {
"IsOpenWeComNotice": true,
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
"APINoticeUserList": [ "u", "wait..." ],
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
"SyncConfigList": [
{
"Domain": "irc.uat.rayplus.net",
"Primary": "AliyunOSS",
"Target": "AWS",
"UploadRegion": "CN",
"TargetRegion": "US",
"IsOpenSync": false
},
{
"Domain": "lili.uat.extimaging.com",
"Primary": "AWS",
"Target": "AliyunOSS",
"UploadRegion": "US",
"TargetRegion": "CN",
"IsOpenSync": false
}
],
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tFUCCmz5TwghZHsj45Y",
"AccessKeySecret": "8evrBy1fVfzJG25i67Jm0xqn9Xcw2T",
"RoleArn": "acs:ram::1078130221702011:role/uat-oss-access",
"BucketName": "heanshu-irc-uat-store",
"ViewEndpoint": "https://heanshu-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"MinIO": {
"endPoint": "hir-oss.uat.extimaging.com",
"port": "80",
"useSSL": false,
"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
//"port": "443",
//"useSSL": true,
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
"bucketName": "irc-uat"
},
"AWS": {
"Region": "us-east-1",
"EndPoint": "s3.us-east-1.amazonaws.com",
"UseSSL": true,
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
"SecretAccessKey": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
"DurationSeconds": 7200
}
},
"BasicSystemConfig": {
//
"QCRiskControl": true,
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 120,
"OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90,
// 1 Elevate 2 Extensive
"TemplateType": 2,
//MFA
"UserMFAVerifyMinutes": 1440
},
"SystemEmailSendConfig": {
//"Port": 465,
//"Host": "smtp.qiye.163.com",
//"Imap": "imap.qiye.163.com",
//"ImapPort": 993,
//"FromEmail": "service@heanshu.com",
//"FromName": "Uat HeAnShu Imaging System",
//"AuthorizationCode": "j#cAPU%XgvcHWn3N",
//"SiteUrl": "https://irc.uat.heanshu.com",
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"Imap": "imap.qiye.aliyun.com",
"ImapPort": 993,
"FromEmail": "service@mail.rayplus.net",
"FromName": "Uat HeAnShu Imaging System",
"AuthorizationCode": "crefHpx3WtenFr6X",
"SiteUrl": "https://irc.uat.heanshu.com",
"PlatformName": "HeAnShu",
"PlatformNameCN": "禾安枢影像云平台",
"SystemShortName": "HeAnShu",
"OrganizationName": "HeAnShu",
"OrganizationNameCN": "HeAnShu",
"CompanyName": "HeAnShu",
"CompanyNameCN": "禾安枢软件科技有限公司",
"CompanyShortName": "HeAnShu",
"CompanyShortNameCN": "禾安枢",
"IsEnv_US": false,
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
"CronEmailDefaultCulture": "zh-CN"
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "101.132.253.119"
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]
}
}

View File

@ -110,7 +110,7 @@
"Imap": "imap.qiye.aliyun.com",
"ImapPort": 993,
"FromEmail": "uat@extimaging.com",
"FromName": "Uat IRC Imaging System",
"FromName": "Uat EIC Imaging System",
"AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.uat.extimaging.com/login",
@ -134,7 +134,7 @@
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"DuplicationWindowMs": 500,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]

View File

@ -0,0 +1,143 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_Rayplus;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=101.132.253.119,1435;Database=Uat_Rayplus_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"WeComNoticeConfig": {
"IsOpenWeComNotice": true,
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
"APINoticeUserList": [ "u", "wait..." ],
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
"SyncConfigList": [
{
"Domain": "irc.uat.rayplus.net",
"Primary": "AliyunOSS",
"Target": "AWS",
"UploadRegion": "CN",
"TargetRegion": "US",
"IsOpenSync": false
},
{
"Domain": "lili.uat.extimaging.com",
"Primary": "AWS",
"Target": "AliyunOSS",
"UploadRegion": "US",
"TargetRegion": "CN",
"IsOpenSync": false
}
],
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tFUCCmz5TwghZHsj45Y",
"AccessKeySecret": "8evrBy1fVfzJG25i67Jm0xqn9Xcw2T",
"RoleArn": "acs:ram::1078130221702011:role/uat-oss-access",
"BucketName": "rayplus-irc-uat-store",
"ViewEndpoint": "https://rayplus-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"MinIO": {
"endPoint": "hir-oss.uat.extimaging.com",
"port": "80",
"useSSL": false,
"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
//"port": "443",
//"useSSL": true,
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
"bucketName": "irc-uat"
},
"AWS": {
"Region": "us-east-1",
"EndPoint": "s3.us-east-1.amazonaws.com",
"UseSSL": true,
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
"SecretAccessKey": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
"DurationSeconds": 7200
}
},
"BasicSystemConfig": {
//
"QCRiskControl": true,
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 120,
"OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90,
// 1 Elevate 2 Extensive
"TemplateType": 2,
//MFA
"UserMFAVerifyMinutes": 1440
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"Imap": "imap.qiye.aliyun.com",
"ImapPort": 993,
"FromEmail": "uat@mail.rayplus.net",
"FromName": "Uat RayPlus Imaging System",
"AuthorizationCode": "QWE1zxcv7632",
"SiteUrl": "https://irc.uat.rayplus.net/login",
"PlatformName": "RayPlus",
"PlatformNameCN": "睿佳影像云平台",
"SystemShortName": "RayPlus",
"OrganizationName": "RayPlus",
"OrganizationNameCN": "RayPlus",
"CompanyName": "RayPlus",
"CompanyNameCN": "睿佳(武汉)软件科技有限公司",
"CompanyShortName": "RayPlus",
"CompanyShortNameCN": "睿佳",
"IsEnv_US": false,
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
"CronEmailDefaultCulture": "zh-CN"
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "101.132.253.119"
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]
}
}

View File

@ -77,7 +77,7 @@
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"DuplicationWindowMs": 500,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]

View File

@ -8,6 +8,8 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
{
using Database.Api;
using DocumentFormat.OpenXml.InkML;
using global::MassTransit;
using IRaCIS.Core.Application.Helper.OtherTool;
using IRaCIS.Core.Application.Service.Common;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
@ -17,6 +19,7 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -35,7 +38,7 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
/// </summary>
/// <param name="logger">logger</param>
/// <param name="accessor">loggerHelper</param>
public class RequestDuplicationFilter(ILogger<RequestDuplicationFilter> logger, IHttpContextAccessor accessor, IUserInfo _userInfo, IStringLocalizer _localizer, IOptionsMonitor<RequestDuplicationOptions> RequestDuplicationOptionsMonitor) : ExceptionFilterAttribute, IAsyncActionFilter
public class RequestDuplicationFilter(ILogger<RequestDuplicationFilter> logger, IHttpContextAccessor accessor, IUserInfo _userInfo, IStringLocalizer _localizer, IOptionsMonitor<RequestDuplicationOptions> RequestDuplicationOptionsMonitor, IConfiguration _config) : ExceptionFilterAttribute, IAsyncActionFilter
{
/// <summary>
/// 传入的参数
@ -70,6 +73,10 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
{
this.RequestDuplication();
}
catch (BusinessValidationFailedException)
{
throw;
}
catch (Exception)
{
@ -89,8 +96,12 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
{
var requestPath = accessor?.HttpContext?.Request?.Path.ToString() ?? string.Empty;
var httpMethod = accessor?.HttpContext?.Request?.Method?.ToUpper() ?? string.Empty;
// 验证请求频繁情况
if (
!httpMethod.Equals("GET", StringComparison.OrdinalIgnoreCase) &&
!requestPath
.Split("/", StringSplitOptions.RemoveEmptyEntries)
.Any(segment => segment.StartsWith("get", StringComparison.OrdinalIgnoreCase)) &&
@ -106,17 +117,54 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
RequestTime = DateTime.Now
};
IRCSystemInfo.RequestRecordList= IRCSystemInfo.RequestRecordList.Where(x => x.RequestTime >= DateTime.Now.AddSeconds(-RequestDuplicationOptionsMonitor.CurrentValue.CacheTimeSeconds)).ToList();
var requestsTimes = IRCSystemInfo.RequestRecordList.Any(x=>
x.RequestTime>= requestInfo.RequestTime.AddMilliseconds(-RequestDuplicationOptionsMonitor.CurrentValue.DuplicationWindowMs)&&
x.RequestKey== requestInfo.RequestKey);
if (requestsTimes)
var isAdded = IRCSystemInfo.TryAddRequestRecord(
requestInfo,
RequestDuplicationOptionsMonitor.CurrentValue.CacheTimeSeconds,
RequestDuplicationOptionsMonitor.CurrentValue.DuplicationWindowMs);
if (!isAdded)
{
throw new BusinessValidationFailedException(_localizer["RequestDuplicationFilter_RequestDuplication"], ApiResponseCodeEnum.BusinessValidationFailed);
SendRequestDuplicationWeComNotice(requestPath);
logger.LogError($"重复请求出现错误:{this.Intoparam}");
throw new BusinessValidationFailedException(_localizer["RequestDuplicationFilter_RequestDuplication"], ApiResponseCodeEnum.NotRemind);
}
IRCSystemInfo.RequestRecordList.Add(requestInfo);
}
}
private void SendRequestDuplicationWeComNotice(string requestPath)
{
try
{
bool isOpenWeComNotice = _config.GetValue<bool>("WeComNoticeConfig:IsOpenWeComNotice");
if (isOpenWeComNotice)
{
string webhook = _config["WeComNoticeConfig:WebhookUrl"] ?? string.Empty;
var uri = new Uri(_config["SystemEmailSendConfig:SiteUrl"]);
var baseUrl = uri.GetLeftPart(UriPartial.Authority);
var userList = _config.GetSection("WeComNoticeConfig:VueNoticeUserList").Get<string[]>();
var request = accessor?.HttpContext?.Request;
_ = WeComNotifier.SendAlertAsync(
webhook: webhook,
alert: new WeComAlert
{
Env = baseUrl,
UserName = _userInfo.UserName.IsNotNullOrEmpty() ? $"{_userInfo.UserName}({_userInfo.UserTypeShortName})" : "匿名",
Api = $"{request?.Method} {requestPath}",
Message = "重复请求拦截",
JsonData = this.Intoparam,
Stack = string.Empty,
AtUsers = userList ?? []
}
);
}
}
catch (Exception ex)
{
logger.LogError($"重复请求过滤器里发送企业微信出现错误:{ex.Message}");
}
}

View File

@ -146,6 +146,31 @@ public class RequestDuplicationOptions
public static class IRCSystemInfo
{
public static List<RequestInfo> RequestRecordList { get; set; } = new List<RequestInfo>();
private static readonly object requestRecordLock = new object();
public static bool TryAddRequestRecord(RequestInfo requestInfo, int cacheTimeSeconds, int duplicationWindowMs)
{
lock (requestRecordLock)
{
var now = DateTime.Now;
RequestRecordList = RequestRecordList
.Where(x => x.RequestTime >= now.AddSeconds(-cacheTimeSeconds))
.ToList();
var isDuplicate = RequestRecordList.Any(x =>
x.RequestTime >= requestInfo.RequestTime.AddMilliseconds(-duplicationWindowMs) &&
x.RequestKey == requestInfo.RequestKey);
if (isDuplicate)
{
return false;
}
RequestRecordList.Add(requestInfo);
return true;
}
}
}
public class RequestInfo
@ -236,4 +261,4 @@ public static class AppSettings
}
}
}

View File

@ -8,6 +8,8 @@ public static class CacheKeys
//项目缓存
public static string Trial(string trialIdStr) => $"TrialId:{trialIdStr}";
public static string TrialVisitTaskMaxCode(Guid trialId) => $"TrialVisitTaskMaxCode:{trialId}";
//检查编号递增锁
public static string TrialStudyMaxCode(Guid trialId) => $"TrialStudyMaxCode:{trialId}";

View File

@ -1,16 +1,8 @@
using DocumentFormat.OpenXml.Office.CustomUI;
using FellowOakDicom;
using FellowOakDicom;
using FellowOakDicom.Media;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using NPOI.Util;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Helper
{

View File

@ -1,6 +1,4 @@
using IRaCIS.Core.Domain.Share;
using NPOI.XWPF.UserModel;
using System.Globalization;
using System.Globalization;
using Xceed.Document.NET;
using Xceed.Words.NET;
@ -54,42 +52,42 @@ public static class WordTempleteHelper
}
public static void Npoi_GetInternationalTempleteStream(string filePath, Stream memoryStream)
{
//public static void Npoi_GetInternationalTempleteStream(string filePath, Stream memoryStream)
//{
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
// var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
XWPFDocument doc = new XWPFDocument(fs);
// using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
// {
// XWPFDocument doc = new XWPFDocument(fs);
// 查找包含指定书签的段落及其索引
var bookmarkParagraph = doc.Paragraphs
.FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == StaticData.CultureInfo.en_US_bookMark));
// // 查找包含指定书签的段落及其索引
// var bookmarkParagraph = doc.Paragraphs
// .FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == StaticData.CultureInfo.en_US_bookMark));
if (bookmarkParagraph != null)
{
int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph);
// if (bookmarkParagraph != null)
// {
// int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph);
if (isEn_US)
{
// 从书签所在段落开始,删除之前的所有段落
for (int i = bookmarkIndex - 1; i >= 0; i--)
{
doc.RemoveBodyElement(i);
}
}
else
{
// 删除书签之后的所有段落
for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--)
{
doc.RemoveBodyElement(i);
}
}
}
doc.Write(memoryStream);
}
}
// if (isEn_US)
// {
// // 从书签所在段落开始,删除之前的所有段落
// for (int i = bookmarkIndex - 1; i >= 0; i--)
// {
// doc.RemoveBodyElement(i);
// }
// }
// else
// {
// // 删除书签之后的所有段落
// for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--)
// {
// doc.RemoveBodyElement(i);
// }
// }
// }
// doc.Write(memoryStream);
// }
//}
}

View File

@ -3,8 +3,11 @@ using FellowOakDicom.Imaging;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.PixelFormats;
using IRaCIS.Core.Application.Helper;
using SixLabors.ImageSharp.Drawing.Processing;
namespace IRaCIS.Core.Application.Helper;
public static class ImageHelper
{
@ -28,7 +31,7 @@ public static class ImageHelper
image.Save(fileStorePath, new JpegEncoder());
}
}
@ -60,6 +63,36 @@ public static class ImageHelper
}
public static class ImageMaskHelper
{
public static async Task MaskAsync(Stream input, Stream output, IEnumerable<MaskRegion> regions)
{
// 确保输入流从起始位置读取
if (input.CanSeek && input.Position != 0)
{
input.Position = 0;
}
using var image = await Image.LoadAsync(input);
// 保存原始图片的编码格式
var originalFormat = image.Metadata.DecodedImageFormat;
image.Mutate(ctx =>
{
foreach (var r in regions)
{
ctx.Fill(Color.Black, new Rectangle(r.X, r.Y, r.Width, r.Height));
}
});
// 使用原始格式保存,保持格式不变
await image.SaveAsync(output, originalFormat);
}
}
}

View File

@ -1,15 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using RestSharp;
using Newtonsoft.Json;
using IRaCIS.Core.Infrastructure.Extention;
using NPOI.SS.Formula.Functions;
namespace IRaCIS.Core.Application.Helper.OtherTool
{

View File

@ -1,9 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>default</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
@ -12,6 +10,7 @@
<OutputPath>..\bin\</OutputPath>
<DocumentationFile>.\IRaCIS.Core.Application.xml</DocumentationFile>
<NoWarn>1701;1702;1591</NoWarn>
<NoWarn>$(NoWarn);NU1903</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
@ -32,13 +31,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ClosedXML" Version="0.105.0" />
<PackageReference Include="IdentityModel.OidcClient" Version="6.0.0" />
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="AWSSDK.S3" Version="4.0.21" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.5.19" />
<PackageReference Include="AWSSDK.S3" Version="4.0.24" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.7" />
<PackageReference Include="DocX" Version="5.0.0" />
<PackageReference Include="FreeSpire.Doc" Version="12.2.0" />
<PackageReference Include="FreeSpire.Doc" Version="14.4.0" />
<PackageReference Include="ExcelDataReader" Version="3.8.0" />
<PackageReference Include="ExcelDataReader.DataSet" Version="3.8.0" />
<PackageReference Include="DistributedLock.Redis" Version="1.1.1" />
@ -47,23 +47,23 @@
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" />
<PackageReference Include="fo-dicom.Codecs" Version="5.16.7" />
<PackageReference Include="IP2Region.Net" Version="3.0.2" />
<PackageReference Include="MailKit" Version="4.15.1" />
<PackageReference Include="MailKit" Version="4.17.0" />
<PackageReference Include="Masa.Contrib.Service.MinimalAPIs" Version="1.1.0" />
<PackageReference Include="MaxMind.GeoIP2" Version="5.4.1" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.10" />
<PackageReference Include="MimeKit" Version="4.15.1" />
<PackageReference Include="MiniExcel" Version="1.41.2" />
<PackageReference Include="Minio" Version="6.0.3" />
<PackageReference Include="MaxMind.GeoIP2" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.8" />
<PackageReference Include="MimeKit" Version="4.17.0" />
<PackageReference Include="MiniExcel" Version="1.44.1" />
<PackageReference Include="Minio" Version="7.0.0" />
<PackageReference Include="MiniWord" Version="0.9.2" />
<PackageReference Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
<PackageReference Include="My.Extensions.Localization.Json" Version="4.0.0">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="NPOI" Version="2.7.4" />
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
<PackageReference Include="RestSharp" Version="114.0.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="10.0.1" />
</ItemGroup>
<ItemGroup>

View File

@ -59,17 +59,17 @@
</member>
<member name="P:IRaCIS.Core.Application.Service.ExcelExportHelper.DynamicColumnConfig.AutoColumnStartIndex">
<summary>
增加动态列开始索引 从0 开始算
增加动态列开始索引 npoi从0开始 现在ClosedXML 从1开始
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.ExcelExportHelper.DynamicColumnConfig.AutoColumnTitleRowIndex">
<summary>
动态列开始的行index 从0开始
动态列开始的行index npoi从0开始 现在ClosedXML 从1开始
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.ExcelExportHelper.DynamicColumnConfig.TempalteLastColumnIndex">
<summary>
模板列最后的索引
模板列最后的索引 npoi从0开始 现在ClosedXML 从1开始
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.ExcelExportHelper.DynamicColumnConfig.ColumnIdNameList">
@ -102,20 +102,6 @@
Excel Title Name
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Service.ExcelExportHelper.CDISC_DataExport_Async(System.String,IRaCIS.Application.Contracts.ExcelExportInfo,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument},Microsoft.AspNetCore.Hosting.IWebHostEnvironment,IRaCIS.Application.Interfaces.IDictionaryService,System.Type,System.Nullable{IRaCIS.Core.Domain.Share.CriterionType},IRaCIS.Core.Application.Service.ExcelExportHelper.DynamicColumnConfig)">
<summary>
暂时废弃--合并到上面
</summary>
<param name="code"></param>
<param name="data"></param>
<param name="_commonDocumentRepository"></param>
<param name="_hostEnvironment"></param>
<param name="_dictionaryService"></param>
<param name="translateType"></param>
<param name="criterionType"></param>
<param name="dynamicColumnConfig"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ExcelExportHelper.ExportTemplateAsync(IRaCIS.Application.Contracts.ExportTemplateServiceDto)">
<summary>
导出文件模板
@ -351,6 +337,12 @@
<param name="taskId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.VisitTaskHelpeService.GenerateTaskNo">
<summary>
从 NewId 的后 3 个字节24 位)生成一个 6 位十六进制字符串
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.VisitTaskHelpeService.GetIsClinicalDataSignTest(System.Guid)">
<summary>
获取GetIsClinicalDataSignTest
@ -363,7 +355,7 @@
访视读片任务
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Service.Allocation.VisitTaskService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskAllocationRule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadModule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTaskReReading},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskMedicalReview},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingClinicalData},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectCriteriaEvaluation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectCriteriaEvaluationVisitFilter},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Segment},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Segmentation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SegmentBinding},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomSeries},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectCanceDoctor},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMarkBinding},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableAnswerRowInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskInfluence},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialQCQuestionAnswer},Microsoft.Extensions.Logging.ILogger{IRaCIS.Core.Application.Service.Allocation.VisitTaskService},IRaCIS.Core.Application.Service.IVisitTaskHelpeService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectCriteriaEvaluationVisitStudyFilter},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer)">
<member name="M:IRaCIS.Core.Application.Service.Allocation.VisitTaskService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskAllocationRule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadModule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTaskReReading},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskMedicalReview},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingClinicalData},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectCriteriaEvaluation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectCriteriaEvaluationVisitFilter},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Segment},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Segmentation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SegmentBinding},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomSeries},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectCanceDoctor},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMarkBinding},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableAnswerRowInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskSeries},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskInfluence},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialQCQuestionAnswer},Microsoft.Extensions.Logging.ILogger{IRaCIS.Core.Application.Service.Allocation.VisitTaskService},IRaCIS.Core.Application.Service.IVisitTaskHelpeService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectCriteriaEvaluationVisitStudyFilter},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer)">
<summary>
访视读片任务
</summary>
@ -1453,6 +1445,14 @@
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.DictionaryService.ChangeTrialObjectNameList(System.Collections.Generic.Dictionary{System.String,System.Collections.Generic.List{IRaCIS.Application.Contracts.BasicDicSelect}},System.Nullable{System.Guid})">
<summary>
替换字典中的项目名称为试验对象名称 --New
</summary>
<param name="data"></param>
<param name="trialId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.DictionaryService.GetBoolValueState(System.Boolean)">
<summary>
获取是和否
@ -1584,6 +1584,13 @@
<param name="_attachmentrepository"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.FileUploadRecordService.AddOrUpdateCommonUploadRecord(IRaCIS.Core.Application.ViewModel.CommonUploadRecordAddOrEdit)">
<summary>
上传通用文件记录
</summary>
<param name="addOrEditCommonUploadRecord"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.FileUploadRecordService.GetSubjectUploadRecordList(IRaCIS.Core.Application.ViewModel.SubjectFileUploadRecordQuery)">
<summary>
按照 subject visit studyCode 三个维度进行分组的查询列表 subject相关
@ -2933,7 +2940,7 @@
<param name="modality"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.DownloadAndUploadService.DownloadImageSuccess(System.Guid)">
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.DownloadAndUploadService.DownloadImageSuccess(System.Guid,System.Nullable{System.Guid})">
<summary>
影像下载成功回调
</summary>
@ -3081,7 +3088,7 @@
SystemAnonymizationService
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Service.SystemAnonymizationService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SystemAnonymization},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer)">
<member name="M:IRaCIS.Core.Application.Service.SystemAnonymizationService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SystemAnonymization},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer,ZiggyCreatures.Caching.Fusion.IFusionCache)">
<summary>
SystemAnonymizationService
</summary>
@ -3277,6 +3284,20 @@
批次Id
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Service.Inspection.InspectionService.getInspectionById(IRaCIS.Core.Application.Service.Inspection.DTO.InspectionDto)">
<summary>
根据Id获取稽查记录
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.Inspection.InspectionService.SetJsonDetail(IRaCIS.Core.Application.Service.Inspection.DTO.InspectionDto)">
<summary>
设置稽查记录JsonDetail
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.Inspection.InspectionService.SetTrialShowInspection(IRaCIS.Core.Application.Service.Inspection.DTO.SetTrialShowInspection)">
<summary>
设置项目稽查配置
@ -3713,29 +3734,6 @@
<param name="code"></param>
<returns></returns>
</member>
<member name="T:IRaCIS.Core.Application.Service.MinimalApiService.FileToPDFService">
<summary>
上传文件转PDF 或者给url 这边下载然后转PDF
</summary>
<param name="_hostEnvironment"></param>
</member>
<member name="M:IRaCIS.Core.Application.Service.MinimalApiService.FileToPDFService.#ctor(Microsoft.AspNetCore.Hosting.IWebHostEnvironment)">
<summary>
上传文件转PDF 或者给url 这边下载然后转PDF
</summary>
<param name="_hostEnvironment"></param>
</member>
<!-- Badly formed XML comment ignored for member "T:IRaCIS.Core.Application.Service.MinimalApiService.TestMinimalApiService" -->
<!-- Badly formed XML comment ignored for member "M:IRaCIS.Core.Application.Service.MinimalApiService.TestMinimalApiService.#ctor(IRaCIS.Core.Domain.Share.IUserInfo,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Infra.EFCore.TestLength})" -->
<member name="M:IRaCIS.Core.Application.Service.MinimalApiService.TestMinimalApiService.TestEfcoreJson">
<summary>
测试efcore json 列支持情况
https://devblogs.microsoft.com/dotnet/array-mapping-in-ef-core-8/
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.HIRActivateService.GetAuthorizationCodeInfo(System.String,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Application.Contracts.SystemHospitalOption})">
<summary>
获取授权码明文信息
@ -3898,6 +3896,15 @@
The ID token, which can be used to verify the identity of the user.
</summary>
</member>
<!-- Badly formed XML comment ignored for member "T:IRaCIS.Core.Application.Service.MinimalApiService.TestMinimalApiService" -->
<!-- Badly formed XML comment ignored for member "M:IRaCIS.Core.Application.Service.MinimalApiService.TestMinimalApiService.#ctor(IRaCIS.Core.Domain.Share.IUserInfo,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Infra.EFCore.TestLength})" -->
<member name="M:IRaCIS.Core.Application.Service.MinimalApiService.TestMinimalApiService.TestEfcoreJson">
<summary>
测试efcore json 列支持情况
https://devblogs.microsoft.com/dotnet/array-mapping-in-ef-core-8/
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.QCCommon.VerifyIsCRCSubmmitAsync(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Domain.Share.IUserInfo,System.Nullable{System.Guid})">
<summary>
验证CRC 是否已提交 已提交 就不允许进行任何操作如果是IQC 那么还验证是否是当前任务领取人
@ -9020,6 +9027,41 @@
外弹力膜面积- 管腔面积
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.IVUSMeasuredValue.PlaqueRupture">
<summary>
斑块破裂
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TemplateData.TargetSegment">
<summary>
靶段
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TemplateData.TargetSegmentRemarks">
<summary>
靶段备注
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TemplateData.ROIAllLength">
<summary>
ROI段落总长度
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TemplateData.PullbackFrameCount">
<summary>
回撤中的图像帧数
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TemplateData.PlaqueType">
<summary>
斑块类型
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.TemplateData.AdjustReason">
<summary>
访视点备注(如有)
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.OCTFCTUploadData.FrameNumber">
<summary>
帧数
@ -9070,6 +9112,16 @@
脂质角度
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.OCTFCTUploadData.PlaqueRupture">
<summary>
斑块破裂
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.OCTFCTUploadData.PlaqueHealing">
<summary>
斑块愈合
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.OCTInfo.PlaqueNum">
<summary>
斑块编号
@ -9750,6 +9802,16 @@
融合的病灶
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetMarkListInDto.VisitTaskId">
<summary>
任务Id
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.NoneDicomMarkInfo.MarkId">
<summary>
标记的唯一标识符
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetCustomTagInDto.VisitTaskId">
<summary>
任务Id
@ -10200,6 +10262,11 @@
问题分类
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetFilterTableQuestionInDto.QuestionClassify">
<summary>
问题分类
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.SetOncologyQuestion.EvaluationResult">
<summary>
评估结果
@ -12381,6 +12448,11 @@
影像工具
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionTrialView.AddDeleteTypeEnum">
<summary>
新增修改类型
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionTrialView.ImageToolAttribute">
<summary>
影像工具属性
@ -13326,6 +13398,11 @@
影像工具
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionTrialInDto.AddDeleteTypeEnum">
<summary>
新增修改类型
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionTrialInDto.ImageToolAttribute">
<summary>
影像工具属性
@ -14736,7 +14813,7 @@
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMarkBinding},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserLog},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingOncologyTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Segmentation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SegmentBinding},IRaCIS.Core.Application.Service.IVisitTaskHelpeService,IRaCIS.Core.Application.Service.IVisitTaskService,IRaCIS.Core.Application.Contracts.IReadingClinicalDataService,IRaCIS.Core.Application.Service.IReadingCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserFeedBack},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingGlobalTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingCriterionPage},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskRelation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingJudgeInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadModule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganTrialInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialDocument},IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoCalculateService,IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoWithoutPETCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTrialCriterionDictionary},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableAnswerRowInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CriterionKeyFileRead},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialCriterionKeyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Application.Service.IGeneralCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskStudy},IRaCIS.Core.Application.Service.ImageAndDoc.IDownloadAndUploadService,IRaCIS.Core.Application.Interfaces.ITrialEmailNoticeConfigService,AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer,ZiggyCreatures.Caching.Fusion.IFusionCache)">
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMarkBinding},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserLog},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingOncologyTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Segmentation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SegmentBinding},IRaCIS.Core.Application.Service.IVisitTaskHelpeService,IRaCIS.Core.Application.Service.IVisitTaskService,IRaCIS.Core.Application.Contracts.IReadingClinicalDataService,IRaCIS.Core.Application.Service.IReadingCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserFeedBack},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingGlobalTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingCriterionPage},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskRelation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingJudgeInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadModule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUserRole},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeUserType},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeConfig},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganTrialInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialDocument},IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoCalculateService,IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoWithoutPETCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTrialCriterionDictionary},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableAnswerRowInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CriterionKeyFileRead},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialCriterionKeyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Application.Service.IGeneralCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskStudy},Microsoft.Extensions.Configuration.IConfiguration,IRaCIS.Core.Application.Service.ImageAndDoc.IDownloadAndUploadService,IRaCIS.Core.Application.Interfaces.ITrialEmailNoticeConfigService,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer,ZiggyCreatures.Caching.Fusion.IFusionCache)">
<summary>
IR影像阅片
</summary>
@ -14828,6 +14905,20 @@
<param name="inQuery"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetMarkList(IRaCIS.Core.Application.Service.Reading.Dto.GetMarkListInDto)">
<summary>
获取标记信息
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetNoneDicomMarkList(IRaCIS.Core.Application.Service.Reading.Dto.GetMarkListInDto)">
<summary>
获取非DICOM标记信息
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetManualList(IRaCIS.Core.Application.Service.Reading.Dto.GetManualListInDto)">
<summary>
获取手册
@ -14959,6 +15050,13 @@
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetFilterTableQuestion(IRaCIS.Core.Application.Service.Reading.Dto.GetFilterTableQuestionInDto)">
<summary>
获取单个表格问题及答案 过滤问题
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetCustomTableQuestionAnswer(IRaCIS.Core.Application.Service.Reading.Dto.GetCustomTableQuestionAnswerInDto)">
<summary>
获取自定义问题以及答案
@ -15178,7 +15276,21 @@
<param name="visitTaskId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.ComputeJudgeResult(System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.GroupTaskAnswerDto})">
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.SendWeComNotifier(System.Guid,System.String)">
<summary>
发送微信通知
</summary>
<param name="visiTaskId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.SendAbnormalEmail(System.Guid,IRaCIS.Core.Domain.Share.EmailBusinessScenario)">
<summary>
发送邮件通知
</summary>
<param name="visiTaskId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.ComputeJudgeResult(System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.GroupTaskAnswerDto},System.Guid)">
<summary>
计算返回的结果 为True表示不相等
</summary>
@ -16063,6 +16175,12 @@
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.DoctorWorkloadService.GetDoctorUserTrialReadingStat(IRaCIS.Application.Contracts.TrialReadingStatQuery)">
<summary>
获取项目阅片统计
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.DoctorWorkloadService.GetTrialEnrollmentWorkloadStats(IRaCIS.Application.Contracts.WorkLoadDoctorQueryDTO)">
<summary>
获取某个项目入组的医生工作量统计列表
@ -16248,7 +16366,7 @@
<param name="logger">logger</param>
<param name="accessor">loggerHelper</param>
</member>
<member name="M:IRaCIS.Core.Application.BusinessFilter.LegacyController.Database.Api.RequestDuplicationFilter.#ctor(Microsoft.Extensions.Logging.ILogger{IRaCIS.Core.Application.BusinessFilter.LegacyController.Database.Api.RequestDuplicationFilter},Microsoft.AspNetCore.Http.IHttpContextAccessor,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.RequestDuplicationOptions})">
<member name="M:IRaCIS.Core.Application.BusinessFilter.LegacyController.Database.Api.RequestDuplicationFilter.#ctor(Microsoft.Extensions.Logging.ILogger{IRaCIS.Core.Application.BusinessFilter.LegacyController.Database.Api.RequestDuplicationFilter},Microsoft.AspNetCore.Http.IHttpContextAccessor,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.RequestDuplicationOptions},Microsoft.Extensions.Configuration.IConfiguration)">
<summary>
请求拦截 请求前后的操作
</summary>
@ -18777,11 +18895,24 @@
NoneDicomStudyService
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Contracts.NoneDicomStudyService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},Medallion.Threading.IDistributedLockProvider,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Application.Service.QCCommon,AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer)">
<member name="M:IRaCIS.Core.Application.Contracts.NoneDicomStudyService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},Medallion.Threading.IDistributedLockProvider,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Application.Helper.IOSSService,IRaCIS.Core.Application.Service.QCCommon,AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer)">
<summary>
NoneDicomStudyService
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Contracts.NoneDicomStudyService.NoneDicomStudyMaskImage(IRaCIS.Core.Application.Contracts.NoneDicomStudyMaskImageCommand)">
<summary>
标注遮盖影像 路径后面加了.MaskNoneDicom_ 就是遮盖的新路径
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Contracts.NoneDicomStudyService.NoneDicomStudyUndoMaskImage(IRaCIS.Core.Application.Contracts.NoneDicomStudyUndoMaskImageCommand)">
<summary>
撤销遮盖的影像,可以单张,也可以整个检查
</summary>
<param name="inCommand"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Contracts.NoneDicomStudyService.GetNoneDicomStudyFileList(System.Guid)">
<summary>
非Dicom检查 文件列表
@ -20245,11 +20376,12 @@
<param name="editTrialSiteCommand"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Services.TrialMaintenanceService.GetTrialSiteSelect(System.Guid)">
<member name="M:IRaCIS.Core.Application.Services.TrialMaintenanceService.GetTrialSiteSelect(System.Guid,System.Nullable{System.Boolean})">
<summary>
获取项目下的 site 下拉框数据 CRC只看到他负责的
</summary>
<param name="trialId"></param>
<param name="ignoreDisable"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Services.TrialMaintenanceService.DeleteTrialSite(System.Guid)">
@ -20857,6 +20989,12 @@
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>
<member name="M:IRaCIS.Core.Application.TrialConfigService.ReplaceSubject">
<summary>
替换受试者
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.TrialConfigService.TrialReadingInfoSignVerify(IRaCIS.Core.Application.Contracts.TrialReadingInfoSignInDto)">
<summary>
阅片信息签名验证接口
@ -20865,6 +21003,33 @@
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>
<member name="M:IRaCIS.Core.Application.TrialConfigService.SetTrialLinkExpirationTime(IRaCIS.Core.Application.Contracts.TrialLinkExpirationTimeDto)">
<summary>
设置项目链接过期时间
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.TrialConfigService.GetTrialLinkExpirationTime(IRaCIS.Core.Application.Contracts.SetTrialLinkExpirationTimeDto)">
<summary>
获取项目链接过期时间
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.TrialConfigService.GetLinkLinkExpirationTime(IRaCIS.Core.Application.Contracts.VerifyLinkExpirationTimeDto)">
<summary>
获取时间是否过期 过期返回true 没有过期返回false
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.TrialConfigService.GetLinkVerificationCodeIsEffective(IRaCIS.Core.Application.Contracts.GetLinkVerificationCodeIsEffectiveDto)">
<summary>
获取是否Code是否有效 有效返回true 无效返回false
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.TrialConfigService.GetTrialConfirmCriterionList(IRaCIS.Core.Application.Contracts.GetTrialConfirmCriterionListInDto)">
<summary>
获取项目已经确认的标准
@ -21831,11 +21996,6 @@
读片数量分类统计
</summary>
</member>
<member name="P:IRaCIS.Application.Contracts.TrialExtraConfig.IsOpenLostVistRead">
<summary>
打开失访可读
</summary>
</member>
<member name="P:IRaCIS.Application.Contracts.TrialConfigInfo.IsImageQualityControl">
<summary>
影像质控风险控制
@ -22090,5 +22250,49 @@
<member name="M:IRaCIS.Application.Interfaces.ITrialEnrollmentService.ConfirmReviewer(System.Guid,System.Guid[],System.Int32)">
<summary>入组流程-向CRO提交医生[Submit]</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Type)">
<summary>
Generates a documentation comment ID for a type.
Example: T:Namespace.Outer+Inner`1 becomes T:Namespace.Outer.Inner`1
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Reflection.PropertyInfo)">
<summary>
Generates a documentation comment ID for a property.
Example: P:Namespace.ContainingType.PropertyName or for an indexer P:Namespace.ContainingType.Item(System.Int32)
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Type,System.String)">
<summary>
Generates a documentation comment ID for a property given its container type and property name.
Example: P:Namespace.ContainingType.PropertyName
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Reflection.MethodInfo)">
<summary>
Generates a documentation comment ID for a method (or constructor).
For example:
M:Namespace.ContainingType.MethodName(ParamType1,ParamType2)~ReturnType
M:Namespace.ContainingType.#ctor(ParamType)
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.GetTypeDocId(System.Type,System.Boolean,System.Boolean)">
<summary>
Generates a documentation ID string for a type.
This method handles nested types (replacing '+' with '.'),
generic types, arrays, pointers, by-ref types, and generic parameters.
The <paramref name="includeGenericArguments"/> flag controls whether
constructed generic type arguments are emitted, while <paramref name="omitGenericArity"/>
controls whether the generic arity marker (e.g. "`1") is appended.
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.NormalizeDocId(System.String)">
<summary>
Normalizes a documentation comment ID to match the compiler-style format.
Strips the return type suffix for ordinary methods but retains it for conversion operators.
</summary>
<param name="docId">The documentation comment ID to normalize.</param>
<returns>The normalized documentation comment ID.</returns>
</member>
</members>
</doc>

View File

@ -64,7 +64,7 @@ namespace IRaCIS.Core.Application.MassTransit.Command
//[Required(ErrorMessage = "受试者筛选号不能为空")]
//[ImporterHeader(Name = "Subject ID", AutoTrim = true)]
[ExcelColumnName("Subject ID")]
[ExcelColumnName("Participant ID")]
public string SubjectCode { get; set; } = string.Empty;
//[Required(ErrorMessage = "访视名称不能为空")]

View File

@ -1,27 +1,9 @@
using DocumentFormat.OpenXml.Office2013.Excel;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Vml;
using DocumentFormat.OpenXml.Wordprocessing;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain;
using IRaCIS.Core.Domain.BaseModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using MassTransit;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.Extensions.Options;
using MimeKit;
using NPOI.SS.Formula.Functions;
using NPOI.Util;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.MassTransit.Consumer;

View File

@ -1,10 +1,6 @@
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using IRaCIS.Core.Domain.BaseModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Domain.BaseModel;
using MassTransit;
using NPOI.SS.Formula.Functions;
using System.Globalization;
public class CultureInfoFilter<T> (IRepository<EventStoreRecord> _eventStoreRecordRepository) : IFilter<ConsumeContext<T>> where T : DomainEvent
{

View File

@ -51,11 +51,13 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
var systemDocQuery =
from sysDoc in _systemDocumentRepository.AsQueryable(false)
from identityUser in _identityUserRepository.AsQueryable(false).Where(t => t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
from identityUser in _identityUserRepository.AsQueryable(false).Where(t => t.Status == UserStateEnum.Enable).Where(t => t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
join confirmc in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = identityUser.Id, SystemDocumentId = sysDoc.Id } equals new { confirmc.ConfirmUserId, confirmc.SystemDocumentId } into cc
from confirm in cc.DefaultIfEmpty()
select new UnionDocumentWithConfirmInfoView()
select new TriaAndSystemlSignDocView()
{
DocLanguageType=sysDoc.DocLanguageType,
UserWorkLanguage=identityUser.UserWorkLanguage,
IsSystemDoc = true,
Id = sysDoc.Id,
CreateTime = sysDoc.CreateTime,
@ -79,7 +81,9 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
};
var datalist = await systemDocQuery.IgnoreQueryFilters().Where(t => t.IsDeleted == false && t.ConfirmTime == null)
.ToListAsync();
datalist = datalist.Where(x => x.SuggestFinishTime != null && x.SuggestFinishTime.Value.Date == DateTime.Now.Date)
datalist = datalist
.Where(x=>x.DocLanguageType == DocLanguageType.CN_US || (int)x.DocLanguageType == (int)x.UserWorkLanguage)
.Where(x => x.SuggestFinishTime != null && x.SuggestFinishTime.Value.Date == DateTime.Now.Date)
.Where(x => x.IsNeedSendEmial).ToList();
var confirmUserIdList = datalist.Select(t => t.ConfirmUserId).Distinct().ToList();
var userinfoList = await _identityUserRepository.Where(x => confirmUserIdList.Contains(x.Id)).ToListAsync();
@ -96,45 +100,42 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
var userWorkLanguageList = userinfoList.Select(x => x.UserWorkLanguage).Distinct().ToList();
foreach (var workLanguage in userWorkLanguageList)
{
try
var langUserInfoList = userinfoList.Where(x => x.UserWorkLanguage == workLanguage).ToList();
if (!langUserInfoList.Any())
{
var langUserInfoList = userinfoList.Where(x => x.UserWorkLanguage == workLanguage).ToList();
if (!langUserInfoList.Any())
{
continue;
}
var userIsEn_US = workLanguage == UserWorkLanguage.US;
var messageToSend = new MimeMessage();
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
foreach (var userinfo in langUserInfoList)
{
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
}
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
var userNames = langUserInfoList.Select(x => x.UserName).ToList();
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
string.Join(',', userNames),
_systemEmailConfig.SiteUrl
);
return (topicStr, htmlBodyStr);
};
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc, workLanguage);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
continue;
}
catch (Exception)
var userIsEn_US = workLanguage == UserWorkLanguage.US;
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
foreach (var userinfo in langUserInfoList)
{
try
{
var messageToSend = new MimeMessage();
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
userinfo.FullName,
_systemEmailConfig.SiteUrl
);
return (topicStr, htmlBodyStr);
};
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc, workLanguage);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
}
catch (Exception)
{
}
}
}
@ -171,7 +172,7 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
Console.WriteLine($"只发送给新增的角色,角色数量: {context.Message.NewUserTypeIds.Count}");
}
// 构建查询
IQueryable<UnionDocumentWithConfirmInfoView> systemDocQuery;
IQueryable<TriaAndSystemlSignDocView> systemDocQuery;
if (context.Message.NewUserTypeIds != null && context.Message.NewUserTypeIds.Any())
{
@ -183,8 +184,10 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
t.UserRoleList.Where(t => t.IsUserRoleDisabled == false)
.Any(t => context.Message.NewUserTypeIds.Contains(t.UserTypeId) &&
sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
select new UnionDocumentWithConfirmInfoView()
select new TriaAndSystemlSignDocView()
{
DocLanguageType = sysDoc.DocLanguageType,
UserWorkLanguage = identityUser.UserWorkLanguage,
IsSystemDoc = true,
Id = sysDoc.Id,
CreateTime = sysDoc.CreateTime,
@ -210,8 +213,10 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
.Where(t => t.Status == UserStateEnum.Enable &&
t.UserRoleList.Where(t => t.IsUserRoleDisabled == false)
.Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
select new UnionDocumentWithConfirmInfoView()
select new TriaAndSystemlSignDocView()
{
DocLanguageType = sysDoc.DocLanguageType,
UserWorkLanguage = identityUser.UserWorkLanguage,
IsSystemDoc = true,
Id = sysDoc.Id,
CreateTime = sysDoc.CreateTime,
@ -229,7 +234,7 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
};
}
var datalist = await systemDocQuery.IgnoreQueryFilters().Where(x => x.IsNeedSendEmial).ToListAsync();
datalist = datalist.Where(x => x.DocLanguageType == DocLanguageType.CN_US || (int)x.DocLanguageType == (int)x.UserWorkLanguage).ToList();
var confirmUserIdList = datalist.Select(t => t.ConfirmUserId).Distinct().ToList();
var userinfoList = await _identityUserRepository.Where(x => confirmUserIdList.Contains(x.Id)).ToListAsync();
@ -240,29 +245,18 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
return;
}
var userWorkLanguageList = userinfoList.Select(x => x.UserWorkLanguage).Distinct().ToList();
foreach (var workLanguage in userWorkLanguageList)
foreach (var userinfo in userinfoList)
{
var langUserInfoList = userinfoList.Where(x => x.UserWorkLanguage == workLanguage).ToList();
if (!langUserInfoList.Any())
{
continue;
}
string msg = $"{langUserInfoList.Count}生效通知,";
string msg = $"{userinfo.UserName}生效通知,";
try
{
var messageToSend = new MimeMessage();
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
foreach (var userinfo in langUserInfoList)
{
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
}
var workLanguage = userinfo.UserWorkLanguage;
var userIsEn_US = workLanguage == UserWorkLanguage.US;
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
var userNames = langUserInfoList.Select(x => x.UserName).ToList();
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
@ -270,7 +264,7 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
var htmlBodyStr = string.Format(
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
string.Join(',', userNames),
userinfo.FullName,
_systemEmailConfig.SiteUrl
);

View File

@ -1,5 +1,4 @@
using DocumentFormat.OpenXml;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Consumer;
@ -10,16 +9,8 @@ using MassTransit;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using MimeKit;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Reactive.Joins;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.MassTransit.Recurring
{
@ -61,7 +52,7 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
var trialDocQuery =
from trialDoc in _trialDocumentRepository.AsQueryable(true)
join trial in _trialRepository.Where(x => x.IsDeleted == false) on trialDoc.TrialId equals trial.Id
join trialIdentityUser in _trialIdentityUserRepository.Where(x => x.IsDeleted == false) on trialDoc.TrialId equals trialIdentityUser.TrialId
join trialUserRole in _trialUserRoleRepository.Where(x => x.IsDeleted == false) on trialIdentityUser.Id equals trialUserRole.TrialUserId
join identityUser in _identityUserRepository.AsQueryable(false).Where(u => u.Status == UserStateEnum.Enable)
@ -73,15 +64,18 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
from confirm in cc.DefaultIfEmpty()
where trialIdentityUser.TrialUserRoleList.Any(ur => !ur.IsDeleted && trialDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == ur.UserRole.UserTypeId))
select new TrialSignDocView()
select new TriaAndSystemlSignDocView()
{
TrialCode = trialDoc.Trial.TrialCode,
ResearchProgramNo = trialDoc.Trial.ResearchProgramNo,
ExperimentName = trialDoc.Trial.ExperimentName,
CurrentStaffTrainDays = trialDoc.CurrentStaffTrainDays,
NewStaffTrainDays = trialDoc.NewStaffTrainDays,
Id = trialDoc.Id,
TrialId= trialDoc.TrialId,
TrialType= trial.TrialType,
IsTestUser= identityUser.IsTestUser,
TrialId = trialDoc.TrialId,
IsSystemDoc = false,
CreateTime = trialDoc.CreateTime,
FullFilePath = trialDoc.Path,
@ -103,7 +97,11 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
};
var datalist = await trialDocQuery.IgnoreQueryFilters().Where(t => t.IsDeleted == false && t.ConfirmTime == null&&t.ConfirmTime==null)
.ToListAsync();
datalist = datalist.Where(x => x.SuggestFinishTime != null && x.SuggestFinishTime.Value.Date == DateTime.Now.Date)
datalist = datalist
.Where(x=>((x.TrialType== TrialType.OfficialTrial|| x.TrialType== TrialType.Training) && !x.IsTestUser) || (x.TrialType==TrialType.NoneOfficial &&x.IsTestUser))
.Where(x => x.SuggestFinishTime != null && x.SuggestFinishTime.Value.Date == DateTime.Now.Date)
.ToList();
var confirmUserIdList = datalist.Select(t => t.ConfirmUserId).Distinct().ToList();
var userinfoList = await _identityUserRepository.Where(x => confirmUserIdList.Contains(x.Id)).ToListAsync();
@ -125,54 +123,53 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
var groupedList = userWithTrialList.GroupBy(x => new { x.TrialId, x.User.UserWorkLanguage }).ToList();
foreach (var groupItem in groupedList)
{
try
var langUserInfoList = groupItem.Select(x => x.User).Distinct().ToList();
if (!langUserInfoList.Any())
{
var langUserInfoList = groupItem.Select(x => x.User).Distinct().ToList();
if (!langUserInfoList.Any())
{
continue;
}
Console.WriteLine($"发送定时过期提醒,数量:{langUserInfoList.Count}");
var trialInfo = await _trialRepository.Where(x => x.Id == groupItem.Key.TrialId).FirstOrDefaultAsync();
if (trialInfo == null)
{
continue;
}
var workLanguage = groupItem.Key.UserWorkLanguage;
var userIsEn_US = workLanguage == UserWorkLanguage.US;
var messageToSend = new MimeMessage();
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
foreach (var userinfo in langUserInfoList)
{
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
}
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
var userNames = langUserInfoList.Select(x => x.UserName).ToList();
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
string.Join(',', userNames),
_systemEmailConfig.SiteUrl
);
return (topicStr, htmlBodyStr);
};
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc, workLanguage);
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
continue;
}
catch (Exception)
{
Console.WriteLine($"发送定时过期提醒,数量:{langUserInfoList.Count}");
var trialInfo = await _trialRepository.Where(x => x.Id == groupItem.Key.TrialId).FirstOrDefaultAsync();
if (trialInfo == null)
{
continue;
}
var workLanguage = groupItem.Key.UserWorkLanguage;
var userIsEn_US = workLanguage == UserWorkLanguage.US;
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
foreach (var userinfo in langUserInfoList)
{
try
{
var messageToSend = new MimeMessage();
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
userinfo.FullName,
_systemEmailConfig.SiteUrl
);
return (topicStr, htmlBodyStr);
};
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc, workLanguage);
await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);
}
catch (Exception)
{
}
}
}
@ -213,20 +210,21 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
Console.WriteLine($"只发送给新增项目的角色,角色数量: {context.Message.NewUserTypeIds.Count}");
}
// 构建查询
IQueryable<UnionDocumentWithConfirmInfoView> systemDocQuery;
IQueryable<TriaAndSystemlSignDocView> trialDocQuery;
if (context.Message.NewUserTypeIds != null && context.Message.NewUserTypeIds.Any())
{
// 只查询新增角色的用户
systemDocQuery =
trialDocQuery =
from trialDoc in _trialDocumentRepository.AsQueryable(false).Where(x => context.Message.Ids.Contains(x.Id))
join trial in _trialRepository.Where(x => x.IsDeleted == false) on trialDoc.TrialId equals trial.Id
join trialIdentityUser in _trialIdentityUserRepository.Where(x=>x.IsDeleted==false) on trialDoc.TrialId equals trialIdentityUser.TrialId
join trialUserRole in _trialUserRoleRepository.Where(x => x.IsDeleted == false) on trialIdentityUser.Id equals trialUserRole.TrialUserId
join identityUser in _identityUserRepository.AsQueryable(false).Where(u => u.Status == UserStateEnum.Enable)
on trialIdentityUser.IdentityUserId equals identityUser.Id
where trialIdentityUser.TrialUserRoleList.Any(ur => !ur.IsDeleted && context.Message.NewUserTypeIds.Contains(ur.UserRole.UserTypeId) && trialDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == ur.UserRole.UserTypeId))
select new UnionDocumentWithConfirmInfoView()
select new TriaAndSystemlSignDocView()
{
IsSystemDoc = true,
Id = trialDoc.Id,
@ -234,6 +232,8 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
CreateTime = trialDoc.CreateTime,
IsDeleted = trialDoc.IsDeleted,
SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes,
TrialType = trial.TrialType,
IsTestUser = identityUser.IsTestUser,
Name = trialDoc.Name,
Path = trialDoc.Path,
FileTypeId = trialDoc.FileTypeId,
@ -248,8 +248,9 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
else
{
// 查询所有相关角色的用户
systemDocQuery =
trialDocQuery =
from trialDoc in _trialDocumentRepository.AsQueryable(false).Where(x => context.Message.Ids.Contains(x.Id))
join trialIdentityUser in _trialIdentityUserRepository.Where(x => x.IsDeleted == false) on trialDoc.TrialId equals trialIdentityUser.TrialId
join trialUserRole in _trialUserRoleRepository.Where(x=>x.IsDeleted==false) on trialIdentityUser.Id equals trialUserRole.TrialUserId
@ -259,7 +260,7 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
where trialIdentityUser.TrialUserRoleList.Any(ur => !ur.IsDeleted &&trialDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == ur.UserRole.UserTypeId))
select new UnionDocumentWithConfirmInfoView()
select new TriaAndSystemlSignDocView()
{
IsSystemDoc = false,
Id = trialDoc.Id,
@ -268,6 +269,8 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
CreateTime = trialDoc.CreateTime,
IsDeleted = trialDoc.IsDeleted,
SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes,
TrialType = trial.TrialType,
IsTestUser = identityUser.IsTestUser,
Name = trialDoc.Name,
Path = trialDoc.Path,
FileTypeId = trialDoc.FileTypeId,
@ -280,7 +283,9 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
};
}
var datalist = await systemDocQuery.IgnoreQueryFilters().ToListAsync();
var datalist = await trialDocQuery.IgnoreQueryFilters().ToListAsync();
datalist = datalist.Where(x => ((x.TrialType == TrialType.OfficialTrial || x.TrialType == TrialType.Training) && !x.IsTestUser) || (x.TrialType == TrialType.NoneOfficial && x.IsTestUser)).ToList();
var confirmUserIdList = datalist.Select(t => t.ConfirmUserId).Distinct().ToList();
var userinfoList = await _identityUserRepository.Where(x => confirmUserIdList.Contains(x.Id)).ToListAsync();
@ -297,37 +302,26 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
join u in userinfoList on ut.ConfirmUserId equals u.Id
select new { ut.TrialId, User = u }).ToList();
var groupedList = userWithTrialList.GroupBy(x => new { x.TrialId, x.User.UserWorkLanguage }).ToList();
foreach (var groupItem in groupedList)
foreach (var userWithTrial in userWithTrialList)
{
var langUserInfoList = groupItem.Select(x => x.User).Distinct().ToList();
if (!langUserInfoList.Any())
{
continue;
}
string msg = $"{langUserInfoList.Count}项目生效通知,";
var userinfo = userWithTrial.User;
string msg = $"{userinfo.UserName}项目生效通知,";
try
{
var messageToSend = new MimeMessage();
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
foreach (var userinfo in langUserInfoList)
{
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
}
var workLanguage = groupItem.Key.UserWorkLanguage;
var workLanguage = userinfo.UserWorkLanguage;
var userIsEn_US = workLanguage == UserWorkLanguage.US;
var companyName = userIsEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
var userNames = langUserInfoList.Select(x => x.UserName).ToList();
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
string.Join(',', userNames),
userinfo.FullName,
_systemEmailConfig.SiteUrl
);
@ -335,7 +329,7 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
};
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc, workLanguage);
var trialInfo = await _trialRepository.Where(x => x.Id == groupItem.Key.TrialId).FirstOrDefaultAsync();
var trialInfo = await _trialRepository.Where(x => x.Id == userWithTrial.TrialId).FirstOrDefaultAsync();
if (trialInfo == null)
{
continue;

View File

@ -439,6 +439,8 @@ namespace IRaCIS.Core.Application.ViewModel
public string TaskName { get; set; } = String.Empty;
public string TaskBlindName { get; set; } = String.Empty;
public Guid? DoctorUserId { get; set; }
public ReadingCategory? ReadingCategory { get; set; }

View File

@ -124,6 +124,45 @@ namespace IRaCIS.Core.Application.Service
}
#region 获取随机编号
/// <summary>
/// 从 NewId 的后 3 个字节24 位)生成一个 6 位十六进制字符串
/// </summary>
/// <returns></returns>
public static string GenerateTaskNo()
{
var bytes = NewId.Next().ToByteArray();
uint value =
BitConverter.ToUInt32(bytes, 0)
^ BitConverter.ToUInt32(bytes, 4)
^ BitConverter.ToUInt32(bytes, 8)
^ BitConverter.ToUInt32(bytes, 12);
return (value & 0xFFFFFF).ToString("X6");
}
private async Task<string> GetRandomTaskName(Guid trialId, List<string> existList)
{
var taskName = GenerateTaskNo();
while (existList.Any(t => t == taskName))
{
taskName = GenerateTaskNo();
}
while (await _visitTaskRepository.AnyAsync(t => t.TaskBlindName == taskName && t.TrialId == trialId))
{
taskName = GenerateTaskNo();
}
existList.Add(taskName);
return taskName;
}
#endregion
//基于标准签名 产生任务 (或者手动选择某些访视生成该标准的任务)
public async Task BaseCritrionGenerateVisitTask(Guid trialId, Guid confirmedTrialReadingCriterionId, bool? isManualSelectVisit = null, List<Guid>? subjectVisitIdList = null)
@ -151,11 +190,11 @@ namespace IRaCIS.Core.Application.Service
var dbMaxCode = _visitTaskRepository.Where(t => t.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max();
var cacheMaxCodeInt = _fusionCache.GetOrDefault<int>(CacheKeys.TrialStudyMaxCode(trialId));
var cacheMaxCodeInt = _fusionCache.GetOrDefault<int>(CacheKeys.TrialVisitTaskMaxCode(trialId));
int currentMaxCodeInt = cacheMaxCodeInt > dbMaxCode ? cacheMaxCodeInt : dbMaxCode;
var randomTaskBlindNameList = new List<string>();
foreach (var subjectGroup in needGenerateVisit.GroupBy(t => t.SubjectId).Select(g => new { SubjectId = g.Key, SubjectVisitList = g.ToList() }))
{
@ -173,6 +212,8 @@ namespace IRaCIS.Core.Application.Service
var blindTaskName = string.Empty;
var isRandom = false;
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{
if (visitNumList.IndexOf(subjectVisit.VisitNum) == 0 && subjectVisit.VisitNum == 0)
@ -185,6 +226,12 @@ namespace IRaCIS.Core.Application.Service
}
}
else if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.Random)
{
blindTaskName = await GetRandomTaskName(trialId, randomTaskBlindNameList);
isRandom = true;
}
else
{
blindTaskName = "Timepoint";
@ -258,12 +305,14 @@ namespace IRaCIS.Core.Application.Service
currentMaxCodeInt = currentMaxCodeInt + 1;
var blindTaskName2 = isRandom ? await GetRandomTaskName(trialId, randomTaskBlindNameList) : blindTaskName;
task2 = await _visitTaskRepository.AddAsync(new VisitTask()
{
TrialId = trialId,
SubjectId = subjectVisit.SubjectId,
IsUrgent = subjectVisit.IsUrgent,
TaskBlindName = blindTaskName,
TaskBlindName = blindTaskName2,
TaskName = subjectVisit.VisitName,
TaskUrgentType = taskUrgentType,
IsCanEditUrgentState = isCanEditUrgentState,
@ -283,7 +332,7 @@ namespace IRaCIS.Core.Application.Service
}
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
@ -344,7 +393,7 @@ namespace IRaCIS.Core.Application.Service
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
@ -590,11 +639,11 @@ namespace IRaCIS.Core.Application.Service
var dbMaxCode = _visitTaskRepository.Where(t => t.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max();
var cacheMaxCodeInt = _fusionCache.GetOrDefault<int>(CacheKeys.TrialStudyMaxCode(trialId));
var cacheMaxCodeInt = _fusionCache.GetOrDefault<int>(CacheKeys.TrialVisitTaskMaxCode(trialId));
int currentMaxCodeInt = cacheMaxCodeInt > dbMaxCode ? cacheMaxCodeInt : dbMaxCode;
var randomTaskBlindNameList = new List<string>();
switch (generateTaskCommand.ReadingCategory)
@ -654,7 +703,9 @@ namespace IRaCIS.Core.Application.Service
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);
var blindTaskName = string.Empty;
var isFullRandom = false;
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{
@ -668,6 +719,12 @@ namespace IRaCIS.Core.Application.Service
}
}
else if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.Random)
{
blindTaskName = await GetRandomTaskName(trialId, randomTaskBlindNameList);
isFullRandom = true;
}
//受试者随机
else
{
blindTaskName = "Timepoint";
@ -721,11 +778,15 @@ namespace IRaCIS.Core.Application.Service
if (!existCurrentVisitTaskList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2))
{
currentMaxCodeInt = currentMaxCodeInt + 1;
var blindTaskName2 = isFullRandom ? await GetRandomTaskName(trialId, randomTaskBlindNameList) : blindTaskName;
task2 = await _visitTaskRepository.AddAsync(new VisitTask()
{
TrialId = trialId,
SubjectId = subjectVisit.SubjectId,
TaskBlindName = blindTaskName,
TaskBlindName = blindTaskName2,
TaskName = subjectVisit.VisitName,
IsUrgent = subjectVisit.IsUrgent,
@ -747,7 +808,7 @@ namespace IRaCIS.Core.Application.Service
}
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
#region 分配
@ -920,7 +981,7 @@ namespace IRaCIS.Core.Application.Service
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
}
@ -992,7 +1053,7 @@ namespace IRaCIS.Core.Application.Service
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
}
@ -1069,7 +1130,7 @@ namespace IRaCIS.Core.Application.Service
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
#region 分配
@ -1197,7 +1258,7 @@ namespace IRaCIS.Core.Application.Service
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
}
@ -1277,6 +1338,7 @@ namespace IRaCIS.Core.Application.Service
var reReadingVisitTask = generateTaskCommand.ReReadingTask;
Guid? subjectVisitId = Guid.Empty;
if (reReadingVisitTask.SourceSubjectVisitId == null)
@ -1317,6 +1379,10 @@ namespace IRaCIS.Core.Application.Service
//&& t.TrialReadingCriterionId == reReadingVisitTask.TrialReadingCriterionId && t.TaskState == TaskState.Effect
// && t.SourceSubjectVisitId == reReadingVisitTask.SourceSubjectVisitId && t.ArmEnum == reReadingVisitTask.ArmEnum && t.DoctorUserId == reReadingVisitTask.DoctorUserId).FirstOrDefault();
var isRandomReading = trialReadingCriterionConfigList.FirstOrDefault(t => t.TrialReadingCriterionId == reReadingVisitTask.TrialReadingCriterionId)?.IsReadingTaskViewInOrder == ReadingOrder.Random;
var taskBlindName = isRandomReading ? await GetRandomTaskName(trialId, randomTaskBlindNameList) : reReadingVisitTask.TaskBlindName;
var newTask = await _visitTaskRepository.AddAsync(new VisitTask()
{
@ -1325,7 +1391,7 @@ namespace IRaCIS.Core.Application.Service
SubjectId = reReadingVisitTask.SubjectId,
ArmEnum = reReadingVisitTask.ArmEnum,
TaskName = reReadingVisitTask.TaskName,
TaskBlindName = reReadingVisitTask.TaskBlindName,
TaskBlindName = taskBlindName,
IsUrgent = reReadingVisitTask.IsAnalysisCreate ? false : subjectVisitUrgentInfo.IsUrgent,
TaskUrgentType = reReadingVisitTask.IsAnalysisCreate ? null : taskUrgent,
@ -1386,7 +1452,7 @@ namespace IRaCIS.Core.Application.Service
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
//}
@ -1491,7 +1557,7 @@ namespace IRaCIS.Core.Application.Service
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
break;
@ -1538,7 +1604,7 @@ namespace IRaCIS.Core.Application.Service
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
break;
@ -1548,6 +1614,11 @@ namespace IRaCIS.Core.Application.Service
var subjectUser = await _subjectUserRepository.Where(x => x.SubjectId == firstTask.SubjectId && x.ArmEnum == Arm.JudgeArm && x.IsConfirmed && x.TrialReadingCriterionId == firstTask.TrialReadingCriterionId).FirstOrDefaultAsync();
var isRandom = trialReadingCriterionConfigList.FirstOrDefault(t => t.TrialReadingCriterionId == firstTask.TrialReadingCriterionId)?.IsReadingTaskViewInOrder == ReadingOrder.Random;
var blindName = isRandom ? await GetRandomTaskName(trialId, randomTaskBlindNameList) : firstTask.TaskBlindName;
VisitTask visitTask = new VisitTask()
{
ArmEnum = Arm.JudgeArm,
@ -1564,7 +1635,7 @@ namespace IRaCIS.Core.Application.Service
SouceReadModuleId = firstTask.SouceReadModuleId,
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)),
TaskState = TaskState.Effect,
TaskBlindName = firstTask.TaskBlindName,
TaskBlindName = blindName,
DoctorUserId = subjectUser == null ? null : subjectUser.DoctorUserId,
TaskAllocationState = subjectUser == null ? TaskAllocationState.NotAllocate : TaskAllocationState.Allocated,
AllocateTime = subjectUser == null ? null : DateTime.Now,
@ -1576,7 +1647,7 @@ namespace IRaCIS.Core.Application.Service
await _visitTaskRepository.AddAsync(visitTask);
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => generateTaskCommand.JudgeVisitTaskIdList.Contains(x.Id), x => new VisitTask()
{
@ -1637,7 +1708,7 @@ namespace IRaCIS.Core.Application.Service
});
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
}
@ -1707,7 +1778,7 @@ namespace IRaCIS.Core.Application.Service
TrialId = originalTaskInfo.TrialId
});
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
_fusionCache.Set<int>(CacheKeys.TrialVisitTaskMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
break;
}

View File

@ -53,7 +53,11 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
IRepository<ReadingNoneDicomMark> _readingNoneDicomMarkRepository,
IRepository<ReadingNoneDicomMarkBinding> _readingNoneDicomMarkBindingRepository,
IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository,
//IRepository<ReadingCustomTag> _readingCustomTagRepository,
//IRepository<ReadingCustomTag> _readingCustomTagRepository,
IRepository<TaskStudy> _taskStudyRepository,
IRepository<TaskSeries> _taskSeriesRepository,
IRepository<TaskInstance> _taskInstanceRepository,
IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository,
IRepository<TaskInfluence> _taskInfluenceRepository,
IRepository<TrialQCQuestionAnswer> _trialQCQuestionAnswerRepository,
ILogger<VisitTaskService> _logger,
@ -91,6 +95,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
{
TrialReadingCriterionId = t.Id,
IsAutoCreate = t.IsAutoCreate,
ReadingTool = t.ReadingTool,
IsAdditionalAssessment = t.IsAdditionalAssessment,
TrialReadingCriterionName = t.CriterionName,
CriterionType = t.CriterionType,
@ -849,7 +854,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<ReReadingTaskView>> GetIRReReadingTaskList(VisitTaskQuery inQuery)
public async Task<IResponseOutput<PageOutput<ReReadingTaskView>>> GetIRReReadingTaskList(VisitTaskQuery inQuery)
{
var visitTaskQueryable = _visitTaskReReadingRepository
@ -873,6 +878,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
.WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskName))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskBlindName), t => t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskBlindName))
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate))
.WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate)
.WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1))
@ -884,7 +890,11 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);
return pageList;
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
.Select(t => new { t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
return ResponseOutput.Ok(pageList, criterionInfo);
}
@ -1237,7 +1247,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<IRHaveReadView>> GetIRHaveReadTaskList(VisitTaskQuery inQuery)
public async Task<IResponseOutput<PageOutput<IRHaveReadView>>> GetIRHaveReadTaskList(VisitTaskQuery inQuery)
{
@ -1256,6 +1266,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
.WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState)
.WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskBlindName), t => t.TaskBlindName.Contains(inQuery.TaskBlindName))
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate))
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate)
.WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1))
@ -1265,7 +1276,10 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);
return pageList;
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
.Select(t => new { t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
return ResponseOutput.Ok(pageList, criterionInfo);
}
@ -2074,29 +2088,27 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
//申请表 设置新任务Id
visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id;
//拷贝原始表单
if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id)
if (origenalTask.ReadingCategory == ReadingCategory.Visit)
{
if (origenalTask.ReadingCategory == ReadingCategory.Visit)
CopyImages(newTask, influenceTask);
//拷贝原始表单
if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id)
{
CopyForms(newTask, origenalTask);
}
}
//拷贝后续表单
if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum)
{
if (origenalTask.ReadingCategory == ReadingCategory.Visit)
//拷贝后续表单
if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum)
{
newTask.IsCopyLesionAnswer = true;
//CopyForms(newTask, origenalTask);
}
}
}
}
@ -2185,6 +2197,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
//申请表 设置新任务Id
visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id;
if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id)
{
if (origenalTask.ReadingCategory == ReadingCategory.Visit)
@ -2194,16 +2207,16 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
}
//拷贝后续表单
if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum)
{
if (origenalTask.ReadingCategory == ReadingCategory.Visit)
{
newTask.IsCopyLesionAnswer = true;
//CopyForms(newTask, origenalTask);
////拷贝后续表单
//if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum)
//{
// if (origenalTask.ReadingCategory == ReadingCategory.Visit)
// {
// newTask.IsCopyLesionAnswer = true;
// //CopyForms(newTask, origenalTask);
}
}
// }
//}
}
}
});
@ -2223,7 +2236,84 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
}
}
private async Task CopyForms(VisitTask newTask, VisitTask origenalTask)
private void CopyImages(VisitTask newTask, VisitTask origenalTask)
{
//拷贝后处理绑定的的Dicom影像
var newTaskId = newTask.Id;
var taskStudyList = _taskStudyRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
var taskSeriesList = _taskSeriesRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
var taskInstanceList = _taskInstanceRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
foreach (var taskStudy in taskStudyList)
{
var newStudyId = IdentifierHelper.CreateGuid(taskStudy.StudyInstanceUid, taskStudy.TrialId.ToString(), newTaskId.ToString());
var newStudy = taskStudy.Clone();
newStudy.Id = newStudyId;
newStudy.SeqId = NewId.NextSequentialGuid();
newStudy.VisitTaskId = newTaskId;
_ = _taskStudyRepository.AddAsync(newStudy).Result;
var studySeriesList = taskSeriesList.Where(t => t.StudyId == taskStudy.Id).ToList();
foreach (var series in studySeriesList)
{
var newSeriesId = IdentifierHelper.CreateGuid(series.StudyInstanceUid, series.SeriesInstanceUid, series.TrialId.ToString(), newTaskId.ToString());
var newSeries = series.Clone();
newSeries.Id = newSeriesId;
newSeries.SeqId = NewId.NextSequentialGuid();
newSeries.StudyId = newStudyId;
newSeries.VisitTaskId = newTaskId;
_ = _taskSeriesRepository.AddAsync(newSeries).Result;
var studyInstanceList = taskInstanceList.Where(t => t.StudyId == taskStudy.Id && t.SeriesId == series.Id).ToList();
foreach (var instance in studyInstanceList)
{
var newInstanceId = IdentifierHelper.CreateGuid(newStudy.StudyInstanceUid, newSeries.SeriesInstanceUid, instance.SopInstanceUid, newStudy.TrialId.ToString(), newTaskId.ToString());
var newInstance = instance.Clone();
newInstance.Id = newInstanceId;
newInstance.SeqId = NewId.NextSequentialGuid();
newInstance.StudyId = newStudyId;
newInstance.SeriesId = newSeriesId;
newInstance.VisitTaskId = newTaskId;
Console.WriteLine($"StudyInstanceUid:{newStudy.StudyInstanceUid} SeriesInstanceUid:{newSeries.SeriesInstanceUid} SopInstanceUid: {instance.SopInstanceUid},newInstanceId:{newInstanceId} ");
_ = _taskInstanceRepository.AddAsync(newInstance).Result;
}
}
}
//拷贝后处理的NoneDicom
var fileList = _noneDicomStudyFileRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
foreach (var file in fileList)
{
var newFile = file.Clone();
newFile.Id = NewId.NextSequentialGuid();
newFile.VisitTaskId = newTaskId;
_ = _noneDicomStudyFileRepository.AddAsync(newFile).Result;
}
}
private void CopyForms(VisitTask newTask, VisitTask origenalTask)
{
newTask.IsCopyLesionAnswer = true;
//自定义
@ -2239,7 +2329,9 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
//_ = _readingCustomTagRepository.AddRangeAsync(readingCustomTagList).Result;
var readingTaskQuestionAnswerList = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
@ -2301,7 +2393,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
#region 分割
Dictionary<Guid, Guid> segmentationRelationship = new Dictionary<Guid, Guid>() { };
var segmentationList = _segmentationRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
var segmentationList = _segmentationRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
foreach (var item in segmentationList)
{
@ -2314,7 +2406,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
Dictionary<Guid, Guid> segmentRelationship = new Dictionary<Guid, Guid>() { };
var segmentList = _segmentRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
var segmentList = _segmentRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();
foreach (var item in segmentList)
{
var newSegmentationId = NewId.NextSequentialGuid();
@ -2327,7 +2419,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
item.VisitTaskId = newTask.Id;
}
var segmentBindingList = _segmentBindingRepository.Where(x => x.VisitTaskId == origenalTask.Id).ToList();
var segmentBindingList = _segmentBindingRepository.Where(x => x.VisitTaskId == origenalTask.Id).ToList();
foreach (var item in segmentBindingList)
{
@ -2718,7 +2810,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
// 处理阅片期的临床数据
var readModuleIdList =await _readModuleRepository.Where(x => x.SubjectVisitId == sv.Id).Select(x => x.Id).ToListAsync();
var readModuleIdList = await _readModuleRepository.Where(x => x.SubjectVisitId == sv.Id).Select(x => x.Id).ToListAsync();
await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => readModuleIdList.Contains(t.ReadingId), c => new ReadingClinicalData()

View File

@ -96,6 +96,8 @@ namespace IRaCIS.Application.Contracts
public Guid? TrialReadingCriterionId { get; set; }
public Guid? SystemReadingCriterionId { get; set; }
public Guid? TrialId { get; set; }
}

View File

@ -4,7 +4,6 @@
// 生成时间 2026-03-10 06:15:31Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using System;
using IRaCIS.Core.Domain.Share;
using System.Collections.Generic;
namespace IRaCIS.Core.Application.ViewModel;
@ -96,7 +95,22 @@ public class FileUploadRecordAddOrEdit
public bool? IsSync { get; set; }
}
public class CommonUploadRecordDto: CommonUploadRecordAddOrEdit
{
}
public class CommonUploadRecordAddOrEdit
{
public Guid? Id { get; set; }
public string FileType { get; set; }
public string FileName { get; set; }
public long FileSize { get; set; }
public string Path { get; set; }
}
public class SubjectFileUploadRecordQuery : PageInput
{
public Guid TrialId { get; set; }

View File

@ -4,6 +4,7 @@ using Medallion.Threading;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
@ -16,7 +17,7 @@ using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service.Common;
[ApiExplorerSettings(GroupName = "Common")]
public class DeployConfigService(IMapper _mapper, IUserInfo _userInfo, IWebHostEnvironment _hostEnvironment, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService
public class DeployConfigService(IMapper _mapper, IConfiguration _configuration, IDistributedLockProvider _distributedLockProvider, IUserInfo _userInfo, IWebHostEnvironment _hostEnvironment, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService
{
/// <summary>
@ -26,7 +27,18 @@ public class DeployConfigService(IMapper _mapper, IUserInfo _userInfo, IWebHostE
/// <returns></returns>
public async Task<ServiceVerifyConfigOption> GetSystemBasicConfigInfo([FromServices] IOptionsMonitor<ServiceVerifyConfigOption> options)
{
return options.CurrentValue;
//var config = _configuration.GetSection("BasicSystemConfig").Get<ServiceVerifyConfigOption>();
//return config;
var path = Path.Combine( _hostEnvironment.ContentRootPath,$"appsettings.{_hostEnvironment.EnvironmentName}.json");
var json = File.ReadAllText(path);
var obj = JObject.Parse(json);
return obj["BasicSystemConfig"]!.ToObject<ServiceVerifyConfigOption>()!;
}
/// <summary>
@ -37,34 +49,45 @@ public class DeployConfigService(IMapper _mapper, IUserInfo _userInfo, IWebHostE
[HttpPost]
public async Task<IResponseOutput> UpdateSystemBasicConfig(ServiceVerifyConfigOption basicSystemConfigOption)
{
var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json";
string text = System.IO.File.ReadAllText(path);
// 修改
JObject obj = JObject.Parse(text);
// QCRiskControl 相关配置
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.QCRiskControl)] = basicSystemConfigOption.QCRiskControl;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenUserComplexPassword)] = basicSystemConfigOption.OpenUserComplexPassword;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenSignDocumentBeforeWork)] = basicSystemConfigOption.OpenSignDocumentBeforeWork;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenTrialRelationDelete)] = basicSystemConfigOption.OpenTrialRelationDelete;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenLoginLimit)] = basicSystemConfigOption.OpenLoginLimit;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.LoginMaxFailCount)] = basicSystemConfigOption.LoginMaxFailCount;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.LoginFailLockMinutes)] = basicSystemConfigOption.LoginFailLockMinutes;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.AutoLoginOutMinutes)] = basicSystemConfigOption.AutoLoginOutMinutes;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenLoginMFA)] = basicSystemConfigOption.OpenLoginMFA;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ContinuousReadingTimeMin)] = basicSystemConfigOption.ContinuousReadingTimeMin;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ReadingRestTimeMin)] = basicSystemConfigOption.ReadingRestTimeMin;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.IsNeedChangePassWord)] = basicSystemConfigOption.IsNeedChangePassWord;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ChangePassWordDays)] = basicSystemConfigOption.ChangePassWordDays;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.TemplateType)] = ((int)basicSystemConfigOption.TemplateType); // 枚举需要转换为字符串
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ThirdPdfUrl)] = basicSystemConfigOption.ThirdPdfUrl;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.UserMFAVerifyMinutes)] = basicSystemConfigOption.UserMFAVerifyMinutes;
//var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json";
var path = Path.Combine(_hostEnvironment.ContentRootPath, $"appsettings.{_hostEnvironment.EnvironmentName}.json");
// 重新写入appsettings.json
string result = obj.ToString();
System.IO.File.WriteAllText(path, result);
var @lock = _distributedLockProvider.CreateLock("WriteConfigFile");
using (await @lock.AcquireAsync())
{
string text = System.IO.File.ReadAllText(path);
// 修改
JObject obj = JObject.Parse(text);
// QCRiskControl 相关配置
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.QCRiskControl)] = basicSystemConfigOption.QCRiskControl;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenUserComplexPassword)] = basicSystemConfigOption.OpenUserComplexPassword;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenSignDocumentBeforeWork)] = basicSystemConfigOption.OpenSignDocumentBeforeWork;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenTrialRelationDelete)] = basicSystemConfigOption.OpenTrialRelationDelete;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenLoginLimit)] = basicSystemConfigOption.OpenLoginLimit;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.LoginMaxFailCount)] = basicSystemConfigOption.LoginMaxFailCount;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.LoginFailLockMinutes)] = basicSystemConfigOption.LoginFailLockMinutes;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.AutoLoginOutMinutes)] = basicSystemConfigOption.AutoLoginOutMinutes;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.OpenLoginMFA)] = basicSystemConfigOption.OpenLoginMFA;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ContinuousReadingTimeMin)] = basicSystemConfigOption.ContinuousReadingTimeMin;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ReadingRestTimeMin)] = basicSystemConfigOption.ReadingRestTimeMin;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.IsNeedChangePassWord)] = basicSystemConfigOption.IsNeedChangePassWord;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ChangePassWordDays)] = basicSystemConfigOption.ChangePassWordDays;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.TemplateType)] = ((int)basicSystemConfigOption.TemplateType); // 枚举需要转换为字符串
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.ThirdPdfUrl)] = basicSystemConfigOption.ThirdPdfUrl;
obj["BasicSystemConfig"][nameof(ServiceVerifyConfigOption.UserMFAVerifyMinutes)] = basicSystemConfigOption.UserMFAVerifyMinutes;
// 重新写入appsettings.json
string result = obj.ToString();
System.IO.File.WriteAllText(path, result);
}
return ResponseOutput.Ok();
@ -77,7 +100,18 @@ public class DeployConfigService(IMapper _mapper, IUserInfo _userInfo, IWebHostE
/// <returns></returns>
public async Task<SystemEmailSendConfig> GetEmailConfigInfo([FromServices] IOptionsMonitor<SystemEmailSendConfig> options)
{
return options.CurrentValue;
//两种方式都有问题
//var config = _configuration.GetSection("BasicSystemConfig").Get<SystemEmailSendConfig>();
//return config;
//return options.CurrentValue;
var path = Path.Combine(_hostEnvironment.ContentRootPath, $"appsettings.{_hostEnvironment.EnvironmentName}.json");
var json = File.ReadAllText(path);
var obj = JObject.Parse(json);
return obj["SystemEmailSendConfig"]!.ToObject<SystemEmailSendConfig>()!;
}
@ -89,41 +123,51 @@ public class DeployConfigService(IMapper _mapper, IUserInfo _userInfo, IWebHostE
[HttpPost]
public async Task<IResponseOutput> UpdateSystemEmailConfig(SystemEmailSendConfig emailConfig)
{
var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json";
var path = Path.Combine(_hostEnvironment.ContentRootPath,$"appsettings.{_hostEnvironment.EnvironmentName}.json");
//var path = $"appsettings.{_hostEnvironment.EnvironmentName}.json";
string text = System.IO.File.ReadAllText(path);
var @lock = _distributedLockProvider.CreateLock("WriteConfigFile");
// 修改
JObject obj = JObject.Parse(text);
// SystemEmailSendConfig 相关配置
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.Port)] = emailConfig.Port;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.Host)] = emailConfig.Host;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.Imap)] = emailConfig.Imap;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.ImapPort)] = emailConfig.ImapPort;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.FromEmail)] = emailConfig.FromEmail;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.FromName)] = emailConfig.FromName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.AuthorizationCode)] = emailConfig.AuthorizationCode;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.SiteUrl)] = emailConfig.SiteUrl;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.PlatformName)] = emailConfig.PlatformName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.PlatformNameCN)] = emailConfig.PlatformNameCN;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.SystemShortName)] = emailConfig.SystemShortName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.OrganizationName)] = emailConfig.OrganizationName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.OrganizationNameCN)] = emailConfig.OrganizationNameCN;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyName)] = emailConfig.CompanyName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyNameCN)] = emailConfig.CompanyNameCN;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyShortName)] = emailConfig.CompanyShortName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyShortNameCN)] = emailConfig.CompanyShortNameCN;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.IsEnv_US)] = emailConfig.IsEnv_US;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.EmailRegexStr)] = emailConfig.EmailRegexStr;
using (await @lock.AcquireAsync())
{
string text = System.IO.File.ReadAllText(path);
// 修改
JObject obj = JObject.Parse(text);
// SystemEmailSendConfig 相关配置
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.Port)] = emailConfig.Port;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.Host)] = emailConfig.Host;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.Imap)] = emailConfig.Imap;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.ImapPort)] = emailConfig.ImapPort;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.FromEmail)] = emailConfig.FromEmail;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.FromName)] = emailConfig.FromName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.AuthorizationCode)] = emailConfig.AuthorizationCode;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.SiteUrl)] = emailConfig.SiteUrl;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.PlatformName)] = emailConfig.PlatformName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.PlatformNameCN)] = emailConfig.PlatformNameCN;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.SystemShortName)] = emailConfig.SystemShortName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.OrganizationName)] = emailConfig.OrganizationName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.OrganizationNameCN)] = emailConfig.OrganizationNameCN;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyName)] = emailConfig.CompanyName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyNameCN)] = emailConfig.CompanyNameCN;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyShortName)] = emailConfig.CompanyShortName;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.CompanyShortNameCN)] = emailConfig.CompanyShortNameCN;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.IsEnv_US)] = emailConfig.IsEnv_US;
obj["SystemEmailSendConfig"][nameof(SystemEmailSendConfig.EmailRegexStr)] = emailConfig.EmailRegexStr;
// 重新写入appsettings.json
string result = obj.ToString();
System.IO.File.WriteAllText(path, result);
// 重新写入appsettings.json
string result = obj.ToString();
System.IO.File.WriteAllText(path, result);
}
return ResponseOutput.Ok();
}

View File

@ -452,14 +452,14 @@ namespace IRaCIS.Core.Application.Service
if (inDto.TrialReadingCriterionId == null && inDto.SystemReadingCriterionId == null)
{
return result;
return await ChangeTrialObjectNameList(result,inDto.TrialId);
}
else if (inDto.TrialReadingCriterionId != null)
{
var trialCriterionType = await _readingQuestionCriterionTrial.Where(x => x.Id == inDto.TrialReadingCriterionId).Select(x => x.CriterionType).FirstOrDefaultAsync();
if (trialCriterionType == CriterionType.SelfDefine)
{
return result;
return await ChangeTrialObjectNameList(result, inDto.TrialId);
}
@ -505,7 +505,7 @@ namespace IRaCIS.Core.Application.Service
result[item.Key] = item.Value;
}
return result;
return await ChangeTrialObjectNameList(result, inDto.TrialId);
}
else
{
@ -548,12 +548,76 @@ namespace IRaCIS.Core.Application.Service
result[item.Key] = item.Value;
}
return result;
return await ChangeTrialObjectNameList(result, inDto.TrialId);
}
}
/// <summary>
/// 替换字典中的项目名称为试验对象名称 --New
/// </summary>
/// <param name="data"></param>
/// <param name="trialId"></param>
/// <returns></returns>
private async Task<Dictionary<string, List<BasicDicSelect>>> ChangeTrialObjectNameList(Dictionary<string, List<BasicDicSelect>> data,Guid? trialId)
{
if (!trialId.HasValue)
{
return data;
}
// 查询映射集合
var trialObjectNameList = await _trialRepository
.Where(x => x.Id == trialId)
.Select(x => x.TrialObjectNameList)
.FirstOrDefaultAsync();
// 无映射数据直接返回
if (trialObjectNameList == null || !trialObjectNameList.Any())
{
return data;
}
// 构建映射字典,过滤空名称,避免无效替换
var replaceDict = trialObjectNameList
.Where(m => !string.IsNullOrEmpty(m.Name))
.ToDictionary(m => m.Name, m => m.TrialName);
// 遍历替换
foreach (var (_, selectList) in data)
{
foreach (var selectItem in selectList)
{
// 替换Value判null保护
if (selectItem.Value != null)
{
string tempVal = selectItem.Value;
foreach (var (oldStr, newStr) in replaceDict)
{
tempVal = tempVal.Replace(oldStr, newStr);
}
selectItem.Value = tempVal;
}
// 替换中文名称ValueCN
if (selectItem.ValueCN != null)
{
string tempCn = selectItem.ValueCN;
foreach (var (oldStr, newStr) in replaceDict)
{
tempCn = tempCn.Replace(oldStr, newStr);
}
selectItem.ValueCN = tempCn;
}
}
}
return data;
}
#region 稽查相关
/// <summary>

View File

@ -4,19 +4,13 @@
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share;
using MailKit;
using MailKit.Net.Imap;
using MailKit.Search;
using MailKit.Security;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using System.Text.RegularExpressions;
namespace IRaCIS.Core.Application.Contracts

View File

@ -1,27 +1,15 @@
using DocumentFormat.OpenXml.Spreadsheet;
using ClosedXML.Excel;
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infra.EFCore.Migrations;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using NPOI.HPSF;
using NPOI.POIFS.Properties;
using NPOI.SS.Formula.Functions;
using NPOI.XSSF.UserModel;
using System.ComponentModel.Design;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using static IRaCIS.Core.Application.Service.ExcelExportHelper;
@ -153,9 +141,9 @@ namespace IRaCIS.Core.Application.Service.Common
var dynamicColumnConfig = new DynamicColumnConfig()
{
AutoColumnTitleRowIndex = 2,
AutoColumnStartIndex = 7,
TempalteLastColumnIndex = 6,
AutoColumnTitleRowIndex = 3, //2
AutoColumnStartIndex = 8, //7
TempalteLastColumnIndex = 7, //6
DynamicItemDicName = "TranslateDicName",
DynamicItemValueName = "Answer",
DynamicItemTitleName = "QuestionName",
@ -167,7 +155,7 @@ namespace IRaCIS.Core.Application.Service.Common
};
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(StaticData.Export.TrialQCResult_Export, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCQuestionResult_Export), dynamicColumnConfig: dynamicColumnConfig);
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(StaticData.Export.TrialQCResult_Export, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCQuestionResult_Export), dynamicColumnConfig: dynamicColumnConfig);
return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
@ -1209,7 +1197,7 @@ namespace IRaCIS.Core.Application.Service.Common
t.VisitTaskList.Where(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == dto.TrialReadingCriterionId && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned).Count() == (int)trialReadingCriterion.ReadingType ?
ReadingStatusEnum.ReadCompleted : t.VisitTaskList.Where(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == dto.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.ReadingCategory == ReadingCategory.Visit && t.TaskAllocationState == TaskAllocationState.Allocated).Count() == (int)trialReadingCriterion.ReadingType ? ReadingStatusEnum.ImageReading :
t.ReadingStatus
}).ToList(),
}).OrderBy(t=>t.VisitTaskNum).ToList(),
ModuleList = subject.ReadModuleList.Where(t => t.TrialReadingCriterionId == dto.TrialReadingCriterionId).Select(t => new SubjectProgressDto.MouduleProgress()
{
@ -1239,55 +1227,60 @@ namespace IRaCIS.Core.Application.Service.Common
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _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_ClosedXMLAsync(StaticData.Export.TrialSubjectProgressList_Export, exportInfo, /*"", */_commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectProgressDto));
// 使用NPOI 进行二次处理
var wb = new XSSFWorkbook(memoryStream);
var sheet = wb.GetSheetAt(0);
// 使用 ClosedXML 进行二次处理
using var workbook = new XLWorkbook(memoryStream);
var worksheet = workbook.Worksheet(1); // 获取第一个工作表索引从1开始
foreach (var subject in list)
{
var index = list.IndexOf(subject);
var row = sheet.GetRow(index + 4);
// ClosedXML 行索引从1开始原来 NPOI 从0开始所以 +1
var row = worksheet.Row(index + 4 + 1); // NPOI: index + 4, ClosedXML: +1 = index + 5
foreach (var item in subject.TotalList)
{
//从第五列开始动态写
var visitIndex = subject.TotalList.IndexOf(item) + 4;
// 从第五列开始动态写ClosedXML 列索引从1开始
var visitIndex = subject.TotalList.IndexOf(item) + 4 + 1; // NPOI: +4, ClosedXML: +1 = +5
var cell = row.CreateCell(visitIndex);
var cell = row.Cell(visitIndex);
if (item.IsLostVisit == true)
{
cell.CellStyle = sheet.GetRow(1).GetCell(7).CellStyle;
//cell.CellStyle = sheet.GetRow(1).GetCell(7).CellStyle;
// 复制样式 - ClosedXML 需要先获取源样式,然后应用到目标单元格
var sourceCell = worksheet.Row(2).Cell(8); // 原 NPOI: GetRow(1).GetCell(7) -> +1 转换
cell.Style = sourceCell.Style;
}
else
{
switch (item.ReadingStatus)
{
case ReadingStatusEnum.ImageNotSubmit:
cell.CellStyle = sheet.GetRow(1).GetCell(1).CellStyle;
cell.Style = worksheet.Row(2).Cell(2).Style; // NPOI: (1,1) -> ClosedXML: (2,2)
break;
case ReadingStatusEnum.ImageQuality:
cell.CellStyle = sheet.GetRow(1).GetCell(2).CellStyle;
cell.Style = worksheet.Row(2).Cell(3).Style; // (1,2) -> (2,3)
break;
case ReadingStatusEnum.ConsistencyCheck:
cell.CellStyle = sheet.GetRow(1).GetCell(3).CellStyle;
cell.Style = worksheet.Row(2).Cell(4).Style; // (1,3) -> (2,4)
break;
case ReadingStatusEnum.TaskAllocate:
cell.CellStyle = sheet.GetRow(1).GetCell(4).CellStyle;
cell.Style = worksheet.Row(2).Cell(5).Style;// (1,4) -> (2,5)
break;
case ReadingStatusEnum.ImageReading:
cell.CellStyle = sheet.GetRow(1).GetCell(5).CellStyle;
cell.Style = worksheet.Row(2).Cell(6).Style;// (1,5) -> (2,6)
break;
case ReadingStatusEnum.ReadCompleted:
cell.CellStyle = sheet.GetRow(1).GetCell(6).CellStyle;
cell.Style = worksheet.Row(2).Cell(7).Style; // (1,6) -> (2,7)
break;
default:
@ -1297,12 +1290,13 @@ namespace IRaCIS.Core.Application.Service.Common
cell.SetCellValue(item.TaskName);
cell.SetValue(item.TaskName);
}
}
// 保存到 MemoryStream
var memoryStream2 = new MemoryStream();
wb.Write(memoryStream2, true);
workbook.SaveAs(memoryStream2);
memoryStream2.Seek(0, SeekOrigin.Begin);
return new FileStreamResult(memoryStream2, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
@ -2709,9 +2703,10 @@ namespace IRaCIS.Core.Application.Service.Common
var dynamicColumnConfig = new DynamicColumnConfig()
{
//可读的列表名行索引,不是{{}} 模板行索引
AutoColumnTitleRowIndex = 2,
AutoColumnStartIndex = 5,
TempalteLastColumnIndex = 4,
AutoColumnTitleRowIndex = 3, //2
AutoColumnStartIndex = 6, //5
TempalteLastColumnIndex = 5, //4
DynamicItemDicName = "TranslateDicName",
DynamicItemValueName = "QuestionValue",
DynamicItemTitleName = "QuestionName",
@ -2722,7 +2717,7 @@ namespace IRaCIS.Core.Application.Service.Common
};
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(AnalysisDynamicCommonExport), criterion.CriterionType, dynamicColumnConfig);
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(AnalysisDynamicCommonExport), criterion.CriterionType, dynamicColumnConfig);
return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
@ -2768,11 +2763,11 @@ namespace IRaCIS.Core.Application.Service.Common
if (criterion.CriterionType == CriterionType.OCT)
{
list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_ReadingLession_Export, ExportCatogory = ExportResult.OCT_ReadingLession_Export });
list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_CDISC_Export, ExportCatogory = ExportResult.OCT_CDISC_Export });
//list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_CDISC_Export, ExportCatogory = ExportResult.OCT_CDISC_Export });
}
if (criterion.CriterionType == CriterionType.IVUS)
{
list.Add(new ExportDocumentDes() { Code = StaticData.Export.IVUS_CDISC_Export, ExportCatogory = ExportResult.IVUS_CDISC_Export });
//list.Add(new ExportDocumentDes() { Code = StaticData.Export.IVUS_CDISC_Export, ExportCatogory = ExportResult.IVUS_CDISC_Export });
}
if (criterion.CriterionGroup != CriterionGroup.Tumor /*&& criterion.CriterionType != CriterionType.OCT && criterion.CriterionType != CriterionType.IVUS*/)
{
@ -2867,7 +2862,8 @@ namespace IRaCIS.Core.Application.Service.Common
if (!criterion.IsArbitrationReading)
{
//仲裁阅片 才有裁判阅片明细表 同时要把模板里面的三列给去掉
removeColumnIndexList = new List<int>() { 6, 7, 8 };
//removeColumnIndexList = new List<int>() { 6, 7, 8 };
removeColumnIndexList = new List<int>() { 7, 8 ,9};
}
//阅片结果表 和阅片结果明细表 没有肿瘤学的时候需要移除肿瘤学三个字段
@ -2876,7 +2872,8 @@ namespace IRaCIS.Core.Application.Service.Common
{
if (inQuery.ReadingExportType == ExportResult.TableOfAssessmentResults || inQuery.ReadingExportType == ExportResult.DetailedTableOfAssessmentResults)
{
removeColumnIndexList = removeColumnIndexList.Union(new List<int>() { 9, 10, 11 }).ToList();
//removeColumnIndexList = removeColumnIndexList.Union(new List<int>() { 9, 10, 11 }).ToList();
removeColumnIndexList = removeColumnIndexList.Union(new List<int>() { 10, 11, 12 }).ToList();
}
}
}
@ -2903,7 +2900,7 @@ namespace IRaCIS.Core.Application.Service.Common
//阅片结果表
export_Template = StaticData.Export.CommonReading_Export;
}
//斑块表
//斑块表
else if (inQuery.ReadingExportType == ExportResult.OCT_ReadingLession_Export)
{
//OCT
@ -2933,7 +2930,7 @@ namespace IRaCIS.Core.Application.Service.Common
arbitrationRule = criterion.ArbitrationRule,
trialReadingCriterionId = inQuery.TrialReadingCriterionId,
isEn_Us = _userInfo.IsEn_Us
}).ToListAsync();
}).AsSplitQuery().ToListAsync();
}
//肿瘤标准 病灶明细表 按照病灶级别 (OCT 暂时不删除,先看是否能覆盖)
@ -2952,7 +2949,7 @@ namespace IRaCIS.Core.Application.Service.Common
arbitrationRule = criterion.ArbitrationRule,
trialReadingCriterionId = inQuery.TrialReadingCriterionId,
isEn_Us = _userInfo.IsEn_Us
}).ToListAsync();
}).AsSplitQuery().ToListAsync();
}
// 非肿瘤标准 包括自定义,以及系统非肿瘤 会配置到表格层级 问题名称是 表格名称_表格子问题名
@ -2970,7 +2967,7 @@ namespace IRaCIS.Core.Application.Service.Common
arbitrationRule = criterion.ArbitrationRule,
trialReadingCriterionId = inQuery.TrialReadingCriterionId,
isEn_Us = _userInfo.IsEn_Us
}).ToListAsync();
}).AsSplitQuery().ToListAsync();
}
// CDISC 导出 只管到 外层问题层级 和阅片结果表是保持一致
@ -2988,7 +2985,7 @@ namespace IRaCIS.Core.Application.Service.Common
arbitrationRule = criterion.ArbitrationRule,
trialReadingCriterionId = inQuery.TrialReadingCriterionId,
isEn_Us = _userInfo.IsEn_Us
}).ToListAsync();
}).AsSplitQuery().ToListAsync();
}
else
{
@ -3000,7 +2997,7 @@ namespace IRaCIS.Core.Application.Service.Common
arbitrationRule = criterion.ArbitrationRule,
trialReadingCriterionId = inQuery.TrialReadingCriterionId,
isEn_Us = _userInfo.IsEn_Us
}).ToListAsync();
}).AsSplitQuery().ToListAsync();
}
}
@ -3170,7 +3167,7 @@ namespace IRaCIS.Core.Application.Service.Common
addLessionInfoList.Add(new CommonQuesionInfo() { QuestionName = _userInfo.IsEn_Us ? "Lesion Type" : "病灶类型", QuestionValue = lession.LessionType, TranslateDicName = "LesionType" });
}
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionName = t.QuestionName, OptionTypeEnum = t.OptionTypeEnum, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName ,Unit=t.Unit});
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionName = t.QuestionName, OptionTypeEnum = t.OptionTypeEnum, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName, Unit = t.Unit });
//有三部分组成 外层问题+ 没有配置病灶编号和类型+ 动态的表格问题
var dynamicLessionInfoList = item.QuestionAnswerList.Union(addLessionInfoList).Union(dynamicPartialLessionInfoList).ToList();
@ -3358,9 +3355,10 @@ namespace IRaCIS.Core.Application.Service.Common
dynamicColumnConfig = new DynamicColumnConfig()
{
AutoColumnTitleRowIndex = 2,
AutoColumnStartIndex = 6,
TempalteLastColumnIndex = 11,
AutoColumnTitleRowIndex = 3, //2
AutoColumnStartIndex = 7, //6
TempalteLastColumnIndex = 12,//11
DynamicItemDicName = "TranslateDicName",
DynamicItemValueName = "QuestionValue",
DynamicItemTitleName = "QuestionName",
@ -3372,7 +3370,7 @@ namespace IRaCIS.Core.Application.Service.Common
TranslateDicNameList = translateDicNameList
};
if (export_Template == StaticData.Export.ReadingLession_Export || export_Template == StaticData.Export.CommonJudgeReadingDetail_Export || export_Template== StaticData.Export.OCT_ReadingLession_Export)
if (export_Template == StaticData.Export.ReadingLession_Export || export_Template == StaticData.Export.CommonJudgeReadingDetail_Export || export_Template == StaticData.Export.OCT_ReadingLession_Export)
{
dynamicColumnConfig.TempalteLastColumnIndex = 8;
}
@ -3391,7 +3389,7 @@ namespace IRaCIS.Core.Application.Service.Common
var trialConfigTableQuestionList = _trialReadingTableQuestionRepository.Where(t => t.TrialId == trialId && t.TrialCriterionId == trialReadingCriterionId).Where(t => t.ExportResultStr.Contains(((int)inQuery.ReadingExportType).ToString()))
.Select(t => new ExportQuestionBasicInfo()
{
QuestionId = t.Id,
QuestionId = t.Id,
TableName = _userInfo.IsEn_Us ? t.ReadingQuestionTrial.QuestionEnName : t.ReadingQuestionTrial.QuestionName,
QuestionName = _userInfo.IsEn_Us ? t.QuestionEnName : t.QuestionName,
CDISCCode = t.CDISCCode,
@ -3435,7 +3433,7 @@ namespace IRaCIS.Core.Application.Service.Common
var dynamicLessionInfoList = new List<CommonQuesionInfo>();
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionId = t.TableQuesionId,OptionTypeEnum=t.OptionTypeEnum, QuestionName = t.QuestionName, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName, CDISCCode = t.CDISCCode, Unit = t.Unit });
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionId = t.TableQuesionId, OptionTypeEnum = t.OptionTypeEnum, QuestionName = t.QuestionName, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName, CDISCCode = t.CDISCCode, Unit = t.Unit });
//两部分组成 外层问题+ 动态的表格问题
dynamicLessionInfoList = item.QuestionAnswerList.Union(dynamicPartialLessionInfoList).ToList();
@ -3458,9 +3456,9 @@ namespace IRaCIS.Core.Application.Service.Common
dynamicColumnConfig = new DynamicColumnConfig()
{
AutoColumnTitleRowIndex = 1,
AutoColumnStartIndex = 6,
TempalteLastColumnIndex = 10,
AutoColumnTitleRowIndex = 2, //1
AutoColumnStartIndex = 7, //6
TempalteLastColumnIndex = 11, //10
DynamicItemDicName = "TranslateDicName",
DynamicItemValueName = "QuestionValue",
DynamicItemTitleName = "QuestionName",
@ -3543,9 +3541,9 @@ namespace IRaCIS.Core.Application.Service.Common
dynamicColumnConfig = new DynamicColumnConfig()
{
AutoColumnTitleRowIndex = 1,
AutoColumnStartIndex = 6,
TempalteLastColumnIndex = 15,
AutoColumnTitleRowIndex = 2, //1
AutoColumnStartIndex = 7, //6
TempalteLastColumnIndex = 16, //15
DynamicItemDicName = "TranslateDicName",
DynamicItemValueName = "QuestionValue",
DynamicItemTitleName = "QuestionName",
@ -3578,9 +3576,9 @@ namespace IRaCIS.Core.Application.Service.Common
dynamicColumnConfig = new DynamicColumnConfig()
{
AutoColumnTitleRowIndex = 1,
AutoColumnStartIndex = 6,
TempalteLastColumnIndex = 10,
AutoColumnTitleRowIndex = 2, //1
AutoColumnStartIndex = 7, //6
TempalteLastColumnIndex = 11, //10
DynamicItemDicName = "TranslateDicName",
DynamicItemValueName = "QuestionValue",
DynamicItemTitleName = "QuestionName",
@ -3650,12 +3648,12 @@ namespace IRaCIS.Core.Application.Service.Common
if (inQuery.ReadingExportType == ExportResult.NoneTumorCDISC)
{
(memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig);
(memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig);
}
else
{
(memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig);
(memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig);
}

View File

@ -1,26 +1,15 @@
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using MiniExcelLibs.OpenXml;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Asn1.X509;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service.Common;

View File

@ -1,32 +1,9 @@
using Amazon.Runtime.Internal.Transform;
using DocumentFormat.OpenXml.Bibliography;
using DocumentFormat.OpenXml.Office2010.CustomUI;
using DocumentFormat.OpenXml.Office2021.DocumentTasks;
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using MailKit;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;
using NetTopologySuite.Triangulate.Tri;
using NPOI.OpenXmlFormats.Spreadsheet;
using NPOI.SS.Formula.Functions;
using NPOI.Util;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static IRaCIS.Core.Application.Service.ExcelExportHelper;
namespace IRaCIS.Core.Application.Service.Common;

View File

@ -24,11 +24,26 @@ namespace IRaCIS.Core.Application.Service;
[ApiExplorerSettings(GroupName = "Common")]
public class FileUploadRecordService(IRepository<FileUploadRecord> _fileUploadRecordRepository, IRepository<UploadFileSyncRecord> _uploadFileSyncRecordRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IOptionsMonitor<ObjectStoreServiceOptions> options,
IRepository<CommonUploadRecord> _commonUploadRecordRepository,
IFusionCache _fusionCache, IRepository<Trial> _trialRepository, FileSyncQueue _fileSyncQueue) : BaseService, IFileUploadRecordService
{
ObjectStoreServiceOptions ObjectStoreServiceConfig = options.CurrentValue;
/// <summary>
/// 上传通用文件记录
/// </summary>
/// <param name="addOrEditCommonUploadRecord"></param>
/// <returns></returns>
public async Task<IResponseOutput> AddOrUpdateCommonUploadRecord(CommonUploadRecordAddOrEdit addOrEditCommonUploadRecord)
{
var entity = await _commonUploadRecordRepository.InsertOrUpdateAsync(addOrEditCommonUploadRecord, true);
return ResponseOutput.Ok(entity.Id.ToString());
}
/// <summary>
@ -222,7 +237,7 @@ public class FileUploadRecordService(IRepository<FileUploadRecord> _fileUploadRe
{
addOrEditFileUploadRecord.IsNeedSync = true;
addOrEditFileUploadRecord.Priority = addOrEditFileUploadRecord.Priority?? 0;
addOrEditFileUploadRecord.Priority = addOrEditFileUploadRecord.Priority ?? 0;
addOrEditFileUploadRecord.IsSync = false;
}

View File

@ -1,44 +1,22 @@
using Aliyun.OSS;
using CommunityToolkit.HighPerformance;
using DocumentFormat.OpenXml.EMMA;
using DocumentFormat.OpenXml.Office.CustomUI;
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.Office2013.Drawing.ChartStyle;
using FellowOakDicom;
using FellowOakDicom.Imaging;
using FellowOakDicom.Imaging.Render;
using FellowOakDicom.IO.Buffer;
using Hangfire.Common;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Medallion.Threading;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using NPOI.Util;
using Org.BouncyCastle.Utilities.Zlib;
using SharpCompress.Common;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO.Compression;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using static IRaCIS.Core.Application.Service.TestService;
using static IRaCIS.Core.Application.Service.TrialImageDownloadService;
using static IRaCIS.Core.Domain.Share.StaticData;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
namespace IRaCIS.Core.Application.Service
{
@ -63,7 +41,7 @@ namespace IRaCIS.Core.Application.Service
try
{
#region 方式一 有的必须在内存中,不能用这种
#region 方式一 有的多帧必须在内存中,不能用这种
//await using var source = await sourceFactory();
//// 如果你是从 stream 打开
//var dicomFile = await DicomFile.OpenAsync(source);
@ -242,6 +220,7 @@ namespace IRaCIS.Core.Application.Service
var skipCount = 0;
foreach (var downloadVisit in downloadVisits)
{
visitIndex++;
var downloadInfo = _trialRepository.Where(t => t.Id == trialId).Select(t => new
{
t.ResearchProgramNo,
@ -347,7 +326,7 @@ namespace IRaCIS.Core.Application.Service
{
var dirDic = new Dictionary<string, string>();
var studyFolderName = $"{studyInfo.StudyCode}_{studyInfo.StudyTime:yyyy-MM-dd}_{string.Join('_', studyInfo.SeriesList.Select(t => t.Modality))}";
var studyFolderName = $"{studyInfo.StudyCode}_{studyInfo.StudyTime:yyyy-MM-dd}_{string.Join('_', studyInfo.SeriesList.Select(t => t.Modality).Distinct())}";
#region DICOMDIR
@ -467,7 +446,7 @@ namespace IRaCIS.Core.Application.Service
var zipPath = Path.Combine(trialFolderPath, visitFolderName + ".zip");
Log.Logger.Warning($"[{visitIndex}] {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}开始打包下载访视:{visitFolderName}");
Log.Logger.Warning($"[{visitIndex}] {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 开始打包下载访视:{visitFolderName}");
try
{
@ -475,14 +454,14 @@ namespace IRaCIS.Core.Application.Service
//Log.Logger.Warning($"zip exists={File.Exists(zipPath)} size={new FileInfo(zipPath).Length}");
Log.Logger.Warning($"[{visitIndex}] {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}访视打包下载完成:{visitFolderName}");
Log.Logger.Warning($"[{visitIndex}] {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 下载完成:{visitFolderName}");
DownloadLogger.Write(logFilePath, visitItem.SubjectCode, visitItem.VisitNum, visitItem.VisitName, "Success");
}
catch (Exception ex)
{
Log.Logger.Warning($"出现异常{ex}删除压缩包:{visitFolderName}");
Log.Logger.Warning($"出现异常{ex}自动删除压缩包:{visitFolderName}");
//如果有异常,删除失败的压缩包
if (File.Exists(zipPath))
{

View File

@ -131,6 +131,11 @@ namespace IRaCIS.Core.Application.Service
CreateMap<FileUploadRecord, FileUploadRecordAddOrEdit>().ReverseMap();
CreateMap<CommonUploadRecordAddOrEdit, CommonUploadRecord>().ReverseMap();
CreateMap<CommonUploadRecord, CommonUploadRecordDto>();
CreateMap<UploadFileSyncRecord, UploadFileSyncRecordView>()
.ForMember(d => d.FileName, u => u.MapFrom(s => s.FileUploadRecord.FileName))
.ForMember(d => d.FileType, u => u.MapFrom(s => s.FileUploadRecord.FileType))

View File

@ -4,26 +4,10 @@
// 生成时间 2025-03-27 06:13:33Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure.Extention;
using System.Threading.Tasks;
using IRaCIS.Core.Infra.EFCore;
using AutoMapper.Execution;
using System.Linq;
using IRaCIS.Core.Infrastructure;
using DocumentFormat.OpenXml.Office2010.Excel;
using MassTransit;
using NPOI.POIFS.Properties;
using Org.BouncyCastle.Crypto;
using Microsoft.AspNetCore.Http;
using IRaCIS.Core.Application.Contracts;
using Microsoft.EntityFrameworkCore;
using static Microsoft.Extensions.Logging.EventSource.LoggingEventSource;
using NPOI.SS.Formula.Functions;
using EFCore.BulkExtensions;
namespace IRaCIS.Core.Application.Service;

View File

@ -80,14 +80,18 @@ namespace IRaCIS.Core.Application.Contracts
}
public class TrialSignDocView : UnionDocumentWithConfirmInfoView
public class TriaAndSystemlSignDocView : UnionDocumentWithConfirmInfoView
{
public string TrialCode { get; set; }
public string ResearchProgramNo { get; set; }
public string ExperimentName { get; set; }
public TrialType TrialType { get; set; }
public bool IsTestUser { get; set; }
public UserWorkLanguage UserWorkLanguage { get; set; }
}
@ -365,6 +369,8 @@ namespace IRaCIS.Core.Application.Contracts
public DocLanguageType DocLanguageType { get; set; }
}

View File

@ -216,6 +216,8 @@ namespace IRaCIS.Core.Application.Services
return ResponseOutput.Result(true);
}
/// <summary>
/// 下线系统文档
/// </summary>

View File

@ -5,18 +5,10 @@
//--------------------------------------------------------------------
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.MassTransit.Consumer;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using MassTransit.Mediator;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using NPOI.SS.Formula.Functions;
using System.Linq;
using System.Linq.Dynamic.Core;
namespace IRaCIS.Core.Application.Services
@ -161,7 +153,7 @@ namespace IRaCIS.Core.Application.Services
}
[HttpPost]
public async Task<PageOutput<TrialSignDocView>> GetTrialSignDocumentList(TrialDocQuery inQuery)
public async Task<PageOutput<TriaAndSystemlSignDocView>> GetTrialSignDocumentList(TrialDocQuery inQuery)
{
var trialDocQueryable = from trialDoc in _trialDocumentRepository.Where(t => t.IsPublish)
.WhereIf(inQuery.TrialId != null, t => t.TrialId == inQuery.TrialId)
@ -172,7 +164,7 @@ namespace IRaCIS.Core.Application.Services
new { trialUser.IdentityUserId, TrialDocumentId = trialDoc.Id } equals new { IdentityUserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
from confirm in cc.DefaultIfEmpty()
select new TrialSignDocView()
select new TriaAndSystemlSignDocView()
{
TrialCode = trialDoc.Trial.TrialCode,
ResearchProgramNo = trialDoc.Trial.ResearchProgramNo,

View File

@ -1551,14 +1551,23 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
.WhereIf(inQuery.IsReturnRequired != null, t => t.IsReturnRequired == inQuery.IsReturnRequired)
.WhereIf(inQuery.IsEnable != null, t => t.IsEnable == inQuery.IsEnable)
.WhereIf(inQuery.IsDistinguishCriteria != null, t => t.IsDistinguishCriteria == inQuery.IsDistinguishCriteria)
.WhereIf(inQuery.IsDistinguishCriteria == true && trialConfig.IsEnrollementQualificationConfirm == true && trialConfig.IsPDProgressView == false, t => t.IsDistinguishCriteria == true && t.BusinessScenarioEnum == EmailBusinessScenario.EnrollConfirmed)
.WhereIf(inQuery.IsDistinguishCriteria == true && trialConfig.IsEnrollementQualificationConfirm == false && trialConfig.IsPDProgressView == true, t => t.IsDistinguishCriteria == true && t.BusinessScenarioEnum == EmailBusinessScenario.PDConfirmed)
.WhereIf(inQuery.IsDistinguishCriteria == true && trialConfig.IsEnrollementQualificationConfirm == true && trialConfig.IsPDProgressView == true, t => t.IsDistinguishCriteria == true)
.WhereIf(inQuery.IsDistinguishCriteria == true && trialConfig.IsEnrollementQualificationConfirm == false && trialConfig.IsPDProgressView == false, t => t.IsDistinguishCriteria == true && (t.BusinessScenarioEnum != EmailBusinessScenario.EnrollConfirmed && t.BusinessScenarioEnum != EmailBusinessScenario.PDConfirmed))
.WhereIf(inQuery.BusinessModuleEnum != null, t => t.BusinessModuleEnum == inQuery.BusinessModuleEnum)
.WhereIf(inQuery.EmailUrgentEnum != null, t => t.EmailUrgentEnum == inQuery.EmailUrgentEnum)
.WhereIf(inQuery.ToUserType != null, t => t.EmailNoticeUserTypeList.Any(t => t.UserType == inQuery.ToUserType && t.EmailUserType == EmailUserType.To))
.WhereIf(inQuery.CopyUserType != null, t => t.EmailNoticeUserTypeList.Any(t => t.UserType == inQuery.CopyUserType && t.EmailUserType == EmailUserType.Copy))
.WhereIf(trialConfig.IsEnrollementQualificationConfirm == false, t => t.BusinessModuleEnum != BusinessModule.EligibilityVerification)
.WhereIf(trialConfig.IsPDProgressView == false, t => t.BusinessModuleEnum != BusinessModule.PDVerification)
.WhereIf(trialConfig.IsEnrollementQualificationConfirm == false && trialConfig.IsPDProgressView == true, t => t.BusinessModuleEnum != BusinessModule.EligibilityVerification)
.WhereIf(trialConfig.IsEnrollementQualificationConfirm == true && trialConfig.IsPDProgressView == false, t => t.BusinessModuleEnum != BusinessModule.PDVerification)
.WhereIf(trialConfig.IsPDProgressView == false && trialConfig.IsEnrollementQualificationConfirm == false, t => t.BusinessModuleEnum != BusinessModule.PDVerification
&& t.BusinessModuleEnum != BusinessModule.EligibilityVerification)
&& t.BusinessModuleEnum != BusinessModule.EligibilityVerification && t.BusinessModuleEnum != BusinessModule.Eligibility_PDVerification)
.ProjectTo<TrialSelectEmailNoticeConfigView>(_mapper.ConfigurationProvider, new { trialId = inQuery.TrialId });
return await emailNoticeConfigQueryable.ToPagedListAsync(inQuery);

View File

@ -749,6 +749,17 @@ namespace IRaCIS.Core.Application.Contracts
public long? FileSize { get; set; }
}
public class DownloadFileDto
{
public Guid Id { get; set; }
public string Path { get; set; }
public string FileName { get; set; }
public string FileType { get; set; }
}
public class DownloadNoneDicomStudyDto
{
public string Modality { get; set; }
@ -849,9 +860,13 @@ namespace IRaCIS.Core.Application.Contracts
public List<TrialKeyPicturePath> QuestionMarkPictureList { get; set; }
public List<TrialKeyPicturePath> TableQuestionRowPictureList { get; set; }
public List<TrialKeyPicturePath> SegmentationFileList { get; set; }
}
public class TrialKeyPicturePath
{
public string SegmentationName { get; set; }
public string PicturePath { get; set; }
public string OtherPicturePath { get; set; }
@ -1160,6 +1175,20 @@ namespace IRaCIS.Core.Application.Contracts
public List<MaskRegion> MaskRegionList { get; set; }
}
public class NoneDicomStudyMaskImageCommand
{
public Guid? NodicomStudyId { get; set; }
public List<Guid>? NoneDicomStudyFileIdList { get; set; }
public List<MaskRegion> MaskRegionList { get; set; }
}
public class NoneDicomStudyUndoMaskImageCommand
{
public Guid? NodicomStudyId { get; set; }
public List<Guid>? NoneDicomStudyFileIdList { get; set; }
}
public class StudyUndoMaskImageCommand

View File

@ -1,31 +1,18 @@
using DocumentFormat.OpenXml.EMMA;
using FellowOakDicom;
using FellowOakDicom.Media;
using FellowOakDicom;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using MassTransit.Initializers;
using MathNet.Numerics;
using Medallion.Threading;
using Microsoft.AspNetCore.Mvc;
using NetTopologySuite.Mathematics;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using System.Data;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Web;
using ZiggyCreatures.Caching.Fusion;
namespace IRaCIS.Core.Application.Service.ImageAndDoc
{
@ -71,8 +58,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{
//subject 随机阅片 或者无序 有上传 才处理任务编号
if (_visitTaskRepository.Any(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId &&
(t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom ||
(t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.Random && t.TrialReadingCriterion.ImageDownloadEnum != ReadingImageDownload.None))))
(t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom
//||(t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.Random && t.TrialReadingCriterion.ImageDownloadEnum != ReadingImageDownload.None)
)))
{
//找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务
var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.UserRoleId
@ -131,6 +119,12 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var subjectCode = string.Empty;
var subjectId = inQuery.SubjectId;
bool? isIRImageDownloaded = null;
if(inQuery.VisitTaskId != null)
{
isIRImageDownloaded= _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId).Select(t => t.IsIRImageDownloaded).FirstOrDefault();
}
if (criterionInfo.IsReadingTaskViewInOrder == ReadingOrder.Random)
{
@ -224,7 +218,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var SVlist = await querySV.ToListAsync();
return ResponseOutput.Ok(SVlist, new { TrialModality = criterionInfo.Modalitys });
return ResponseOutput.Ok(SVlist, new { TrialModality = criterionInfo.Modalitys, IsReadingTaskViewInOrder = criterionInfo.IsReadingTaskViewInOrder });
}
else
@ -337,7 +331,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}
return ResponseOutput.Ok(list, new { TrialModality = criterionInfo.Modalitys });
return ResponseOutput.Ok(list, new { TrialModality = criterionInfo.Modalitys, IsReadingTaskViewInOrder = criterionInfo.IsReadingTaskViewInOrder, IsIRImageDownloaded= isIRImageDownloaded });
}
@ -714,9 +708,12 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
TaskSeries dicomSeries = await _taskSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
var isNewSeries = false;
//判断重复
if (dicomSeries == null)
{
isNewSeries = true;
var series = _mapper.Map<TaskSeries>(seriesItem);
series.Id = seriesId;
@ -761,7 +758,10 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
await _taskInstanceRepository.AddAsync(insntance);
dicomSeries.InstanceCount++;
if (isNewSeries == false)
{
dicomSeries.InstanceCount++;
}
findStudy.InstanceCount++;
}
@ -911,6 +911,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var subjectCode = inQuery.SubjectCode;
var subjectId = inQuery.SubjectId;
var doctorUserId = _userInfo.UserRoleId;
bool? isIRImageDownloaded = null;
if (inQuery.VisitTaskId != null)
{
@ -922,18 +923,20 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
SubjectCode = t.IsAnalysisCreate ? t.BlindSubjectCode : t.Subject.Code,
SubjectId = t.SubjectId,
t.DoctorUserId,
t.IsAnalysisCreate
t.IsAnalysisCreate,
t.IsIRImageDownloaded,
}).FirstNotNullAsync();
subjectId = taskInfo.SubjectId;
subjectCode = taskInfo.SubjectCode;
doctorUserId = (Guid)taskInfo.DoctorUserId!;
isIRImageDownloaded = taskInfo.IsIRImageDownloaded;
}
var info = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
.Select(t => new { t.IsImageFilter, t.CriterionType, t.TrialId, t.CriterionModalitys, t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
var config = await _subjectRepository.Where(t => t.Id == subjectId).Select(t => new { t.Trial.ImageFormatList, t.Trial.StudyNameList, t.Trial.IsShowStudyName }).FirstOrDefaultAsync();
var config = await _subjectRepository.Where(t => t.Id == subjectId).Select(t => new { t.Trial.ImageFormatList, t.Trial.StudyNameList, t.Trial.IsShowStudyName, IsIRImageDownloaded= isIRImageDownloaded }).FirstOrDefaultAsync();
//靶段标注上传,查看访视级别,上传绑定访视级别
@ -1663,7 +1666,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
#endregion
var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id) && t.CheckState == CheckStateEnum.CVPassed))
//一致性分析,导致查询出来两条数据
//一致性分析,导致查询出来两条数据
join visitTask in _visitTaskRepository.Where(t => taskIdList.Contains(t.Id)) on sv.Id equals visitTask.SourceSubjectVisitId into cc
from leftVisitTask in cc.DefaultIfEmpty()
select new ImageDownloadDto()
@ -1887,10 +1890,15 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
/// </summary>
/// <param name="trialImageDownloadId"></param>
/// <returns></returns>
public async Task<IResponseOutput> DownloadImageSuccess(Guid trialImageDownloadId)
public async Task<IResponseOutput> DownloadImageSuccess(Guid trialImageDownloadId, Guid? visitTaskId)
{
await _trialImageDownloadRepository.UpdatePartialFromQueryAsync(t => t.Id == trialImageDownloadId, u => new TrialImageDownload()
{ DownloadEndTime = DateTime.Now, IsSuccess = true }, true);
if (visitTaskId != null)
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTaskId.Value, u => new VisitTask() { IsIRImageDownloaded = true });
}
return ResponseOutput.Ok();
}
@ -2017,7 +2025,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
public async Task<List<Guid?>> GetTrialUnreadVisitList(Guid trialId)
{
var subjectVisitList = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.SourceSubjectVisitId!=null).Select(t => t.SourceSubjectVisitId)
var subjectVisitList = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId)
.Distinct().ToListAsync();
return subjectVisitList;
@ -2067,6 +2075,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
TableQuestionRowPictureList = t.LesionList.Select(c => new TrialKeyPicturePath { PicturePath = c.PicturePath, OtherPicturePath = c.OtherPicturePath }).ToList(),
SegmentationFileList = t.SegmentationList.Select(c => new TrialKeyPicturePath { PicturePath = c.SEGUrl, SegmentationName = c.SegmentationName, OtherPicturePath = string.Empty }).ToList(),
Id = t.Id,
//裁判选择结果
JudgeResultTaskId = t.JudgeVisitTask.JudgeResultTaskId,

View File

@ -3,16 +3,12 @@
// 生成时间 2021-12-06 10:54:55
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using DocumentFormat.OpenXml.EMMA;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Infrastructure;
using Medallion.Threading;
using Microsoft.AspNetCore.Mvc;
using NPOI.SS.Formula.Functions;
using System.ComponentModel.DataAnnotations;
using static ImageHelper;
namespace IRaCIS.Core.Application.Contracts
{
@ -25,11 +21,176 @@ namespace IRaCIS.Core.Application.Contracts
IRepository<Trial> _trialRepository,
IDistributedLockProvider _distributedLockProvider,
IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<VisitTask> _visitTaskRepository,
IRepository<VisitTask> _visitTaskRepository, IOSSService _oSSService,
QCCommon _qCCommon, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, INoneDicomStudyService
{
/// <summary>
/// 标注遮盖影像 路径后面加了.MaskNoneDicom_ 就是遮盖的新路径
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> NoneDicomStudyMaskImage(NoneDicomStudyMaskImageCommand inCommand)
{
if (inCommand.NodicomStudyId == null && inCommand.NoneDicomStudyFileIdList == null)
{
return ResponseOutput.NotOk("NodicomStudyId and NoneDicomStudyFileIdList can not both be null");
}
var idPathList = new List<DownloadFileDto>();
if (inCommand.NodicomStudyId == null && inCommand.NoneDicomStudyFileIdList != null)
{
idPathList = await _noneDicomStudyFileRepository.Where(t => inCommand.NoneDicomStudyFileIdList.Contains(t.Id)).ProjectTo<DownloadFileDto>(_mapper.ConfigurationProvider).ToListAsync();
}
else
{
idPathList = await _noneDicomStudyFileRepository.Where(t => inCommand.NodicomStudyId == t.NoneDicomStudyId).ProjectTo<DownloadFileDto>(_mapper.ConfigurationProvider).ToListAsync();
}
var errorList = new List<DownloadFileDto>();
var okList = new List<DownloadFileDto>();
var batchId = Guid.NewGuid();
foreach (var item in idPathList)
{
var path = item.Path;
try
{
// 1. 下载文件
using var inputStream = new MemoryStream();
await (await _oSSService.GetStreamFromOSSAsync(path)).CopyToAsync(inputStream);
inputStream.Position = 0;
// 2. 处理图片
using var outputStream = new MemoryStream();
await ImageMaskHelper.MaskAsync(inputStream, outputStream, inCommand.MaskRegionList);
outputStream.Position = 0;
var prefix = path.Substring(1, path.LastIndexOf('/') - 1);
//每次都用一个新的名字
var maskFileName = string.Empty;
if (path.Contains(".MaskNoneDicom_"))
{
//清理缓存的里面的遮盖图,多次遮盖同一张图时,清除缓存很重要
await _oSSService.DeleteFromPrefix(path, true); //清理缓存的里面的遮盖图,多次遮盖同一张图时,清除缓存很重要
//本身就是遮盖的图那么就要要替换guid
var length = Guid.Empty.ToString().Length + ".MaskNoneDicom_".Length;
var restorePath = item.Path[..^length];
maskFileName = $"{Path.GetFileName(restorePath)}.MaskNoneDicom_{batchId}";
}
else
{
//没有遮盖的,直接加上.批次_MaskDicom
maskFileName = $"{Path.GetFileName(path)}.MaskNoneDicom_{batchId}";
}
await _oSSService.UploadToOSSAsync(outputStream, prefix, maskFileName, false);
var newPath = $"/{prefix}/{maskFileName}";
okList.Add(new DownloadFileDto() { Id = item.Id, Path = newPath });
await _noneDicomStudyFileRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new NoneDicomStudyFile() { Path = newPath, IsMasked = true });
}
catch (Exception ex)
{
errorList.Add(new DownloadFileDto() { Id = item.Id, Path = path });
Log.Logger.Error(ex, $"NoneDicomStudyMaskImage Error for NoneDicomStudyFileIdList Path:{path} {ex.Message}");
}
}
await _noneDicomStudyFileRepository.SaveChangesAsync();
return ResponseOutput.Ok(new { OkList = okList, ErrorList = errorList });
}
/// <summary>
/// 撤销遮盖的影像,可以单张,也可以整个检查
/// </summary>
/// <param name="inCommand"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> NoneDicomStudyUndoMaskImage(NoneDicomStudyUndoMaskImageCommand inCommand)
{
if (inCommand.NodicomStudyId == null && inCommand.NoneDicomStudyFileIdList == null)
{
return ResponseOutput.NotOk("NodicomStudyId and NoneDicomStudyFileIdList can not both be null");
}
var idPathList = new List<DownloadFileDto>();
if (inCommand.NodicomStudyId == null && inCommand.NoneDicomStudyFileIdList != null)
{
idPathList = await _noneDicomStudyFileRepository.Where(t => inCommand.NoneDicomStudyFileIdList.Contains(t.Id)).ProjectTo<DownloadFileDto>(_mapper.ConfigurationProvider).ToListAsync();
}
else
{
idPathList = await _noneDicomStudyFileRepository.Where(t => inCommand.NodicomStudyId == t.NoneDicomStudyId).ProjectTo<DownloadFileDto>(_mapper.ConfigurationProvider).ToListAsync();
}
var okList = new List<DownloadFileDto>();
foreach (var item in idPathList)
{
if (item.Path.Contains(".MaskNoneDicom_"))
{
await _oSSService.DeleteFromPrefix(item.Path, true);
var length = Guid.Empty.ToString().Length + ".MaskNoneDicom_".Length;
var newPath = item.Path[..^length];
okList.Add(new DownloadFileDto() { Id = item.Id, Path = newPath });
await _noneDicomStudyFileRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new NoneDicomStudyFile() { Path = newPath, IsMasked = false });
}
//if (item.Path.EndsWith("."))
//{
// await _oSSService.DeleteFromPrefix(item.Path, true);
// var newPath = item.Path[..^1];
// okList.Add(new InstanceIdPath() { Id = item.Id, Path = newPath });
// await _dicomInstanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new DicomInstance() { Path = newPath, IsMasked = false });
//}
}
await _noneDicomStudyFileRepository.SaveChangesAsync();
return ResponseOutput.Ok(new { OkList = okList });
}
[HttpGet]
public async Task<IResponseOutput<List<NoneDicomStudyView>>> GetNoneDicomStudyList(

View File

@ -2,24 +2,14 @@
using FellowOakDicom.Imaging;
using FellowOakDicom.IO.Buffer;
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 MathNet.Numerics;
using Medallion.Threading;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;
using NetTopologySuite.Algorithm;
using SharpCompress.Common;
using SkiaSharp;
using System.Data;
using System.Drawing;
using ZiggyCreatures.Caching.Fusion;
namespace IRaCIS.Core.Application.Service.ImageAndDoc
{

View File

@ -4,6 +4,7 @@
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using Microsoft.AspNetCore.Mvc;
@ -13,7 +14,7 @@ namespace IRaCIS.Core.Application.Service
/// SystemAnonymizationService
/// </summary>
[ApiExplorerSettings(GroupName = "Image")]
public class SystemAnonymizationService(IRepository<SystemAnonymization> _systemAnonymizationRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ISystemAnonymizationService
public class SystemAnonymizationService(IRepository<SystemAnonymization> _systemAnonymizationRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, ISystemAnonymizationService
{
@ -37,6 +38,7 @@ namespace IRaCIS.Core.Application.Service
var entity = await _systemAnonymizationRepository.InsertOrUpdateAsync(addOrEditSystemAnonymization, true);
await _fusionCache.SetAsync(CacheKeys.SystemAnonymization, CacheHelper.GetSystemAnonymizationListAsync(_systemAnonymizationRepository), TimeSpan.FromDays(7));
return ResponseOutput.Ok(entity.Id.ToString());

View File

@ -187,8 +187,13 @@ namespace IRaCIS.Core.Application.Service
CreateMap<DicomInstance, DownloadDicomInstanceDto>()
.ForMember(d => d.InstanceId, u => u.MapFrom(s => s.Id));
CreateMap<NoneDicomStudyFile, DownloadFileDto>();
}
}

View File

@ -449,6 +449,12 @@ namespace IRaCIS.Core.Application.Service.Inspection.DTO
public List<GetTrialShowInspectionOutDto> Children { get; set; }
}
public class InspectionDto
{
public Guid Id { get; set; }
public string? JsonDetail { get; set; }
}
public class SetTrialShowInspection
{

View File

@ -27,6 +27,39 @@ namespace IRaCIS.Core.Application.Service.Inspection
IRepository<FrontAuditConfig> _frontAuditConfigRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IInspectionService
{
/// <summary>
/// 根据Id获取稽查记录
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> getInspectionById(InspectionDto inDto)
{
var dataInspection = await _dataInspectionRepository.Where(x=>x.Id==inDto.Id).Select(x=> new InspectionDto()
{
Id=x.Id,
JsonDetail = x.JsonDetail,
}).FirstOrDefaultAsync();
return ResponseOutput.Ok(dataInspection);
}
/// <summary>
/// 设置稽查记录JsonDetail
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SetJsonDetail(InspectionDto inDto)
{
await _dataInspectionRepository.BatchUpdateNoTrackingAsync(x => x.Id == inDto.Id, u => new DataInspection() { JsonDetail = inDto.JsonDetail });
return ResponseOutput.Ok(inDto);
}
/// <summary>
/// 设置项目稽查配置
/// </summary>
@ -127,9 +160,9 @@ namespace IRaCIS.Core.Application.Service.Inspection
join trialSign in _trialSignRepository.Where().IgnoreQueryFilters() on data.SignId equals trialSign.Id into trialSigntemp
from lefttrialSign in trialSigntemp.DefaultIfEmpty()
join leftfrontAuditConfig in _frontAuditConfigRepository.Where().Where(x => x.ConfigType == "M" && x.Identification != null && x.IsEnable == true) on
data.Identification.ToLower()
data.Identification
equals
leftfrontAuditConfig.Identification.ToLower()
leftfrontAuditConfig.Identification
join moduleTypec in _dictionaryRepository.Where() on new { ModuleType = leftfrontAuditConfig.ModuleTypeId!.Value } equals new { ModuleType = moduleTypec.Id } into moduleTypectemp
from leftmoduleTypec in moduleTypectemp.DefaultIfEmpty()
join OptTypec in _dictionaryRepository.Where() on new { ModuleType = leftfrontAuditConfig.OptTypeId!.Value } equals new { ModuleType = OptTypec.Id } into optTypetemp

View File

@ -103,6 +103,8 @@ namespace IRaCIS.Application.Contracts
public bool IsZhiZhun { get; set; }
public bool IsFirstAdd { get; set; }
public bool IsNeedResetPwd { get; set; }
public bool NeedChangePassWord { get; set; } = false;

View File

@ -263,6 +263,8 @@ namespace IRaCIS.Core.Application.Service
IsFirstAdd = false,
IsNeedResetPwd = false,
EmailToken = String.Empty
}, true);
@ -301,7 +303,7 @@ namespace IRaCIS.Core.Application.Service
await _identityUserRepository.UpdatePartialFromQueryAsync(t => t.Id == identityUserId, u => new IdentityUser()
{
Password = MD5Helper.Md5(pwd),
IsFirstAdd = true
IsNeedResetPwd = true
});
var userName = _identityUserRepository.Where(t => t.Id == identityUserId).Select(t => t.UserName).FirstOrDefault();
@ -449,9 +451,9 @@ namespace IRaCIS.Core.Application.Service
catch (Exception)
{
}
var find = await _identityUserRepository.FindAsync(identityUserId);
@ -489,7 +491,7 @@ namespace IRaCIS.Core.Application.Service
{
Password = editPwModel.NewPassWord,
LastChangePassWordTime = DateTime.Now,
IsFirstAdd = false
IsNeedResetPwd = false
});
await _userPassWordLogRepository.AddAsync(new UserPassWordLog()
@ -1279,7 +1281,7 @@ namespace IRaCIS.Core.Application.Service
PermissionStr = t.UserTypeRole.PermissionStr,
UserName = t.IdentityUser.UserName,
UserTypeShortName = t.UserTypeRole.UserTypeShortName,
UserWorkLanguage=t.IdentityUser.UserWorkLanguage
UserWorkLanguage = t.IdentityUser.UserWorkLanguage
}).FirstOrDefaultAsync();
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = userTokenInfo.IdentityUserId, ActionUserName = $"{userTokenInfo.UserName}", ActionUserType = userTokenInfo.UserTypeShortName, OptType = UserOptType.LoginSelectRole }, true);

View File

@ -1,16 +1,8 @@
using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Service.DTO;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Configuration;
using NPOI.HPSF;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service
{

View File

@ -1,137 +1,137 @@
using IRaCIS.Core.Application.Helper;
using MassTransit;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using RestSharp;
using SharpCompress.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//using IRaCIS.Core.Application.Helper;
//using MassTransit;
//using Microsoft.AspNetCore.Authorization;
//using Microsoft.AspNetCore.Builder;
//using Microsoft.AspNetCore.Hosting;
//using Microsoft.AspNetCore.Http;
//using Microsoft.AspNetCore.Mvc;
//using Microsoft.AspNetCore.StaticFiles;
//using RestSharp;
//using SharpCompress.Common;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service.MinimalApiService
{
/// <summary>
/// 上传文件转PDF 或者给url 这边下载然后转PDF
///
/// </summary>
/// <param name="_hostEnvironment"></param>
[ApiExplorerSettings(GroupName = "Institution")]
public class FileToPDFService(IWebHostEnvironment _hostEnvironment) : ServiceBase
{
//namespace IRaCIS.Core.Application.Service.MinimalApiService
//{
// /// <summary>
// /// 上传文件转PDF 或者给url 这边下载然后转PDF
// ///
// /// </summary>
// /// <param name="_hostEnvironment"></param>
// [ApiExplorerSettings(GroupName = "Institution")]
// public class FileToPDFService(IWebHostEnvironment _hostEnvironment) : ServiceBase
// {
[AllowAnonymous]
[RoutePattern(HttpMethod = "Post")]
public async Task<IResult> UploadFileAsync([FromForm] IFormFile file)
{
var tempFileName = NewId.NextGuid() + file.FileName;
var tempPDFName = Path.GetFileNameWithoutExtension(tempFileName) + ".pdf";
// [AllowAnonymous]
// [RoutePattern(HttpMethod = "Post")]
// public async Task<IResult> UploadFileAsync([FromForm] IFormFile file)
// {
// var tempFileName = NewId.NextGuid() + file.FileName;
// var tempPDFName = Path.GetFileNameWithoutExtension(tempFileName) + ".pdf";
// 获取wwwroot目录
var wwwRootPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "temp");
// // 获取wwwroot目录
// var wwwRootPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "temp");
// 检查wwwroot/temp目录是否存在不存在则创建
if (!Directory.Exists(wwwRootPath))
{
Directory.CreateDirectory(wwwRootPath);
}
// // 检查wwwroot/temp目录是否存在不存在则创建
// if (!Directory.Exists(wwwRootPath))
// {
// Directory.CreateDirectory(wwwRootPath);
// }
// 文件保存路径
var pdfFilePath = Path.Combine(wwwRootPath, tempPDFName);
var tempFilePath = Path.Combine(wwwRootPath, tempFileName);
// // 文件保存路径
// var pdfFilePath = Path.Combine(wwwRootPath, tempPDFName);
// var tempFilePath = Path.Combine(wwwRootPath, tempFileName);
using var stream = File.OpenWrite(tempFilePath);
await file.CopyToAsync(stream);
// using var stream = File.OpenWrite(tempFilePath);
// await file.CopyToAsync(stream);
FileConvertHelper.ConvertWordToPdf(tempFilePath, Path.GetDirectoryName(pdfFilePath));
// FileConvertHelper.ConvertWordToPdf(tempFilePath, Path.GetDirectoryName(pdfFilePath));
var fileBytes = await File.ReadAllBytesAsync(pdfFilePath);
// var fileBytes = await File.ReadAllBytesAsync(pdfFilePath);
// 清理临时上传的文件和pdf
if (File.Exists(pdfFilePath))
{
File.Delete(pdfFilePath);
}
if (File.Exists(tempFilePath))
{
File.Delete(tempFilePath);
}
// // 清理临时上传的文件和pdf
// if (File.Exists(pdfFilePath))
// {
// File.Delete(pdfFilePath);
// }
// if (File.Exists(tempFilePath))
// {
// File.Delete(tempFilePath);
// }
new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(tempPDFName), out var contentType);
// new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(tempPDFName), out var contentType);
return Results.File(fileBytes, contentType);
// return Results.File(fileBytes, contentType);
}
// }
public async Task<IResult> GetPDFFileAsync(string fileUrl)
{
var tempFileName = NewId.NextGuid() + Path.GetFileName(fileUrl);
var tempPDFName = Path.GetFileNameWithoutExtension(tempFileName) + ".pdf";
// public async Task<IResult> GetPDFFileAsync(string fileUrl)
// {
// var tempFileName = NewId.NextGuid() + Path.GetFileName(fileUrl);
// var tempPDFName = Path.GetFileNameWithoutExtension(tempFileName) + ".pdf";
// 获取wwwroot目录
var wwwRootPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "temp");
// // 获取wwwroot目录
// var wwwRootPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "temp");
// 检查wwwroot/temp目录是否存在不存在则创建
if (!Directory.Exists(wwwRootPath))
{
Directory.CreateDirectory(wwwRootPath);
}
// // 检查wwwroot/temp目录是否存在不存在则创建
// if (!Directory.Exists(wwwRootPath))
// {
// Directory.CreateDirectory(wwwRootPath);
// }
// 文件保存路径
var pdfFilePath = Path.Combine(wwwRootPath, tempPDFName);
var tempFilePath = Path.Combine(wwwRootPath, tempFileName);
// // 文件保存路径
// var pdfFilePath = Path.Combine(wwwRootPath, tempPDFName);
// var tempFilePath = Path.Combine(wwwRootPath, tempFileName);
//请求url获取文件
var client = new RestClient(fileUrl);
// //请求url获取文件
// var client = new RestClient(fileUrl);
var request = new RestRequest(fileUrl, Method.Get);
// var request = new RestRequest(fileUrl, Method.Get);
var response = await client.ExecuteAsync(request);
// var response = await client.ExecuteAsync(request);
// 检查响应是否成功
if (response.IsSuccessful)
{
// 将响应内容写入到本地文件
await File.WriteAllBytesAsync(tempFilePath, response.RawBytes);
// // 检查响应是否成功
// if (response.IsSuccessful)
// {
// // 将响应内容写入到本地文件
// await File.WriteAllBytesAsync(tempFilePath, response.RawBytes);
FileConvertHelper.ConvertWordToPdf(tempFilePath, Path.GetDirectoryName(pdfFilePath));
// FileConvertHelper.ConvertWordToPdf(tempFilePath, Path.GetDirectoryName(pdfFilePath));
var fileBytes = await File.ReadAllBytesAsync(pdfFilePath);
// var fileBytes = await File.ReadAllBytesAsync(pdfFilePath);
// 清理临时上传的文件和pdf
if (File.Exists(pdfFilePath))
{
File.Delete(pdfFilePath);
}
if (File.Exists(tempFilePath))
{
File.Delete(tempFilePath);
}
// // 清理临时上传的文件和pdf
// if (File.Exists(pdfFilePath))
// {
// File.Delete(pdfFilePath);
// }
// if (File.Exists(tempFilePath))
// {
// File.Delete(tempFilePath);
// }
new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(tempPDFName), out var contentType);
// new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(tempPDFName), out var contentType);
return Results.File(fileBytes, contentType);
}
else
{
Console.WriteLine($"下载文件失败: {response.ErrorMessage}");
// return Results.File(fileBytes, contentType);
// }
// else
// {
// Console.WriteLine($"下载文件失败: {response.ErrorMessage}");
return Results.Problem("下载文件失败", statusCode: StatusCodes.Status500InternalServerError);
// return Results.Problem("下载文件失败", statusCode: StatusCodes.Status500InternalServerError);
}
// }
}
// }
}
}
// }
//}

View File

@ -1,6 +1,4 @@
using Azure.Core;
using IdentityModel;
using IdentityModel.Client;
using IdentityModel.Client;
using IRaCIS.Core.Application.Service.OAuth;
using MassTransit;
using Microsoft.AspNetCore.Authorization;
@ -8,18 +6,11 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Utilities.Net;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service
{

View File

@ -1,15 +1,10 @@
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit.Initializers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using NPOI.SS.Formula.Functions;
using System.Linq;
namespace IRaCIS.Core.Application.Image.QA
{
@ -45,8 +40,10 @@ namespace IRaCIS.Core.Application.Image.QA
public async Task<IResponseOutput<PageOutput<ImageBackViewModel>>> GetImageBackList(ImageBackQueryDto inQuery)
{
var svExpression = QCCommon.GetSubjectVisitImageBackRecordFilter(inQuery.VisitPlanArray);
var isCRC = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA;
var query = _subjectVisitImageBackRecordReposiotry.Where(t => t.SubjectVisit.TrialId == inQuery.TrialId)
.WhereIf(isCRC == true, t => t.SubjectVisit.Trial.TrialSiteUserList.Any(t => t.UserId == _userInfo.UserRoleId))
.WhereIf(inQuery.TrialSiteId != null, t => t.SubjectVisit.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode))
.WhereIf(!string.IsNullOrEmpty(inQuery.VisitName), t => t.SubjectVisit.VisitName.Contains(inQuery.VisitName))
@ -458,6 +455,15 @@ namespace IRaCIS.Core.Application.Image.QA
}
var isFilterIVUSNoneDicom = false;
//ivus-在访视的时候visitTaskId==null 需要过滤掉空检查 ,但是在靶段标注的查看访视级别的时候不能过滤
if (_subjectVisitRepository.Where(t => t.Id == subjectVisitId).SelectMany(t => t.Trial.TrialReadingCriterionList)
.Where(t => (t.CriterionType == CriterionType.IVUS || t.CriterionType == CriterionType.OCT) && t.IsConfirm).Distinct().Count() == 2
)
{
isFilterIVUSNoneDicom = true;
}
return new TrialVisitQADTO
{
IsSupportQCDownloadImage = isSupportQCImageDownload,
@ -470,7 +476,7 @@ namespace IRaCIS.Core.Application.Image.QA
ExistsManual = (await _IReadingImageTaskService.GetManualList(new GetManualListInDto() { TrialId = sv.TrialId })).Count() > 0,
SeriesList = temp.SeriesList,
RelationInfo = await GetVisitQCSubjectInfo(subjectVisitId),
NoneDicomStudyList = await _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId, ignoreQueryFilters: true).ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider).ToListAsync(),
NoneDicomStudyList = await _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId, ignoreQueryFilters: true).Where(t => isFilterIVUSNoneDicom ? t.Modality != "IVUS" : true).ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider).ToListAsync(),
SubjectClinicalData = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId)
.ProjectTo<SubjectClinicalDataDto>(_mapper.ConfigurationProvider, new { subjectVisitId = subjectVisitId, token = _userInfo.UserToken }).FirstOrDefaultAsync()
};

View File

@ -1,14 +1,8 @@
using AutoMapper;
using AutoMapper.EquivalencyExpression;
using AutoMapper.EquivalencyExpression;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Migrations;
using NPOI.SS.Formula.Functions;
using System.Linq;
namespace IRaCIS.Core.Application.Service
{

View File

@ -238,6 +238,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
return this.Emm - this.Lumen;
}
}
/// <summary>
/// 斑块破裂
/// </summary>
public string PlaqueRupture { get; set; }
}
public class TemplateData
@ -245,6 +250,37 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public string TaskBlindName { get; set; }
public string SubjectID { get; set; }
/// <summary>
/// 靶段
/// </summary>
public string TargetSegment { get; set; } = string.Empty;
/// <summary>
/// 靶段备注
/// </summary>
public string TargetSegmentRemarks { get; set; } = string.Empty;
/// <summary>
/// ROI段落总长度
/// </summary>
public string ROIAllLength { get; set; } = string.Empty;
/// <summary>
/// 回撤中的图像帧数
/// </summary>
public string PullbackFrameCount { get; set; } = string.Empty;
/// <summary>
/// 斑块类型
/// </summary>
public string PlaqueType { get; set; } = string.Empty;
/// <summary>
/// 访视点备注(如有)
/// </summary>
public string AdjustReason { get; set; } = string.Empty;
}
public class OCTFCTUploadData
@ -300,6 +336,16 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public decimal? LipidAngle { get; set; }
/// <summary>
/// 斑块破裂
/// </summary>
public string PlaqueRupture { get; set; }
/// <summary>
/// 斑块愈合
/// </summary>
public string PlaqueHealing { get; set; }
public decimal? Avg
{

View File

@ -192,6 +192,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public class GetReadingReportEvaluationOutDto
{
public Guid? VisitTaskId { get; set; }
public object ReportCalculateResult { get; set; }
@ -452,6 +453,58 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public List<AdditionalQuestionAnswer> AnswerList { get; set; } = new List<AdditionalQuestionAnswer>();
}
public class GetMarkListInDto
{
/// <summary>
/// 任务Id
/// </summary>
public Guid VisitTaskId { get; set; }
}
public class MarkListInfo
{
public string MeasureData { get; set; } = string.Empty;
public string PicturePath { get; set; } = string.Empty;
public Guid? InstanceId { get; set; }
public Guid? SeriesId { get; set; }
public Guid? StudyId { get; set; }
public string MarkName { get; set; } = string.Empty;
public string StudyInstanceUid { get; set; }
public string SopInstanceUid { get; set; }
public int NumberOfFrames { get; set; }
}
public class NoneDicomMarkInfo
{
public Guid? StudyId { get; set; }
public Guid? NoneDicomFileId { get; set; }
public string Path { get; set; }
public string PicturePath { get; set; } = string.Empty;
public string MeasureData { get; set; } = string.Empty;
public string MarkTool { get; set; }
public string MarkName { get; set; }
public string FileName { get; set; } = string.Empty;
/// <summary>
/// 标记的唯一标识符
/// </summary>
public Guid? MarkId { get; set; }
}
public class GetCustomTagInDto
{
/// <summary>
@ -544,6 +597,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public string Value { get; set; }
public string DictionaryCode { get; set; }
public bool IsHighlight { get; set; } = false;
public Guid? VisitTaskId { get; set; }
}
public class ChartItem
@ -1489,6 +1546,20 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public QuestionClassify? QuestionClassify { get; set; }
}
public class GetFilterTableQuestionInDto
{
public Guid TrialId { get; set; }
public Guid VisitTaskId { get; set; }
public Guid QuestionId { get; set; }
/// <summary>
/// 问题分类
/// </summary>
public QuestionClassify? QuestionClassify { get; set; }
}
#endregion
public class GetHistoryGlobalInfoOutDto
{

View File

@ -1002,6 +1002,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public string ImageTool { get; set; } = string.Empty;
/// <summary>
/// 新增修改类型
/// </summary>
public AddDeleteType AddDeleteTypeEnum { get; set; } = AddDeleteType.Arbitrium;
/// <summary>
/// 影像工具属性
/// </summary>
@ -2483,6 +2488,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public string ImageTool { get; set; } = string.Empty;
/// <summary>
/// 新增修改类型
/// </summary>
public AddDeleteType AddDeleteTypeEnum { get; set; } = AddDeleteType.Arbitrium;
/// <summary>
/// 影像工具属性
/// </summary>

View File

@ -1,16 +1,12 @@
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using Panda.DynamicWebApi.Attributes;
using System.Reflection;
using System.Text;
@ -250,9 +246,9 @@ namespace IRaCIS.Core.Application.Service
var visitTaskAnswer = await _readingTaskQuestionAnswerRepository.Where(x => taskIds.Contains(x.VisitTaskId) && x.ReadingQuestionTrial.IsJudgeQuestion).Select(x => new JudgeQuestionAnswerInfo
{
Answer = x.Answer,
Unit=x.ReadingQuestionTrial.Unit,
ValueType=x.ReadingQuestionTrial.ValueType,
CustomUnit=x.ReadingQuestionTrial.CustomUnit,
Unit = x.ReadingQuestionTrial.Unit,
ValueType = x.ReadingQuestionTrial.ValueType,
CustomUnit = x.ReadingQuestionTrial.CustomUnit,
VisitTaskId = x.VisitTaskId,
DictionaryCode = x.ReadingQuestionTrial.DictionaryCode,
ShowOrder = x.ReadingQuestionTrial.ShowOrder,
@ -647,8 +643,8 @@ namespace IRaCIS.Core.Application.Service
[HttpPost]
public async Task<string> TestGetJointMedicalReviewDialog(Guid id)
{
var dialog = await _readingMedicalReviewDialogRepository.Where(x => x.Id == id)
.ProjectTo<GetMedicalReviewDialogOutDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
var dialog = await _readingMedicalReviewDialogRepository.Where(x => x.Id == id)
.ProjectTo<GetMedicalReviewDialogOutDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
Dictionary<string, string> i18NKeys = new Dictionary<string, string>()
@ -665,11 +661,11 @@ namespace IRaCIS.Core.Application.Service
};
var i18Values = i18NKeys.Select(x => x.Value).ToList();
var i18nList=await _internationalizationRepository.Where(x => i18Values.Contains(x.Code))
.Select(x => new
var i18nList = await _internationalizationRepository.Where(x => i18Values.Contains(x.Code))
.Select(x => new
{
Code= x.Code,
Value= _userInfo.IsEn_Us?x.Value:x.ValueCN
Code = x.Code,
Value = _userInfo.IsEn_Us ? x.Value : x.ValueCN
}).ToListAsync();
List<string> dictionaryCodeList = new List<string>()
@ -680,16 +676,16 @@ namespace IRaCIS.Core.Application.Service
"YesOrNo",
};
var dictionadParents=await _dictionaryRepository.Where(x=> dictionaryCodeList.Contains(x.Parent.Code))
var dictionadParents = await _dictionaryRepository.Where(x => dictionaryCodeList.Contains(x.Parent.Code))
.Select(x => new
{
ParentCode = x.Parent.Code,
Code=x.Code,
Code = x.Code,
Value = _userInfo.IsEn_Us ? x.Value : x.ValueCN
}).ToListAsync();
JointMedicalReviewI18n i18N = new JointMedicalReviewI18n() { };
foreach (var kv in i18NKeys)
foreach (var kv in i18NKeys)
{
PropertyInfo? pi = i18N.GetType().GetProperty(kv.Key);
if (pi != null && pi.CanWrite)
@ -710,7 +706,7 @@ namespace IRaCIS.Core.Application.Service
}
}
return await JointMedicalReviewDialog(dialog,i18N);
return await JointMedicalReviewDialog(dialog, i18N);
@ -914,7 +910,7 @@ namespace IRaCIS.Core.Application.Service
[HttpPost]
public async Task<GetIRMedicalFeedbackListOutDto> GetNextIRMedicalFeedback(GetNextIRMedicalFeedbackInDto inDto)
{
var list = await GetIRMedicalFeedbackList(new GetIRMedicalFeedbackListInDto()
var responseOutput = await GetIRMedicalFeedbackList(new GetIRMedicalFeedbackListInDto()
{
TrialId = inDto.TrialId,
TrialReadingCriterionId = inDto.TrialReadingCriterionId,
@ -923,6 +919,8 @@ namespace IRaCIS.Core.Application.Service
PageSize = 99999,
});
var list = responseOutput.Data;
var index = list.CurrentPageData.ToList().FindIndex(x => x.Id == inDto.TaskMedicalReviewId);
var result = new GetIRMedicalFeedbackListOutDto() { };
@ -953,12 +951,12 @@ namespace IRaCIS.Core.Application.Service
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<GetIRMedicalFeedbackListOutDto>> GetIRMedicalFeedbackList(GetIRMedicalFeedbackListInDto inDto)
public async Task<IResponseOutput<PageOutput<GetIRMedicalFeedbackListOutDto>>> GetIRMedicalFeedbackList(GetIRMedicalFeedbackListInDto inDto)
{
var taskMedicalReviewquery = _taskMedicalReviewRepository.Where(x => x.TrialId == inDto.TrialId).Include(x => x.VisitTask)
.Where(x => x.VisitTask.DoctorUserId == _userInfo.UserRoleId)
.Where(x => x.IsHaveQuestion)
.WhereIf(!inDto.TaskBlindName.IsNullOrEmpty(), x => x.VisitTask.TaskBlindName == inDto.TaskBlindName)
.WhereIf(!inDto.TaskBlindName.IsNullOrEmpty(), x => x.VisitTask.TaskBlindName.Contains(inDto.TaskBlindName))
.WhereIf(inDto.SubjectId != null, x => x.VisitTask.SubjectId == inDto.SubjectId!)
.WhereIf(inDto.IsUrgent != null, x => x.VisitTask.IsUrgent == inDto.IsUrgent!)
.WhereIf(inDto.AuditState != null, x => x.AuditState == inDto.AuditState!)
@ -1008,7 +1006,11 @@ namespace IRaCIS.Core.Application.Service
var result = await taskMedicalReviewquery.ToPagedListAsync(inDto, nameof(GetIRMedicalFeedbackListOutDto.AuditState));
return result;
var criterionInfo = await _readingQuestionCriterionTrial.Where(t => t.Id == inDto.TrialReadingCriterionId)
.Select(t => new { t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
return ResponseOutput.Ok(result, criterionInfo);
}
}
}

View File

@ -1,31 +1,21 @@
using Amazon.Runtime.Internal.Transform;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments;
using DocumentFormat.OpenXml;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Helper.OtherTool;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.ImageAndDoc;
using IRaCIS.Core.Application.Service.OAuth;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.Service.ReadingCalculate.Interface;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using NPOI.POIFS.Properties;
using NPOI.SS.Formula.Functions;
using Panda.DynamicWebApi.Attributes;
using System.Linq;
using ZiggyCreatures.Caching.Fusion;
namespace IRaCIS.Core.Application.Service
{
@ -61,6 +51,9 @@ namespace IRaCIS.Core.Application.Service
IRepository<ReadModule> _readModuleRepository,
IRepository<DicomInstance> _dicomInstanceRepository,
IRepository<OrganInfo> _organInfoRepository,
IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<EmailNoticeUserType> _emailNoticeUserTypeRepository,
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
IRepository<OrganTrialInfo> _organTrialInfoRepository,
IRepository<TrialDocument> _trialDocumentRepository,
ILuganoCalculateService _luganoCalculateService,
@ -80,10 +73,13 @@ namespace IRaCIS.Core.Application.Service
IGeneralCalculateService _generalCalculateService,
IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
IRepository<TaskStudy> _taskStudyRepository,
IConfiguration _config,
IDownloadAndUploadService _downloadAndUploadService,
ITrialEmailNoticeConfigService _trialEmailNoticeConfigService,
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, IReadingImageTaskService
{
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
/// <summary>
/// 获取报告图表数据
@ -452,6 +448,81 @@ namespace IRaCIS.Core.Application.Service
return result;
}
/// <summary>
/// 获取标记信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<MarkListInfo>> GetMarkList(GetMarkListInDto inDto)
{
var questionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId&&x.InstanceId!=null)
.Select(x => new MarkListInfo() {
MeasureData = x.MeasureData,
PicturePath = x.PicturePath,
InstanceId = x.InstanceId,
SeriesId = x.SeriesId,
StudyId = x.StudyId,
MarkName= x.OrderMarkName,
SopInstanceUid = x.Instance.SopInstanceUid,
StudyInstanceUid = x.Instance.StudyInstanceUid,
NumberOfFrames= x.Instance.NumberOfFrames,
}).ToListAsync();
var rowMarkList=await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.InstanceId != null)
.Select(x => new MarkListInfo()
{
MeasureData = x.MeasureData,
PicturePath = x.PicturePath,
InstanceId = x.InstanceId,
SeriesId = x.SeriesId,
StudyId = x.StudyId,
MarkName = x.RowMark,
SopInstanceUid = x.Instance.SopInstanceUid,
StudyInstanceUid = x.Instance.StudyInstanceUid,
NumberOfFrames = x.Instance.NumberOfFrames,
}).ToListAsync();
return questionMarkList.Union(rowMarkList).OrderBy(x=>x.MarkName).ToList();
}
/// <summary>
/// 获取非DICOM标记信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<NoneDicomMarkInfo>> GetNoneDicomMarkList(GetMarkListInDto inDto)
{
var markList = await _readingNoneDicomMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).Include(x => x.NoneDicomStudyFile)
.Select(x => new NoneDicomMarkInfo()
{
StudyId = x.StudyId,
NoneDicomFileId = x.NoneDicomFileId,
Path = x.Path,
PicturePath = x.PicturePath,
MeasureData = x.MeasureData,
MarkTool = x.MarkTool,
MarkName = x.OrderMarkName,
FileName = x.NoneDicomStudyFile==null? string.Empty: x.NoneDicomStudyFile.FileName,
MarkId = x.MarkId,
}).ToListAsync();
return markList.OrderBy(x => x.MarkName).ToList();
}
/// <summary>
/// 获取手册
/// </summary>
@ -1330,6 +1401,38 @@ namespace IRaCIS.Core.Application.Service
}); ;
}
/// <summary>
/// 获取单个表格问题及答案 过滤问题
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> GetFilterTableQuestion(GetFilterTableQuestionInDto inDto)
{
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var tableAnswers = await _readingTableQuestionAnswerRepository
.ProjectTo<ReadingTableQuestionAnswerInfo>(_mapper.ConfigurationProvider)
.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToListAsync();
var tableAnsweRowInfos = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<TableAnsweRowInfo>(_mapper.ConfigurationProvider).ToListAsync();
var organIds = tableAnsweRowInfos.Where(x => x.OrganInfoId != null).Select(x => x.OrganInfoId).Distinct().ToList();
var organList = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync();
var questionPage = await GetReadingTableQuestion(
new GetReadingTableQuestionOrAnswerInDto()
{
TrialReadingCriterionId = taskinfo.TrialReadingCriterionId,
TaskId = inDto.VisitTaskId,
TableAnswers = tableAnswers,
TableAnsweRowInfos = tableAnsweRowInfos,
OrganInfos = organList,
QuestionClassify = inDto.QuestionClassify,
});
var result = questionPage.SinglePage.SelectMany(x => x.Childrens).Where(x => x.Id == inDto.QuestionId).FirstOrDefault();
return ResponseOutput.Ok(result);
}
/// <summary>
/// 获取自定义问题以及答案
/// </summary>
@ -3363,6 +3466,29 @@ namespace IRaCIS.Core.Application.Service
[HttpPost]
public async Task<IResponseOutput> VerifyVisitTaskQuestions(VerifyVisitTaskQuestionsInDto inDto)
{
// 验证一个问题不能有多个答案
bool hasDuplicate = await _readingTaskQuestionAnswerRepository
.Where(x => x.VisitTaskId == inDto.VisitTaskId)
.GroupBy(x => x.ReadingQuestionTrialId)
.AnyAsync(g => g.Count() > 1);
if (hasDuplicate)
{
try
{
_ = SendWeComNotifier(inDto.VisitTaskId, "阅片问题答案有重复");
_ = SendAbnormalEmail(inDto.VisitTaskId, EmailBusinessScenario.RepeatedVisitAnswers);
}
catch (Exception)
{
}
throw new BusinessValidationFailedException(_localizer["ReadingImage_VisitAnswerRepeated"]);
}
//验证后处理影像必须传
if (_visitTaskRepository.Any(t => t.Id == inDto.VisitTaskId && t.TrialReadingCriterion.ImageUploadEnum != ReadingImageUpload.None))
{

View File

@ -1,5 +1,9 @@
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Helper.OtherTool;
using IRaCIS.Core.Application.MassTransit.Consumer;
using IRaCIS.Core.Application.MassTransit.Consumer.Dto;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
@ -7,6 +11,8 @@ using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using MimeKit;
using Newtonsoft.Json;
namespace IRaCIS.Core.Application.Service
@ -676,7 +682,7 @@ namespace IRaCIS.Core.Application.Service
JudgeDifferenceType = x.Key.JudgeDifferenceType,
TaskAnswerList = x.Select(y => y.Answer).ToList(),
}).ToList();
noteEqual = noteEqual || ComputeJudgeResult(groupTasks);
noteEqual = noteEqual || ComputeJudgeResult(groupTasks, visitTask.Id);
}
}
@ -708,7 +714,7 @@ namespace IRaCIS.Core.Application.Service
JudgeDifferenceType = x.Key.JudgeDifferenceType,
TaskAnswerList = x.Select(y => y.Answer).ToList(),
}).ToList();
noteEqual = ComputeJudgeResult(groupTasks);
noteEqual = ComputeJudgeResult(groupTasks, visitTask.Id);
}
break;
@ -757,7 +763,8 @@ namespace IRaCIS.Core.Application.Service
JudgeDifferenceValue = x.Key.JudgeDifferenceValue,
JudgeDifferenceType = x.Key.JudgeDifferenceType,
}).ToList();
noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks);
noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks, visitTask.Id);
}
}
@ -819,7 +826,8 @@ namespace IRaCIS.Core.Application.Service
JudgeDifferenceType = x.Key.JudgeDifferenceType,
TaskAnswerList = x.Select(y => y.Answer).ToList(),
}).ToList();
noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks);
noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks, visitTask.Id);
}
@ -922,12 +930,154 @@ namespace IRaCIS.Core.Application.Service
}
/// <summary>
/// 发送微信通知
/// </summary>
/// <param name="visiTaskId"></param>
/// <returns></returns>
public async Task SendWeComNotifier(Guid visiTaskId,string msg)
{
try
{
bool isOpenWeComNotice = _config.GetValue<bool>("WeComNoticeConfig:IsOpenWeComNotice");
if (isOpenWeComNotice)
{
string webhook = _config["WeComNoticeConfig:WebhookUrl"] ?? string.Empty;
var uri = new Uri(_config["SystemEmailSendConfig:SiteUrl"]);
var baseUrl = uri.GetLeftPart(UriPartial.Authority);
var userList = _config.GetSection("WeComNoticeConfig:APINoticeUserList").Get<string[]>();
var visitTask = _visitTaskRepository.Where(x => x.Id == visiTaskId).Include(x=>x.Subject).Include(x=>x.Trial).Include(x=>x.SourceSubjectVisit).FirstOrDefault();
// 🔔 异步告警(不要阻塞请求)
_ = WeComNotifier.SendAlertAsync(
webhook: webhook,
alert: new WeComAlert
{
Env = baseUrl,
UserName = msg,
Api = "",
Message = $"异常信息:{msg}, 项目方案号:{visitTask.Trial.ResearchProgramNo}, 试验参与者:{visitTask.Subject.Code}, 访视:{visitTask.SourceSubjectVisit.VisitName}, 任务名称:{visitTask.TaskName} 任务Id:{visiTaskId}",
Stack = string.Empty,
AtUsers = userList ?? []
}
);
}
}
catch (Exception ex)
{
Log.Logger.Error($"MassTransit里发送企业微信出现错误{ex.Message}");
}
}
/// <summary>
/// 发送邮件通知
/// </summary>
/// <param name="visiTaskId"></param>
/// <returns></returns>
public async Task SendAbnormalEmail(Guid visiTaskId, EmailBusinessScenario type)
{
var emailNotice = _emailNoticeConfigrepository.Where(x => x.BusinessScenarioEnum == type).FirstOrDefault();
var taskinfo= _visitTaskRepository.Where(x => x.Id == visiTaskId).Include(x => x.Trial).Include(x => x.Subject).Include(x => x.SourceSubjectVisit).FirstOrDefault();
if (taskinfo == null)
{
return;
}
// 根据不同场景获取不同角色的用户
var trialUser = _trialUserRoleRepository.Where(x => x.TrialId == taskinfo.TrialId && !x.TrialUser.IsDeleted).Include(x => x.UserRole).Select(x => x.UserRole)
.Select(x => new SendEmailUserDto()
{
UserTypeEnum = x.UserTypeEnum,
FullName = x.FullName,
UserWorkLanguage = x.IdentityUser.UserWorkLanguage,
EMail = x.EMail,
})
.ToList();
// 根据场景确定收件人
List<SendEmailUserDto> toUserList = new List<SendEmailUserDto>();
List<SendEmailUserDto> ccUserList = new List<SendEmailUserDto>();
var emailNoticeUserList = _emailNoticeUserTypeRepository.Where(x => x.EmailNoticeConfigId == emailNotice.Id).ToList();
var toList = emailNoticeUserList.Where(x => x.EmailUserType == EmailUserType.To).Select(x => x.UserType).ToList();
toUserList = trialUser.Where(x => toList.Contains(x.UserTypeEnum)).ToList();
var ccList = emailNoticeUserList.Where(x => x.EmailUserType == EmailUserType.Copy).Select(x => x.UserType).ToList();
ccUserList = trialUser.Where(x => ccList.Contains(x.UserTypeEnum)).ToList();
// 如果没有收件人,则不发送邮件
if (toUserList.Count == 0)
{
return;
}
var userWorkLanguageList = toUserList.Select(x => x.UserWorkLanguage).Distinct().ToList();
foreach (var workLanguage in userWorkLanguageList)
{
var userinfoList = toUserList.Where(x => x.UserWorkLanguage == workLanguage).ToList();
var messageToSend = new MimeMessage();
// 发件地址
messageToSend.From.Add(new MailboxAddress(taskinfo.Trial.EmailFromName, taskinfo.Trial.EmailFromEmail));
foreach (var userinfo in userinfoList)
{
messageToSend.To.Add(new MailboxAddress(userinfo.FullName, userinfo.EMail));
}
// 添加抄送
foreach (var ccUser in ccUserList)
{
messageToSend.Cc.Add(new MailboxAddress(ccUser.FullName, ccUser.EMail));
}
var userNames = userinfoList.Select(x => x.FullName).ToList();
// 格式化邮件内容
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, taskinfo.Trial.ResearchProgramNo, taskinfo.Subject.Code,taskinfo.SourceSubjectVisit.VisitName);
var htmlBodyStr = string.Format(
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr, workLanguage),
string.Join(',', userNames), // 用户名 {0}
taskinfo.Trial.ExperimentName, // 项目 {1}
taskinfo.Subject.Code, // 受试者编号 {2}
taskinfo.SourceSubjectVisit.VisitName, // 访视名称 {3}
type== EmailBusinessScenario.JudgeExceptio ? _systemEmailConfig.SiteUrl: taskinfo.TaskName, // 任务名称 {4}
taskinfo.Id.ToString(), // 任务Id {5}
_systemEmailConfig.SiteUrl // 链接 {6}
);
return (topicStr, htmlBodyStr);
};
await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailNotice, messageToSend, emailConfigFunc, workLanguage);
await SendEmailHelper.SendTrialEmailAsync(messageToSend, taskinfo.Trial);
}
}
/// <summary>
/// 计算返回的结果 为True表示不相等
/// </summary>
/// <param name="groupTasks"></param>
/// <returns></returns>
private bool ComputeJudgeResult(List<GroupTaskAnswerDto> groupTasks)
private bool ComputeJudgeResult(List<GroupTaskAnswerDto> groupTasks,Guid visiTaskId)
{
var noteEqual = false;
foreach (var item in groupTasks)
@ -935,11 +1085,34 @@ namespace IRaCIS.Core.Application.Service
// 裁判问题可以不必填
if(item.TaskAnswerList.Count()==0)
{
try
{
_ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案等于0");
_ = SendAbnormalEmail(visiTaskId, EmailBusinessScenario.JudgeExceptio);
}
catch (Exception)
{
}
break;
}
else if (item.TaskAnswerList.Count() != 2)
{
noteEqual = true;
try
{
// 发送微信通知
_ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案不等于2");
_ = SendAbnormalEmail(visiTaskId, EmailBusinessScenario.JudgeExceptio);
}
catch (Exception)
{
}
break;
}
else if (noteEqual)

View File

@ -1,12 +1,8 @@
using DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using Microsoft.AspNetCore.Mvc;
using NPOI.POIFS.Properties;
using Panda.DynamicWebApi.Attributes;
using System.Collections.Generic;
namespace IRaCIS.Core.Application.Service
{

View File

@ -527,7 +527,7 @@ namespace IRaCIS.Core.Application.Service
var subjectVisitQuery = _subjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId)/*.Where(t => t.IsLostVisit == false)*/
.Where(t => t.Subject.IsSubjectQuit == false || (t.Subject.IsSubjectQuit == true && t.SubmitState == SubmitStateEnum.Submitted))
.Where(sv => sv.Subject.FinalSubjectVisitId == null ? true : sv.VisitNum <= sv.Subject.LatestSubjectVisit.VisitNum).Select(sv => new ReadModuleView()
.Where(sv => sv.Subject.FinalSubjectVisitId == null ? true : sv.VisitNum <= sv.Subject.FinalSubjectVisit.VisitNum).Select(sv => new ReadModuleView()
{
Id = sv.Id,
CreateTime = sv.CreateTime,

View File

@ -1,14 +1,9 @@
using DocumentFormat.OpenXml.Drawing;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using NPOI.Util;
namespace IRaCIS.Core.Application.Service
{

View File

@ -1,4 +1,5 @@
using DocumentFormat.OpenXml.Drawing.Spreadsheet;
using Amazon.Runtime.Internal.Transform;
using DocumentFormat.OpenXml.Drawing.Spreadsheet;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
@ -10,6 +11,7 @@ using MassTransit.Saga;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using MiniExcelLibs;
using System.Collections.Immutable;
using System.Data;
using System.IO;
using System.Text;
@ -18,6 +20,10 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
{
public class GeneralCalculateService(IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository,
IRepository<VisitTask> _visitTaskRepository,
IRepository<Segmentation> _segmentationRepository,
IRepository<Segment> _segmentRepository,
IRepository<SegmentBinding> _segmentBindingRepository,
IRepository<ReadingTaskQuestionMark> _readingTaskQuestionMarkRepository,
IRepository<ReadingNoneDicomMark> _readingNoneDicomMarkRepository,
IRepository<ReadingNoneDicomMarkBinding> _readingNoneDicomMarkBindingRepository,
@ -225,6 +231,13 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
return;
}
// 如果有表格问题或者外层问题答案就不复制了
if ((await _readingTableQuestionAnswerRepository.AnyAsync(x => x.VisitTaskId == taskinfo.Id))
|| (await _readingTaskQuestionAnswerRepository.AnyAsync(x => x.VisitTaskId == taskinfo.Id)))
{
return;
}
if (taskinfo.IsCopyLesionAnswer)
{
var historyTaskId = await _visitTaskRepository.Where(x =>
@ -255,7 +268,10 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
var questionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == historyTaskId).ToListAsync();
var noneDicomMarkList = await _readingNoneDicomMarkRepository.Where(x => x.VisitTaskId == historyTaskId).ToListAsync();
var noneDicomMarkBindingList = await _readingNoneDicomMarkBindingRepository.Where(x => x.VisitTaskId == historyTaskId).ToListAsync();
Dictionary<Guid, Guid> lesionRelationship = new Dictionary<Guid, Guid>() { };
// 这里后续还要添加病灶 比如现在是访视三 要把失效任务访视三的 在访视三的病灶添加过来
// 同时自定义的 除了根据器官判断还需要根据 复制前值的答案相不相等
foreach (var item in tableRowList)
{
if (item.SplitOrMergeType == SplitOrMergeType.Merged)
@ -272,6 +288,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
if (historyRow != null)
{
lesionRelationship.Add(historyRow.Id, item.Id);
item.StudyId = historyRow.StudyId;
item.SeriesId = historyRow.SeriesId;
item.InstanceId = historyRow.InstanceId;
@ -380,6 +397,63 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
item.Id = NewId.NextGuid();
}
#region 分割
Dictionary<Guid, Guid> segmentationRelationship = new Dictionary<Guid, Guid>() { };
var segmentationList = _segmentationRepository.Where(t => t.VisitTaskId == historyTaskId).ToList();
foreach (var item in segmentationList)
{
var newSegmentationId = NewId.NextSequentialGuid();
segmentationRelationship.Add(item.Id, newSegmentationId);
item.Id = newSegmentationId;
item.VisitTaskId = taskinfo.Id;
}
Dictionary<Guid, Guid> segmentRelationship = new Dictionary<Guid, Guid>() { };
var segmentList = _segmentRepository.Where(t => t.VisitTaskId == historyTaskId).ToList();
foreach (var item in segmentList)
{
var newSegmentationId = NewId.NextSequentialGuid();
segmentRelationship.Add(item.Id, newSegmentationId);
if (segmentationRelationship.ContainsKey(item.SegmentationId))
{
item.SegmentationId = segmentationRelationship[item.SegmentationId];
}
item.Id = newSegmentationId;
item.VisitTaskId = taskinfo.Id;
}
var segmentBindingList = _segmentBindingRepository.Where(x => x.VisitTaskId == historyTaskId).ToList();
foreach (var item in segmentBindingList)
{
if (segmentationRelationship.ContainsKey(item.SegmentationId))
{
item.SegmentationId = segmentationRelationship[item.SegmentationId];
}
if (segmentRelationship.ContainsKey(item.SegmentId))
{
item.SegmentId = segmentRelationship[item.SegmentId];
}
if (item.RowId != null && lesionRelationship.ContainsKey(item.RowId.Value))
{
item.RowId = lesionRelationship[item.RowId.Value];
}
item.Id = NewId.NextSequentialGuid();
item.VisitTaskId = taskinfo.Id;
}
_ = _segmentationRepository.AddRangeAsync(segmentationList).Result;
_ = _segmentRepository.AddRangeAsync(segmentList).Result;
_ = _segmentBindingRepository.AddRangeAsync(segmentBindingList).Result;
#endregion
await _readingNoneDicomMarkRepository.AddRangeAsync(noneDicomMarkList);

View File

@ -30,6 +30,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
IRepository<OrganInfo> _organInfoRepository,
IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository,
IRepository<ReadingJudgeInfo> _readingJudgeInfoRepository,
IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<TumorAssessment_IRECIST1Point1> _tumorAssessmentRepository,
IGeneralCalculateService _generalCalculateService,
@ -508,12 +509,14 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
TrialId = task.TrialId,
VisitTaskId = task.Id,
});
data.VisitTaskId= task.Id;
}
return data;
}
EvaluationColumn BuildEvaluationTable(GetReadingReportEvaluationOutDto r1, GetReadingReportEvaluationOutDto r2)
async Task<EvaluationColumn> BuildEvaluationTable(GetReadingReportEvaluationOutDto r1, GetReadingReportEvaluationOutDto r2)
{
EvaluationColumn result = new EvaluationColumn()
{
@ -537,6 +540,74 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
break;
}
Arm? highlightArm = null;
ArbitrationRule? highlightRule = null;
decimal? highlightVisitTaskNum = null;
if (r1.VisitTaskId != null && r2.VisitTaskList != null)
{
var judgeInfo =await _visitTaskRepository.Where(x => x.SubjectId == inDto.SubjectId && x.TrialReadingCriterionId == inDto.TrialCriterionId
&& x.TaskState == TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned
&& x.ReadingCategory== ReadingCategory.Judge
).OrderByDescending(x => x.VisitTaskNum).Include(x=>x.JudgeResultTask).FirstOrDefaultAsync();
if (judgeInfo != null && judgeInfo.JudgeResultTask != null)
{
if (judgeInfo.JudgeResultTask.ArmEnum == Arm.DoubleReadingArm1
|| judgeInfo.JudgeResultTask.ArmEnum == Arm.DoubleReadingArm2)
{
highlightArm = judgeInfo.JudgeResultTask.ArmEnum;
highlightRule = criterion.ArbitrationRule;
highlightVisitTaskNum = judgeInfo.VisitTaskNum;
}
}
}
void SetHighlight(List<EvaluationValue> data, Arm arm)
{
if (highlightArm != arm || highlightVisitTaskNum == null)
{
return;
}
if (highlightRule == ArbitrationRule.Reading)
{
for (var index = 0; index < data.Count && index < highlightVisitTaskNum.Value; index++)
{
data[index].IsHighlight = true;
}
}
else if (highlightRule == ArbitrationRule.Visit)
{
var index = decimal.ToInt32(decimal.Floor(highlightVisitTaskNum.Value));
if (index >= 0 && index < data.Count)
{
data[index].IsHighlight = true;
}
}
}
void SetVisitTaskId(List<EvaluationValue> data, List<VisitTaskInfo> VisitTaskList)
{
for (var index = 0; index < data.Count; index++)
{
try
{
data[index].VisitTaskId = VisitTaskList[index].VisitTaskId;
}
catch (Exception)
{
}
}
}
result.Evaluation.Add(visitTaskName.Select(x => new EvaluationValue()
@ -570,6 +641,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
r1data = r1data.Concat(Enumerable.Repeat(new EvaluationValue() { Value = "" }, length))
.Take(length)
.ToList();
SetHighlight(r1data, Arm.DoubleReadingArm1);
SetVisitTaskId(r1data, r1.VisitTaskList);
result.Evaluation.Add(r1data);
@ -601,6 +674,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
r2data = r2data.Concat(Enumerable.Repeat(new EvaluationValue() { Value = "" }, length))
.Take(length)
.ToList();
SetHighlight(r2data, Arm.DoubleReadingArm2);
SetVisitTaskId(r2data, r2.VisitTaskList);
result.Evaluation.Add(r2data);
}
@ -679,7 +754,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
}
result.Evaluation = BuildEvaluationTable(r1Data, r2Data);
result.Evaluation =await BuildEvaluationTable(r1Data, r2Data);
if (r1Data != null)
{
var r1Target = await BuildTargetChart(r1Data, Arm.DoubleReadingArm1);

View File

@ -1,18 +1,14 @@
using DocumentFormat.OpenXml.EMMA;
using DocumentFormat.OpenXml.Presentation;
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using MathNet.Numerics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using MiniExcelLibs;
using System;
using Newtonsoft.Json;
namespace IRaCIS.Core.Application.Service.ReadingCalculate
{
@ -25,6 +21,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository,
IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
IRepository<OrganInfo> _organInfoRepository,
ISubjectVisitService iSubjectVisitService,
IRepository<Dictionary> _dictionaryRepository,
IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository,
IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<TumorAssessment_IRECIST1Point1> _tumorAssessmentRepository,
@ -305,10 +303,10 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
//new ReadingCalculateData (){QuestionType=QuestionType.Plaque3PVA,GetDecimalNullFun=GetPlaque3PVA},
// (EEM-Lumen)求和
// 获取EMM求和
new ReadingCalculateData (){QuestionType=QuestionType.EEMSum,GetDecimalNullFun=GetEmmSum},
// 斑块2-PAV
// (EEM-Lumen)求和
new ReadingCalculateData (){QuestionType=QuestionType.EEMSubLumenSum,GetDecimalNullFun=GetEEMLumenSum},
// PAV冠状动脉粥样硬化体积百分比)
@ -421,10 +419,70 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x=>x.Subject).FirstNotNullAsync();
//靶段
var targetSegmentdic = await _dictionaryRepository.Where(x => x.Parent.Code == "TargetSegment").ToListAsync();
//斑块类型
var plaqueTypedic = await _dictionaryRepository.Where(x => x.Parent.Code == "PlaqueType").ToListAsync();
var awswerList=await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).Include(x=>x.ReadingQuestionTrial).ToListAsync();
var targetSegmentAnswer = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.TargetSegment).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
if (targetSegmentAnswer.IsNotNullOrEmpty())
{
var data= JsonConvert.DeserializeObject<List<string>>(targetSegmentAnswer);
targetSegmentAnswer = string.Join(",", targetSegmentdic
.Where(x => data.Contains(x.Code))
.Select(x => x.ValueCN));
}
else
{
var targetSegmentData = await iSubjectVisitService.GetReadingVisitStudyList(new Contracts.GetReadingVisitStudyListIndto()
{
SujectVisitId = taskinfo.SourceSubjectVisitId ?? default(Guid),
TrialId = taskinfo.TrialId,
VisitTaskId = inDto.VisitTaskId
});
targetSegmentAnswer = string.Join(",", targetSegmentData
.Where(x => x.BodyPartForEdit.IsNotNullOrEmpty())
.SelectMany(x => x.BodyPartForEdit.Split('|'))
.Where(s => !string.IsNullOrWhiteSpace(s))
.Distinct());
}
var plaqueTypeAnswer = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.PlaqueType).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
if (plaqueTypeAnswer.IsNotNullOrEmpty())
{
var data = JsonConvert.DeserializeObject<List<string>>(plaqueTypeAnswer);
plaqueTypeAnswer = string.Join(",", plaqueTypedic
.Where(x => data.Contains(x.Code))
.Select(x => x.ValueCN));
}
var values = new TemplateData()
{
SubjectID = (taskinfo.BlindSubjectCode.IsNullOrEmpty() ? taskinfo.Subject.Code : taskinfo.BlindSubjectCode),
TaskBlindName = taskinfo.TaskBlindName,
TargetSegment= targetSegmentAnswer,
TargetSegmentRemarks = awswerList.Where(x=>x.ReadingQuestionTrial.QuestionType == QuestionType.TargetSegmentRemarks).Select(x=>x.Answer).FirstOrDefault()??string.Empty,
//ROIAllLength = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.ROIAllLength).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
//PullbackFrameCount = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.PullbackFrameCount).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
//AdjustReason = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.AdjustReason).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
//PlaqueType = plaqueTypeAnswer,
};
return await _visitTaskHelpeService.ExportTemplateAsync(new IRaCIS.Application.Contracts.ExportTemplateAsyncDto()
{
@ -449,7 +507,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
List<string> sheetNames = new List<string>()
{
"各匹配片段测量值","MeasuredValue"
"ROI测量值","ROI 测量值"
};
if (sheetNames.Intersect(uploadInfo.SheetNames).Count() == 0)
@ -501,20 +559,63 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
}
string getNone(string value)
{
if (value == string.Empty || value == null)
{
return "无";
}
else
{
return value;
}
}
Dictionary<string, string> isPresent = new Dictionary<string, string>()
{
{ "1","1"},
{ "0","0"},
{ "有","1"},
{ "无","0"},
{ "Existence","1"},
{ "Non-existence","0"},
{ string.Empty,string.Empty},
};
Dictionary<string, string> yesOrNo = new Dictionary<string, string>()
{
{ "1","1"},
{ "0","0"},
{ "是","1"},
{ "否","0"},
{ "Yes","1"},
{ "No","0"},
};
List<IVUSMeasuredValue> measuredValueList = new List<IVUSMeasuredValue>();
var errorRow = new List<int> { };
for (int i = 3; i < dataTable.Rows.Count; i++)
for (int i = 9; i < dataTable.Rows.Count; i++)
{
IVUSMeasuredValue iVUSMeasuredValue = new IVUSMeasuredValue() { };
try
{
// 手动抛出异常进入catch
if (!yesOrNo.ContainsKey(dataTable.Rows[i]["D"].ToString()))
{
throw new InvalidOperationException("NullError");
}
iVUSMeasuredValue = new IVUSMeasuredValue()
{
//PlaqueNum = int.Parse(dataTable.Rows[i]["A"].ToString()),
FrameNumber = dataTable.Rows[i]["A"].ToString()??string.Empty,
Emm = getdecimalEmptyData(dataTable.Rows[i]["B"].ToString()),
Lumen = getdecimalEmptyData(dataTable.Rows[i]["C"].ToString()),
PlaqueRupture= getNone(dataTable.Rows[i]["D"].ToString()),
};
}
catch (Exception)
@ -630,6 +731,18 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
TableQuestionId = tableQuestionList.Where(x => x.ReadingQuestionId == questionInfo.Id && x.QuestionMark == QuestionMark.ElasticAreaDiffValue).Select(x => x.Id).FirstOrDefault(),
});
// 斑块破裂
tableAnswers.Add(new ReadingTableQuestionAnswer()
{
Answer = yesOrNo[item.PlaqueRupture.ToString()],
QuestionId = questionInfo.Id,
TrialId = taskinfo.TrialId,
VisitTaskId = taskinfo.Id,
RowId = newRowId,
RowIndex = maxnum,
TableQuestionId = tableQuestionList.Where(x => x.ReadingQuestionId == questionInfo.Id && x.QuestionMark == QuestionMark.PlaqueRupture).Select(x => x.Id).FirstOrDefault(),
});
// 添加其他问题答案
foreach (var otherQuestion in tableQuestionList.Where(x => !tableAnswers.Any(y => y.TableQuestionId == x.Id && y.RowId == newRowId)))
@ -647,7 +760,100 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
}
}
#region 构造外层问题答案
List<ReadingTaskQuestionAnswer> questionAnswers = new List<ReadingTaskQuestionAnswer>();
var readingQuestionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId).ToListAsync();
var targetSegmentAnswer = dataTable.Rows[2]["B"].ToString();
if (targetSegmentAnswer.IsNotNullOrEmpty())
{
var targetSegmentValues = targetSegmentAnswer.Replace(" ", "").Replace("", ",").Split(",").ToList();
var targetSegmentdic = await _dictionaryRepository.Where(x => x.Parent.Code == "TargetSegment").ToListAsync();
targetSegmentAnswer = JsonConvert.SerializeObject(targetSegmentdic.Where(x => targetSegmentValues.Contains(x.ValueCN.Replace(" ", ""))).Select(x => x.Code).ToList());
}
questionAnswers.Add(new ReadingTaskQuestionAnswer()
{
Answer= targetSegmentAnswer??string.Empty,
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.TargetSegment).Select(x => x.Id).FirstOrDefault(),
TrialId = taskinfo.TrialId,
SubjectId= taskinfo.SubjectId,
VisitTaskId = taskinfo.Id,
});
questionAnswers.Add(new ReadingTaskQuestionAnswer()
{
Answer = dataTable.Rows[3]["B"].ToString()??string.Empty,
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.TargetSegmentRemarks).Select(x => x.Id).FirstOrDefault(),
TrialId = taskinfo.TrialId,
SubjectId = taskinfo.SubjectId,
VisitTaskId = taskinfo.Id,
});
questionAnswers.Add(new ReadingTaskQuestionAnswer()
{
Answer = dataTable.Rows[4]["B"].ToString() ?? string.Empty,
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.ROIAllLength).Select(x => x.Id).FirstOrDefault(),
TrialId = taskinfo.TrialId,
SubjectId = taskinfo.SubjectId,
VisitTaskId = taskinfo.Id,
});
questionAnswers.Add(new ReadingTaskQuestionAnswer()
{
Answer = dataTable.Rows[5]["B"].ToString() ?? string.Empty,
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.PullbackFrameCount).Select(x => x.Id).FirstOrDefault(),
TrialId = taskinfo.TrialId,
SubjectId = taskinfo.SubjectId,
VisitTaskId = taskinfo.Id,
});
var plaqueTypeAnswer = dataTable.Rows[6]["B"].ToString();
if (plaqueTypeAnswer.IsNotNullOrEmpty())
{
var plaqueTypeAnswerValues = plaqueTypeAnswer.Replace(" ", "").Replace("", ",").Split(",").ToList();
var plaqueTypeAnswerdic = await _dictionaryRepository.Where(x => x.Parent.Code == "PlaqueType").ToListAsync();
plaqueTypeAnswer = JsonConvert.SerializeObject(plaqueTypeAnswerdic
.Where(x => plaqueTypeAnswerValues.Any(val => x.ValueCN.Replace(" ", "").Contains(val)))
.Select(x => x.Code)
.ToList());
}
questionAnswers.Add(new ReadingTaskQuestionAnswer()
{
Answer = plaqueTypeAnswer ?? string.Empty,
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.PlaqueType).Select(x => x.Id).FirstOrDefault(),
TrialId = taskinfo.TrialId,
SubjectId = taskinfo.SubjectId,
VisitTaskId = taskinfo.Id,
});
questionAnswers.Add(new ReadingTaskQuestionAnswer()
{
Answer = dataTable.Rows[7]["B"].ToString() ?? string.Empty,
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.AdjustReason).Select(x => x.Id).FirstOrDefault(),
TrialId = taskinfo.TrialId,
SubjectId = taskinfo.SubjectId,
VisitTaskId = taskinfo.Id,
});
var questionids = questionAnswers.Select(x => x.ReadingQuestionTrialId).ToList();
await _readingTaskQuestionAnswerRepository.DeleteFromQueryAsync(x => x.VisitTaskId == taskinfo.Id && questionids.Contains(x.ReadingQuestionTrialId));
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
await _readingTaskQuestionAnswerRepository.AddRangeAsync(questionAnswers);
await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
#endregion
await _readingTableAnswerRowInfoRepository.DeleteFromQueryAsync(x => x.QuestionId == questionInfo.Id && x.VisitTaskId == taskinfo.Id);
await _readingTableQuestionAnswerRepository.DeleteFromQueryAsync(x => x.QuestionId == questionInfo.Id && x.VisitTaskId == taskinfo.Id);
await _readingTableQuestionAnswerRepository.SaveChangesAsync();

View File

@ -2,6 +2,7 @@
using DocumentFormat.OpenXml.Drawing.Spreadsheet;
using DocumentFormat.OpenXml.Office.SpreadSheetML.Y2023.MsForms;
using DocumentFormat.OpenXml.Office2010.Excel;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
@ -12,6 +13,7 @@ using MassTransit;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace IRaCIS.Core.Application.Service.ReadingCalculate
{
@ -24,6 +26,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository,
IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
IRepository<OrganInfo> _organInfoRepository,
ISubjectVisitService iSubjectVisitService,
IRepository<Dictionary> _dictionaryRepository,
IHttpContextAccessor httpContext,
IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository,
IRepository<SubjectVisit> _subjectVisitRepository,
@ -271,10 +275,68 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
public async Task<FileResult> GetOCTFCTTemplate(GetExportTemplateInDto inDto)
{
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.Subject).FirstNotNullAsync();
//靶段
var targetSegmentdic = await _dictionaryRepository.Where(x => x.Parent.Code == "TargetSegment").ToListAsync();
//斑块类型
var plaqueTypedic = await _dictionaryRepository.Where(x => x.Parent.Code == "PlaqueType").ToListAsync();
var awswerList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).Include(x => x.ReadingQuestionTrial).ToListAsync();
var targetSegmentAnswer = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.TargetSegment).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
if (targetSegmentAnswer.IsNotNullOrEmpty())
{
var data = JsonConvert.DeserializeObject<List<string>>(targetSegmentAnswer);
targetSegmentAnswer = string.Join(",", targetSegmentdic
.Where(x => data.Contains(x.Code))
.Select(x => x.ValueCN));
}
else
{
var targetSegmentData = await iSubjectVisitService.GetReadingVisitStudyList(new Contracts.GetReadingVisitStudyListIndto()
{
SujectVisitId = taskinfo.SourceSubjectVisitId ?? default(Guid),
TrialId = taskinfo.TrialId,
VisitTaskId = inDto.VisitTaskId
});
targetSegmentAnswer = string.Join(",", targetSegmentData
.Where(x => x.BodyPartForEdit.IsNotNullOrEmpty())
.SelectMany(x => x.BodyPartForEdit.Split('|'))
.Where(s => !string.IsNullOrWhiteSpace(s))
.Distinct());
}
var plaqueTypeAnswer = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.PlaqueType).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
if (plaqueTypeAnswer.IsNotNullOrEmpty())
{
var data = JsonConvert.DeserializeObject<List<string>>(plaqueTypeAnswer);
plaqueTypeAnswer = string.Join(",", plaqueTypedic
.Where(x => data.Contains(x.Code))
.Select(x => x.ValueCN));
}
var values = new TemplateData()
{
SubjectID = (taskinfo.BlindSubjectCode.IsNullOrEmpty() ? taskinfo.Subject.Code : taskinfo.BlindSubjectCode),
TaskBlindName = taskinfo.TaskBlindName,
TargetSegment = targetSegmentAnswer,
TargetSegmentRemarks = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.TargetSegmentRemarks).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
//ROIAllLength = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.ROIAllLength).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
////PullbackFrameCount = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.PullbackFrameCount).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
//PlaqueType = plaqueTypeAnswer,
//AdjustReason = awswerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.AdjustReason).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
};
return await _visitTaskHelpeService.ExportTemplateAsync(new IRaCIS.Application.Contracts.ExportTemplateAsyncDto()
{
@ -299,7 +361,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
List<string> sheetNames = new List<string>()
{
"FCT导入","FCT"
"ROI测量值","ROI 测量值"
};
if (sheetNames.Intersect(uploadInfo.SheetNames).Count() == 0)
@ -336,6 +398,17 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
List<OCTFCTUploadData> measuredValueList = new List<OCTFCTUploadData>();
var errorRow = new List<int> { };
Dictionary<string, string> yesOrNo = new Dictionary<string, string>()
{
{ "1","1"},
{ "0","0"},
{ "是","1"},
{ "否","0"},
{ "Yes","1"},
{ "No","0"},
};
string getNone(string value)
{
if (value == string.Empty || value == null)
@ -347,23 +420,34 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
return value;
}
}
for (int i = 3; i < dataTable.Rows.Count; i++)
for (int i = 8; i < dataTable.Rows.Count; i++)
{
try
{
// 手动抛出异常进入catch
if (!yesOrNo.ContainsKey(dataTable.Rows[i]["K"].ToString())|| !yesOrNo.ContainsKey(dataTable.Rows[i]["L"].ToString()))
{
throw new InvalidOperationException("NullError");
}
measuredValueList.Add(new OCTFCTUploadData()
{
//PlaqueNum = int.Parse(dataTable.Rows[i]["A"].ToString()),
FrameNumber = dataTable.Rows[i]["A"].ToString() ?? string.Empty,
FirstData = getdecimalEmptyData(dataTable.Rows[i]["B"].ToString()),
SecondData = getdecimalEmptyData(dataTable.Rows[i]["C"].ToString()),
ThirdData = getdecimalEmptyData(dataTable.Rows[i]["D"].ToString()),
MacrophageInfiltrationMeasurement = getNone(dataTable.Rows[i]["E"].ToString()),
MacrophageInfiltrationAngle = getdecimalEmptyData(dataTable.Rows[i]["F"].ToString() ?? string.Empty),
LumenAreaMeasurement = getdecimalEmptyData(dataTable.Rows[i]["B"].ToString()),
LipidAngle = getdecimalEmptyData(dataTable.Rows[i]["C"].ToString() ?? string.Empty),
FirstData = getdecimalEmptyData(dataTable.Rows[i]["D"].ToString()),
SecondData = getdecimalEmptyData(dataTable.Rows[i]["E"].ToString()),
ThirdData = getdecimalEmptyData(dataTable.Rows[i]["F"].ToString()),
MicrochannelMeasurement = getNone(dataTable.Rows[i]["G"].ToString()),
CholesterolCrystalMeasurement = getNone(dataTable.Rows[i]["H"].ToString()),
LumenAreaMeasurement = getdecimalEmptyData(dataTable.Rows[i]["I"].ToString()),
LipidAngle = getdecimalEmptyData(dataTable.Rows[i]["J"].ToString() ?? string.Empty),
MacrophageInfiltrationMeasurement = getNone(dataTable.Rows[i]["I"].ToString()),
MacrophageInfiltrationAngle = getdecimalEmptyData(dataTable.Rows[i]["J"].ToString() ?? string.Empty),
PlaqueRupture = getNone(dataTable.Rows[i]["K"].ToString()),
PlaqueHealing = getNone(dataTable.Rows[i]["L"].ToString()),
});
}
catch (Exception)
@ -385,6 +469,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
Dictionary<string, string> isPresent = new Dictionary<string, string>()
{
{ "1","1"},
{ "0","0"},
{ "有","1"},
{ "无","0"},
{ "Existence","1"},
@ -392,7 +478,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
{ string.Empty,string.Empty},
};
int row = 3;
int row = 8;
foreach (var item in measuredValueList)
{
row++;
@ -598,6 +684,30 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
TableQuestionId = tableQuestionList.Where(x => x.ReadingQuestionId == questionInfo.Id && x.QuestionMark == QuestionMark.LipidAngle).Select(x => x.Id).FirstOrDefault(),
});
// 斑块破裂
tableAnswers.Add(new ReadingTableQuestionAnswer()
{
Answer = yesOrNo[item.PlaqueRupture.ToString()],
QuestionId = questionInfo.Id,
TrialId = taskinfo.TrialId,
VisitTaskId = taskinfo.Id,
RowId = newRowId,
RowIndex = maxnum,
TableQuestionId = tableQuestionList.Where(x => x.ReadingQuestionId == questionInfo.Id && x.QuestionMark == QuestionMark.PlaqueRupture).Select(x => x.Id).FirstOrDefault(),
});
// 斑块愈合
tableAnswers.Add(new ReadingTableQuestionAnswer()
{
Answer = yesOrNo[item.PlaqueHealing.ToString()],
QuestionId = questionInfo.Id,
TrialId = taskinfo.TrialId,
VisitTaskId = taskinfo.Id,
RowId = newRowId,
RowIndex = maxnum,
TableQuestionId = tableQuestionList.Where(x => x.ReadingQuestionId == questionInfo.Id && x.QuestionMark == QuestionMark.PlaqueHealing).Select(x => x.Id).FirstOrDefault(),
});
}
catch (Exception)
{
@ -621,6 +731,91 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
}
}
#region 构造外层问题答案
List<ReadingTaskQuestionAnswer> questionAnswers = new List<ReadingTaskQuestionAnswer>();
var readingQuestionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId).ToListAsync();
var targetSegmentAnswer = dataTable.Rows[2]["B"].ToString();
if (targetSegmentAnswer.IsNotNullOrEmpty())
{
var targetSegmentValues = targetSegmentAnswer.Replace(" ", "").Replace("", ",").Split(",").ToList();
var targetSegmentdic = await _dictionaryRepository.Where(x => x.Parent.Code == "TargetSegment").ToListAsync();
targetSegmentAnswer = JsonConvert.SerializeObject(targetSegmentdic.Where(x => targetSegmentValues.Contains(x.ValueCN.Replace(" ", ""))).Select(x => x.Code).ToList());
}
questionAnswers.Add(new ReadingTaskQuestionAnswer()
{
Answer = targetSegmentAnswer ?? string.Empty,
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.TargetSegment).Select(x => x.Id).FirstOrDefault(),
TrialId = taskinfo.TrialId,
SubjectId = taskinfo.SubjectId,
VisitTaskId = taskinfo.Id,
});
questionAnswers.Add(new ReadingTaskQuestionAnswer()
{
Answer = dataTable.Rows[3]["B"].ToString() ?? string.Empty,
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.TargetSegmentRemarks).Select(x => x.Id).FirstOrDefault(),
TrialId = taskinfo.TrialId,
SubjectId = taskinfo.SubjectId,
VisitTaskId = taskinfo.Id,
});
questionAnswers.Add(new ReadingTaskQuestionAnswer()
{
Answer = dataTable.Rows[4]["B"].ToString() ?? string.Empty,
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.ROIAllLength).Select(x => x.Id).FirstOrDefault(),
TrialId = taskinfo.TrialId,
SubjectId = taskinfo.SubjectId,
VisitTaskId = taskinfo.Id,
});
var plaqueTypeAnswer = dataTable.Rows[5]["B"].ToString();
if (plaqueTypeAnswer.IsNotNullOrEmpty())
{
var plaqueTypeAnswerValues = plaqueTypeAnswer.Replace(" ", "").Replace("", ",").Split(",").ToList();
var plaqueTypeAnswerdic = await _dictionaryRepository.Where(x => x.Parent.Code == "PlaqueType").ToListAsync();
plaqueTypeAnswer = JsonConvert.SerializeObject(plaqueTypeAnswerdic
.Where(x => plaqueTypeAnswerValues.Any(val => x.ValueCN.Replace(" ", "").Contains(val)))
.Select(x => x.Code)
.ToList());
}
questionAnswers.Add(new ReadingTaskQuestionAnswer()
{
Answer = plaqueTypeAnswer ?? string.Empty,
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.PlaqueType).Select(x => x.Id).FirstOrDefault(),
TrialId = taskinfo.TrialId,
SubjectId = taskinfo.SubjectId,
VisitTaskId = taskinfo.Id,
});
questionAnswers.Add(new ReadingTaskQuestionAnswer()
{
Answer = dataTable.Rows[6]["B"].ToString() ?? string.Empty,
ReadingQuestionCriterionTrialId = taskinfo.TrialReadingCriterionId,
ReadingQuestionTrialId = readingQuestionList.Where(x => x.QuestionType == QuestionType.AdjustReason).Select(x => x.Id).FirstOrDefault(),
TrialId = taskinfo.TrialId,
SubjectId = taskinfo.SubjectId,
VisitTaskId = taskinfo.Id,
});
var questionids = questionAnswers.Select(x => x.ReadingQuestionTrialId).ToList();
await _readingTaskQuestionAnswerRepository.DeleteFromQueryAsync(x => x.VisitTaskId == taskinfo.Id && questionids.Contains(x.ReadingQuestionTrialId));
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
await _readingTaskQuestionAnswerRepository.AddRangeAsync(questionAnswers);
await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
#endregion
await _readingTableAnswerRowInfoRepository.DeleteFromQueryAsync(x => x.QuestionId == questionInfo.Id && x.VisitTaskId == taskinfo.Id);
await _readingTableQuestionAnswerRepository.DeleteFromQueryAsync(x => x.QuestionId == questionInfo.Id && x.VisitTaskId == taskinfo.Id);
await _readingTableQuestionAnswerRepository.SaveChangesAsync();

View File

@ -1,11 +1,8 @@
using DocumentFormat.OpenXml.EMMA;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using NPOI.Util;
namespace IRaCIS.Core.Application.Service.ReadingCalculate
{
@ -299,11 +296,10 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
}
}
if(trialReadingCriterion.IsOncologyReading)
{
await _generalCalculateService.CopyHistoryAnswer(taskinfo, addRowList, addTableQuestionAnswerList);
}
// 自定义的复制
await _generalCalculateService.CopyHistoryAnswer(taskinfo, addRowList, addTableQuestionAnswerList);
await _readingTableAnswerRowInfoRepository.AddRangeAsync(addRowList);
await _readingTableQuestionAnswerRepository.AddRangeAsync(addTableQuestionAnswerList);
await _readingTableQuestionAnswerRepository.SaveChangesAsync();

View File

@ -5,6 +5,7 @@
//--------------------------------------------------------------------
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using System.ComponentModel.DataAnnotations;
namespace IRaCIS.Core.Application.Contracts
@ -162,7 +163,7 @@ namespace IRaCIS.Core.Application.Contracts
public DateTime? ReviewerTime { get; set; }
public CommonUploadRecordDto SiteSurveyFile { get; set; }
}
@ -360,7 +361,7 @@ namespace IRaCIS.Core.Application.Contracts
[Comment("不严格按照影像手册参数完成刻盘原因")]
public string NotStrictManualBurnFlagReason { get; set; }
public Guid? CommonUploadRecordId { get; set; }
}

View File

@ -3,36 +3,17 @@
// 生成时间 2021-12-23 13:20:59
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Vml.Spreadsheet;
using IdentityModel;
using IdentityModel.OidcClient;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.Service.OAuth;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Medallion.Threading;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.VisualBasic;
using MimeKit;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using Panda.DynamicWebApi.Attributes;
using StackExchange.Redis;
using System.Security.Policy;
using System.Text.RegularExpressions;
using static MassTransit.ValidationResultExtensions;
namespace IRaCIS.Core.Application.Contracts
{
@ -849,7 +830,8 @@ namespace IRaCIS.Core.Application.Contracts
}
var config = await _trialRepository.Where(t => t.Id == trialSiteSurvey.TrialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefaultAsync();
var extralConfig = JsonConvert.DeserializeObject<TrialExtraConfig>(config);
var siteUserList = await _trialSiteUserSurveyRepository.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId)
.Where(t => !(t.IsHistoryUser && t.IsHistoryUserDeleted == true))
@ -868,7 +850,7 @@ namespace IRaCIS.Core.Application.Contracts
//var currentUserList = siteUserList.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId).ToList();
if (!siteUserList.Any(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.CRA))
if (!siteUserList.Any(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.CRA) && extralConfig.IsOnlyUploadFile == false)
{
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_MissingAccount"]);
}
@ -938,7 +920,7 @@ namespace IRaCIS.Core.Application.Contracts
var trialType = _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialType).FirstOrDefault();
foreach (var item in needGenerateList.GroupBy(t => t.Email))
foreach (var item in needSendEmailList.GroupBy(t => t.Email))
{
var addUserRoleList = item.ToList();
@ -1155,23 +1137,26 @@ namespace IRaCIS.Core.Application.Contracts
await _trialSiteUserSurveyRepository.UpdatePartialFromQueryAsync(t => userJoinIdList.Contains(t.Id), u => new TrialSiteUserSurvey() { IsJoin = true, SystemUserId = existSysUser.Id });
//中心调研设置用户角色退出
var needQuitUserList = item.Where(t => t.IsHistoryUser && t.IsHistoryUserOriginDeleted == false && t.IsHistoryUserDeleted == true).ToList();
var queitUserTypeIdList = needQuitUserList.Select(t => t.UserTypeId).ToList();
await _trialSiteUserRoleRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId && queitUserTypeIdList.Contains(t.UserRole.UserTypeId), c => new TrialSiteUserRole()
{
IsDeleted = true,
DeletedTime = DateTime.Now,
});
await _trialSiteUserRoleRepository.SaveChangesAsync();
}
//中心调研设置用户角色退出
var needQuitUserList = allUserList.Where(t => t.IsHistoryUser && t.IsHistoryUserOriginDeleted == false && t.IsHistoryUserDeleted == true).ToList();
var queitUserTypeIdList = needQuitUserList.Select(t => t.UserTypeId).ToList();
await _trialSiteUserRoleRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId && queitUserTypeIdList.Contains(t.UserRole.UserTypeId), c => new TrialSiteUserRole()
{
IsDeleted = true,
DeletedTime = DateTime.Now,
});
await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.SPMApproved, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.PMCreatedAndLock, ReviewerUserId = _userInfo.UserRoleId, ReviewerTime = DateTime.Now });
}

View File

@ -56,6 +56,12 @@ namespace IRaCIS.Core.Application.Contracts
var item = addOrEditTrialSiteUserSurvey;
if (item.UserTypeId == null)
{
throw new BusinessValidationFailedException(_localizer["SystemCommon_WebErrorArgument"]);
}
//找下系统中是否存在该用户类型的 并且邮箱 或者手机的账户
var sysUserInfo = await _identityUserRepository.Where(t => t.EMail == item.Email,true).Include(t => t.UserRoleList).FirstOrDefaultAsync();

View File

@ -46,6 +46,7 @@ namespace IRaCIS.Core.Application.AutoMapper
CreateMap<TrialSiteSurvey, TrialSiteSurveyView>()
.ForMember(d => d.TrialSiteAliasName, u => u.MapFrom(s => s.TrialSite.TrialSiteAliasName))
.ForMember(d => d.SiteName, u => u.MapFrom(s => s.TrialSite.TrialSiteName))
.ForMember(d => d.SiteSurveyFile, u => u.MapFrom(s => s.SiteSurveyFile))
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode));
CreateMap<TrialSiteSurvey, TrialSiteSurveySelectView>();

View File

@ -750,6 +750,59 @@ namespace IRaCIS.Core.Application.Contracts
public Guid TrialReadingCriterionId { get; set; }
}
public class TrialLinkExpirationTimeDto
{
public Guid TrialId { get; set; }
public int ExpirationDays { get; set; }
public string LinkVerificationCode { get; set; }
}
public class SetTrialLinkExpirationTimeDto
{
public Guid TrialId { get; set; }
public DateTime? LinkExpirationTime { get; set; }
public string LinkVerificationCode { get; set; }
public string ResearchProgramNo { get; set; } = string.Empty;
}
public class VerifyLinkExpirationTimeDto
{
public Guid TrialId { get; set; }
}
public class VerifyLinkExpirationTimeOutDto
{
public DateTime? LinkExpirationTime { get; set; }
public bool IsExpired
{
get
{
return this.LinkExpirationTime != null && this.LinkExpirationTime < DateTime.Now;
}
}
}
public class GetLinkVerificationCodeIsEffectiveDto
{
public Guid TrialId { get; set; }
public string LinkVerificationCode { get; set; }
}
public class GetLinkVerificationCodeIsEffectiveOutDto
{
public bool IsEffective { get; set; }
}
public class GetTrialReadingCriterionInfoOutDto
{

View File

@ -245,18 +245,10 @@ namespace IRaCIS.Application.Contracts
}
public class TrialExtraConfig
{
#region QC 影像下载--下个版本删除
//QC质控下载
public bool IsSupportQCDownloadImage { get; set; } = false;
/// <summary>
/// 打开失访可读
/// </summary>
public bool IsOpenLostVistRead { get; set; } = true;
#endregion
public bool IsSupportUploadFile { get; set; }
public bool IsOnlyUploadFile { get; set; }
#region 中心调研
@ -296,6 +288,8 @@ namespace IRaCIS.Application.Contracts
#endregion
public TrialDataStore TrialDataStoreType { get; set; }
public TrialType TrialType { get; set; }
}
public class TrialPacsInfo

View File

@ -13,6 +13,6 @@ namespace IRaCIS.Core.Application.Interfaces
Task<PageOutput<SiteStatDTO>> GetSiteCRCList(SiteCrcQueryDTO param);
Task<IResponseOutput<PageOutput<SiteStatSimpleDTO>> > GetSiteCRCSimpleList(SiteCrcQueryDTO param);
Task<PageOutput<TrialSiteScreeningDTO>> GetTrialSiteScreeningList(TrialSiteQuery trialSiteQuery);
Task<IEnumerable<TrialSiteForSelect>> GetTrialSiteSelect(Guid trialId);
Task<IEnumerable<TrialSiteForSelect>> GetTrialSiteSelect(Guid trialId, bool? ignoreDisable);
}
}

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