Compare commits

..

712 Commits

Author SHA1 Message Date
hang c036aab9c4 修改refer
continuous-integration/drone/push Build is passing
2025-03-24 17:13:43 +08:00
hang 2eb85b6b71 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-24 16:59:47 +08:00
hang 712f1ceb61 修改非dicom 检查
continuous-integration/drone/push Build is passing
2025-03-24 16:59:11 +08:00
he adf873639c 修改稽查报错问题
continuous-integration/drone/push Build is passing
2025-03-24 16:46:33 +08:00
hang 4e9460e7da 为cdn 部署取项目Id 修改
continuous-integration/drone/push Build is passing
2025-03-24 15:17:44 +08:00
hang 5481eac988 增加环境变量
continuous-integration/drone/push Build is passing
2025-03-24 11:20:03 +08:00
he b7c9abca02 拷贝表单
continuous-integration/drone/push Build is passing
2025-03-20 17:37:18 +08:00
he 447d3fc36f Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-20 14:37:26 +08:00
he 71702b2abb 修改显示检查名称 2025-03-20 14:37:25 +08:00
hang 2ffb24d630 维护oss 数据大小
continuous-integration/drone/push Build is passing
2025-03-20 13:15:50 +08:00
he 81ecd9ff7f Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-20 09:38:24 +08:00
he ebe012ca67 修改 2025-03-20 09:38:22 +08:00
hang 805176c3ea 修改编译错误
continuous-integration/drone/push Build is running
2025-03-20 09:35:34 +08:00
hang f99cab6983 获取文件大小 oss
continuous-integration/drone/push Build is passing
2025-03-19 17:16:39 +08:00
he c94d800646 移动文件
continuous-integration/drone/push Build is passing
2025-03-19 15:47:31 +08:00
he 0cbc345f49 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-18 15:20:07 +08:00
he d34f3f1576 修改 2025-03-18 15:20:05 +08:00
hang 73f5e67e3c 切换账户排序修改
continuous-integration/drone/push Build is passing
2025-03-18 13:55:30 +08:00
he 5cf8c7a898 查询撤销
continuous-integration/drone/push Build is passing
2025-03-18 10:33:43 +08:00
he 11c9cebf47 接口修改
continuous-integration/drone/push Build is passing
2025-03-18 10:08:53 +08:00
he bd9362fb25 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-18 09:43:03 +08:00
he 3aa588f125 修改 2025-03-18 09:43:01 +08:00
hang 6d33a2c1b0 修改角色排序
continuous-integration/drone/push Build is passing
2025-03-18 09:33:38 +08:00
he 9e4cf1d1db 修改
continuous-integration/drone/push Build is passing
2025-03-17 16:44:43 +08:00
he ae38c84ef7 修改
continuous-integration/drone/push Build is passing
2025-03-17 16:30:27 +08:00
he 6306c6752a 修改
continuous-integration/drone/push Build is passing
2025-03-17 16:23:38 +08:00
he 5490630922 修改
continuous-integration/drone/push Build is passing
2025-03-17 15:31:53 +08:00
he d1ea886e76 修改排序
continuous-integration/drone/push Build is passing
2025-03-17 14:48:16 +08:00
he 7dc1205bb6 修改
continuous-integration/drone/push Build is passing
2025-03-17 14:14:01 +08:00
he 15b094a422 修改
continuous-integration/drone/push Build is passing
2025-03-17 13:52:23 +08:00
he 78c46572a2 修改路径
continuous-integration/drone/push Build is passing
2025-03-17 11:21:56 +08:00
he abeda7820d 修改文件路径
continuous-integration/drone/push Build is passing
2025-03-17 10:50:21 +08:00
he 2dac67618c 修改
continuous-integration/drone/push Build is passing
2025-03-14 17:10:22 +08:00
he bb9b1283bf 修改
continuous-integration/drone/push Build is passing
2025-03-14 16:47:39 +08:00
he b9458ecb38 修改
continuous-integration/drone/push Build is passing
2025-03-14 16:12:42 +08:00
he b205757f8f 修改
continuous-integration/drone/push Build is passing
2025-03-14 16:01:41 +08:00
he 0b937663ff 修改
continuous-integration/drone/push Build is passing
2025-03-14 15:11:21 +08:00
he 7a75d107dc 修改
continuous-integration/drone/push Build is passing
2025-03-14 14:50:12 +08:00
he 0f682dd184 修改
continuous-integration/drone/push Build is passing
2025-03-14 14:40:14 +08:00
he c2360dd519 修改
continuous-integration/drone/push Build is passing
2025-03-14 14:25:02 +08:00
he f9c2ac030a 修改
continuous-integration/drone/push Build is passing
2025-03-14 13:29:01 +08:00
he 7ce2386aea 修改
continuous-integration/drone/push Build is passing
2025-03-14 12:52:14 +08:00
he 67b226ee44 修改
continuous-integration/drone/push Build is passing
2025-03-14 11:45:20 +08:00
he 70c7f8a740 查询修改
continuous-integration/drone/push Build is passing
2025-03-14 10:20:55 +08:00
he e409aa3c05 修改
continuous-integration/drone/push Build is passing
2025-03-13 16:59:47 +08:00
he a3b5129ee2 修改
continuous-integration/drone/push Build is passing
2025-03-13 16:43:19 +08:00
he 57cd0281fa 查询条件修改
continuous-integration/drone/push Build is passing
2025-03-13 16:33:53 +08:00
he ba9d3abc52 修改
continuous-integration/drone/push Build is passing
2025-03-13 16:16:30 +08:00
he b9bc1f6da0 入项记录上传与修改
continuous-integration/drone/push Build is passing
2025-03-13 15:43:53 +08:00
he 08f1998e61 修改
continuous-integration/drone/push Build is passing
2025-03-13 15:22:40 +08:00
he bc19ead2f5 添加optuserType
continuous-integration/drone/push Build is passing
2025-03-13 14:36:37 +08:00
he f9327c56db Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-13 10:42:59 +08:00
he 17f3d821ea 修改 2025-03-13 10:42:57 +08:00
hang 02f3e97654 修改质控看到的列表
continuous-integration/drone/push Build is passing
2025-03-12 18:05:34 +08:00
he 94bba7837c 国际化修改
continuous-integration/drone/push Build is passing
2025-03-12 11:12:35 +08:00
he 626fcb9cf3 修改
continuous-integration/drone/push Build is passing
2025-03-12 09:37:36 +08:00
he bf92165432 修改
continuous-integration/drone/push Build is running
2025-03-12 09:36:55 +08:00
he 92e99edbbd 修改项目稽查
continuous-integration/drone/push Build is passing
2025-03-11 16:59:34 +08:00
he 94507c7887 修改稽查
continuous-integration/drone/push Build is passing
2025-03-11 16:41:36 +08:00
he 0cce75befa Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-11 16:36:34 +08:00
he 96469c28d3 修改 2025-03-11 16:36:33 +08:00
hang a12db2637e Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-11 15:37:18 +08:00
hang 0a406da3a4 修改过滤 2025-03-11 15:37:14 +08:00
he 6271dd4144 修改中心排序
continuous-integration/drone/push Build is passing
2025-03-11 15:12:57 +08:00
he 4182809657 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-10 17:40:03 +08:00
he ab6ec064fa 修改重复验证的问题 2025-03-10 17:40:03 +08:00
hang d921a48a09 阿里云返回oss 预览地址
continuous-integration/drone/push Build is passing
2025-03-10 17:35:30 +08:00
he 0f03dbc75b 修改
continuous-integration/drone/push Build is passing
2025-03-10 14:45:03 +08:00
he e5fa3a09b3 修改查询
continuous-integration/drone/push Build is passing
2025-03-10 14:17:22 +08:00
he 4cdfb60fdf 添加阅片人接口
continuous-integration/drone/push Build is passing
2025-03-10 13:46:12 +08:00
he 200bdaccc4 修改
continuous-integration/drone/push Build is passing
2025-03-10 11:38:10 +08:00
he 17a35e0fdb 修改
continuous-integration/drone/push Build is passing
2025-03-10 11:13:43 +08:00
he 28f2bf1629 修改
continuous-integration/drone/push Build is passing
2025-03-10 11:06:53 +08:00
he bec04ab795 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-10 10:56:12 +08:00
he 54cefab633 修改 2025-03-10 10:56:07 +08:00
hang 2918c0e93f 文件级别设置阅片过滤删除
continuous-integration/drone/push Build is passing
2025-03-07 15:54:05 +08:00
hang 92c495ed07 非dicom 预览阅片
continuous-integration/drone/push Build is passing
2025-03-07 15:41:46 +08:00
hang d9d807e3d1 修改dicom 只有一个序列设置删除 检查被过滤
continuous-integration/drone/push Build is passing
2025-03-07 10:35:18 +08:00
hang 959b49a2cc 非dicom 预览阅片影像 过滤是否阅片
continuous-integration/drone/push Build is passing
2025-03-06 16:46:17 +08:00
hang 17f131cf63 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-06 15:48:11 +08:00
hang 4ef67beafc 修改非dicom 过滤文件是否阅片,是否删除 2025-03-06 15:48:10 +08:00
he 826a04ef31 修改
continuous-integration/drone/push Build is passing
2025-03-06 14:38:12 +08:00
he 104b1208ed 修改
continuous-integration/drone/push Build is passing
2025-03-06 14:34:47 +08:00
he 8b3040c24d Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-06 13:12:10 +08:00
he 153dbd2016 添加排序 2025-03-06 13:12:09 +08:00
hang 91d5cbce16 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-06 11:06:25 +08:00
hang 7218427ec2 用户参与项目,返回授权 和禁用时间 2025-03-06 11:06:24 +08:00
he 5d91ae8157 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-06 10:47:56 +08:00
he 0f61d746e5 修改 2025-03-06 10:47:54 +08:00
hang e931e740e6 非dicom 文件修改列表预览可以查看删除
continuous-integration/drone/push Build is passing
2025-03-05 15:57:03 +08:00
hang 38917e05ab Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-05 15:21:05 +08:00
hang dd33f7e086 修改忽略过滤器 2025-03-05 15:21:04 +08:00
he 43d4d679b5 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-05 13:13:39 +08:00
he e02fa28cd0 修改非Dicom排序 2025-03-05 13:13:37 +08:00
he 055e085d2a 修改非Dicom排序
continuous-integration/drone/push Build is passing
2025-03-05 13:12:48 +08:00
he caf1fb6b32 修改
continuous-integration/drone/push Build is passing
2025-03-05 11:41:36 +08:00
he 6b049e68cd Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-05 11:24:53 +08:00
he 2a4360cc64 修改数据库结构 2025-03-05 11:24:50 +08:00
hang 8efc254f3c Merge branch 'Uat_IRC_Net8' into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-05 10:43:11 +08:00
hang f89b3daf50 qc 序列层级返回更新时间
continuous-integration/drone/push Build is passing
2025-03-05 10:42:58 +08:00
hang 29f6196698 合并
continuous-integration/drone/push Build is passing
2025-03-05 09:47:41 +08:00
hang 09ff2468e9 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-05 09:44:36 +08:00
hang 1867277e1b 修改非dicom 检查编号重复问题 2025-03-05 09:44:34 +08:00
he 053a09a5b2 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-05 09:40:03 +08:00
he fae86f0836 修改非dicom 影像 排序 先按检查时间,再按创建时间排序 2025-03-05 09:39:45 +08:00
he 2e539dfa71 修改非dicom 影像 排序 先按检查时间,再按创建时间排序
continuous-integration/drone/push Build is passing
2025-03-05 09:31:37 +08:00
he a9efd85aec 修改
continuous-integration/drone/push Build is passing
2025-03-04 17:58:33 +08:00
he 09e70b9f21 修改
continuous-integration/drone/push Build is passing
2025-03-04 17:48:33 +08:00
he 2d184e0f08 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-04 16:39:44 +08:00
he 43d6c7d8db 查询条件修改 2025-03-04 16:39:42 +08:00
hang 19487acc64 Merge branch 'Uat_IRC_Net8' into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-04 15:20:27 +08:00
hang 336e7768b8 时间拼写错误
continuous-integration/drone/push Build is passing
2025-03-04 15:20:06 +08:00
hang 9b49dc41c8 Merge branch 'Uat_IRC_Net8' into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-04 11:20:51 +08:00
hang 74f896cf00 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2025-03-04 11:20:22 +08:00
hang 10b0bde1d0 检查列表增加时间 2025-03-04 11:20:21 +08:00
he 411b5d5f8f 培训记录修改
continuous-integration/drone/push Build is passing
2025-03-04 10:45:29 +08:00
he b6da27ac07 修改
continuous-integration/drone/push Build is passing
2025-03-03 17:20:38 +08:00
he a6b81b038f 修改
continuous-integration/drone/push Build is passing
2025-03-03 16:49:43 +08:00
he e2c80babfa 修改
continuous-integration/drone/push Build is passing
2025-03-03 16:34:58 +08:00
he 01b9f28e7b 批量添加
continuous-integration/drone/push Build is passing
2025-03-03 16:08:50 +08:00
he 2c9fad60fb 修改
continuous-integration/drone/push Build is passing
2025-03-03 16:03:04 +08:00
he 398baea876 字段修改
continuous-integration/drone/push Build is passing
2025-03-03 13:56:01 +08:00
he aec94d0a46 数据库修改
continuous-integration/drone/push Build is passing
2025-03-03 13:43:34 +08:00
he 4b69e45d44 实体修改
continuous-integration/drone/push Build is passing
2025-03-03 13:18:11 +08:00
he 12f2c2becb 修改
continuous-integration/drone/push Build is passing
2025-03-03 11:06:44 +08:00
he 699f79278b 修改
continuous-integration/drone/push Build is passing
2025-02-28 17:55:45 +08:00
he 88e07d28fd Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-28 16:35:03 +08:00
he 226ba06bf3 修改 2025-02-28 16:35:02 +08:00
hang c1667fc48b Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-28 11:29:15 +08:00
hang f900e675da 清理项目删除项目参与用户 2025-02-28 11:29:14 +08:00
he ee51b9eade 添加 ImageFormatList
continuous-integration/drone/push Build is passing
2025-02-27 17:19:53 +08:00
he bf62ee92dd 添加 ImageFormatList
continuous-integration/drone/push Build is passing
2025-02-27 17:19:35 +08:00
he 78532803bc 影像质疑超限天数修改
continuous-integration/drone/push Build is passing
2025-02-27 17:12:28 +08:00
he 86ea3ebc32 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-27 17:12:01 +08:00
he 01aba3f3e0 影像质疑超限天数修改 2025-02-27 17:11:59 +08:00
hang 6dc1ef5728 增加查询配置
continuous-integration/drone/push Build is passing
2025-02-27 16:15:11 +08:00
hang 02e5d770db 增加查询配置
continuous-integration/drone/push Build is passing
2025-02-27 16:14:46 +08:00
hang f8c3704c87 合并修改
continuous-integration/drone/push Build is passing
2025-02-27 15:39:48 +08:00
hang 4c21459e00 修改StudyName 存放位置
continuous-integration/drone/push Build is passing
2025-02-27 15:38:51 +08:00
he cdbbe460ab 修改实体
continuous-integration/drone/push Build is passing
2025-02-27 14:31:38 +08:00
he 45da1645e0 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-27 14:31:02 +08:00
he 9a1f4697c2 修改实体 2025-02-27 14:31:01 +08:00
hang 217b8713ff 合并到测试环境
continuous-integration/drone/push Build is passing
2025-02-27 13:17:08 +08:00
hang 0998f047e4 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-27 13:05:10 +08:00
hang 47755bc2aa 检查 返回配置字段 2025-02-27 13:05:09 +08:00
he 72efd36649 实体修改
continuous-integration/drone/push Build is running
2025-02-27 13:05:00 +08:00
he 553a8d392f 查询返回检查名称
continuous-integration/drone/push Build is passing
2025-02-27 11:33:31 +08:00
he f050416265 数据库文件
continuous-integration/drone/push Build is passing
2025-02-27 11:21:32 +08:00
he a7d1a92a01 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-27 11:17:15 +08:00
he bf9ce9b213 影像配置数据库字段添加 2025-02-27 11:17:13 +08:00
he a9c7c79fb5 影像配置数据库字段添加
continuous-integration/drone/push Build is passing
2025-02-27 11:16:53 +08:00
hang dc3a830909 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-27 10:49:59 +08:00
hang 171bfde031 质控删除文件 2025-02-27 10:49:58 +08:00
he f471ce1535 修改
continuous-integration/drone/push Build is passing
2025-02-26 13:37:30 +08:00
hang 56170b73ed 修改非dicom 阅片
continuous-integration/drone/push Build is passing
2025-02-26 13:25:56 +08:00
he 2a9c1ec45c Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-26 09:46:28 +08:00
he 3ccb3ff4de 授权修改 2025-02-26 09:46:26 +08:00
hang 6c078806cd 修改token 过期时间
continuous-integration/drone/push Build is passing
2025-02-25 16:36:18 +08:00
hang c2f768bef8 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-25 16:11:49 +08:00
hang 1b7bb5a4fe 修改链接过期+ 删除oss 数据ok 2025-02-25 16:11:47 +08:00
he dfe6d13182 修改
continuous-integration/drone/push Build is passing
2025-02-25 15:51:16 +08:00
he 4c04718db4 修改
continuous-integration/drone/push Build is passing
2025-02-25 15:23:42 +08:00
he 64d803cbc0 修改
continuous-integration/drone/push Build is passing
2025-02-25 15:01:57 +08:00
he 54ccae5762 修改
continuous-integration/drone/push Build is passing
2025-02-25 14:48:05 +08:00
he 8d6bf0c7b1 修改
continuous-integration/drone/push Build is passing
2025-02-25 14:26:21 +08:00
he 8496e6bcd7 修改
continuous-integration/drone/push Build is running
2025-02-25 14:24:44 +08:00
he 7770fc264b Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-25 14:07:26 +08:00
he 51f21805be 非Dicom 2025-02-25 14:07:25 +08:00
hang 434e49ea85 修改用户来源为null bug
continuous-integration/drone/push Build is passing
2025-02-25 11:31:19 +08:00
hang 468f7c7070 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2025-02-25 11:29:52 +08:00
hang 4577db7582 修改bug 2025-02-25 11:29:51 +08:00
he cc17816dae Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-25 11:12:44 +08:00
he 172cecebe4 修改 2025-02-25 11:12:42 +08:00
hang 7913acdf70 修改运维增加字段
continuous-integration/drone/push Build is passing
2025-02-25 11:08:37 +08:00
hang e9f57b5001 临时注释提交,手动维护
continuous-integration/drone/push Build is passing
2025-02-25 11:02:52 +08:00
he b8c0bd7082 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-25 10:38:14 +08:00
he 6200ec1ba7 代码提交 2025-02-25 10:38:11 +08:00
hang 73912fd875 修改列表
continuous-integration/drone/push Build is passing
2025-02-25 10:26:55 +08:00
hang 812035686e 修改用户参与项目接口
continuous-integration/drone/push Build is passing
2025-02-25 09:57:45 +08:00
hang 1f8caa4616 合并
continuous-integration/drone/push Build is passing
2025-02-24 17:21:28 +08:00
hang 4a1e0a87ba 修改管理用户类型过滤 2025-02-24 17:21:09 +08:00
he 337bda45fd 修改
continuous-integration/drone/push Build is passing
2025-02-24 17:17:25 +08:00
he c2412bfb4b 复制系统到项目
continuous-integration/drone/push Build is passing
2025-02-24 16:54:05 +08:00
he cff6b87daa Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-24 16:15:00 +08:00
he 2f93a490f0 查询项目信息 2025-02-24 16:14:59 +08:00
hang 1856ef9483 修改合并
continuous-integration/drone/push Build is passing
2025-02-24 16:09:42 +08:00
hang b45602556c 用户创建来源维护,以及用户参与项目列表修改 2025-02-24 16:07:52 +08:00
he b5326d4928 修改
continuous-integration/drone/push Build is passing
2025-02-24 13:45:55 +08:00
he 8bbc8c449f 合并
continuous-integration/drone/push Build is running
2025-02-24 13:44:57 +08:00
he dcd6375d7d 系统配置 2025-02-24 13:43:22 +08:00
hang 8b53517f2c 角色修改
continuous-integration/drone/push Build is running
2025-02-24 13:43:21 +08:00
hang 1c3ddcf1cd 修改邮箱登录bug
continuous-integration/drone/push Build is passing
2025-02-24 13:32:54 +08:00
hang fc4ef6b939 账号初始化链接过期+初始化不允许忘记密码修改密码
continuous-integration/drone/push Build is passing
2025-02-24 13:24:41 +08:00
hang 6d009c4f86 增加备注
continuous-integration/drone/push Build is passing
2025-02-24 11:32:26 +08:00
hang f995187925 修改文件类型基础代码
continuous-integration/drone/push Build is passing
2025-02-24 11:25:03 +08:00
hang 67a6a5f861 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-21 17:08:35 +08:00
hang 6bfa4da72d 文档服务初步提交 2025-02-21 17:08:33 +08:00
he 9797c94aa8 修改
continuous-integration/drone/push Build is passing
2025-02-21 14:46:10 +08:00
hang 5dd2dfd17b 增加项目文档新表
continuous-integration/drone/push Build is passing
2025-02-21 14:20:39 +08:00
hang 5791aca9fd 最后一次登录时间 和ip 记录
continuous-integration/drone/push Build is passing
2025-02-20 15:26:36 +08:00
hang f61ce70b82 修改项目培训统计数字
continuous-integration/drone/push Build is passing
2025-02-20 15:05:13 +08:00
hang c8091d3215 清理签名文档的表
continuous-integration/drone/push Build is passing
2025-02-20 13:47:09 +08:00
hang 7153d810aa 删除用户角色表部分字段,修改统计
continuous-integration/drone/push Build is passing
2025-02-20 13:08:06 +08:00
hang 68053d24b6 项目创建账户的时候,没有用户名,但是目标用户Id 有值,导致查询出来有名字
continuous-integration/drone/push Build is passing
2025-02-19 14:20:06 +08:00
hang a49b4c8ef7 修改冲突
continuous-integration/drone/push Build is passing
2025-02-19 10:13:37 +08:00
hang c6c036c152 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-19 09:39:21 +08:00
hang db0d087396 修改国际化bug 2025-02-19 09:39:20 +08:00
he 263f43b1a9 项目下拉修改
continuous-integration/drone/push Build is passing
2025-02-18 13:35:22 +08:00
hang 21626cda9d 维护历史退出人员数据
continuous-integration/drone/push Build is passing
2025-02-18 13:15:05 +08:00
he 77d920a2ef Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-18 10:40:31 +08:00
he bbf7af8405 项目筛选修改 2025-02-18 10:40:29 +08:00
hang d0bbc58b20 Merge branch 'Uat_IRC_Net8' into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-17 17:15:44 +08:00
hang fed2cbe043 修改 创建账号仅仅记录一条
continuous-integration/drone/push Build is passing
2025-02-17 17:15:25 +08:00
hang 4d4bb08423 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-17 15:13:02 +08:00
hang dd09c78cd2 项目退出人员维护数据 2025-02-17 15:12:59 +08:00
hang 771091a557 IR 反馈bug 重新设置状态
continuous-integration/drone/push Build is passing
2025-02-17 14:16:34 +08:00
he 8ce1bdf21c Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-17 10:06:06 +08:00
he 679cc26225 状态修改 2025-02-17 10:06:04 +08:00
hang ff5be827d0 Merge branch 'Uat_IRC_Net8' into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-17 09:28:02 +08:00
hang 4555997957 修改文档查询条件问题
continuous-integration/drone/push Build is passing
2025-02-17 09:22:58 +08:00
hang 3b43bee0f1 x
continuous-integration/drone/push Build is passing
2025-02-14 17:30:21 +08:00
hang 3677a30bab 修改日志角色查询
continuous-integration/drone/push Build is passing
2025-02-14 17:19:50 +08:00
hang 2e8b2a24ae 合并冲突
continuous-integration/drone/push Build is passing
2025-02-14 16:51:09 +08:00
hang 26500aa1cf 修改日志
continuous-integration/drone/push Build is passing
2025-02-14 16:48:52 +08:00
hang adfd6b50c1 修改登录日志
continuous-integration/drone/push Build is failing
2025-02-14 16:39:38 +08:00
hang b58bdc184e Merge branch 'Uat_IRC_Net8' into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-14 16:15:37 +08:00
hang 580eea7a61 修改稽查查询条件bug
continuous-integration/drone/push Build is passing
2025-02-14 16:15:21 +08:00
hang da27b65e56 用户登录日志 项目参与用户修改
continuous-integration/drone/push Build is passing
2025-02-14 16:11:48 +08:00
hang bb493fe827 修改日志,和稽查查询 2025-02-14 16:02:49 +08:00
hang 655fe18138 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-14 16:00:48 +08:00
hang 9d70d61013 修改日志,和稽查查询 2025-02-14 16:00:46 +08:00
he 68452beba0 添加是否存在未处理反馈的状态
continuous-integration/drone/push Build is passing
2025-02-14 15:40:34 +08:00
he 409e9e9bc0 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-14 15:18:12 +08:00
he f241f2cd2b 去除掉已经停止的项目 2025-02-14 15:18:10 +08:00
hang 2ea90a66ae Merge branch 'Uat_IRC_Net8' into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-14 14:18:51 +08:00
hang c2c8f65aaa 修改质控问题答案排序
continuous-integration/drone/push Build is passing
2025-02-14 14:07:33 +08:00
hang a578be8336 Merge branch 'Uat_IRC_Net8' into Test_IRC_Net8 2025-02-14 13:27:52 +08:00
hang 45b469682a 影像质控,质控人看到的是过滤了删除的,其他人看到的是原始的
continuous-integration/drone/push Build is passing
2025-02-14 13:09:26 +08:00
hang 1e9f4d890f 质控预览再次修改0214
continuous-integration/drone/push Build is passing
2025-02-14 10:54:00 +08:00
hang 44f74fd9e6 修改 预览根据质控状态过滤
continuous-integration/drone/push Build is passing
2025-02-13 18:01:17 +08:00
hang f1c8415899 修改阅片预览影像(同时标记了删除 和阅片)
continuous-integration/drone/push Build is passing
2025-02-13 17:11:21 +08:00
hang 823ada5673 合并
continuous-integration/drone/push Build is passing
2025-02-13 16:53:27 +08:00
hang 55f146a44a 修改序列上的Instance 数量
continuous-integration/drone/push Build is passing
2025-02-13 16:52:13 +08:00
hang 5fe972bd99 修改质控预览影像 uat 修改
continuous-integration/drone/push Build is passing
2025-02-13 16:43:59 +08:00
hang 0578263e10 修改质控预览影像 uat 修改
continuous-integration/drone/push Build is passing
2025-02-13 16:40:34 +08:00
hang 9316c0814f 合并
continuous-integration/drone/push Build is passing
2025-02-13 16:16:18 +08:00
hang 8bdd9e29ab 修改阅片看到得instance 序列
continuous-integration/drone/push Build is failing
2025-02-13 16:13:52 +08:00
hang ae14a8a530 修改预览不阅片影像数字
continuous-integration/drone/push Build is passing
2025-02-13 15:53:02 +08:00
hang 2a170cc97e 修改预览不阅片影像数字
continuous-integration/drone/push Build is passing
2025-02-13 15:52:44 +08:00
hang c109e14a93 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-13 14:01:02 +08:00
hang 240d406a1a Merge branch 'Uat_IRC_Net8' into Test_IRC_Net8 2025-02-13 14:00:53 +08:00
hang b6cf988058 导表 裁判选择原因bug
continuous-integration/drone/push Build is passing
2025-02-13 14:00:34 +08:00
he c16153fa19 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-13 13:12:11 +08:00
he a0797a99ff 修改 2025-02-13 13:12:09 +08:00
hang 376cfa3167 合并bug
continuous-integration/drone/push Build is passing
2025-02-13 11:06:32 +08:00
hang 14690dc3cc 合并修改
continuous-integration/drone/push Build is passing
2025-02-13 10:59:23 +08:00
hang 6dd0831a66 质控预览 增加是否阅片 是否删除 第二次提交
continuous-integration/drone/push Build is passing
2025-02-13 10:40:18 +08:00
hang a150156810 修改配置文件
continuous-integration/drone/push Build is passing
2025-02-13 10:21:57 +08:00
hang d61fba9d95 Uat 影像阅片初步修改 2025-02-13 10:21:49 +08:00
hang 7cb8d04ca9 Uat 影像阅片初步修改
continuous-integration/drone/push Build is passing
2025-02-13 10:17:01 +08:00
he a2fc2c5075 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-12 16:52:43 +08:00
he 1ed8788c83 修改邮箱 2025-02-12 16:52:39 +08:00
hang 14e95fd303 修改配置文件
continuous-integration/drone/push Build is passing
2025-02-12 14:01:53 +08:00
hang 3dca5aa06f Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-11 15:45:54 +08:00
hang faea3a4f86 肿瘤学阅片结果导出 2025-02-11 15:45:50 +08:00
he a5dcad1767 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-11 14:38:09 +08:00
he 6754121b17 肿瘤学修改 2025-02-11 14:38:07 +08:00
hang 131425774a 修改MFA 日志
continuous-integration/drone/push Build is passing
2025-02-10 15:08:14 +08:00
hang 585e4cdc1b 修改一致性核查对话判断
continuous-integration/drone/push Build is passing
2025-02-10 14:54:04 +08:00
hang 12ddeba2a3 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-10 09:25:38 +08:00
hang ab0c256e0b 修改国际化返回更多信息 2025-02-10 09:25:37 +08:00
hang 8a24b33757 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-08 15:58:17 +08:00
hang 8f6e2e342a 肿瘤评估标准-Id匹配合并去重bug 2025-02-08 15:58:12 +08:00
he 4dfeb653b1 修改逻辑
continuous-integration/drone/push Build is passing
2025-02-08 15:43:11 +08:00
he 670a754eb2 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-08 11:06:54 +08:00
he 3f46103dc3 修改 2025-02-08 11:06:53 +08:00
hang 6c2901daca Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-02-08 10:54:45 +08:00
hang a73e5d4133 增加一致性核查排序 以及一致性核查国际化调整填充公司简称 2025-02-08 10:54:44 +08:00
he b067cb66f3 接口修改
continuous-integration/drone/push Build is running
2025-02-08 10:54:06 +08:00
he f1185758d6 修改领取规则
continuous-integration/drone/push Build is passing
2025-02-08 10:48:00 +08:00
he 0d4a0adf00 添加IsPACSConnect
continuous-integration/drone/push Build is passing
2025-02-08 10:23:22 +08:00
he 20f6f95b89 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2025-02-08 10:20:18 +08:00
he 7e7c186784 临床数据修改 2025-02-08 10:20:15 +08:00
hang 70e0a1325a HIR 推送影像bug 修改到IRC 测试
continuous-integration/drone/push Build is passing
2025-02-08 09:33:29 +08:00
he 91471dee13 修改配置
continuous-integration/drone/push Build is passing
2025-02-07 15:03:14 +08:00
hang a80dc14dcc 修改一致性核查测试
continuous-integration/drone/push Build is passing
2025-01-24 16:26:57 +08:00
hang e1cd187f4b 修改部位排序
continuous-integration/drone/push Build is passing
2025-01-24 15:55:33 +08:00
hang 35fb7533db x
continuous-integration/drone/push Build is passing
2025-01-24 14:30:47 +08:00
hang bdd9b69dfd Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-24 13:43:49 +08:00
hang 82a043a233 修改配置文件 2025-01-24 13:43:48 +08:00
he 66819a1e89 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-24 12:28:56 +08:00
he 9089376e5e 添加美国正式环境 2025-01-24 12:28:54 +08:00
hang 8d3f654fe5 修改生产配置文件
continuous-integration/drone/push Build is passing
2025-01-24 10:30:08 +08:00
hang c607af9736 搜素条件修改
continuous-integration/drone/push Build is passing
2025-01-24 09:52:08 +08:00
hang 0b45c30d0b 修改配置
continuous-integration/drone/push Build is passing
2025-01-23 18:22:51 +08:00
hang 1b7de79209 修改统计数字过滤删除的
continuous-integration/drone/push Build is running
2025-01-23 18:19:50 +08:00
hang 4ffedb4052 修改参与人员退出限制
continuous-integration/drone/push Build is passing
2025-01-23 17:40:05 +08:00
hang d8eb7acf2e 修改登录设置自动退出时间
continuous-integration/drone/push Build is passing
2025-01-23 16:53:18 +08:00
hang 6f3a4d723c 修改配置文件
continuous-integration/drone/push Build is passing
2025-01-23 16:47:42 +08:00
hang 0b2305ae65 修改登录挤账号登录
continuous-integration/drone/push Build is passing
2025-01-23 16:35:02 +08:00
hang e86c255186 修改配置文件
continuous-integration/drone/push Build is passing
2025-01-23 15:40:38 +08:00
hang d8658dca2a 修改美国生产配置文件
continuous-integration/drone/push Build is passing
2025-01-23 14:51:33 +08:00
hang 4372202a5b 修改中心导入数据
continuous-integration/drone/push Build is passing
2025-01-23 14:42:26 +08:00
hang affdc3e229 修改导入数据空格问题
continuous-integration/drone/push Build is passing
2025-01-23 14:37:30 +08:00
hang cfa384d02a 修改文档签署统计数字
continuous-integration/drone/push Build is passing
2025-01-23 12:54:09 +08:00
hang a33b7d606b 修改过滤
continuous-integration/drone/push Build is passing
2025-01-23 11:19:27 +08:00
hang da9ea70e5e Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-23 11:15:22 +08:00
hang 6f254ca958 增加MIM
continuous-integration/drone/push Build is passing
2025-01-23 10:42:29 +08:00
hang da3bd07607 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-23 10:38:41 +08:00
hang 1569010d69 修改内外部筛选 2025-01-23 10:38:39 +08:00
he ea7b3f4f7a Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-23 09:33:35 +08:00
he fc041e810c 修改KeyFramesList 2025-01-23 09:33:33 +08:00
hang ebc00e3e6d 修改文档过滤
continuous-integration/drone/push Build is passing
2025-01-22 16:29:46 +08:00
hang 612c0b127c 修改取账号排序
continuous-integration/drone/push Build is passing
2025-01-22 14:56:00 +08:00
hang a67df04da6 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-22 10:42:14 +08:00
hang 43ae270eb7 修改邮件配置
continuous-integration/drone/push Build is passing
2025-01-22 10:40:43 +08:00
he d41c88beeb 修改配置
continuous-integration/drone/push Build is passing
2025-01-22 10:25:12 +08:00
he 92486d8320 修改导出配置 2025-01-22 10:25:09 +08:00
hang 0d2d3408b5 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-22 10:14:41 +08:00
hang f76b66c35d 修改内外部 2025-01-22 10:14:38 +08:00
he 48a98de7cc 修改配置
continuous-integration/drone/push Build is passing
2025-01-22 09:27:24 +08:00
he 23ba634a42 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2025-01-22 09:25:51 +08:00
he 23d7598722 修改导出配置 2025-01-22 09:25:49 +08:00
hang 7885cd151a 优化逻辑
continuous-integration/drone/push Build is passing
2025-01-21 22:54:23 +08:00
hang fb478aa5f2 修改导表填充测试
continuous-integration/drone/push Build is passing
2025-01-21 22:23:45 +08:00
hang 31f56a39a5 导表临时修改
continuous-integration/drone/push Build is passing
2025-01-21 19:00:01 +08:00
hang 6860f9437b 修改裁判重阅问题
continuous-integration/drone/push Build is passing
2025-01-21 18:29:36 +08:00
hang a06e7a9a2c 维护密码历史日志
continuous-integration/drone/push Build is passing
2025-01-21 15:16:40 +08:00
hang ac8875acdf 修改验证码
continuous-integration/drone/push Build is passing
2025-01-21 11:40:18 +08:00
hang f79c12165e 修改用户密码增加记录
continuous-integration/drone/push Build is passing
2025-01-21 09:16:44 +08:00
hang 91b358e674 修改 前三次密码验证
continuous-integration/drone/push Build is passing
2025-01-20 20:14:44 +08:00
hang 7ec274fb72 修改密码逻辑
continuous-integration/drone/push Build is passing
2025-01-20 19:53:54 +08:00
hang 7d419595ca 修改添加pacs 影像bug
continuous-integration/drone/push Build is passing
2025-01-20 19:39:08 +08:00
hang a6e260dce1 签名文档bug
continuous-integration/drone/push Build is passing
2025-01-20 17:36:37 +08:00
hang 2e9a75279d 修改邮箱修改邮箱验证码错误
continuous-integration/drone/push Build is running
2025-01-20 17:35:25 +08:00
hang 68a57594ff 修改时间
continuous-integration/drone/push Build is passing
2025-01-20 17:23:21 +08:00
hang bd4d6c8c5f 修改退回bug
continuous-integration/drone/push Build is passing
2025-01-20 16:01:05 +08:00
hang a36a0513fe 修改scp 服务地址
continuous-integration/drone/push Build is passing
2025-01-20 15:51:52 +08:00
hang 02e418f660 修改账号日志
continuous-integration/drone/push Build is passing
2025-01-20 15:17:53 +08:00
hang 199f7060fa Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-20 14:53:23 +08:00
hang 9bdb782b8d 修改查看日志 和项目列表过滤
continuous-integration/drone/push Build is passing
2025-01-20 14:52:43 +08:00
he 9b9bbfbd5d Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-20 14:24:50 +08:00
he a9a034923f 删除OSS脏文件夹 2025-01-20 14:24:49 +08:00
hang 07b63077d1 Merge branch 'Uat_IRC_Net8' into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-20 11:34:35 +08:00
hang 013b9720b3 添加中心增加验证
continuous-integration/drone/push Build is passing
2025-01-20 11:33:48 +08:00
hang f924b4985a Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-20 11:27:40 +08:00
hang 40b986e310 修改默认值 和账号已过期 2025-01-20 11:27:39 +08:00
he 146b0635c8 修改默认值
continuous-integration/drone/push Build is passing
2025-01-20 11:22:53 +08:00
he e76a5d189e Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-20 11:17:26 +08:00
he 6f81c39c62 全局阅片 默认值改为false 2025-01-20 11:17:24 +08:00
hang 036565ec81 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-20 11:12:09 +08:00
hang a2225d7cba 修改发放token
continuous-integration/drone/push Build is passing
2025-01-20 11:09:55 +08:00
hang 3463b69b78 修改邮件 多了IR
continuous-integration/drone/push Build is passing
2025-01-20 10:44:27 +08:00
Hewt bf61a05e45 修改查询问题
continuous-integration/drone/push Build is passing
2025-01-18 23:03:58 +08:00
Hewt d930d51d0d 修改查询问题
continuous-integration/drone/push Build is passing
2025-01-18 22:55:22 +08:00
hang 629fbfb037 修改邮件
continuous-integration/drone/push Build is passing
2025-01-17 15:23:46 +08:00
hang 2255ee1b03 维护数据不要权限
continuous-integration/drone/push Build is passing
2025-01-17 14:10:19 +08:00
hang 5d269b699c Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-17 13:58:42 +08:00
hang 7b7723426b 修改统计数字
continuous-integration/drone/push Build is passing
2025-01-17 10:17:15 +08:00
hang 07f1511bb9 修改导入表
continuous-integration/drone/push Build is passing
2025-01-16 17:48:39 +08:00
hang 36f0e20340 修改备注
continuous-integration/drone/push Build is passing
2025-01-16 16:51:58 +08:00
hang 63919c8f6b 修改维护方法
continuous-integration/drone/push Build is passing
2025-01-16 15:13:58 +08:00
he 77798e929e Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-16 15:06:52 +08:00
he f407c5f514 稽查修改 2025-01-16 15:06:50 +08:00
hang e66df9bbc9 修改登录记录异地登录
continuous-integration/drone/push Build is passing
2025-01-16 13:31:14 +08:00
hang 38fe5aea25 修改枚举值
continuous-integration/drone/push Build is passing
2025-01-16 13:19:36 +08:00
hang 2d792b4557 修改用户登录
continuous-integration/drone/push Build is passing
2025-01-16 12:26:26 +08:00
hang 5222cdb8f1 屏幕解锁+ 密码错误 也异地登录
continuous-integration/drone/push Build is passing
2025-01-16 11:47:24 +08:00
hang 453d3f7653 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-16 11:22:40 +08:00
hang dca0dfb003 修改裁判阅片明细表过滤 2025-01-16 11:22:39 +08:00
he 2d1e2f53ee Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-16 11:12:57 +08:00
he 82167463e4 修改登录状态 2025-01-16 11:12:55 +08:00
hang e46f204204 非肿瘤评估标准,多表格 和单表格处理
continuous-integration/drone/push Build is passing
2025-01-16 08:59:21 +08:00
hang 9d6cdd5711 修改导表配置完成
continuous-integration/drone/push Build is passing
2025-01-15 22:48:54 +08:00
hang fc70ec7ad0 修改导表bug
continuous-integration/drone/push Build is passing
2025-01-15 22:39:20 +08:00
hang 68845ae44b 临时提交
continuous-integration/drone/push Build is passing
2025-01-15 21:09:06 +08:00
hang 5570c56b1e 修改导表 Excel 列名处理
continuous-integration/drone/push Build is passing
2025-01-15 12:54:58 +08:00
hang 2fdd7bf464 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-15 11:13:26 +08:00
hang 24c259a38b 修改导表 2025-01-15 11:13:24 +08:00
he f4a97b940a Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-15 10:57:03 +08:00
he 0f74444b22 修改 2025-01-15 10:57:02 +08:00
hang cf9d42dc49 修改翻译字典名
continuous-integration/drone/push Build is passing
2025-01-15 10:15:36 +08:00
hang f518b44007 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-14 15:50:13 +08:00
hang 95a203881e 修改1.1 导表配置 2025-01-14 15:50:12 +08:00
he b86361bf0e 修改
continuous-integration/drone/push Build is passing
2025-01-14 14:55:24 +08:00
he 5c97f37a75 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-14 13:20:54 +08:00
he 307d982fcb 删除项目 2025-01-14 13:20:52 +08:00
hang 3d791d2e41 修改阅片结果导出
continuous-integration/drone/push Build is passing
2025-01-14 10:45:12 +08:00
hang 538cfa279a 修改维护数据
continuous-integration/drone/push Build is passing
2025-01-13 16:55:04 +08:00
hang 3f2315c96d 异地登录修改
continuous-integration/drone/push Build is passing
2025-01-13 16:07:12 +08:00
he 293933ec7d 修改
continuous-integration/drone/push Build is passing
2025-01-13 15:35:53 +08:00
he 97d3b986de Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-13 15:22:55 +08:00
he f8fea6561d 修改 2025-01-13 15:22:54 +08:00
hang dfa8474a6e 修改导表
continuous-integration/drone/push Build is passing
2025-01-13 15:20:53 +08:00
he e022eb058b 修改
continuous-integration/drone/push Build is passing
2025-01-13 15:15:36 +08:00
he d04b425d62 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-13 14:56:16 +08:00
he c1fdf67d39 修改 2025-01-13 14:56:14 +08:00
hang dd902c1355 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-13 14:28:03 +08:00
hang b21b122d24 修改导表 2025-01-13 14:28:02 +08:00
he 7544bc81a3 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-13 13:51:38 +08:00
he aab998d5c6 修改 2025-01-13 13:51:37 +08:00
hang 3dc5507b6b 参与人员导表
continuous-integration/drone/push Build is passing
2025-01-13 13:08:28 +08:00
hang 12fbc2643c 修改角色停用,签名文档问题
continuous-integration/drone/push Build is passing
2025-01-13 11:46:26 +08:00
hang b14e712126 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-13 11:39:40 +08:00
hang c303f6677b 修改国际化和导表 2025-01-13 11:39:31 +08:00
he 1976cd8cdd 去掉ExportIdentification
continuous-integration/drone/push Build is passing
2025-01-13 11:25:14 +08:00
he cc6d5d2b4f 修改
continuous-integration/drone/push Build is passing
2025-01-10 15:41:32 +08:00
he b72edbf326 修改稽查
continuous-integration/drone/push Build is passing
2025-01-10 15:03:53 +08:00
he b0b23593f6 代码修改
continuous-integration/drone/push Build is passing
2025-01-10 14:54:31 +08:00
he 941eee9857 修改
continuous-integration/drone/push Build is passing
2025-01-10 14:38:48 +08:00
he 8f8751103e 修改
continuous-integration/drone/push Build is passing
2025-01-10 14:31:57 +08:00
he c575e15c55 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-10 14:17:50 +08:00
he 56afa2bf8d 修改 2025-01-10 14:17:48 +08:00
hang 2e993149a9 修改默认配置文件
continuous-integration/drone/push Build is passing
2025-01-10 14:06:51 +08:00
hang 89421ee731 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2025-01-10 14:05:10 +08:00
hang 2509e26aae 修改角色禁用 2025-01-10 14:05:05 +08:00
he db7e9b90ec 添加 SplitAndConcatenate 方法处理 IP 地址字符串 2025-01-10 10:29:56 +08:00
he 9827b22b6f 修改验证
continuous-integration/drone/push Build is passing
2025-01-10 10:09:53 +08:00
he 9636efcb56 修改标记
continuous-integration/drone/push Build is passing
2025-01-10 09:14:18 +08:00
he 06d8e4bea8 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-09 17:12:05 +08:00
he 5111372972 修改 2025-01-09 17:12:03 +08:00
hang 4cdf94d29c Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-09 16:20:40 +08:00
hang 5bacf2667f 修改最晚拍片日期 2025-01-09 16:20:39 +08:00
he 81cb833d57 修改
continuous-integration/drone/push Build is passing
2025-01-09 15:47:49 +08:00
he 53e96811ce 修改
continuous-integration/drone/push Build is running
2025-01-09 15:46:27 +08:00
he 7b52c0b785 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-09 15:34:54 +08:00
he 9362d29fae 添加重复验证 2025-01-09 15:34:53 +08:00
hang 212268cfa5 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-09 15:23:31 +08:00
hang 862da87a0c 修改用户日志 2025-01-09 15:23:28 +08:00
he 0dae3c000c 首次添加病灶
continuous-integration/drone/push Build is passing
2025-01-09 15:06:54 +08:00
he 55ea791387 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2025-01-09 15:05:11 +08:00
he 3a62189503 稽查修改 2025-01-09 15:05:10 +08:00
hang d3396d9683 修改导表错位
continuous-integration/drone/push Build is passing
2025-01-09 13:59:23 +08:00
hang 7672c9ab85 修改导表
continuous-integration/drone/push Build is passing
2025-01-09 13:19:18 +08:00
he afbc43b83f 修改
continuous-integration/drone/push Build is passing
2025-01-09 11:22:53 +08:00
he 4613f98154 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-09 11:11:33 +08:00
he 52f34d70b7 提交 2025-01-09 11:11:33 +08:00
hang 02d378e0e6 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-09 11:06:47 +08:00
hang c29bb8e1a3 发布版本 2025-01-09 11:06:46 +08:00
he 1eaa56bb2a Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-09 11:01:28 +08:00
he 54cdd14889 稽查修改 2025-01-09 11:01:26 +08:00
hang 01c253952b 修改医生bug
continuous-integration/drone/push Build is passing
2025-01-09 09:47:28 +08:00
hang 060be72143 打出日志
continuous-integration/drone/push Build is passing
2025-01-09 09:41:34 +08:00
hang f5032b95ce Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-09 09:27:35 +08:00
hang 8fce9f4bf2 修改阅片人 产生用户名 2025-01-09 09:27:34 +08:00
he 857e7c5523 修改
continuous-integration/drone/push Build is passing
2025-01-08 17:49:40 +08:00
he 67dbf7c701 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-08 17:09:18 +08:00
he 17fd46c2dc 计算修改 2025-01-08 17:09:17 +08:00
hang 75b3a60ca6 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-08 16:09:54 +08:00
hang f499a9b803 修改培训导表 2025-01-08 16:09:52 +08:00
he c87c724685 修改计算
continuous-integration/drone/push Build is passing
2025-01-08 16:02:45 +08:00
he 36ea9f526e 修改
continuous-integration/drone/push Build is passing
2025-01-08 14:43:10 +08:00
he e5bf8c4c8c 修改
continuous-integration/drone/push Build is passing
2025-01-08 13:49:28 +08:00
he 60a5cc4602 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-08 13:39:41 +08:00
he c376fe1d22 计算修改 2025-01-08 13:39:39 +08:00
hang 8111b60d4f 修改参与人员导表
continuous-integration/drone/push Build is passing
2025-01-08 13:22:24 +08:00
hang 86c871bc9f Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-08 11:32:25 +08:00
hang a21cca53f8 修改文档返回状态 2025-01-08 11:32:24 +08:00
he 4a03467968 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-08 10:48:37 +08:00
he f6151b7ce1 计算修改 2025-01-08 10:48:37 +08:00
hang cbfc2f9538 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-08 10:37:06 +08:00
hang 35ca08ee04 CMM SMM 阅片人筛选 2025-01-08 10:37:04 +08:00
he 0781496c69 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2025-01-08 10:36:47 +08:00
he 0cca369eaa 修改 2025-01-08 10:36:46 +08:00
hang 62fafeb7d2 添加用户 重新发送邮件
continuous-integration/drone/push Build is passing
2025-01-08 09:50:25 +08:00
hang f513829c94 修改统计数字
continuous-integration/drone/push Build is passing
2025-01-07 18:04:14 +08:00
hang bbb3a41293 中心人员添加
continuous-integration/drone/push Build is passing
2025-01-07 15:26:30 +08:00
hang e966779cc8 修改中心调研发现的bug
continuous-integration/drone/push Build is passing
2025-01-07 14:25:50 +08:00
hang bcc576dfd1 修改映射
continuous-integration/drone/push Build is passing
2025-01-07 11:40:26 +08:00
hang dac9453048 修改查询
continuous-integration/drone/push Build is passing
2025-01-07 11:31:31 +08:00
hang faf5430248 修改返回真实名字
continuous-integration/drone/push Build is passing
2025-01-07 10:51:52 +08:00
hang 561e1748d6 修改部位
continuous-integration/drone/push Build is running
2025-01-07 10:49:40 +08:00
hang 83749e15cb CDISC_Reading_Export
continuous-integration/drone/push Build is passing
2025-01-07 10:34:19 +08:00
hang 1a64c07c8e 导表准备
continuous-integration/drone/push Build is passing
2025-01-06 17:58:17 +08:00
hang 6ead8ffd53 修改配置临时提交
continuous-integration/drone/push Build is passing
2025-01-06 17:29:53 +08:00
hang 1676516441 修改返回的配置
continuous-integration/drone/push Build is passing
2025-01-06 16:41:33 +08:00
hang c97186a557 修改废除文档签署数字
continuous-integration/drone/push Build is passing
2025-01-06 16:05:02 +08:00
he 59f88175b4 修改枚举
continuous-integration/drone/push Build is passing
2025-01-06 15:40:07 +08:00
he 77b45e80fe 合并
continuous-integration/drone/push Build is passing
2025-01-06 15:17:55 +08:00
he 2b9272c495 修改 2025-01-06 14:28:23 +08:00
hang 5dae08d9c0 修改列表过滤
continuous-integration/drone/push Build is passing
2025-01-06 13:59:04 +08:00
hang 653533020f 修改文档签署
continuous-integration/drone/push Build is passing
2025-01-06 13:23:49 +08:00
hang 5a12879182 修改签名
continuous-integration/drone/push Build is passing
2025-01-06 13:14:38 +08:00
hang 8132f9a2ea x
continuous-integration/drone/push Build is passing
2025-01-06 13:07:33 +08:00
hang 293865fc3f 修改稽查
continuous-integration/drone/push Build is passing
2025-01-06 11:41:54 +08:00
hang cfbe3d2589 检查部位智能处理
continuous-integration/drone/push Build is passing
2025-01-06 10:05:10 +08:00
hang 69151bbddb 修改查询
continuous-integration/drone/push Build is passing
2025-01-03 17:58:33 +08:00
hang 5faf1a5442 修改筛选忽略过滤器
continuous-integration/drone/push Build is passing
2025-01-03 17:42:19 +08:00
hang 25648a8a69 修改启用禁用查询
continuous-integration/drone/push Build is passing
2025-01-03 17:16:13 +08:00
hang 522d619ee8 xx
continuous-integration/drone/push Build is passing
2025-01-03 16:56:58 +08:00
hang 4a901085d8 x
continuous-integration/drone/push Build is passing
2025-01-03 16:49:40 +08:00
hang 49d60f6f68 修改测试
continuous-integration/drone/push Build is running
2025-01-03 16:47:27 +08:00
hang 73b8cfe723 修改系统角色状态
continuous-integration/drone/push Build is passing
2025-01-03 16:34:43 +08:00
hang 05a4de1464 项目参与用户修改
continuous-integration/drone/push Build is passing
2025-01-03 16:29:11 +08:00
hang 9002d850a5 遗漏了else
continuous-integration/drone/push Build is passing
2025-01-03 15:22:18 +08:00
hang 23cfe72d40 裁判未分配导致没有被影响到bug 修复测试
continuous-integration/drone/push Build is passing
2025-01-03 15:16:39 +08:00
hang 8303f9faae spm 逻辑修改
continuous-integration/drone/push Build is passing
2025-01-03 15:09:56 +08:00
hang 517c799e00 设置重阅
continuous-integration/drone/push Build is passing
2025-01-03 14:30:01 +08:00
hang 69f5b54919 修改SPM 逻辑
continuous-integration/drone/push Build is passing
2025-01-03 13:38:28 +08:00
hang 5c0d30d2bc 修改文档签署
continuous-integration/drone/push Build is passing
2025-01-03 13:32:49 +08:00
hang c62086f8e8 撤回修改
continuous-integration/drone/push Build is passing
2025-01-03 13:20:22 +08:00
hang 2dfcedfe3c 修改签署文档
continuous-integration/drone/push Build is passing
2025-01-03 13:17:49 +08:00
hang 77180ea7ba xx
continuous-integration/drone/push Build is passing
2025-01-03 11:50:25 +08:00
hang 8656ed09bb 修改PM 申审批
continuous-integration/drone/push Build is passing
2025-01-03 10:52:34 +08:00
hang 7cdfce354c xx
continuous-integration/drone/push Build is passing
2025-01-03 10:29:05 +08:00
hang 2ac7af44b9 修改mfa 登录
continuous-integration/drone/push Build is running
2025-01-03 10:27:12 +08:00
hang a0b18bbf72 修改登录mfa
continuous-integration/drone/push Build is passing
2025-01-03 09:50:18 +08:00
hang 6713a9c8e2 修改mfa 验证
continuous-integration/drone/push Build is passing
2025-01-03 09:38:24 +08:00
hang ecfc603dda 修改mfa 登录
continuous-integration/drone/push Build is passing
2025-01-03 09:34:59 +08:00
hang 55db1a2eab 修改发送邮件人员判断
continuous-integration/drone/push Build is passing
2025-01-02 17:33:42 +08:00
hang f117fbb571 邮件发送
continuous-integration/drone/push Build is passing
2025-01-02 17:20:13 +08:00
he 5a1687b45f Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-02 16:58:51 +08:00
he d31e560a6b 接口名称修改 2025-01-02 16:58:50 +08:00
hang de4bf6951f 管理员重置密码修改
continuous-integration/drone/push Build is running
2025-01-02 16:55:01 +08:00
hang f034d9ca87 MFA 登录修改
continuous-integration/drone/push Build is running
2025-01-02 16:53:54 +08:00
hang f62e849f80 忘记密码记录日志
continuous-integration/drone/push Build is passing
2025-01-02 16:47:13 +08:00
hang 055537ddbb 修改账号禁用日志
continuous-integration/drone/push Build is passing
2025-01-02 16:28:24 +08:00
hang 13efa0f1d3 修改创建账号日志
continuous-integration/drone/push Build is passing
2025-01-02 16:17:09 +08:00
he 901438a4a7 修改
continuous-integration/drone/push Build is passing
2025-01-02 15:37:34 +08:00
he 7b26af01b1 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-02 15:32:08 +08:00
he de0534c3a1 代码修改 2025-01-02 15:32:07 +08:00
hang 1f490138a0 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-02 15:23:52 +08:00
hang ed3d0421db 增加信息验证 2025-01-02 15:23:49 +08:00
he b83e42d788 代码导出配置修改
continuous-integration/drone/push Build is passing
2025-01-02 15:06:09 +08:00
he 141fbc2e75 代码修改
continuous-integration/drone/push Build is running
2025-01-02 15:03:26 +08:00
he 2e7cbbb8b0 修改
continuous-integration/drone/push Build is passing
2025-01-02 14:41:09 +08:00
he 461a59b678 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2025-01-02 14:18:15 +08:00
he 774680ced0 代码修改 2025-01-02 14:18:13 +08:00
hang 8a26c42857 修改批量增加到中心
continuous-integration/drone/push Build is passing
2025-01-02 13:20:55 +08:00
hang 25a91904b8 加人软删除逻辑有问题
continuous-integration/drone/push Build is passing
2025-01-02 13:09:21 +08:00
hang 1fa94b95f0 修改用户类型展示
continuous-integration/drone/push Build is passing
2025-01-02 11:26:18 +08:00
hang 52efdc28e4 修改映射
continuous-integration/drone/push Build is passing
2025-01-02 11:19:17 +08:00
hang 678599f218 修改创建角色设置id
continuous-integration/drone/push Build is passing
2025-01-02 10:48:07 +08:00
hang ba49164db6 修改登录中心调研表
continuous-integration/drone/push Build is passing
2024-12-31 17:49:45 +08:00
hang 6089fef0a8 修改邮件内容 首次登录区分用户名
continuous-integration/drone/push Build is passing
2024-12-31 17:27:44 +08:00
hang 8b3dd419b7 修改筛选用户角色启用
continuous-integration/drone/push Build is passing
2024-12-31 16:49:17 +08:00
hang 86236e865e 外部人员bug
continuous-integration/drone/push Build is passing
2024-12-31 16:44:31 +08:00
hang e696873025 修改状态
continuous-integration/drone/push Build is passing
2024-12-31 15:50:41 +08:00
hang e4c602095f 修改bug
continuous-integration/drone/push Build is passing
2024-12-31 15:44:09 +08:00
hang be1f8dfad9 记录日志
continuous-integration/drone/push Build is passing
2024-12-31 14:00:07 +08:00
hang 9571775343 修改启用项目参与人员的状态
continuous-integration/drone/push Build is passing
2024-12-31 13:37:22 +08:00
hang 518ed694fb 修改添加人员
continuous-integration/drone/push Build is passing
2024-12-31 13:28:14 +08:00
hang bf2b439ce1 修改账号角色禁用
continuous-integration/drone/push Build is passing
2024-12-31 13:12:39 +08:00
hang bfed24028a 修改邮件发送
continuous-integration/drone/push Build is passing
2024-12-31 11:18:44 +08:00
hang da570f8c5a 修改加入人员逻辑
continuous-integration/drone/push Build is passing
2024-12-31 10:41:12 +08:00
hang 99fa476b80 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-31 10:35:05 +08:00
hang e0ee9abd61 修改内部人员退出 2024-12-31 10:35:03 +08:00
he 4696951923 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-31 10:23:36 +08:00
he ea0209f20d 代码修改 2024-12-31 10:23:36 +08:00
hang 28a56ee298 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-31 10:19:26 +08:00
hang 2691da82ae 修改内部人员 查询列表接口 2024-12-31 10:19:25 +08:00
he c5519976ee Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-31 10:09:24 +08:00
he bc079d3586 导出修改 2024-12-31 10:09:23 +08:00
hang a8ec762a7d 修改项目参与人员列表
continuous-integration/drone/push Build is passing
2024-12-31 10:03:11 +08:00
hang 2b6ae95160 医生生成账号修改
continuous-integration/drone/push Build is passing
2024-12-31 09:42:24 +08:00
hang c9c38b5053 用户角色签名修改
continuous-integration/drone/push Build is passing
2024-12-31 09:26:05 +08:00
hang f97df34b65 文档列表查询修改
continuous-integration/drone/push Build is passing
2024-12-30 21:39:58 +08:00
hang aec6757748 修改查询
continuous-integration/drone/push Build is passing
2024-12-30 19:53:02 +08:00
hang 33c27cccc2 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-30 18:24:24 +08:00
hang a449013c5d 项目文档修改临时提交 2024-12-30 18:24:21 +08:00
he b0b3744cb1 添加defaultValue
continuous-integration/drone/push Build is passing
2024-12-30 16:01:59 +08:00
he b2ba48ea90 修改
continuous-integration/drone/push Build is passing
2024-12-30 15:41:47 +08:00
he 8a20051436 修改计算
continuous-integration/drone/push Build is passing
2024-12-30 14:53:57 +08:00
he eedfa4b84d Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-30 14:24:34 +08:00
he 4403a09e79 修改 2024-12-30 14:24:33 +08:00
hang 12fb19c47c Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-30 14:08:11 +08:00
hang 14c62a8852 修改项目参与人员判断 2024-12-30 14:08:08 +08:00
he 2c818b9caa Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-30 13:59:56 +08:00
he db8f587e93 修改 2024-12-30 13:59:55 +08:00
hang 260be98cef 修改登录日志查询接口
continuous-integration/drone/push Build is passing
2024-12-30 13:26:08 +08:00
hang b42bf4e201 修改日志,以及添加项目参与人员
continuous-integration/drone/push Build is passing
2024-12-30 11:36:25 +08:00
hang 2a42a921c4 修改退出
continuous-integration/drone/push Build is passing
2024-12-27 15:01:02 +08:00
hang e84b8c25f1 修改项目增加接口
continuous-integration/drone/push Build is passing
2024-12-27 14:41:46 +08:00
hang 8b44900931 中心调研初步维护
continuous-integration/drone/push Build is passing
2024-12-27 14:29:13 +08:00
hang 918362e854 导入人员发送邮件
continuous-integration/drone/push Build is passing
2024-12-27 13:50:26 +08:00
hang ba2965e295 修改外部人员邀请邮件以及添加账号
continuous-integration/drone/push Build is passing
2024-12-27 12:33:48 +08:00
hang ecdd0fda85 增加查询条件
continuous-integration/drone/push Build is passing
2024-12-27 11:43:35 +08:00
hang dba356446e 登录选择角色
continuous-integration/drone/push Build is passing
2024-12-27 11:35:53 +08:00
hang 4e1ea21ba8 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-27 11:32:18 +08:00
hang 7853614d2d 修改查询 2024-12-27 11:32:17 +08:00
he 8cabb7440a Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-27 09:37:16 +08:00
he 4fc68e1f82 修改排序 2024-12-27 09:37:15 +08:00
hang c06681f379 修改账号编号问题
continuous-integration/drone/push Build is passing
2024-12-26 17:59:04 +08:00
hang 57539b0471 用户反馈修改查询条件
continuous-integration/drone/push Build is passing
2024-12-26 17:49:39 +08:00
hang 8b7c429e9f 修改日志查询条数有问题
continuous-integration/drone/push Build is passing
2024-12-26 17:38:42 +08:00
hang 9b94ad70ee Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-26 17:25:03 +08:00
hang 9aa8bb99dc 修改中心人员 2024-12-26 17:25:00 +08:00
he b203c891a4 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-26 17:16:25 +08:00
he 3833a1e696 登录修改 2024-12-26 17:16:24 +08:00
hang 6e83891139 修改稽查查询
continuous-integration/drone/push Build is passing
2024-12-26 17:10:18 +08:00
hang 39616448b8 添加内部人员修改
continuous-integration/drone/push Build is running
2024-12-26 17:07:31 +08:00
hang 6b9feca865 修改日志
continuous-integration/drone/push Build is passing
2024-12-26 16:48:20 +08:00
hang e0779ab295 修改用户发邮件
continuous-integration/drone/push Build is passing
2024-12-26 16:23:30 +08:00
hang 32e3153434 修改角色禁用bug
continuous-integration/drone/push Build is passing
2024-12-26 16:03:51 +08:00
hang b40bfe26c5 修改枚举值
continuous-integration/drone/push Build is passing
2024-12-26 15:53:14 +08:00
hang b8d5ed2bb7 修改密码bug
continuous-integration/drone/push Build is passing
2024-12-26 15:44:51 +08:00
hang 96e1f84c8c 修改映射
continuous-integration/drone/push Build is running
2024-12-26 15:37:48 +08:00
hang 353e03c4fe Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-26 15:23:13 +08:00
hang aa60cb4822 修改日志展示 2024-12-26 15:23:12 +08:00
he 7eaa61678b Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-26 14:57:25 +08:00
he d74cf15138 修改 2024-12-26 14:57:24 +08:00
hang 6238361bd2 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2024-12-26 14:54:14 +08:00
hang cf9248b0cc 修改用户日志 2024-12-26 14:54:13 +08:00
he 8c884b3269 删除表格标记
continuous-integration/drone/push Build is passing
2024-12-26 14:49:42 +08:00
he 8710edf1bd 修改计算
continuous-integration/drone/push Build is passing
2024-12-26 12:23:28 +08:00
he 5f9572a0ab Merge branch 'IRC_NewDev' into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-26 11:12:00 +08:00
hang 21c10307b9 增加修改用户角色接口
continuous-integration/drone/push Build is running
2024-12-26 11:10:36 +08:00
hang 6e0dc64981 修改查询映射
continuous-integration/drone/push Build is passing
2024-12-26 11:00:34 +08:00
hang 66922f8e7b 修改token 名字
continuous-integration/drone/push Build is passing
2024-12-26 09:27:05 +08:00
hang 2aa0382376 医生加入项目修改
continuous-integration/drone/push Build is passing
2024-12-25 19:30:42 +08:00
hang 5cdc5400dc 修改医生生成账号
continuous-integration/drone/push Build is passing
2024-12-25 19:19:41 +08:00
hang 53bcdaa6ce 增加用户映射
continuous-integration/drone/push Build is passing
2024-12-25 17:55:49 +08:00
hang 473e218b2b 增加用户基本信息修改接口
continuous-integration/drone/push Build is passing
2024-12-25 17:36:04 +08:00
he 99ae6c2a14 FirstAddTaskId 值修改 2024-12-25 17:24:02 +08:00
he bf3d3be6c9 复制修改 2024-12-25 16:40:15 +08:00
he 6f775a3303 修改标记复制 2024-12-25 16:23:01 +08:00
hang 2eaf2d5c69 修改项目添加参与人员
continuous-integration/drone/push Build is passing
2024-12-25 16:19:57 +08:00
he 6de66c9a5e 添加映射 2024-12-25 16:16:53 +08:00
he 3ae311bd02 添加上一次 2024-12-25 16:09:10 +08:00
hang 25116a9f0e 中心调研邮件初步修改
continuous-integration/drone/push Build is passing
2024-12-25 16:02:49 +08:00
he 2e9afc2ce8 计算修改 2024-12-25 15:44:50 +08:00
hang 7535d49844 导入人员
continuous-integration/drone/push Build is passing
2024-12-25 15:43:42 +08:00
hang 340f5c580e 添加用户修改
continuous-integration/drone/push Build is passing
2024-12-25 14:53:19 +08:00
hang 1d4eedf5bb 修改映射
continuous-integration/drone/push Build is passing
2024-12-25 14:21:16 +08:00
hang 3ff0230fc1 增加更新角色接口
continuous-integration/drone/push Build is passing
2024-12-25 14:02:17 +08:00
hang c2166556ea 修改项目用户
continuous-integration/drone/push Build is passing
2024-12-25 13:53:38 +08:00
hang 4b938e6643 外部用户修改
continuous-integration/drone/push Build is passing
2024-12-25 13:42:05 +08:00
hang 4740e04ff1 修改映射
continuous-integration/drone/push Build is passing
2024-12-25 13:29:43 +08:00
hang ccdad2f4fd 修改中心命名提交
continuous-integration/drone/push Build is passing
2024-12-25 13:18:40 +08:00
hang 54d17f2e24 项目中心修改
continuous-integration/drone/push Build is passing
2024-12-25 13:07:57 +08:00
hang 0b3fe111b7 项目中心人员修改
continuous-integration/drone/push Build is passing
2024-12-25 12:27:48 +08:00
hang a6080b76b1 修改用户临时提交
continuous-integration/drone/push Build is passing
2024-12-25 11:25:45 +08:00
he 7d00b51db2 格式化修改 2024-12-25 10:51:46 +08:00
he be0d1c5c65 添加tablequestionid 2024-12-25 10:43:46 +08:00
he e1f19e9eae 阅片修改 2024-12-25 10:38:02 +08:00
hang 26cba15742 项目用户表增加初步修改
continuous-integration/drone/push Build is passing
2024-12-25 10:20:17 +08:00
hang 32c6d745b6 用户角色重命名初步修改
continuous-integration/drone/push Build is passing
2024-12-25 09:31:36 +08:00
hang 76649f264b 重置密码修改
continuous-integration/drone/push Build is passing
2024-12-24 17:39:44 +08:00
hang db360938fd 修改用户重置密码
continuous-integration/drone/push Build is passing
2024-12-24 17:32:45 +08:00
hang bd82470995 列表增加时间
continuous-integration/drone/push Build is passing
2024-12-24 17:26:08 +08:00
hang 87560e0602 修改用户编辑
continuous-integration/drone/push Build is passing
2024-12-24 17:16:14 +08:00
hang 89cd31cd03 修改提交
continuous-integration/drone/push Build is passing
2024-12-24 17:06:42 +08:00
hang 1badf2610e 账号管理提交
continuous-integration/drone/push Build is passing
2024-12-24 17:00:56 +08:00
hang 1129a2210a 修改映射
continuous-integration/drone/push Build is passing
2024-12-24 16:49:19 +08:00
hang a1199b44a3 修改提交
continuous-integration/drone/push Build is passing
2024-12-24 16:36:54 +08:00
hang dc32df27ec 添加新的用户表提交
continuous-integration/drone/push Build is pending
2024-12-24 16:25:04 +08:00
he 7f874eaff0 修改 2024-12-24 11:09:19 +08:00
he 21fdd4b0e4 返回表格问题的标记 2024-12-24 10:04:10 +08:00
hang f7519b2095 修改账户信息
continuous-integration/drone/push Build is passing
2024-12-23 18:06:26 +08:00
hang 686c7bac9b 修改账户信息
continuous-integration/drone/push Build is passing
2024-12-23 17:49:25 +08:00
he 3cde829319 表格问题病灶 2024-12-23 17:45:42 +08:00
hang 230852b2a9 修改获取账户信息
continuous-integration/drone/push Build is passing
2024-12-23 17:41:03 +08:00
hang 613957d0ac 修改传递参数
continuous-integration/drone/push Build is passing
2024-12-23 17:25:18 +08:00
hang 4fe61ac51a 修改传参方式
continuous-integration/drone/push Build is passing
2024-12-23 17:01:54 +08:00
hang e9bafe9e38 返回用户简称
continuous-integration/drone/push Build is passing
2024-12-23 16:45:53 +08:00
hang d1bf517aa7 修改传递的参数
continuous-integration/drone/push Build is passing
2024-12-23 16:34:32 +08:00
hang a2809dc15a Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-23 15:47:41 +08:00
hang c1a58401eb 用户初步修改 2024-12-23 15:47:39 +08:00
he e22a015fcb 变量修改 2024-12-23 14:21:40 +08:00
he f45b0afc49 添加8 条 2024-12-23 14:14:04 +08:00
he f652c95d8c 修改 2024-12-23 11:34:27 +08:00
he bcfb91bc05 修改 2024-12-23 11:34:22 +08:00
he d1f04d5c0c 修改 2024-12-23 11:34:19 +08:00
he e0cf5f804e 修改
continuous-integration/drone/push Build is passing
2024-12-20 17:48:28 +08:00
he a0725e1318 修改
continuous-integration/drone/push Build is passing
2024-12-20 17:25:55 +08:00
he 70b7fe73ad 修改
continuous-integration/drone/push Build is passing
2024-12-20 17:16:30 +08:00
he 5b616026ab Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-20 17:10:51 +08:00
he a001db2da5 修改 2024-12-20 17:10:49 +08:00
hang 2e7a0fe68d Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-20 14:54:15 +08:00
hang 519eeb6df1 修改账号token 2024-12-20 14:54:11 +08:00
he 3e9221b39c 修改医院
continuous-integration/drone/push Build is passing
2024-12-20 14:06:30 +08:00
hang d165632cc8 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-20 13:42:45 +08:00
hang 65e50fec54 修改scp 配置 2024-12-20 13:42:43 +08:00
he 460575d959 修改
continuous-integration/drone/push Build is passing
2024-12-20 13:29:45 +08:00
he 6e34bc3c17 MRIPDFF标准
continuous-integration/drone/push Build is passing
2024-12-20 10:37:10 +08:00
hang 781a4a7b0b 增加配置
continuous-integration/drone/push Build is passing
2024-12-18 17:02:00 +08:00
hang 89d1f2f800 修改项目配置
continuous-integration/drone/push Build is passing
2024-12-18 16:18:10 +08:00
hang 3cd3315964 SPM 流程配置以及修改
continuous-integration/drone/push Build is passing
2024-12-18 15:14:23 +08:00
hang e73c775296 删除返回的机构名称
continuous-integration/drone/push Build is passing
2024-12-18 13:37:19 +08:00
hang 496396fa6b 删除返回的机构名称
continuous-integration/drone/push Build is passing
2024-12-18 13:36:52 +08:00
hang 3b28e13fd8 修改时间展示
continuous-integration/drone/push Build is passing
2024-12-18 11:33:21 +08:00
hang eedc9c5ab8 修改时间展示
continuous-integration/drone/push Build is passing
2024-12-18 11:32:58 +08:00
hang 0578168db0 修改时间
continuous-integration/drone/push Build is running
2024-12-18 11:31:17 +08:00
hang b12877e39b 修改时间
continuous-integration/drone/push Build is passing
2024-12-18 11:16:05 +08:00
hang 5694addef6 修改提交
continuous-integration/drone/push Build is passing
2024-12-17 16:50:58 +08:00
hang f037f0fac2 导表Excel 移除指定列修改 2024-12-17 16:49:57 +08:00
hang 55132ff36f 导表Excel 移除指定列修改
continuous-integration/drone/push Build is running
2024-12-17 16:49:46 +08:00
hang 33e0470f5d Merge branch 'Uat_IRC_Net8' into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-17 16:13:30 +08:00
hang 90b8bd8812 修改排序
continuous-integration/drone/push Build is passing
2024-12-17 16:12:53 +08:00
he 9424de56c2 修改
continuous-integration/drone/push Build is passing
2024-12-17 15:50:24 +08:00
hang 789e7ea2b0 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-17 15:49:50 +08:00
hang 3fecac40df 修改服务器配置 2024-12-17 15:49:37 +08:00
hang 80426f5ccd 修改排序 2024-12-17 15:49:02 +08:00
he 12a4b9151c 修改
continuous-integration/drone/push Build is passing
2024-12-17 14:00:39 +08:00
he e3a781b950 代码修改
continuous-integration/drone/push Build is passing
2024-12-17 11:34:49 +08:00
hang e16f32b5b9 修改排序
continuous-integration/drone/push Build is passing
2024-12-17 11:28:53 +08:00
he bba3a038af 修改
continuous-integration/drone/push Build is passing
2024-12-13 10:59:53 +08:00
he b385dcfdc0 修改
continuous-integration/drone/push Build is passing
2024-12-13 10:10:55 +08:00
he 11dd4fa789 修改
continuous-integration/drone/push Build is failing
2024-12-13 09:56:41 +08:00
he 5576b54518 修改
continuous-integration/drone/push Build is passing
2024-12-13 09:34:18 +08:00
he 483c622fce 修改
continuous-integration/drone/push Build is running
2024-12-13 09:32:49 +08:00
he b13976d620 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is failing
2024-12-13 09:27:26 +08:00
he 23cb3e1278 项目问题导出配置 2024-12-13 09:27:23 +08:00
hang 67c01da64b 修改服务器配置
continuous-integration/drone/push Build is passing
2024-12-12 16:58:02 +08:00
hang e5592338d0 放开中心调研的权限
continuous-integration/drone/push Build is passing
2024-12-12 16:45:51 +08:00
hang 07df412118 放开中心调研的权限
continuous-integration/drone/push Build encountered an error
2024-12-12 16:35:10 +08:00
hang 4c672cd91c 修改存储路径
continuous-integration/drone/push Build is passing
2024-12-12 13:33:47 +08:00
hang a74b264f39 软删除配置调整
continuous-integration/drone/push Build is passing
2024-12-11 22:46:26 +08:00
hang 2a217c1a20 回退撤销
continuous-integration/drone/push Build is passing
2024-12-11 19:44:28 +08:00
hang 1f4aff2796 xx
continuous-integration/drone/push Build is passing
2024-12-11 19:26:31 +08:00
hang d10c936003 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-12-11 15:16:07 +08:00
hang 4330afd683 软删除修改--pre 2024-12-11 15:16:06 +08:00
338 changed files with 729927 additions and 5027 deletions
+16 -8
View File
@@ -126,16 +126,22 @@ builder.Services.Configure<ForwardedHeadersOptions>(options =>
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
}); });
builder.Services.AddFellowOakDicom().AddTranscoderManager<NativeTranscoderManager>()
//.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>()
.AddImageManager<ImageSharpImageManager>();
//Dicom影像渲染图片 跨平台 //Dicom影像渲染图片 跨平台
//builder.Services.AddDicomSetup(); //builder.Services.AddDicomSetup();
new DicomSetupBuilder() //new DicomSetupBuilder()
.RegisterServices(s => // .RegisterServices(s =>
s.AddFellowOakDicom() // s.AddFellowOakDicom()
.AddTranscoderManager<NativeTranscoderManager>() // .AddTranscoderManager<NativeTranscoderManager>()
//.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>() // //.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>()
.AddImageManager<ImageSharpImageManager>()) // .AddImageManager<ImageSharpImageManager>())
.SkipValidation() // .SkipValidation()
.Build(); // .Build();
@@ -211,6 +217,8 @@ else
#endregion #endregion
DicomSetupBuilder.UseServiceProvider(app.Services);
var logger = app.Services.GetService<Microsoft.Extensions.Logging.ILogger<Program>>(); var logger = app.Services.GetService<Microsoft.Extensions.Logging.ILogger<Program>>();
var server = DicomServerFactory.Create<CStoreSCPService>(_configuration.GetSection("DicomSCPServiceConfig").GetValue<int>("ServerPort"), userState: app.Services,logger: logger); var server = DicomServerFactory.Create<CStoreSCPService>(_configuration.GetSection("DicomSCPServiceConfig").GetValue<int>("ServerPort"), userState: app.Services,logger: logger);
@@ -20,6 +20,16 @@
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Uat_IRC_SCP" "ASPNETCORE_ENVIRONMENT": "Uat_IRC_SCP"
} }
},
"US_Prod_IRC_SCP": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:6200",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "US_Prod_SCP"
}
} }
} }
} }
+4 -5
View File
@@ -76,9 +76,10 @@ namespace IRaCIS.Core.SCP.Service
}; };
public CStoreSCPService(INetworkStream stream, Encoding fallbackEncoding, Microsoft.Extensions.Logging.ILogger log, DicomServiceDependencies dependencies) public CStoreSCPService(INetworkStream stream, Encoding fallbackEncoding, Microsoft.Extensions.Logging.ILogger log, DicomServiceDependencies dependencies, IServiceProvider injectServiceProvider)
: base(stream, fallbackEncoding, log, dependencies) : base(stream, fallbackEncoding, log, dependencies)
{ {
_serviceProvider = injectServiceProvider.CreateScope().ServiceProvider;
} }
@@ -92,9 +93,7 @@ namespace IRaCIS.Core.SCP.Service
Log.Logger.Warning($"接收到来自{association.CallingAE}的连接"); Log.Logger.Warning($"接收到来自{association.CallingAE}的连接");
_serviceProvider = (IServiceProvider)this.UserState; //_serviceProvider = (IServiceProvider)this.UserState;
var _trialDicomAERepository = _serviceProvider.GetService<IRepository<TrialDicomAE>>(); var _trialDicomAERepository = _serviceProvider.GetService<IRepository<TrialDicomAE>>();
@@ -275,7 +274,7 @@ namespace IRaCIS.Core.SCP.Service
var _distributedLockProvider = _serviceProvider.GetService<IDistributedLockProvider>(); var _distributedLockProvider = _serviceProvider.GetService<IDistributedLockProvider>();
var storeRelativePath = string.Empty; var storeRelativePath = string.Empty;
var ossFolderPath = $"{_trialId}/Image/PACS/{_trialSiteId}{studyInstanceUid}"; var ossFolderPath = $"{_trialId}/Image/PACS/{_trialSiteId}/{studyInstanceUid}";
long fileSize = 0; long fileSize = 0;
+2 -2
View File
@@ -21,8 +21,8 @@
} }
}, },
"ConnectionStrings": { "ConnectionStrings": {
"RemoteNew": "Server=us-prod-mssql-service,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", "RemoteNew": "Server=us-mssql-prod,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=us-prod-mssql-service,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" "Hangfire": "Server=us-mssql-prod,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
}, },
"DicomSCPServiceConfig": { "DicomSCPServiceConfig": {
"CalledAEList": [ "CalledAEList": [
+22 -203
View File
@@ -1,5 +1,6 @@
using Amazon.Auth.AccessControlPolicy; using Amazon.Auth.AccessControlPolicy;
using Amazon.SecurityToken; using Amazon.SecurityToken;
using AutoMapper;
using Azure.Core; using Azure.Core;
using IdentityModel.Client; using IdentityModel.Client;
using IdentityModel.OidcClient; using IdentityModel.OidcClient;
@@ -24,6 +25,7 @@ using RestSharp;
using RestSharp.Authenticators; using RestSharp.Authenticators;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
@@ -105,196 +107,6 @@ namespace IRaCIS.Api.Controllers
/// <summary> 系统用户登录接口[New] </summary>
[HttpPost, Route("user/login")]
[AllowAnonymous]
public async Task<IResponseOutput> Login(UserLoginDTO loginUser,
[FromServices] IFusionCache _fusionCache,
[FromServices] IUserService _userService,
[FromServices] ITokenService _tokenService,
[FromServices] IReadingImageTaskService readingImageTaskService,
[FromServices] IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig,
[FromServices] IOptionsMonitor<SystemEmailSendConfig> _emailConfig,
[FromServices] IMailVerificationService _mailVerificationService)
{
var emailConfig = _emailConfig.CurrentValue;
var companyInfo = new SystemEmailSendConfigView() { CompanyName = emailConfig.CompanyName, CompanyNameCN = emailConfig.CompanyNameCN, CompanyShortName = emailConfig.CompanyShortName, CompanyShortNameCN = emailConfig.CompanyShortNameCN };
//MFA 邮箱验证 前端传递用户Id 和MFACode
if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA)
{
Guid userId = (Guid)loginUser.UserId;
//验证MFA 编码是否有问题 ,前端要拆开,自己调用验证的逻辑
//await _userService.VerifyMFACodeAsync(userId, loginUser.MFACode);
//var loginUser = await _userRepository.Where(u => u.UserName.Equals(userName) && u.Password == password).ProjectTo<UserBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
var basicInfo = await _userService.GetUserBasicInfo(userId, loginUser.Password);
var loginReturn = new LoginReturnDTO() { BasicInfo = basicInfo };
loginReturn.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(loginReturn.BasicInfo));
// 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
var option = new CookieOptions
{
Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
HttpOnly = false, // 确保 cookie 只能通过 HTTP 访问
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None, // 设置 SameSite 属性
Secure = false // 确保 cookie 只能通过 HTTPS 访问
};
HttpContext.Response.Cookies.Append("access_token", loginReturn.JWTStr, option);
// 验证阅片休息时间
await readingImageTaskService.ResetReadingRestTime(userId);
await _fusionCache.SetAsync(CacheKeys.UserToken(userId), loginReturn.JWTStr, TimeSpan.FromDays(7));
await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(userId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
loginReturn.CompanyInfo = companyInfo;
return ResponseOutput.Ok(loginReturn);
}
else
{
var returnModel = await _userService.Login(loginUser.UserName, loginUser.Password);
if (returnModel.IsSuccess)
{
#region GRPC IIS问题 http/2 使
////重试策略
//var defaultMethodConfig = new MethodConfig
//{
// Names = { MethodName.Default },
// RetryPolicy = new RetryPolicy
// {
// MaxAttempts = 3,
// InitialBackoff = TimeSpan.FromSeconds(1),
// MaxBackoff = TimeSpan.FromSeconds(5),
// BackoffMultiplier = 1.5,
// RetryableStatusCodes = { Grpc.Core.StatusCode.Unavailable }
// }
//};
//#region unable to trust the certificate then the gRPC client can be configured to ignore the invalid certificate
//var httpHandler = new HttpClientHandler();
//// Return `true` to allow certificates that are untrusted/invalid
//httpHandler.ServerCertificateCustomValidationCallback =
// HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
//////这一句是让grpc支持本地 http 如果本地访问部署在服务器上,那么是访问不成功的
//AppContext.SetSwitch(
// "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
//#endregion
//var grpcAdress = configuration.GetValue<string>("GrpcAddress");
////var grpcAdress = "http://localhost:7200";
//var channel = GrpcChannel.ForAddress(grpcAdress, new GrpcChannelOptions
//{
// HttpHandler = httpHandler,
// ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }
//});
////var channel = GrpcChannel.ForAddress(grpcAdress);
//var grpcClient = new TokenGrpcService.TokenGrpcServiceClient(channel);
//var userInfo = returnModel.Data.BasicInfo;
//var tokenResponse = grpcClient.GetUserToken(new GetTokenReuqest()
//{
// Id = userInfo.Id.ToString(),
// ReviewerCode = userInfo.ReviewerCode,
// IsAdmin = userInfo.IsAdmin,
// RealName = userInfo.RealName,
// UserTypeEnumInt = (int)userInfo.UserTypeEnum,
// UserTypeShortName = userInfo.UserTypeShortName,
// UserName = userInfo.UserName
//});
//returnModel.Data.JWTStr = tokenResponse.Token;
#endregion
var userId = returnModel.Data.BasicInfo.Id;
if (_verifyConfig.CurrentValue.OpenLoginMFA)
{
//MFA 发送邮件
returnModel.Data.IsMFA = true;
var email = returnModel.Data.BasicInfo.EMail;
var hiddenEmail = IRCEmailPasswordHelper.MaskEmail(email);
returnModel.Data.BasicInfo.EMail = hiddenEmail;
//修改密码
if (returnModel.Data.BasicInfo.IsFirstAdd || returnModel.Data.BasicInfo.LoginState == 1)
{
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
}
else
{
//正常登录才发送邮件
await _userService.SendMFAEmail(userId);
}
}
else
{
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
// 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
var option = new CookieOptions
{
Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
HttpOnly = false, // 确保 cookie 只能通过 HTTP 访问
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None, // 设置 SameSite 属性
Secure = false // 确保 cookie 只能通过 HTTPS 访问
};
HttpContext.Response.Cookies.Append("access_token", returnModel.Data.JWTStr, option);
// 验证阅片休息时间
await readingImageTaskService.ResetReadingRestTime(returnModel.Data.BasicInfo.Id);
await _fusionCache.SetAsync(CacheKeys.UserToken(userId), returnModel.Data.JWTStr, TimeSpan.FromDays(7));
await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(userId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
}
}
returnModel.Data.CompanyInfo = companyInfo;
return returnModel;
}
}
[AllowAnonymous] [AllowAnonymous]
[HttpGet, Route("user/getPublicKey")] [HttpGet, Route("user/getPublicKey")]
public IResponseOutput GetPublicKey([FromServices] IOptionsMonitor<IRCEncreptOption> _IRCEncreptOption) public IResponseOutput GetPublicKey([FromServices] IOptionsMonitor<IRCEncreptOption> _IRCEncreptOption)
@@ -309,18 +121,13 @@ namespace IRaCIS.Api.Controllers
[AllowAnonymous] [AllowAnonymous]
public IResponseOutput ShareImage([FromServices] ITokenService _tokenService) public IResponseOutput ShareImage([FromServices] ITokenService _tokenService)
{ {
var token = _tokenService.GetToken(IRaCISClaims.Create(new UserBasicInfo() var token = _tokenService.GetToken(new UserTokenInfo()
{ {
Id = Guid.NewGuid(), IdentityUserId = Guid.NewGuid(),
IsReviewer = false,
IsAdmin = false,
RealName = "Share001",
UserName = "Share001", UserName = "Share001",
Sex = 0,
//UserType = "ShareType",
UserTypeEnum = UserTypeEnum.ShareImage, UserTypeEnum = UserTypeEnum.ShareImage,
Code = "ShareCode001",
})); });
return ResponseOutput.Ok("/showdicom?studyId=f7b67793-8155-0223-2f15-118f2642efb8&type=Share&token=" + token); return ResponseOutput.Ok("/showdicom?studyId=f7b67793-8155-0223-2f15-118f2642efb8&type=Share&token=" + token);
} }
@@ -379,7 +186,7 @@ namespace IRaCIS.Api.Controllers
[HttpGet("User/UserRedirect")] [HttpGet("User/UserRedirect")]
[AllowAnonymous] [AllowAnonymous]
public async Task<IActionResult> UserRedirect([FromServices] IRepository<User> _userRepository, string url, [FromServices] ILogger<ExtraController> _logger) public async Task<IActionResult> UserRedirect([FromServices] IRepository<IdentityUser> _useRepository, string url, [FromServices] ILogger<ExtraController> _logger, [FromServices] ITokenService _tokenService)
{ {
var decodeUrl = System.Web.HttpUtility.UrlDecode(url); var decodeUrl = System.Web.HttpUtility.UrlDecode(url);
@@ -394,10 +201,22 @@ namespace IRaCIS.Api.Controllers
var errorUrl = domainStrList[0] + "//" + domainStrList[2] + "/error"; var errorUrl = domainStrList[0] + "//" + domainStrList[2] + "/error";
if (lang == "zh")
if (!await _userRepository.AnyAsync(t => t.Id == Guid.Parse(userId) && t.EmailToken == token && t.IsFirstAdd))
{ {
decodeUrl = errorUrl + $"?lang={lang}&ErrorMessage={System.Web.HttpUtility.UrlEncode(lang == "zh" ? "" : "ErrorThe initialization link has expired. Return")} "; CultureInfo.CurrentCulture = new CultureInfo(StaticData.CultureInfo.zh_CN);
CultureInfo.CurrentUICulture = new CultureInfo(StaticData.CultureInfo.zh_CN);
}
else
{
CultureInfo.CurrentCulture = new CultureInfo(StaticData.CultureInfo.en_US);
CultureInfo.CurrentUICulture = new CultureInfo(StaticData.CultureInfo.en_US);
}
var isExpire = _tokenService.IsTokenExpired(token);
if (!await _useRepository.AnyAsync(t => t.Id == Guid.Parse(userId) && t.EmailToken == token && t.IsFirstAdd) || isExpire)
{
decodeUrl = errorUrl + $"?lang={lang}&ErrorMessage={System.Web.HttpUtility.UrlEncode(I18n.T("UserRedirect_InitializationLinkExpire"))} ";
} }
return Redirect(decodeUrl); return Redirect(decodeUrl);
@@ -51,30 +51,30 @@ namespace IRaCIS.Core.API.Controllers.Special
[TrialGlobalLimit( "AddOrUpdateTrial", "BeforeOngoingCantOpt", "AfterStopCannNotOpt" )] [TrialGlobalLimit( "AddOrUpdateTrial", "BeforeOngoingCantOpt", "AfterStopCannNotOpt" )]
public async Task<IResponseOutput<Trial>> AddOrUpdateTrial(TrialCommand param) public async Task<IResponseOutput<Trial>> AddOrUpdateTrial(TrialCommand param)
{ {
var userId = Guid.Parse(User.FindFirst("id").Value); //var userId = Guid.Parse(User.FindFirst("id").Value);
var result = await _trialService.AddOrUpdateTrial(param); var result = await _trialService.AddOrUpdateTrial(param);
if (_trialService.TrialExpeditedChange) //if (_trialService.TrialExpeditedChange)
{ //{
var needCalReviewerIds = await _trialService.GetTrialEnrollmentReviewerIds(param.Id.Value); // var needCalReviewerIds = await _trialService.GetTrialEnrollmentReviewerIds(param.Id.Value);
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty); // var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty);
calcList.ForEach(t => // calcList.ForEach(t =>
{ // {
if (needCalReviewerIds.Contains(t.DoctorId)) // if (needCalReviewerIds.Contains(t.DoctorId))
{ // {
_calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO() // _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{ // {
NeedCalculateReviewers = new List<Guid>() // NeedCalculateReviewers = new List<Guid>()
{ // {
t.DoctorId // t.DoctorId
}, // },
CalculateMonth = DateTime.Parse(t.YearMonth) // CalculateMonth = DateTime.Parse(t.YearMonth)
}, User.FindFirst("id").Value); // }, User.FindFirst("id").Value);
} // }
}); // });
} //}
return result; return result;
} }
@@ -522,10 +522,10 @@ namespace IRaCIS.Core.API.Controllers
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> ConfirmReReading(DataInspectionDto<ConfirmReReadingCommand> opt, [FromServices] IVisitTaskHelpeService _visitTaskCommonService, [FromServices] IVisitTaskService _visitTaskService) public async Task<IResponseOutput> ConfirmReReading(DataInspectionDto<ConfirmReReadingCommand> opt, [FromServices] IVisitTaskService _visitTaskService)
{ {
var singId = await _inspectionService.RecordSing(opt.SignInfo); var singId = await _inspectionService.RecordSing(opt.SignInfo);
var result = await _visitTaskService.ConfirmReReading(opt.Data, _visitTaskCommonService); var result = await _visitTaskService.ConfirmReReading(opt.Data);
await _inspectionService.CompletedSign(singId, result); await _inspectionService.CompletedSign(singId, result);
return result; return result;
} }
@@ -297,7 +297,7 @@ namespace IRaCIS.Core.API.Controllers
[HttpPost, Route("Study/ArchiveStudy")] [HttpPost, Route("Study/ArchiveStudy")]
[DisableFormValueModelBinding] [DisableFormValueModelBinding]
[DisableRequestSizeLimit] [DisableRequestSizeLimit]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> ArchiveStudyNew(Guid trialId, Guid subjectVisitId, string studyInstanceUid, Guid? abandonStudyId, Guid studyMonitorId, public async Task<IResponseOutput> ArchiveStudyNew(Guid trialId, Guid subjectVisitId, string studyInstanceUid, Guid? abandonStudyId, Guid studyMonitorId,
[FromServices] ILogger<UploadDownLoadController> _logger, [FromServices] ILogger<UploadDownLoadController> _logger,
[FromServices] IStudyService _studyService, [FromServices] IStudyService _studyService,
@@ -370,7 +370,7 @@ namespace IRaCIS.Core.API.Controllers
//await _uploadHub.Clients.All.ReceivProgressAsync(archiveStudyCommand.StudyInstanceUid, receivedCount); //await _uploadHub.Clients.All.ReceivProgressAsync(archiveStudyCommand.StudyInstanceUid, receivedCount);
await _uploadHub.Clients.User(_userInfo.Id.ToString()).ReceivProgressAsync(archiveStudyCommand.StudyInstanceUid, receivedCount); await _uploadHub.Clients.User(_userInfo.UserRoleId.ToString()).ReceivProgressAsync(archiveStudyCommand.StudyInstanceUid, receivedCount);
archiveResult.ReceivedFileCount = receivedCount; archiveResult.ReceivedFileCount = receivedCount;
@@ -452,7 +452,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="_studyMonitorRepository"></param> /// <param name="_studyMonitorRepository"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Study/PreArchiveStudy")] [HttpPost, Route("Study/PreArchiveStudy")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> PreArchiveStudy(PreArchiveStudyCommand preArchiveStudyCommand, public async Task<IResponseOutput> PreArchiveStudy(PreArchiveStudyCommand preArchiveStudyCommand,
[FromServices] IStudyService _studyService, [FromServices] IStudyService _studyService,
[FromServices] IRepository<StudyMonitor> _studyMonitorRepository) [FromServices] IRepository<StudyMonitor> _studyMonitorRepository)
@@ -488,7 +488,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="_noneDicomStudyFileRepository"></param> /// <param name="_noneDicomStudyFileRepository"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost("NoneDicomStudy/UploadNoneDicomFile")] [HttpPost("NoneDicomStudy/UploadNoneDicomFile")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> UploadNoneDicomFile(UploadNoneDicomFileCommand incommand, public async Task<IResponseOutput> UploadNoneDicomFile(UploadNoneDicomFileCommand incommand,
[FromServices] IRepository<NoneDicomStudy> _noneDicomStudyRepository, [FromServices] IRepository<NoneDicomStudy> _noneDicomStudyRepository,
[FromServices] IRepository<StudyMonitor> _studyMonitorRepository, [FromServices] IRepository<StudyMonitor> _studyMonitorRepository,
@@ -560,7 +560,7 @@ namespace IRaCIS.Core.API.Controllers
/// <returns></returns> /// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception> /// <exception cref="BusinessValidationFailedException"></exception>
[HttpPost("QCOperation/UploadVisitCheckExcel/{trialId:guid}")] [HttpPost("QCOperation/UploadVisitCheckExcel/{trialId:guid}")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> UploadVisitCheckExcel(Guid trialId, [FromServices] IOSSService oSSService, [FromServices] IRepository<InspectionFile> _inspectionFileRepository) public async Task<IResponseOutput> UploadVisitCheckExcel(Guid trialId, [FromServices] IOSSService oSSService, [FromServices] IRepository<InspectionFile> _inspectionFileRepository)
{ {
@@ -850,11 +850,18 @@ namespace IRaCIS.Core.API.Controllers
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidCenters"]); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidCenters"]);
} }
if (excelList.GroupBy(t => new { t.TrialSiteCode, t.UserTypeStr, t.Email }).Any(g => g.Count() > 1)) foreach (var item in excelList.GroupBy(t => t.Email.Trim()))
{ {
// 同一邮箱,同一用户类型,只能生成一个账户,请核查Excel数据 var itemList = item.ToList();
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_CheckDuplicateAccounts"]); var first = item.First();
if (itemList.Any(t => t.Email.Trim() != first.Email.Trim() || t.Phone.Trim() != first.Phone.Trim() || t.OrganizationName.Trim() != first.OrganizationName.Trim() || t.FirstName.Trim() != first.FirstName.Trim() || t.LastName.Trim() != first.LastName.Trim()))
{
//同一邮箱,用户信息应该保持一致!
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_CheckDuplicateAccounts"]);
}
} }
if (excelList.Any(t => !t.Email.Contains("@"))) if (excelList.Any(t => !t.Email.Contains("@")))
@@ -879,7 +886,7 @@ namespace IRaCIS.Core.API.Controllers
foreach (var item in excelList) foreach (var item in excelList)
{ {
switch (item.UserTypeStr.ToUpper()) switch (item.UserTypeStr.Trim().ToUpper())
{ {
case "CRC": case "CRC":
@@ -896,7 +903,7 @@ namespace IRaCIS.Core.API.Controllers
} }
item.TrialSiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.ToUpper() == item.TrialSiteCode.ToUpper()).TrialSiteId; item.TrialSiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.Trim().ToUpper() == item.TrialSiteCode.Trim().ToUpper()).TrialSiteId;
} }
var list = excelList.Where(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.CRA).ToList(); var list = excelList.Where(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.CRA).ToList();
+1 -4
View File
@@ -34,9 +34,6 @@
<param name="doctorId"></param> <param name="doctorId"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,ZiggyCreatures.Caching.Fusion.IFusionCache,IRaCIS.Core.Application.Service.IUserService,IRaCIS.Core.Application.Auth.ITokenService,IRaCIS.Core.Application.Contracts.IReadingImageTaskService,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig},IRaCIS.Core.Application.Service.IMailVerificationService)">
<summary> 系统用户登录接口[New] </summary>
</member>
<member name="M:IRaCIS.Api.Controllers.ExtraController.OAuthCallBack(System.String,System.String)"> <member name="M:IRaCIS.Api.Controllers.ExtraController.OAuthCallBack(System.String,System.String)">
<summary> <summary>
回调到前端,前端调用后端的接口 回调到前端,前端调用后端的接口
@@ -284,7 +281,7 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.ConfirmReReading(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.ViewModel.ConfirmReReadingCommand},IRaCIS.Core.Application.Service.IVisitTaskHelpeService,IRaCIS.Core.Application.Service.IVisitTaskService)"> <member name="M:IRaCIS.Core.API.Controllers.InspectionController.ConfirmReReading(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.ViewModel.ConfirmReReadingCommand},IRaCIS.Core.Application.Service.IVisitTaskService)">
<summary> <summary>
重阅同意 重阅同意
</summary> </summary>
+18 -3
View File
@@ -37,6 +37,11 @@ var config = new ConfigurationBuilder()
var enviromentName = config["ASPNETCORE_ENVIRONMENT"]; var enviromentName = config["ASPNETCORE_ENVIRONMENT"];
var openSwaggerStr = config["ASPNETCORE_OpenSwagger"];
var isOpenSwagger= openSwaggerStr == null&& openSwaggerStr?.ToLower()=="true";
if (string.IsNullOrWhiteSpace(enviromentName)) if (string.IsNullOrWhiteSpace(enviromentName))
{ {
@@ -111,8 +116,13 @@ builder.Services.AddAutoMapperSetup();
builder.Services.AddEFSetup(_configuration, enviromentName); builder.Services.AddEFSetup(_configuration, enviromentName);
//Http 响应压缩 //Http 响应压缩
builder.Services.AddResponseCompressionSetup(); builder.Services.AddResponseCompressionSetup();
//Swagger Api 文档
builder.Services.AddSwaggerSetup(); if (isOpenSwagger)
{
//Swagger Api 文档
builder.Services.AddSwaggerSetup();
}
//JWT Token 验证 //JWT Token 验证
builder.Services.AddJWTAuthSetup(_configuration); builder.Services.AddJWTAuthSetup(_configuration);
@@ -217,7 +227,12 @@ app.UseLogDashboard("/LogDashboard");
app.UseHangfireConfig(env); app.UseHangfireConfig(env);
// Swagger // Swagger
SwaggerSetup.Configure(app, env);
if (isOpenSwagger)
{
SwaggerSetup.Configure(app, env);
}
//serilog 记录请求的用户信息 //serilog 记录请求的用户信息
app.UseSerilogConfig(env); app.UseSerilogConfig(env);
+10 -1
View File
@@ -20,7 +20,8 @@
"commandName": "Project", "commandName": "Project",
"launchBrowser": true, "launchBrowser": true,
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Test_IRC" "ASPNETCORE_ENVIRONMENT": "Test_IRC",
"ASPNETCORE_OpenSwagger": "true"
}, },
"applicationUrl": "http://localhost:6100" "applicationUrl": "http://localhost:6100"
}, },
@@ -69,6 +70,14 @@
"ASPNETCORE_ENVIRONMENT": "US_Uat_IRC" "ASPNETCORE_ENVIRONMENT": "US_Uat_IRC"
}, },
"applicationUrl": "http://localhost:6100" "applicationUrl": "http://localhost:6100"
},
"IRaCIS.US_Prod_IRC": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "US_Prod_IRC"
},
"applicationUrl": "http://localhost:6100"
} }
} }
+1 -1
View File
@@ -17,7 +17,7 @@ namespace IRaCIS.Core.API
{ {
public virtual string GetUserId(HubConnectionContext connection) public virtual string GetUserId(HubConnectionContext connection)
{ {
return connection.User?.FindFirst(JwtIRaCISClaimType.Id)?.Value!; return connection.User?.FindFirst(JwtIRaCISClaimType.IdentityUserId)?.Value!;
} }
} }
@@ -38,7 +38,7 @@ namespace IRaCIS.Core.API
diagnosticContext.Set("QueryString", request.QueryString.Value); diagnosticContext.Set("QueryString", request.QueryString.Value);
} }
diagnosticContext.Set("FullName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.RealName)?.Value); diagnosticContext.Set("FullName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.FullName)?.Value);
diagnosticContext.Set("UserType", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value); diagnosticContext.Set("UserType", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value);
@@ -1,5 +1,6 @@
using EntityFramework.Exceptions.SqlServer; using EntityFramework.Exceptions.SqlServer;
using IRaCIS.Core.Application.Triggers; using IRaCIS.Core.Application.Triggers;
using IRaCIS.Core.Application.Triggers.AfterSaveTrigger;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infra.EFCore.Interceptor; using IRaCIS.Core.Infra.EFCore.Interceptor;
@@ -81,6 +82,11 @@ namespace IRaCIS.Core.API
triggerOptions.AddTrigger<UserAddTrigger>(); triggerOptions.AddTrigger<UserAddTrigger>();
triggerOptions.AddTrigger<UserLogAfterTrigger>();
triggerOptions.AddTrigger<IdenttiyUserRoleInfoTrigger>();
}); });
}); });
@@ -16,6 +16,9 @@ namespace IRaCIS.Core.API;
public enum SwaggerVersion public enum SwaggerVersion
{ {
[Description("文件记录")]
FileRecord = -1,
[Description("医生模块")] [Description("医生模块")]
Reviewer = 1, Reviewer = 1,
[Description("项目模块")] [Description("项目模块")]
+4 -6
View File
@@ -43,27 +43,25 @@
"OpenLoginLimit": true, "OpenLoginLimit": true,
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30, "LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 120,
"AutoLoginOutMinutes": 360,
"OpenLoginMFA": false, "OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120, "ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10, "ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true, "IsNeedChangePassWord": true,
"ChangePassWordDays": 90 "ChangePassWordDays": 90
}, },
"SystemEmailSendConfig": { "SystemEmailSendConfig": {
"Port": 465, "Port": 465,
"Host": "smtp.qiye.aliyun.com", "Host": "smtp.qiye.aliyun.com",
"FromEmail": "IRC@extimaging.com", "FromEmail": "irc@extimaging.com",
"FromName": "IRC", "FromName": "irc",
"AuthorizationCode": "ExtImg@2022", "AuthorizationCode": "ExtImg@2022",
"SiteUrl": "http://irc.extimaging.com/login", "SiteUrl": "http://irc.extimaging.com/login",
"SystemShortName": "IRC",
"OrganizationName": "Extlmaging", "OrganizationName": "Extlmaging",
"OrganizationNameCN": "Extlmaging", "OrganizationNameCN": "Extlmaging",
"CompanyName": "Extensive Imaging", "CompanyName": "Extensive Imaging",
+10 -11
View File
@@ -23,9 +23,11 @@
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV", "AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access", "RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
"BucketName": "zy-irc-test-store", "BucketName": "zy-irc-test-store",
"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", //"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"ViewEndpoint": "https://zy-irc-test-dev-cache.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai", "Region": "oss-cn-shanghai",
"DurationSeconds": 7200 "DurationSeconds": 7200,
"PreviewEndpoint": "https://test-oss.test.extimaging.com"
}, },
"MinIO": { "MinIO": {
"EndPoint": "hir-oss.test.extimaging.com", "EndPoint": "hir-oss.test.extimaging.com",
@@ -52,28 +54,24 @@
"BasicSystemConfig": { "BasicSystemConfig": {
"OpenUserComplexPassword": false, "OpenUserComplexPassword": false,
"OpenSignDocumentBeforeWork": false, "OpenSignDocumentBeforeWork": false,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false, "OpenLoginLimit": false,
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 1, "LoginFailLockMinutes": 1,
"AutoLoginOutMinutes": 10,
"AutoLoginOutMinutes": 1,
"OpenLoginMFA": false, "OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120, "ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10, "ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90, "ChangePassWordDays": 90,
"OpenTrialRelationDelete": true,
"ThirdPdfUrl": "http://106.14.89.110:30088/api/v1/convert/file/pdf" "ThirdPdfUrl": "http://106.14.89.110:30088/api/v1/convert/file/pdf"
}, },
@@ -85,6 +83,7 @@
"AuthorizationCode": "SHzyyl2021", "AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.test.extimaging.com/login", "SiteUrl": "http://irc.test.extimaging.com/login",
"SystemShortName": "IRC",
"OrganizationName": "Extlmaging", "OrganizationName": "Extlmaging",
"OrganizationNameCN": "Extlmaging", "OrganizationNameCN": "Extlmaging",
"CompanyName": "Extensive Imaging", "CompanyName": "Extensive Imaging",
+16 -15
View File
@@ -7,8 +7,8 @@
} }
}, },
"ConnectionStrings": { "ConnectionStrings": {
"RemoteNew": "Server=us-prod-mssql-service,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", "RemoteNew": "Server=us-mssql-prod,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=us-prod-mssql-service,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" "Hangfire": "Server=us-mssql-prod,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
//"RemoteNew": "Server=44.210.231.169,1435;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", //"RemoteNew": "Server=44.210.231.169,1435;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
//"Hangfire": "Server=44.210.231.169,1435;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true", //"Hangfire": "Server=44.210.231.169,1435;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
}, },
@@ -39,25 +39,25 @@
}, },
"BasicSystemConfig": { "BasicSystemConfig": {
"OpenUserComplexPassword": false, "OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenSignDocumentBeforeWork": false,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30, "LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60, "AutoLoginOutMinutes": 120,
"OpenLoginMFA": true,
"ContinuousReadingTimeMin": 120, "ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10, "ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90 "IsNeedChangePassWord": true,
"ChangePassWordDays": 90,
"OpenTrialRelationDelete": false
}, },
"SystemEmailSendConfig": { "SystemEmailSendConfig": {
@@ -67,6 +67,7 @@
"FromName": "LiLi", "FromName": "LiLi",
"AuthorizationCode": "Q#669869497420ul", "AuthorizationCode": "Q#669869497420ul",
"SystemShortName": "LiLi",
"OrganizationName": "Elevate Imaging", "OrganizationName": "Elevate Imaging",
"OrganizationNameCN": "Elevate Imaging", "OrganizationNameCN": "Elevate Imaging",
"CompanyName": "Elevate Imaging Inc.", "CompanyName": "Elevate Imaging Inc.",
@@ -75,7 +76,7 @@
"CompanyShortNameCN": "展影医疗", "CompanyShortNameCN": "展影医疗",
"SiteUrl": "https://lili.elevateimaging.ai/login", "SiteUrl": "https://lili.elevateimaging.ai/login",
"IsEnv_US": true, "IsEnv_US": true,
"IsOpenErrorNoticeEmail": true, "IsOpenErrorNoticeEmail": false,
"ErrorNoticeEmailList": [ "872297557@qq.com" ] "ErrorNoticeEmailList": [ "872297557@qq.com" ]
}, },
@@ -75,6 +75,7 @@
"FromName": "LiLi", "FromName": "LiLi",
"AuthorizationCode": "Q#669869497420ul", "AuthorizationCode": "Q#669869497420ul",
"SystemShortName": "LiLi",
"OrganizationName": "Elevate Imaging", "OrganizationName": "Elevate Imaging",
"OrganizationNameCN": "Elevate Imaging", "OrganizationNameCN": "Elevate Imaging",
"CompanyName": "Elevate Imaging Inc.", "CompanyName": "Elevate Imaging Inc.",
+8 -13
View File
@@ -50,26 +50,20 @@
"BasicSystemConfig": { "BasicSystemConfig": {
"OpenUserComplexPassword": true, "OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true, "OpenSignDocumentBeforeWork": true,
"OpenTrialRelationDelete": true, "OpenLoginLimit": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30, "LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60, "AutoLoginOutMinutes": 120,
"OpenLoginMFA": true,
"ContinuousReadingTimeMin": 120, "ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10, "ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true, "IsNeedChangePassWord": true,
"ChangePassWordDays": 90
"ChangePassWordDays": 90,
"OpenLoginMFA": false
}, },
"SystemEmailSendConfig": { "SystemEmailSendConfig": {
@@ -79,13 +73,14 @@
"FromName": "LiLi", "FromName": "LiLi",
"AuthorizationCode": "Q#669869497420ul", "AuthorizationCode": "Q#669869497420ul",
"SystemShortName": "LiLi",
"OrganizationName": "Elevate Imaging", "OrganizationName": "Elevate Imaging",
"OrganizationNameCN": "Elevate Imaging", "OrganizationNameCN": "Elevate Imaging",
"CompanyName": "Elevate Imaging Inc.", "CompanyName": "Elevate Imaging Inc.",
"CompanyNameCN": "上海展影医疗科技有限公司", "CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Elevate Imaging", "CompanyShortName": "Elevate Imaging",
"CompanyShortNameCN": "展影医疗", "CompanyShortNameCN": "展影医疗",
"SiteUrl": "https://lili.test.elevateimaging.ai/login", "SiteUrl": "https://lili.uat.elevateimaging.ai/login",
"IsEnv_US": true, "IsEnv_US": true,
"IsOpenErrorNoticeEmail": false, "IsOpenErrorNoticeEmail": false,
"ErrorNoticeEmailList": [ "872297557@qq.com" ] "ErrorNoticeEmailList": [ "872297557@qq.com" ]
+6 -5
View File
@@ -56,21 +56,20 @@
"BasicSystemConfig": { "BasicSystemConfig": {
"OpenUserComplexPassword": true, "OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true, "OpenSignDocumentBeforeWork": true,
"OpenLoginLimit": true, "OpenLoginLimit": true,
"LoginMaxFailCount": 5, "LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30, "LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60, "AutoLoginOutMinutes": 120,
"OpenLoginMFA": false, "OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120, "ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10, "ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90 "ChangePassWordDays": 90
}, },
@@ -81,6 +80,8 @@
"FromName": "UAT_IRC", "FromName": "UAT_IRC",
"AuthorizationCode": "SHzyyl2021", "AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.uat.extimaging.com/login", "SiteUrl": "http://irc.uat.extimaging.com/login",
"SystemShortName": "IRC",
"OrganizationName": "Extlmaging", "OrganizationName": "Extlmaging",
"OrganizationNameCN": "Extlmaging", "OrganizationNameCN": "Extlmaging",
"CompanyName": "Extensive Imaging", "CompanyName": "Extensive Imaging",
@@ -94,7 +95,7 @@
"SystemPacsConfig": { "SystemPacsConfig": {
"Port": "11113", "Port": "11113",
"IP": "47.117.164.182" "IP": "101.132.253.119"
} }
} }
+1 -1
View File
@@ -3,7 +3,7 @@
"SecurityKey": "ShangHaiZhanYing_SecurityKey_SHzyyl@2021", "SecurityKey": "ShangHaiZhanYing_SecurityKey_SHzyyl@2021",
"Issuer": "Extimaging", "Issuer": "Extimaging",
"Audience": "EICS", "Audience": "EICS",
"TokenExpireDays": "7" "TokenExpireMinute": "10080"//7天
}, },
"IpRateLimiting": { "IpRateLimiting": {
"EnableEndpointRateLimiting": true, "EnableEndpointRateLimiting": true,
+132 -11
View File
@@ -270,10 +270,10 @@ var abp = abp || {};
function loginUserInternal(tenantId, callback) { function loginUserInternal(tenantId, callback) {
var usernameOrEmailAddress = document.getElementById('userName').value; var usernameOrEmailAddress = document.getElementById('userName').value;
if (!usernameOrEmailAddress) { // if (!usernameOrEmailAddress) {
alert('UserName Can Not Be Null'); // alert('UserName Can Not Be Null');
return false; // return false;
} // }
var password = document.getElementById('password').value; var password = document.getElementById('password').value;
var pwdMd5 = document.getElementById('pwdMd5').value; var pwdMd5 = document.getElementById('pwdMd5').value;
@@ -288,9 +288,9 @@ var abp = abp || {};
xhr.onreadystatechange = function () { xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) { if (xhr.readyState === XMLHttpRequest.DONE) {
debugger; // debugger;
if (xhr.status === 200) { if (xhr.status === 200) {
debugger; // debugger;
var resultdata = JSON.parse(xhr.responseText); var resultdata = JSON.parse(xhr.responseText);
if (resultdata.ErrorMessage != '') { if (resultdata.ErrorMessage != '') {
@@ -303,9 +303,14 @@ var abp = abp || {};
else { else {
var responseJSON = JSON.parse(xhr.responseText); var responseJSON = JSON.parse(xhr.responseText);
var result = responseJSON; var result = responseJSON;
var expireDate = new Date(Date.now() + (60*60*24 * 1000)); var expireDate = new Date(Date.now() + (60 * 60 * 24 * 1000));
abp.auth.setToken(result.Result.JWTStr, expireDate); abp.auth.setToken(result.Result.JWTStr, expireDate);
callback(); let selectDom = document.getElementById("roleSelect")
selectDom.options.length = 0;
result.Result.BasicInfo.AccountList.forEach(item => {
selectDom.options.add(new Option(item.UserTypeShortName, item.Id));
})
// callback();
} }
} else { } else {
@@ -314,7 +319,7 @@ var abp = abp || {};
} }
}; };
xhr.open('POST', '/user/login', true); xhr.open('POST', '/User/getUserLoginRoleList', true);
xhr.setRequestHeader('Abp.TenantId', tenantId); xhr.setRequestHeader('Abp.TenantId', tenantId);
xhr.setRequestHeader('Content-type', 'application/json'); xhr.setRequestHeader('Content-type', 'application/json');
var parm = { var parm = {
@@ -330,7 +335,63 @@ var abp = abp || {};
//xhr.send("{" + "userName:'" + usernameOrEmailAddress + "'," + "passWord:'" + password + "'}"); //xhr.send("{" + "userName:'" + usernameOrEmailAddress + "'," + "passWord:'" + password + "'}");
}; };
function loginUserInternalRole(tenantId, callback) {
var usernameOrEmailAddress = document.getElementById('roleSelect').value;
//if (!usernameOrEmailAddress) {
// alert('UserName Can Not Be Null');
// return false;
//}
var password = document.getElementById('password').value;
var pwdMd5 = document.getElementById('pwdMd5').value;
console.log(pwdMd5);
if (!password && !pwdMd5) {
alert('PassWord And Md5 Can Not Be Null');
return false;
}
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
// debugger;
if (xhr.status === 200) {
// debugger;
var resultdata = JSON.parse(xhr.responseText);
if (resultdata.ErrorMessage != '') {
alert(resultdata.ErrorMessage);
return false;
}
if (resultdata.code == 300) {
alert(resultdata.message);
}
else {
var responseJSON = JSON.parse(xhr.responseText);
var result = responseJSON;
var expireDate = new Date(Date.now() + (60 * 60 * 24 * 1000));
abp.auth.setToken(result.Result, expireDate);
callback();
}
} else {
alert('Login failed !');
}
}
};
xhr.open('get', `/User/loginSelectUserRole?userRoleId=${usernameOrEmailAddress}`, true);
xhr.setRequestHeader('Abp.TenantId', tenantId);
xhr.setRequestHeader('Content-type', 'application/json');
var authToken = abp.auth.getToken();
xhr.setRequestHeader('Authorization', `Bearer ${authToken}`);
xhr.send();
//xhr.send("{" + "userName:'" + usernameOrEmailAddress + "'," + "passWord:'" + password + "'}");
};
abp.swagger.login = function (callback) { abp.swagger.login = function (callback) {
//Get TenantId first //Get TenantId first
var tenancyName = document.getElementById('tenancyName').value; var tenancyName = document.getElementById('tenancyName').value;
@@ -356,6 +417,31 @@ var abp = abp || {};
loginUserInternal(null, callback); // Login for host loginUserInternal(null, callback); // Login for host
} }
}; };
abp.swagger.loginRole = function (callback) {
//Get TenantId first
var tenancyName = document.getElementById('tenancyName').value;
if (tenancyName) {
var xhrTenancyName = new XMLHttpRequest();
xhrTenancyName.onreadystatechange = function () {
if (xhrTenancyName.readyState === XMLHttpRequest.DONE && xhrTenancyName.status === 200) {
var responseJSON = JSON.parse(xhrTenancyName.responseText);
var result = responseJSON.result;
if (result.state === 1) { // Tenant exists and active.
loginUserInternalRole(result.tenantId, callback); // Login for tenant
} else {
alert('There is no such tenant or tenant is not active !');
}
}
};
xhrTenancyName.open('POST', '/api/services/app/Account/IsTenantAvailable', true);
xhrTenancyName.setRequestHeader('Content-type', 'application/json');
xhrTenancyName.send("{" + "tenancyName:'" + tenancyName + "'}");
} else {
loginUserInternalRole(null, callback); // Login for host
}
};
abp.swagger.logout = function () { abp.swagger.logout = function () {
abp.auth.clearToken(); abp.auth.clearToken();
@@ -419,9 +505,10 @@ var abp = abp || {};
//Inputs //Inputs
createInput(modalUxContent, 'tenancyName', 'Tenancy Name (Leave empty for Host)'); createInput(modalUxContent, 'tenancyName', 'Tenancy Name (Leave empty for Host)');
createInput(modalUxContent, 'userName', 'Username or email address','text','cyldev'); createInput(modalUxContent, 'userName', 'Username or email address', 'text', 'cyldev');
createInput(modalUxContent, 'password', 'Password', 'password', '123456'); createInput(modalUxContent, 'password', 'Password', 'password', '123456');
createInput(modalUxContent, 'pwdMd5', 'PwdMd5', 'text', ''); createInput(modalUxContent, 'pwdMd5', 'PwdMd5', 'text', '');
createSelect(modalUxContent, 'roleSelect', 'role', [])
//Buttons //Buttons
var authBtnWrapper = document.createElement('div'); var authBtnWrapper = document.createElement('div');
@@ -444,9 +531,18 @@ var abp = abp || {};
abp.swagger.login(loginCallback); abp.swagger.login(loginCallback);
}; };
authBtnWrapper.appendChild(authorizeButton); authBtnWrapper.appendChild(authorizeButton);
// login role
var authorizeButton = document.createElement('button');
authorizeButton.className = 'btn modal-btn auth authorize button';
authorizeButton.innerText = 'LoginRole';
authorizeButton.onclick = function () {
abp.swagger.loginRole(loginCallback);
};
authBtnWrapper.appendChild(authorizeButton);
} }
function createInput(container, id, title, type, value="") { function createInput(container, id, title, type, value = "") {
var wrapper = document.createElement('div'); var wrapper = document.createElement('div');
wrapper.className = 'wrapper'; wrapper.className = 'wrapper';
if (id == "tenancyName") { if (id == "tenancyName") {
@@ -470,6 +566,31 @@ var abp = abp || {};
input.autocomplete = "off"; input.autocomplete = "off";
section.appendChild(input);
}
function createSelect(container, id, title, option = []) {
var wrapper = document.createElement('div');
wrapper.className = 'wrapper';
if (id == "tenancyName") {
wrapper.style.display = 'none';
}
container.appendChild(wrapper);
var label = document.createElement('label');
label.innerText = title;
wrapper.appendChild(label);
var section = document.createElement('section');
section.className = 'block-tablet col-10-tablet block-desktop col-10-desktop';
wrapper.appendChild(section);
var input = document.createElement('select');
input.id = id;
input.style.width = '100%';
option.forEach(item => {
input.options.add(new Option(item.UserTypeShortName, item.Id));
})
section.appendChild(input); section.appendChild(input);
} }
@@ -1,46 +0,0 @@
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.Application.Auth
{
public class IRaCISClaims
{
public Guid Id { get; set; }
public string FullName { get; set; } = String.Empty;
public string Code { get; set; } = String.Empty;
public string RealName { get; set; } = String.Empty;
public string UserTypeShortName { get; set; } = String.Empty;
public UserTypeEnum UserTypeEnum { get; set; }
public string PermissionStr { get; set; } = String.Empty;
public Guid UserTypeId { get; set; }
public int IsAdmin { get; }
public bool IsTestUser { get; set; }
public bool IsZhiZhun { get; set; }
public string Phone { get; set; } = String.Empty;
public static IRaCISClaims Create(UserBasicInfo user)
{
return new IRaCISClaims
{
Id = user.Id,
FullName = user.UserName,
RealName = user.RealName,
UserTypeEnum = user.UserTypeEnum,
UserTypeId = user.UserTypeId,
IsTestUser = user.IsTestUser,
Code = user.Code,
PermissionStr = user.PermissionStr,
IsZhiZhun = user.IsZhiZhun,
UserTypeShortName = user.UserTypeShortName
};
}
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ namespace IRaCIS.Core.Application.Auth
/// <summary> /// <summary>
/// 过期时间 /// 过期时间
/// </summary> /// </summary>
public int TokenExpireDays { get; set; } public int TokenExpireMinute { get; set; }
//public Dictionary<string, object> Claims { get; set; } //public Dictionary<string, object> Claims { get; set; }
+23 -7
View File
@@ -8,7 +8,9 @@ namespace IRaCIS.Core.Application.Auth
public interface ITokenService public interface ITokenService
{ {
string GetToken(IRaCISClaims user); string GetToken(UserTokenInfo user);
bool IsTokenExpired(string token);
} }
@@ -21,16 +23,16 @@ namespace IRaCIS.Core.Application.Auth
_jwtSetting = option.Value; _jwtSetting = option.Value;
} }
public string GetToken(IRaCISClaims user) public string GetToken(UserTokenInfo user)
{ {
//创建用户身份标识,可按需要添加更多信息 //创建用户身份标识,可按需要添加更多信息
var claims = new Claim[] var claims = new Claim[]
{ {
new Claim(Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtIRaCISClaimType.Id, user.Id.ToString()), new Claim(JwtIRaCISClaimType.IdentityUserId, user.IdentityUserId.ToString()),
new Claim(JwtIRaCISClaimType.Name, user.FullName), new Claim(JwtIRaCISClaimType.UserRoleId, user.UserRoleId.ToString()),
new Claim(JwtIRaCISClaimType.RealName, user.RealName), new Claim(JwtIRaCISClaimType.UserName, user.UserName),
new Claim(JwtIRaCISClaimType.Code,user.Code), new Claim(JwtIRaCISClaimType.FullName, user.FullName),
new Claim(JwtIRaCISClaimType.UserTypeId,user.UserTypeId.ToString()), new Claim(JwtIRaCISClaimType.UserTypeId,user.UserTypeId.ToString()),
new Claim(JwtIRaCISClaimType.UserTypeEnum,user.UserTypeEnum.ToString()), new Claim(JwtIRaCISClaimType.UserTypeEnum,user.UserTypeEnum.ToString()),
new Claim(JwtIRaCISClaimType.UserTypeEnumInt,((int)user.UserTypeEnum).ToString()), new Claim(JwtIRaCISClaimType.UserTypeEnumInt,((int)user.UserTypeEnum).ToString()),
@@ -47,13 +49,27 @@ namespace IRaCIS.Core.Application.Auth
signingCredentials: _jwtSetting.Credentials, signingCredentials: _jwtSetting.Credentials,
claims: claims, claims: claims,
notBefore: DateTime.Now, notBefore: DateTime.Now,
expires: DateTime.Now.AddDays(_jwtSetting.TokenExpireDays) expires: DateTime.Now.AddMinutes(_jwtSetting.TokenExpireMinute)
); );
string jwtToken = new JwtSecurityTokenHandler().WriteToken(token); string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
return jwtToken; return jwtToken;
} }
public bool IsTokenExpired(string token)
{
var handler = new JwtSecurityTokenHandler();
try
{
var jwtToken = handler.ReadJwtToken(token);
return jwtToken.ValidTo < DateTime.UtcNow;
}
catch
{
return true; // 无效 Token 也视为已过期
}
}
} }
@@ -0,0 +1,27 @@
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.Application.Auth
{
public class UserTokenInfo
{
public Guid IdentityUserId { get; set; }
public Guid UserRoleId { get; set; }
public Guid UserTypeId { get; set; }
public UserTypeEnum UserTypeEnum { get; set; }
public string UserName { get; set; } = string.Empty;
public string FullName { get; set; } = string.Empty;
public string PermissionStr { get; set; } = string.Empty;
public bool IsTestUser { get; set; }
public bool IsZhiZhun { get; set; }
public string UserTypeShortName { get; set; } = string.Empty;
}
}
@@ -48,7 +48,7 @@ public class LimitUserRequestAuthorization(
//2、在这里取缓存 进行比较 看是否有其他人进行了登陆,如果其他人登陆了,就把之前用户挤掉 //2、在这里取缓存 进行比较 看是否有其他人进行了登陆,如果其他人登陆了,就把之前用户挤掉
var cacheUserToken = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.UserToken(_userInfo.Id)); var cacheUserToken = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.UserToken(_userInfo.IdentityUserId));
@@ -58,17 +58,17 @@ public class LimitUserRequestAuthorization(
cacheUserToken = _userInfo.UserToken; cacheUserToken = _userInfo.UserToken;
//设置当前用户最新Token //设置当前用户最新Token
await _fusionCache.SetAsync(CacheKeys.UserToken(_userInfo.Id), _userInfo.UserToken, TimeSpan.FromDays(7)); await _fusionCache.SetAsync(CacheKeys.UserToken(_userInfo.IdentityUserId), _userInfo.UserToken, TimeSpan.FromDays(7));
//重启应用程序,所有人续期,不一下子踢出所有人 //重启应用程序,所有人续期,不一下子踢出所有人
await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(_userInfo.Id), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes)); await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(_userInfo.IdentityUserId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes));
} }
//是同一个人 //是同一个人
else if (cacheUserToken == _userInfo.UserToken) else if (cacheUserToken == _userInfo.UserToken)
{ {
var cacheTime = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.UserAutoLoginOut(_userInfo.Id)); var cacheTime = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.UserAutoLoginOut(_userInfo.IdentityUserId));
//过期了 需要自动退出 //过期了 需要自动退出
if (string.IsNullOrEmpty(cacheTime)) if (string.IsNullOrEmpty(cacheTime))
@@ -80,7 +80,7 @@ public class LimitUserRequestAuthorization(
} }
else else
{ {
await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(_userInfo.Id), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes)); await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(_userInfo.IdentityUserId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes));
} }
} }
else else
@@ -93,6 +93,21 @@ public class LimitUserRequestAuthorization(
} }
//用户或者角色禁用,那么操作的人退出
var isDisable = await _fusionCache.GetOrDefaultAsync<bool>(CacheKeys.UserDisable(_userInfo.IdentityUserId),false);
var isRoleDisable = await _fusionCache.GetOrDefaultAsync<bool>(CacheKeys.UserRoleDisable(_userInfo.UserRoleId),false);
if (isDisable == true || isRoleDisable == true)
{
context.HttpContext.Response.ContentType = "application/json";
context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
// 用户或者角色被禁用。
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["LimitUser_AccountOrRoleDisable"], ApiResponseCodeEnum.AutoLoginOut));
}
} }
} }
@@ -41,19 +41,19 @@ public class LimitUserRequestAuthorizationEndpointFilter(
} }
// 获取缓存中的用户 token // 获取缓存中的用户 token
var cacheUserToken = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.UserToken(_userInfo.Id)); var cacheUserToken = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.UserToken(_userInfo.IdentityUserId));
// 缓存中没有取到 token // 缓存中没有取到 token
if (string.IsNullOrWhiteSpace(cacheUserToken)) if (string.IsNullOrWhiteSpace(cacheUserToken))
{ {
// 设置当前用户最新 token // 设置当前用户最新 token
await _fusionCache.SetAsync(CacheKeys.UserToken(_userInfo.Id), _userInfo.UserToken, TimeSpan.FromDays(7)); await _fusionCache.SetAsync(CacheKeys.UserToken(_userInfo.IdentityUserId), _userInfo.UserToken, TimeSpan.FromDays(7));
await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(_userInfo.Id), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes)); await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(_userInfo.IdentityUserId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes));
} }
// 如果是同一个用户 // 如果是同一个用户
else if (cacheUserToken == _userInfo.UserToken) else if (cacheUserToken == _userInfo.UserToken)
{ {
var cacheTime = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.UserAutoLoginOut(_userInfo.Id)); var cacheTime = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.UserAutoLoginOut(_userInfo.IdentityUserId));
// 如果过期,自动登出 // 如果过期,自动登出
if (string.IsNullOrEmpty(cacheTime)) if (string.IsNullOrEmpty(cacheTime))
@@ -63,7 +63,7 @@ public class LimitUserRequestAuthorizationEndpointFilter(
} }
else else
{ {
await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(_userInfo.Id), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes)); await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(_userInfo.IdentityUserId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes));
} }
} }
else else
@@ -51,6 +51,8 @@ public class SystemEmailSendConfig
public string SiteUrl { get; set; } = string.Empty; public string SiteUrl { get; set; } = string.Empty;
public string SystemShortName { get; set; } = string.Empty;
public string OrganizationName { get; set; } = string.Empty; public string OrganizationName { get; set; } = string.Empty;
public string OrganizationNameCN { get; set; } = string.Empty; public string OrganizationNameCN { get; set; } = string.Empty;
@@ -140,7 +142,7 @@ public static class AppSettings
case nameof(Doctor): case nameof(Doctor):
return IRaCISBasicConfig.DoctorCodePrefix + codeInt.ToString("D4"); return IRaCISBasicConfig.DoctorCodePrefix + codeInt.ToString("D4");
case nameof(User): case nameof(IdentityUser):
return IRaCISBasicConfig.UserCodePrefix + codeInt.ToString("D4"); return IRaCISBasicConfig.UserCodePrefix + codeInt.ToString("D4");
case nameof(QCChallenge): case nameof(QCChallenge):
+1
View File
@@ -10,5 +10,6 @@ global using Microsoft.Extensions.Localization;
global using AutoMapper; global using AutoMapper;
global using IRaCIS.Core.Domain.Share; global using IRaCIS.Core.Domain.Share;
global using IRaCIS.Core.Application.BusinessFilter; global using IRaCIS.Core.Application.BusinessFilter;
global using IdentityUser = IRaCIS.Core.Domain.Models.IdentityUser;
@@ -27,6 +27,11 @@ public static class CacheKeys
//超时没请求接口自动退出 //超时没请求接口自动退出
public static string UserAutoLoginOut(Guid userId) => $"UserAutoLoginOut:{userId}"; public static string UserAutoLoginOut(Guid userId) => $"UserAutoLoginOut:{userId}";
public static string UserDisable(Guid userId) => $"UserDisable:{userId}";
public static string UserRoleDisable(Guid userRoleId) => $"UserRoleDisable:{userRoleId}";
/// <summary> /// <summary>
/// 用户登录错误 限制登录 /// 用户登录错误 限制登录
/// </summary> /// </summary>
@@ -64,7 +64,7 @@ public static class ExcelExportHelper
foreach (var key in dic.Keys) foreach (var key in dic.Keys)
{ {
//是数组 那么找到对应的属性 进行翻译 //是数组 那么找到对应的属性 进行翻译
if (dic[key]!=null && dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>))) if (dic[key] != null && dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)))
{ {
var newObjList = new List<object>(); var newObjList = new List<object>();
@@ -255,13 +255,17 @@ public static class ExcelExportHelper
/// </summary> /// </summary>
public int AutoColumnTitleRowIndex { get; set; } public int AutoColumnTitleRowIndex { get; set; }
/// <summary>
/// 模板列最后的索引
/// </summary>
public int TempalteLastColumnIndex { get; set; } public int TempalteLastColumnIndex { get; set; }
public List<string> CDISCList { get; set; } = new List<string>();
/// <summary> /// <summary>
/// 动态的列名 /// 动态的列名 如果Id 重复,那么就按照名称填充,否则就按照Id 填充列数据
/// </summary> /// </summary>
public List<string> ColumnNameList { get; set; } = new List<string>(); public List<ColumItem> ColumnIdNameList { get; set; }
/// <summary> /// <summary>
/// 动态翻译的字典名 /// 动态翻译的字典名
@@ -288,7 +292,29 @@ public static class ExcelExportHelper
/// </summary> /// </summary>
public string DynamicItemTitleName { get; set; } public string DynamicItemTitleName { get; set; }
public string DynamicItemTitleId { get; set; }
public List<int> RemoveColunmIndexList { get; set; } = new List<int>(); public List<int> RemoveColunmIndexList { get; set; } = new List<int>();
public class ColumItem
{
public Guid Id { get; set; }
public string Name { get; set; }
public override bool Equals(object obj)
{
if (obj is not ColumItem other) return false;
return Id == other.Id && Name == other.Name;
}
public override int GetHashCode()
{
return HashCode.Combine(Id, Name);
}
}
public List<string> ColumnIdList => ColumnIdNameList == null ? new List<string>() : ColumnIdNameList.Select(t => t.Id.ToString()).ToList();
public List<string> ColumnNameList => ColumnIdNameList == null ? new List<string>() : ColumnIdNameList.Select(t => t.Name).ToList();
} }
@@ -421,7 +447,7 @@ public static class ExcelExportHelper
workbook.RemoveSheetAt(1); workbook.RemoveSheetAt(1);
} }
//中文替换项目术语 #region
if (data.TrialObjectNameList?.Count > 0) if (data.TrialObjectNameList?.Count > 0)
{ {
var replaceObjectList = data.TrialObjectNameList; var replaceObjectList = data.TrialObjectNameList;
@@ -457,21 +483,28 @@ public static class ExcelExportHelper
} }
} }
} }
#endregion
if (dynamicColumnConfig != null) if (dynamicColumnConfig != null)
{ {
var isCdics = dynamicColumnConfig.CDISCList.Count > 0;
var sheet = workbook.GetSheetAt(0); var sheet = workbook.GetSheetAt(0);
var cdicsRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex - 1);
var titelRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex); var titelRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex);
var templateRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex + 1); var templateRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex + 1);
//动态移除列的数量 //动态移除列的数量
var dynamicRemoveColunmCount = dynamicColumnConfig.RemoveColunmIndexList.Count(); var dynamicRemoveColunmCount = dynamicColumnConfig.RemoveColunmIndexList.Count();
//在动态列开始前移除的数量
var beforeDynamicRemoveCount = dynamicColumnConfig.RemoveColunmIndexList.Where(t => t < dynamicColumnConfig.AutoColumnStartIndex).Count(); var beforeDynamicRemoveCount = dynamicColumnConfig.RemoveColunmIndexList.Where(t => t < dynamicColumnConfig.AutoColumnStartIndex).Count();
//动态添加列的数量 //动态添加列的数量
var needAddCount = dynamicColumnConfig.ColumnNameList.Count; var needAddCount = dynamicColumnConfig.ColumnIdNameList.Count;
//原始表 最终索引 //原始表 最终索引
var originTotalEndIndex = dynamicColumnConfig.TempalteLastColumnIndex; var originTotalEndIndex = dynamicColumnConfig.TempalteLastColumnIndex;
@@ -513,8 +546,14 @@ public static class ExcelExportHelper
//创建新的列 //创建新的列
for (int i = originTotalEndIndex; i < originTotalEndIndex + needAddCount; i++) for (int i = originTotalEndIndex; i < originTotalEndIndex + needAddCount; i++)
{ {
titelRow.CreateCell(i + 1); titelRow.CreateCell(i + 1);
templateRow.CreateCell(i + 1); templateRow.CreateCell(i + 1);
if (isCdics)
{
cdicsRow.CreateCell(i + 1);
}
} }
//移动Title 和下面的模板标识 //移动Title 和下面的模板标识
@@ -534,10 +573,17 @@ public static class ExcelExportHelper
for (int i = dynamicColunmStartIndex; i < dynamicColunmStartIndex + needAddCount; i++) for (int i = dynamicColunmStartIndex; i < dynamicColunmStartIndex + needAddCount; i++)
{ {
var name = dynamicColumnConfig.ColumnNameList[i - dynamicColunmStartIndex]; var name = dynamicColumnConfig.ColumnIdNameList[i - dynamicColunmStartIndex].Name;
titelRow.GetCell(i).SetCellValue(name); titelRow.GetCell(i).SetCellValue(name);
templateRow.GetCell(i).SetCellValue(""); templateRow.GetCell(i).SetCellValue("");
if (isCdics)
{
var cdicsCode = dynamicColumnConfig.CDISCList[i - dynamicColunmStartIndex];
cdicsRow.GetCell(i).SetCellValue(cdicsCode);
}
} }
} }
@@ -569,6 +615,9 @@ public static class ExcelExportHelper
if (dynamicColumnConfig != null) if (dynamicColumnConfig != null)
{ {
//Excel 列是按照名称填充 还是Id 填充
var isExcelAddDataWithName = dynamicColumnConfig.ColumnIdNameList.Select(t => t.Id).Distinct().Count() == 1;
var dynamicTranslateDataList = await _dictionaryService.GetBasicDataSelect(dynamicColumnConfig.TranslateDicNameList.ToArray()); var dynamicTranslateDataList = await _dictionaryService.GetBasicDataSelect(dynamicColumnConfig.TranslateDicNameList.ToArray());
// 使用NPOI 进行二次处理 // 使用NPOI 进行二次处理
@@ -599,7 +648,17 @@ public static class ExcelExportHelper
//var writeIndex = itemList.IndexOf(itemObj) + dynamicColumnConfig.AutoColumnStartIndex; //var writeIndex = itemList.IndexOf(itemObj) + dynamicColumnConfig.AutoColumnStartIndex;
var writeIndex = dynamicColumnConfig.ColumnNameList.IndexOf(iteObjDic[dynamicColumnConfig.DynamicItemTitleName].ToString()) + dynamicColumnConfig.AutoColumnStartIndex; var writeIndex = 0;
if (isExcelAddDataWithName)
{
writeIndex = dynamicColumnConfig.ColumnNameList.IndexOf(iteObjDic[dynamicColumnConfig.DynamicItemTitleName].ToString()) + dynamicColumnConfig.AutoColumnStartIndex;
}
else
{
writeIndex = dynamicColumnConfig.ColumnIdList.IndexOf(iteObjDic[dynamicColumnConfig.DynamicItemTitleId].ToString()) + dynamicColumnConfig.AutoColumnStartIndex;
}
if (itemDicName.IsNotNullOrEmpty()) if (itemDicName.IsNotNullOrEmpty())
{ {
@@ -634,6 +693,332 @@ public static class ExcelExportHelper
#endregion #endregion
} }
/// <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>
public static async Task<(MemoryStream, string)> CDISC_DataExport_Async(string code, ExcelExportInfo data, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null, DynamicColumnConfig? dynamicColumnConfig = null)
{
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
//判断是否有字典翻译
object translateData = data;
Dictionary<string, object> translatedDic = default;
if (_dictionaryService != null && translateType != null)
{
//一个值 对应不同的字典翻译
var needTranslatePropertyList = translateType.GetProperties().Where(t => t.IsDefined(typeof(DictionaryTranslateAttribute), true))
.SelectMany(c =>
c.GetCustomAttributes(typeof(DictionaryTranslateAttribute), false).Select(f => (DictionaryTranslateAttribute?)f).Where(t => t.CriterionType == criterionType || t.CriterionType == null)
.Select(k => new { c.Name, k.DicParentCode, k.IsTranslateDenpendOtherProperty, k.DependPropertyName, k.DependPropertyValueStr })
).ToList();
//字典表查询出所有需要翻译的数据
var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());
var dic = data.ConvertToDictionary();
//var dic = (JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull())).IfNullThrowException();
foreach (var key in dic.Keys)
{
//是数组 那么找到对应的属性 进行翻译
if (dic[key] != null && dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)))
//if (dic[key].GetType().IsAssignableFrom(typeof(JArray)))
{
var newObjList = new List<object>();
var no = 1;
foreach (var item in dic[key] as IList)
//foreach (var item in dic[key] as JArray)
{
//var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull());
var itemDic = item.ConvertToDictionary();
foreach (var needTranslateProperty in needTranslatePropertyList)
{
if (itemDic.Keys.Any(t => t == needTranslateProperty.Name))
{
//翻译的属性依赖其他属性
if (needTranslateProperty.IsTranslateDenpendOtherProperty)
{
if (itemDic[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower())
{
var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
}
}
//普通翻译 或者某一标准翻译
else
{
var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
}
}
}
itemDic.Add("No", no++);
newObjList.Add(itemDic);
}
dic[key] = newObjList;
}
}
//data = dic;
translateData = dic;
translatedDic = dic;
}
var (physicalPath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);
//模板路径
var tplPath = physicalPath;
#region sheet
// 打开模板文件
var templateFile = new FileStream(tplPath, FileMode.Open, FileAccess.Read);
// 获取文件流
var templateStream = new MemoryStream();
templateFile.CopyTo(templateStream);
templateStream.Seek(0, SeekOrigin.Begin);
var workbook = new XSSFWorkbook(templateStream);
int sheetCount = workbook.NumberOfSheets;
if (sheetCount == 2)
{
if (isEn_US)
{
workbook.RemoveSheetAt(0);
}
else
{
workbook.RemoveSheetAt(1);
}
if (dynamicColumnConfig != null)
{
var sheet = workbook.GetSheetAt(0);
var cdicsRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex - 1);
var titelRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex);
var templateRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex + 1);
//动态移除列的数量
var dynamicRemoveColunmCount = dynamicColumnConfig.RemoveColunmIndexList.Count();
//在动态列开始前移除的数量
var beforeDynamicRemoveCount = dynamicColumnConfig.RemoveColunmIndexList.Where(t => t < dynamicColumnConfig.AutoColumnStartIndex).Count();
//动态添加列的数量
var needAddCount = dynamicColumnConfig.ColumnIdNameList.Count;
//原始表 最终索引
var originTotalEndIndex = dynamicColumnConfig.TempalteLastColumnIndex;
//减去动态移除后原始结束索引
var originRemoveEndIndex = originTotalEndIndex - dynamicRemoveColunmCount;
//最终表 动态列开始索引
var dynamicColunmStartIndex = dynamicColumnConfig.AutoColumnStartIndex - beforeDynamicRemoveCount;
//最终表 动态列的终止索引
var dynamicColunmEndIndex = dynamicColunmStartIndex + needAddCount - 1;
//最终表 最终索引
var totalColunmEndIndex = originTotalEndIndex + needAddCount - dynamicRemoveColunmCount;
//动态列后需要移动的数量
var backMoveCount = totalColunmEndIndex - dynamicColunmEndIndex;
//删除需要动态删除的列 从大到小移除,否则索引会变
foreach (var removeIndex in dynamicColumnConfig.RemoveColunmIndexList.OrderByDescending(t => t))
{
//将后面的列向前移动
for (var i = 0; i < originTotalEndIndex - removeIndex; i++)
{
Console.WriteLine(titelRow.GetCell(removeIndex + i + 1).StringCellValue);
titelRow.GetCell(removeIndex + i).SetCellValue(titelRow.GetCell(removeIndex + i + 1).StringCellValue);
templateRow.GetCell(removeIndex + i).SetCellValue(templateRow.GetCell(removeIndex + i + 1).StringCellValue);
//后面的数据要清空
titelRow.GetCell(removeIndex + i + 1).SetCellValue("");
templateRow.GetCell(removeIndex + i + 1).SetCellValue("");
}
}
//创建新的列
for (int i = originTotalEndIndex; i < originTotalEndIndex + needAddCount; i++)
{
cdicsRow.CreateCell(i + 1);
titelRow.CreateCell(i + 1);
templateRow.CreateCell(i + 1);
}
//移动Title 和下面的模板标识
var gap = totalColunmEndIndex - originRemoveEndIndex;
for (int i = totalColunmEndIndex; i > dynamicColunmEndIndex; i--)
{
titelRow.GetCell(i).SetCellValue(titelRow.GetCell(i - gap).StringCellValue);
templateRow.GetCell(i).SetCellValue(templateRow.GetCell(i - gap).StringCellValue);
}
//设置动态Tilte
for (int i = dynamicColunmStartIndex; i < dynamicColunmStartIndex + needAddCount; i++)
{
var name = dynamicColumnConfig.ColumnIdNameList[i - dynamicColunmStartIndex].Name;
var cdicsCode = dynamicColumnConfig.CDISCList[i - dynamicColunmStartIndex];
cdicsRow.GetCell(i).SetCellValue(cdicsCode);
titelRow.GetCell(i).SetCellValue(name);
templateRow.GetCell(i).SetCellValue("");
}
}
using (var memoryStream2 = new MemoryStream())
{
workbook.Write(memoryStream2, true);
memoryStream2.Seek(0, SeekOrigin.Begin);
templateStream = memoryStream2;
}
}
#endregion
#region MiniExcel
var memoryStream = new MemoryStream();
var config = new OpenXmlConfiguration()
{
IgnoreTemplateParameterMissing = true,
};
await MiniExcel.SaveAsByTemplateAsync(memoryStream, templateStream.ToArray(), translateData, config);
memoryStream.Seek(0, SeekOrigin.Begin);
if (dynamicColumnConfig != null)
{
var isExcelAddDataWithName = dynamicColumnConfig.ColumnIdNameList.Select(t => t.Id).Count() == 1;
var dynamicTranslateDataList = await _dictionaryService.GetBasicDataSelect(dynamicColumnConfig.TranslateDicNameList.ToArray());
// 使用NPOI 进行二次处理
var wb = new XSSFWorkbook(memoryStream);
var sheet = wb.GetSheetAt(0);
var list = translatedDic["List"] as IList;
foreach (var itemResult in list)
{
var index = list.IndexOf(itemResult);
//从第四行开始处理动态列
var row = sheet.GetRow(index + dynamicColumnConfig.AutoColumnTitleRowIndex + 1);
var itemDic = itemResult.ToDictionary();
var itemList = itemDic[dynamicColumnConfig.DynamicListName] as IList;
//这个数组是动态的,有的多,有的少,所以在此对比Title 一致才赋值
foreach (var itemObj in itemList)
{
var iteObjDic = itemObj.ToDictionary();
var itemDicName = iteObjDic[dynamicColumnConfig.DynamicItemDicName]?.ToString();
var itemValue = iteObjDic[dynamicColumnConfig.DynamicItemValueName]?.ToString();
//var writeIndex = itemList.IndexOf(itemObj) + dynamicColumnConfig.AutoColumnStartIndex;
var writeIndex = 0;
if (isExcelAddDataWithName)
{
writeIndex = dynamicColumnConfig.ColumnNameList.IndexOf(iteObjDic[dynamicColumnConfig.DynamicItemTitleName].ToString()) + dynamicColumnConfig.AutoColumnStartIndex;
}
else
{
writeIndex = dynamicColumnConfig.ColumnIdList.IndexOf(iteObjDic[dynamicColumnConfig.DynamicItemTitleId].ToString()) + dynamicColumnConfig.AutoColumnStartIndex;
}
if (itemDicName.IsNotNullOrEmpty())
{
var translatedItemData = dynamicTranslateDataList[itemDicName].Where(t => t.Code.ToLower() == itemValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
row.GetCell(writeIndex).SetCellValue(translatedItemData);
}
else
{
row.GetCell(writeIndex).SetCellValue(itemValue);
}
}
}
var memoryStream2 = new MemoryStream();
wb.Write(memoryStream2, true);
memoryStream2.Seek(0, SeekOrigin.Begin);
memoryStream = memoryStream2;
}
return (memoryStream, fileName);
#endregion
}
/// <summary> /// <summary>
/// 导出文件模板 /// 导出文件模板
+415 -6
View File
@@ -1,5 +1,6 @@
using AlibabaCloud.SDK.Sts20150401; using AlibabaCloud.SDK.Sts20150401;
using Aliyun.OSS; using Aliyun.OSS;
using Aliyun.OSS.Common;
using Amazon; using Amazon;
using Amazon.Runtime; using Amazon.Runtime;
using Amazon.S3; using Amazon.S3;
@@ -9,9 +10,12 @@ using Amazon.SecurityToken.Model;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.NewtonsoftJson; using IRaCIS.Core.Infrastructure.NewtonsoftJson;
using MassTransit; using MassTransit;
using MassTransit.Caching.Internals;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Minio; using Minio;
using Minio.DataModel;
using Minio.DataModel.Args; using Minio.DataModel.Args;
using Minio.Exceptions;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@@ -59,7 +63,7 @@ public class AliyunOSSOptions
public int DurationSeconds { get; set; } public int DurationSeconds { get; set; }
public string PreviewEndpoint { get; set; }
} }
@@ -105,6 +109,7 @@ public class AliyunOSSTempToken
public string SecurityToken { get; set; } public string SecurityToken { get; set; }
public DateTime Expiration { get; set; } public DateTime Expiration { get; set; }
public string PreviewEndpoint { get; set; }
} }
@@ -143,9 +148,17 @@ public interface IOSSService
public Task<string> GetSignedUrl(string ossRelativePath); public Task<string> GetSignedUrl(string ossRelativePath);
public Task DeleteFromPrefix(string prefix); public Task DeleteFromPrefix(string prefix, bool isCache = false);
public Task DeleteObjects(List<string> objectKeys);
List<string> GetRootFolderNames();
public ObjectStoreDTO GetObjectStoreTempToken(); public ObjectStoreDTO GetObjectStoreTempToken();
public Task MoveObject(string sourcePath, string destPath, bool overwrite = true);
public Task<long> GetObjectSizeAsync(string sourcePath);
} }
@@ -526,12 +539,240 @@ public class OSSService : IOSSService
} }
/// <summary>
/// 移动OSS文件到新路径
/// </summary>
/// <param name="sourcePath">原文件路径(格式:bucket/key</param>
/// <param name="destPath">新文件路径(格式:bucket/key</param>
/// <param name="overwrite">是否覆盖已存在的目标文件(默认true</param>
public async Task MoveObject(string sourcePath, string destPath, bool overwrite = true)
{
GetObjectStoreTempToken();
switch (ObjectStoreServiceOptions.ObjectStoreUse)
{
case "AliyunOSS":
#region
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var client = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
if (sourcePath.StartsWith("/"))
{
sourcePath = sourcePath.Substring(1);
}
if (destPath.StartsWith("/"))
{
destPath = destPath.Substring(1);
}
var sourceBucket = aliConfig.BucketName;
var sourceKey = sourcePath;
var destBucket = aliConfig.BucketName;
var destKey = destPath;
try
{
// 检查目标是否存在(当不允许覆盖时)
if (!overwrite && client.DoesObjectExist(destBucket, destKey))
{
throw new InvalidOperationException("File Exist");
}
//var copyRequest = new Aliyun.OSS.CopyObjectRequest(sourceBucket, sourceKey, sourceBucket, destKey);
//var result = client.CopyObject(copyRequest);
//// 2. 删除原文件(可选,根据是否需要保留原文件)
//client.DeleteObject(sourceBucket, sourceKey);
// 执行复制
var copyRequestAli = new Aliyun.OSS.CopyObjectRequest(
sourceBucket, sourceKey,
destBucket, destKey);
// 保持原文件元数据
copyRequestAli.NewObjectMetadata = new ObjectMetadata
{
ContentType = client.GetObjectMetadata(sourceBucket, sourceKey).ContentType
};
var result = client.CopyObject(copyRequestAli);
// 删除原文件(仅在复制成功后)
client.DeleteObject(sourceBucket, sourceKey);
}
catch (OssException ex)
{
throw new Exception($"[{ex.ErrorCode}] {ex.Message}", ex);
}
#endregion
break;
case "MinIO":
#region MinIO
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient()
.WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey)
.WithSSL(minIOConfig.UseSSL)
.Build();
// 定义源路径和目标路径
string destinationKey = "b路径/文件名";
try
{
// 1. 复制文件到新路径[2,5](@ref)
using (var memoryStream = new MemoryStream())
{
// 下载源文件流
await minioClient.GetObjectAsync(new GetObjectArgs()
.WithBucket(minIOConfig.BucketName)
.WithObject(sourcePath)
.WithCallbackStream(stream => stream.CopyTo(memoryStream)));
memoryStream.Position = 0; // 重置流位置
// 上传到新路径
await minioClient.PutObjectAsync(new PutObjectArgs()
.WithBucket(minIOConfig.BucketName)
.WithObject(destinationKey)
.WithStreamData(memoryStream)
.WithObjectSize(memoryStream.Length));
}
// 2. 删除原文件[1,6](@ref)
await minioClient.RemoveObjectAsync(new RemoveObjectArgs()
.WithBucket(minIOConfig.BucketName)
.WithObject(sourcePath));
}
catch (MinioException ex)
{
// 处理异常(例如:记录日志或抛出)
throw new Exception();
}
#endregion
break;
case "AWS":
#region AWS
var awsConfig = ObjectStoreServiceOptions.AWS;
var credentials = new SessionAWSCredentials(
AWSTempToken.AccessKeyId,
AWSTempToken.SecretAccessKey,
AWSTempToken.SessionToken
);
var clientConfig = new AmazonS3Config
{
RegionEndpoint = RegionEndpoint.USEast1,
UseHttp = true,
};
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
// 定义原路径和目标路径
// 1. 复制对象到新路径
var copyRequest = new Amazon.S3.Model.CopyObjectRequest
{
SourceBucket = awsConfig.BucketName,
SourceKey = sourcePath,
DestinationBucket = awsConfig.BucketName,
DestinationKey = destPath
};
try
{
// 执行复制操作
await amazonS3Client.CopyObjectAsync(copyRequest);
// 2. 删除原对象
var deleteRequest = new Amazon.S3.Model.DeleteObjectRequest
{
BucketName = awsConfig.BucketName,
Key = sourcePath
};
await amazonS3Client.DeleteObjectAsync(deleteRequest);
}
catch (AmazonS3Exception ex)
{
Console.WriteLine($"ERROR: {ex.Message}");
// 可根据异常类型细化处理(如文件不存在、权限问题等)
}
#endregion
break;
default:
throw new BusinessValidationFailedException("ERROR");
}
}
/// <summary>
/// 获取所有根目录名称
/// </summary>
/// <returns></returns>
public List<string> GetRootFolderNames()
{
GetObjectStoreTempToken();
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint,
AliyunOSSTempToken.AccessKeyId,
AliyunOSSTempToken.AccessKeySecret,
AliyunOSSTempToken.SecurityToken);
List<string> rootFolders = new List<string>();
string nextMarker = null;
try
{
ObjectListing objectListing = null;
do
{
// 列出根目录下的对象和文件夹
objectListing = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(aliConfig.BucketName)
{
MaxKeys = 1000,
Marker = nextMarker,
Delimiter = "/" // 使用分隔符来模拟文件夹
});
// 遍历 CommonPrefixes 获取根文件夹名称
foreach (var prefix in objectListing.CommonPrefixes)
{
rootFolders.Add(prefix.TrimEnd('/')); // 去掉末尾的斜杠
}
// 设置 NextMarker 以获取下一页的数据
nextMarker = objectListing.NextMarker;
} while (objectListing.IsTruncated);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
return rootFolders;
}
/// <summary> /// <summary>
/// 删除某个目录的文件 /// 删除某个目录的文件
/// </summary> /// </summary>
/// <param name="prefix"></param> /// <param name="prefix"></param>
/// <returns></returns> /// <returns></returns>
public async Task DeleteFromPrefix(string prefix) public async Task DeleteFromPrefix(string prefix, bool isCache = false)
{ {
GetObjectStoreTempToken(); GetObjectStoreTempToken();
@@ -541,6 +782,21 @@ public class OSSService : IOSSService
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken); var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
var bucketName = string.Empty;
if (isCache)
{
Uri uri = new Uri(aliConfig.ViewEndpoint);
string host = uri.Host; // 获取 "zy-irc-test-dev-cache.oss-cn-shanghai.aliyuncs.com"
string[] parts = host.Split('.');
bucketName = parts[0];
}
else
{
bucketName = aliConfig.BucketName;
}
try try
{ {
@@ -549,7 +805,7 @@ public class OSSService : IOSSService
do do
{ {
// 使用 prefix 模拟目录结构,设置 MaxKeys 和 NextMarker // 使用 prefix 模拟目录结构,设置 MaxKeys 和 NextMarker
objectListing = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(aliConfig.BucketName) objectListing = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(bucketName)
{ {
Prefix = prefix, Prefix = prefix,
MaxKeys = 1000, MaxKeys = 1000,
@@ -561,7 +817,7 @@ public class OSSService : IOSSService
// 删除获取到的文件 // 删除获取到的文件
if (keys.Count > 0) if (keys.Count > 0)
{ {
_ossClient.DeleteObjects(new Aliyun.OSS.DeleteObjectsRequest(aliConfig.BucketName, keys, false)); _ossClient.DeleteObjects(new Aliyun.OSS.DeleteObjectsRequest(bucketName, keys, false));
} }
// 设置 NextMarker 以获取下一页的数据 // 设置 NextMarker 以获取下一页的数据
@@ -618,7 +874,6 @@ public class OSSService : IOSSService
var awsConfig = ObjectStoreServiceOptions.AWS; var awsConfig = ObjectStoreServiceOptions.AWS;
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证 // 提供awsAccessKeyId和awsSecretAccessKey构造凭证
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken); var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
@@ -670,6 +925,159 @@ public class OSSService : IOSSService
} }
} }
public async Task DeleteObjects(List<string> objectKeys)
{
GetObjectStoreTempToken();
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
if (objectKeys.Count > 0)
{
var result = _ossClient.DeleteObjects(new Aliyun.OSS.DeleteObjectsRequest(aliConfig.BucketName, objectKeys, false));
}
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
.Build();
if (objectKeys.Count > 0)
{
var objArgs = new RemoveObjectsArgs()
.WithBucket(minIOConfig.BucketName)
.WithObjects(objectKeys);
// 删除对象
await minioClient.RemoveObjectsAsync(objArgs);
}
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
var awsConfig = ObjectStoreServiceOptions.AWS;
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
//提供awsEndPoint(域名)进行访问配置
var clientConfig = new AmazonS3Config
{
RegionEndpoint = RegionEndpoint.USEast1,
UseHttp = true,
};
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
if (objectKeys.Count > 0)
{
// 准备删除请求
var deleteObjectsRequest = new Amazon.S3.Model.DeleteObjectsRequest
{
BucketName = awsConfig.BucketName,
Objects = objectKeys.Select(t => new KeyVersion() { Key = t }).ToList()
};
// 批量删除对象
var deleteObjectsResponse = await amazonS3Client.DeleteObjectsAsync(deleteObjectsRequest);
}
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
}
private bool isFirstCall = true;
public async Task<long> GetObjectSizeAsync(string sourcePath)
{
if (isFirstCall)
{
GetObjectStoreTempToken();
isFirstCall = false;
}
var objectkey = sourcePath.Trim('/');
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
var metadata = _ossClient.GetObjectMetadata(aliConfig.BucketName, objectkey);
long fileSize = metadata.ContentLength; // 文件大小(字节)
return fileSize;
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
.Build();
var stat = await minioClient.StatObjectAsync(new Minio.DataModel.Args.StatObjectArgs()
.WithBucket(minIOConfig.BucketName)
.WithObject(objectkey));
return stat.Size; // 文件大小(字节)
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
var awsConfig = ObjectStoreServiceOptions.AWS;
// 提供awsAccessKeyId和awsSecretAccessKey构造凭证
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
//提供awsEndPoint(域名)进行访问配置
var clientConfig = new AmazonS3Config
{
RegionEndpoint = RegionEndpoint.USEast1,
UseHttp = true,
};
var request = new Amazon.S3.Model.GetObjectMetadataRequest
{
BucketName = awsConfig.BucketName,
Key = objectkey
};
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
var response = await amazonS3Client.GetObjectMetadataAsync(request);
long fileSize = response.ContentLength; // 文件大小(字节)
return fileSize;
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
}
public ObjectStoreDTO GetObjectStoreTempToken() public ObjectStoreDTO GetObjectStoreTempToken()
{ {
@@ -713,6 +1121,7 @@ public class OSSService : IOSSService
BucketName = ossOptions.BucketName, BucketName = ossOptions.BucketName,
EndPoint = ossOptions.EndPoint, EndPoint = ossOptions.EndPoint,
ViewEndpoint = ossOptions.ViewEndpoint, ViewEndpoint = ossOptions.ViewEndpoint,
PreviewEndpoint = ossOptions.PreviewEndpoint
}; };
File diff suppressed because it is too large Load Diff
@@ -4,6 +4,7 @@ using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using MassTransit; using MassTransit;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Text; using System.Text;
@@ -21,6 +22,8 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
private readonly IRepository<NoneDicomStudy> _noneDicomStudyRepository; private readonly IRepository<NoneDicomStudy> _noneDicomStudyRepository;
public IStringLocalizer _localizer { get; set; } public IStringLocalizer _localizer { get; set; }
private readonly SystemEmailSendConfig _systemEmailConfig;
/// <summary> /// <summary>
/// 构造函数注入 /// 构造函数注入
/// </summary> /// </summary>
@@ -28,7 +31,7 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
public ConsistencyCheckConsumer(IRepository<DicomStudy> studyRepository, IUserInfo userInfo, public ConsistencyCheckConsumer(IRepository<DicomStudy> studyRepository, IUserInfo userInfo,
IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository, IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository,
IRepository<TrialSite> trialSiteRepository, IRepository<NoneDicomStudy> noneDicomStudyRepository, IRepository<TrialSite> trialSiteRepository, IRepository<NoneDicomStudy> noneDicomStudyRepository,
IMapper mapper, IStringLocalizer localizer) IMapper mapper, IStringLocalizer localizer, IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig)
{ {
_noneDicomStudyRepository = noneDicomStudyRepository; _noneDicomStudyRepository = noneDicomStudyRepository;
_studyRepository = studyRepository; _studyRepository = studyRepository;
@@ -38,6 +41,8 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
_trialSiteRepository = trialSiteRepository; _trialSiteRepository = trialSiteRepository;
_mapper = mapper; _mapper = mapper;
_localizer = localizer; _localizer = localizer;
_systemEmailConfig = systemEmailConfig.CurrentValue;
} }
@@ -186,17 +191,17 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
{ {
dialogMsg.AppendLine($"<br/>"); dialogMsg.AppendLine($"<br/>");
//---核对EDC数据,完全一致, 审核通过 //---核对EDC数据,完全一致, 审核通过
dialogMsg.AppendLine(_localizer["ConsistencyVerification_EDCA"]); dialogMsg.AppendLine(_localizer["ConsistencyVerification_EDCA", _systemEmailConfig.SystemShortName]);
// dialogMsg.AppendLine(@$"<br>说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。"); // dialogMsg.AppendLine(@$"<br>说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。");
dbSV.CheckState = CheckStateEnum.CVPassed; dbSV.CheckState = CheckStateEnum.CVPassed;
dbSV.CheckUserId = _userInfo.Id; dbSV.CheckUserId = _userInfo.UserRoleId;
dbSV.CheckPassedTime = DateTime.Now; dbSV.CheckPassedTime = DateTime.Now;
dbSV.CheckChallengeState = CheckChanllengeTypeEnum.Closed; dbSV.CheckChallengeState = CheckChanllengeTypeEnum.Closed;
//---核对EDC数据,完全一致 //---核对EDC数据,完全一致
dbSV.CheckResult = _localizer["ConsistencyVerification_EDCB"]; dbSV.CheckResult = _localizer["ConsistencyVerification_EDCB", _systemEmailConfig.SystemShortName];
//---自动核查通过 //---自动核查通过
dbSV.ManualPassReason = _localizer["ConsistencyVerification_Auto"]; dbSV.ManualPassReason = _localizer["ConsistencyVerification_Auto"];
@@ -217,14 +222,14 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
else else
{ {
//"Problems are as follows: //"Problems are as follows:
dialogMsg.AppendLine($"<br/><div style='color: red'>{_localizer["ConsistencyVerification_Prob"]}</div>"); dialogMsg.AppendLine($"<br/><div>{_localizer["ConsistencyVerification_Prob"]}</div>");
num = 0; num = 0;
foreach (var item in dbExceptExcel) foreach (var item in dbExceptExcel)
{ {
num++; num++;
//影像检查(EDC 缺少) ConsistencyVerification_EdcL //影像检查(EDC 缺少) ConsistencyVerification_EdcL
dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_EdcL", item.StudyDate, item.Modality]}</div>"); dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_EdcL", item.StudyDate, item.Modality, _systemEmailConfig.SystemShortName]}</div>");
} }
@@ -232,15 +237,15 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer
{ {
num++; num++;
// 影像检查(IRC 缺少) // 影像检查(IRC 缺少)
dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_IrcLi", item.StudyDate, item.Modality]}</div>"); dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_IrcLi", item.StudyDate, item.Modality, _systemEmailConfig.SystemShortName]}</div>");
} }
dialogMsg.AppendLine($"<br/>"); dialogMsg.AppendLine($"<br/>");
dialogMsg.AppendLine(@$"<div>{_localizer["ConsistencyVerification_Desc"]}</div>"); dialogMsg.AppendLine(@$"<div>{_localizer["ConsistencyVerification_Desc"]}</div>");
dbSV.CheckResult = _localizer["ConsistencyVerification_Conf"] + dbSV.CheckResult =
String.Join(" | ", dbExceptExcel.Select(t => $"{_localizer["ConsistencyVerification_EdcL", t.StudyDate, t.Modality]}")) + " | " String.Join(" | ", dbExceptExcel.Select(t => $"{_localizer["ConsistencyVerification_EdcL", t.StudyDate, t.Modality, _systemEmailConfig.SystemShortName]}")) + " | "
+ String.Join(" | ", excelExceptDB.Select(t => $"{_localizer["ConsistencyVerification_IrcLi", t.StudyDate, t.Modality]}")); + String.Join(" | ", excelExceptDB.Select(t => $"{_localizer["ConsistencyVerification_IrcLi", t.StudyDate, t.Modality, _systemEmailConfig.SystemShortName]}"));
//新增一致性核查质疑记录 //新增一致性核查质疑记录
@@ -22,7 +22,7 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer;
/// 加急的医学反馈任务 通知MIM /// 加急的医学反馈任务 通知MIM
/// </summary> /// </summary>
public class UrgentMedicalReviewAddedEventConsumer( public class UrgentMedicalReviewAddedEventConsumer(
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<TaskMedicalReview> _taskMedicalReviewRepository, IRepository<TaskMedicalReview> _taskMedicalReviewRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
@@ -58,7 +58,7 @@ public class UrgentMedicalReviewAddedEventConsumer(
return; return;
} }
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId); var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId);
var userinfo = await _userRepository.Where(x => x.Id == medicalReview.MedicalManagerUserId).FirstOrDefaultAsync(); var userinfo = await _userRoleRepository.Where(x => x.Id == medicalReview.MedicalManagerUserId).FirstOrDefaultAsync();
var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x=>x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync(); var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x=>x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync();
@@ -128,7 +128,7 @@ public class UrgentMedicalReviewAddedEventConsumer(
//IR 回复医学反馈通知MIM //IR 回复医学反馈通知MIM
public class UrgentIRRepliedMedicalReviewConsumer( public class UrgentIRRepliedMedicalReviewConsumer(
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<TaskMedicalReview> _taskMedicalReviewRepository, IRepository<TaskMedicalReview> _taskMedicalReviewRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
@@ -159,7 +159,7 @@ public class UrgentIRRepliedMedicalReviewConsumer(
return; return;
} }
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId); var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId);
var userinfo = await _userRepository.Where(x => x.Id == medicalReview.MedicalManagerUserId).FirstOrDefaultAsync(); var userinfo = await _userRoleRepository.Where(x => x.Id == medicalReview.MedicalManagerUserId).FirstOrDefaultAsync();
var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x => x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync(); var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x => x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync();
@@ -231,7 +231,7 @@ public class UrgentIRRepliedMedicalReviewConsumer(
/// MIM 回复医学返回通知IR /// MIM 回复医学返回通知IR
/// </summary> /// </summary>
public class UrgentMIMRepliedMedicalReviewConsumer( public class UrgentMIMRepliedMedicalReviewConsumer(
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<TaskMedicalReview> _taskMedicalReviewRepository, IRepository<TaskMedicalReview> _taskMedicalReviewRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
@@ -268,7 +268,7 @@ public class UrgentMIMRepliedMedicalReviewConsumer(
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId); var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == medicalReview.VisitTask.TrialReadingCriterionId);
var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x => x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync(); var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).Include(x => x.SourceSubjectVisit).Include(x => x.ReadModule).Include(x => x.Subject).FirstNotNullAsync();
var userinfo = await _userRepository.Where(x => x.Id == taskInfo.DoctorUserId).FirstOrDefaultAsync(); var userinfo = await _userRoleRepository.Where(x => x.Id == taskInfo.DoctorUserId).FirstOrDefaultAsync();
@@ -346,8 +346,8 @@ public class UrgentMIMRepliedMedicalReviewConsumer(
/// 加急阅片 IR 申请重阅 或者PM 申请重阅 /// 加急阅片 IR 申请重阅 或者PM 申请重阅
/// </summary> /// </summary>
public class UrgentIRApplyedReReadingConsumer( public class UrgentIRApplyedReReadingConsumer(
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<TrialUser> _trialUseRepository, IRepository<TrialUserRole> _trialUseRoleRepository,
IRepository<TaskMedicalReview> _taskMedicalReviewRepository, IRepository<TaskMedicalReview> _taskMedicalReviewRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
@@ -370,9 +370,9 @@ public class UrgentIRApplyedReReadingConsumer(
var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == taskInfo.TrialReadingCriterionId); var criterion = await _readingQuestionCriterionTrialRepository.FirstOrDefaultAsync(x => x.Id == taskInfo.TrialReadingCriterionId);
var doctorInfo = await _userRepository.Where(x => x.Id == taskInfo.DoctorUserId).FirstOrDefaultAsync(); var doctorInfo = await _userRoleRepository.Where(x => x.Id == taskInfo.DoctorUserId).FirstOrDefaultAsync();
var trialUser = await _trialUseRepository.Where(x => x.TrialId == taskInfo.TrialId).Include(x => x.User).Select(x=>x.User).ToListAsync(); var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == taskInfo.TrialId).Include(x => x.UserRole).Select(x=>x.UserRole).ToListAsync();
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.ProjectManager||x.UserTypeEnum==UserTypeEnum.APM).ToList(); var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.ProjectManager||x.UserTypeEnum==UserTypeEnum.APM).ToList();
if (context.Message.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) if (context.Message.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
@@ -30,7 +30,7 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer;
public class UserSiteSurveySubmitedEventConsumer( public class UserSiteSurveySubmitedEventConsumer(
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<TrialSite> _trialSiteRepository, IRepository<TrialSite> _trialSiteRepository,
IRepository<TrialUser> _trialUserRepository, IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<TrialSiteSurvey> _trialSiteSurveyRepository, IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository, IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig
@@ -47,9 +47,9 @@ public class UserSiteSurveySubmitedEventConsumer(
var trialId = siteSurveyInfo.TrialId; var trialId = siteSurveyInfo.TrialId;
var trialUserList = await _trialUserRepository.Where(t => t.TrialId == siteSurveyInfo.TrialId) var trialUserList = await _trialUserRoleRepository.Where(t => t.TrialId == siteSurveyInfo.TrialId)
.Where(t => t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM || t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM) .Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM || t.UserRole.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserRole.UserTypeEnum == UserTypeEnum.APM)
.Select(t => new { t.User.FullName, t.User.EMail, t.User.UserTypeEnum }).ToListAsync(); .Select(t => new { t.UserRole.FullName, t.UserRole.IdentityUser.EMail, t.UserRole.UserTypeEnum }).ToListAsync();
var sPMOrCPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.SPM || t.UserTypeEnum == UserTypeEnum.CPM).ToList(); var sPMOrCPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.SPM || t.UserTypeEnum == UserTypeEnum.CPM).ToList();
var pmAndAPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserTypeEnum == UserTypeEnum.APM).ToList(); var pmAndAPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserTypeEnum == UserTypeEnum.APM).ToList();
@@ -125,7 +125,7 @@ public class UserSiteSurveySubmitedEventConsumer(
/// </summary> /// </summary>
public class SiteSurveySPMSubmitedEventConsumer( public class SiteSurveySPMSubmitedEventConsumer(
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<TrialUser> _trialUserRepository, IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<TrialSite> _trialSiteRepository, IRepository<TrialSite> _trialSiteRepository,
IRepository<TrialSiteSurvey> _trialSiteSurveyRepository, IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository, IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
@@ -145,9 +145,9 @@ public class SiteSurveySPMSubmitedEventConsumer(
var messageToSend = new MimeMessage(); var messageToSend = new MimeMessage();
var trialUserList = _trialUserRepository.Where(t => t.TrialId == trialId) var trialUserList = _trialUserRoleRepository.Where(t => t.TrialId == trialId)
.Where(t => t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM || t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM) .Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM || t.UserRole.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserRole.UserTypeEnum == UserTypeEnum.APM)
.Select(t => new { t.User.EMail, t.User.FullName, t.User.UserTypeEnum }).ToList(); .Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum }).ToList();
var sPMOrCPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.SPM || t.UserTypeEnum == UserTypeEnum.CPM).ToList(); var sPMOrCPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.SPM || t.UserTypeEnum == UserTypeEnum.CPM).ToList();
var pmAndAPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserTypeEnum == UserTypeEnum.APM).ToList(); var pmAndAPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserTypeEnum == UserTypeEnum.APM).ToList();
@@ -200,7 +200,7 @@ public class SiteSurveySPMSubmitedEventConsumer(
/// 调研表驳回发送邮件 之前已有,需要迁移过来 /// 调研表驳回发送邮件 之前已有,需要迁移过来
/// </summary> /// </summary>
public class SiteSurverRejectedEventConsumer( public class SiteSurverRejectedEventConsumer(
IRepository<TrialUser> _trialUserRepository, IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<TrialSite> _trialSiteRepository, IRepository<TrialSite> _trialSiteRepository,
IRepository<TrialSiteSurvey> _trialSiteSurveyRepository, IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
@@ -229,13 +229,13 @@ public class SiteSurverRejectedEventConsumer(
//PM 驳回到SPM //PM 驳回到SPM
if (siteSurveyInfo.State == TrialSiteSurveyEnum.CRCSubmitted) if (siteSurveyInfo.State == TrialSiteSurveyEnum.CRCSubmitted)
{ {
//var user = await _userRepository.FirstOrDefaultAsync(t => t.Id == siteSurveyInfo.PreliminaryUserId); //var user = await _userRoleRepository.FirstOrDefaultAsync(t => t.Id == siteSurveyInfo.PreliminaryUserId);
//name = user.FullName; //name = user.FullName;
var sPMOrCPMList = _trialUserRepository.Where(t => t.TrialId == trialId) var sPMOrCPMList = _trialUserRoleRepository.Where(t => t.TrialId == trialId)
.Where(t => t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM) .Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM)
.Select(t => new { t.User.EMail, t.User.FullName, t.User.UserTypeEnum }).ToList(); .Select(t => new { t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum }).ToList();
foreach (var user in sPMOrCPMList) foreach (var user in sPMOrCPMList)
@@ -23,8 +23,8 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer;
/// CRC 提交了 通知QC进行质控 Code005006 /// CRC 提交了 通知QC进行质控 Code005006
/// </summary> /// </summary>
public class CRCSubmitedAndQCToAuditEventConsumer( public class CRCSubmitedAndQCToAuditEventConsumer(
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<TrialUser> _trialUseRepository, IRepository<TrialUserRole> _trialUseRoleRepository,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository, IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
@@ -43,7 +43,7 @@ public class CRCSubmitedAndQCToAuditEventConsumer(
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstOrDefaultAsync(); var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstOrDefaultAsync();
var trialUser = await _trialUseRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.User).Select(x => x.User).ToListAsync(); var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.IQC).ToList(); var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.IQC).ToList();
@@ -127,8 +127,8 @@ public class CRCSubmitedAndQCToAuditEventConsumer(
/// CRC 回复质控质疑 通知QC Code012013 /// CRC 回复质控质疑 通知QC Code012013
/// </summary> /// </summary>
public class CRCRepliedQCChallengeEventConsumer( public class CRCRepliedQCChallengeEventConsumer(
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<TrialUser> _trialUseRepository, IRepository<TrialUserRole> _trialUseRoleRepository,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<QCChallenge> _qCChallengeRepository, IRepository<QCChallenge> _qCChallengeRepository,
@@ -153,7 +153,7 @@ public class CRCRepliedQCChallengeEventConsumer(
var trialUser = await _trialUseRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.User).Select(x => x.User).ToListAsync(); var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
@@ -224,8 +224,8 @@ public class CRCRepliedQCChallengeEventConsumer(
/// QC回复 质控质疑,通知CRC (014015) /// QC回复 质控质疑,通知CRC (014015)
/// </summary> /// </summary>
public class QCRepliedQCChallengeEventConsumer( public class QCRepliedQCChallengeEventConsumer(
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<TrialUser> _trialUseRepository, IRepository<TrialUserRole> _trialUseRoleRepository,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<QCChallenge> _qCChallengeRepository, IRepository<QCChallenge> _qCChallengeRepository,
@@ -259,7 +259,7 @@ public class QCRepliedQCChallengeEventConsumer(
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync(); var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync();
var trialUser = await _trialUseRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.User).Select(x => x.User).ToListAsync(); var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).ToList(); var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).ToList();
@@ -333,8 +333,8 @@ public class QCRepliedQCChallengeEventConsumer(
/// CRC 回复一致性核查质疑 通知PM (019,020) /// CRC 回复一致性核查质疑 通知PM (019,020)
/// </summary> /// </summary>
public class CRCRepliedCheckChallengeEventConsumer( public class CRCRepliedCheckChallengeEventConsumer(
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<TrialUser> _trialUseRepository, IRepository<TrialUserRole> _trialUseRoleRepository,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<QCChallenge> _qCChallengeRepository, IRepository<QCChallenge> _qCChallengeRepository,
@@ -354,7 +354,7 @@ public class CRCRepliedCheckChallengeEventConsumer(
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync(); var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync();
var trialUser = await _trialUseRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.User).Select(x => x.User).ToListAsync(); var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList(); var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList();
@@ -425,8 +425,8 @@ public class CRCRepliedCheckChallengeEventConsumer(
/// </summary> /// </summary>
public class PMRepliedCheckChallengeEventConsumer( public class PMRepliedCheckChallengeEventConsumer(
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<TrialUser> _trialUseRepository, IRepository<TrialUserRole> _trialUseRoleRepository,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<CheckChallengeDialog> _checkChallengeDialogRepository, IRepository<CheckChallengeDialog> _checkChallengeDialogRepository,
@@ -446,7 +446,7 @@ public class PMRepliedCheckChallengeEventConsumer(
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.NoneDicomStudyList).Include(x => x.StudyList).Include(x => x.Subject).FirstNotNullAsync(); var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.NoneDicomStudyList).Include(x => x.StudyList).Include(x => x.Subject).FirstNotNullAsync();
var trialUser = await _trialUseRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.User).Select(x => x.User).ToListAsync(); var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).ToList(); var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).ToList();
@@ -524,8 +524,8 @@ public class PMRepliedCheckChallengeEventConsumer(
/// 通知PM 进行一致性核查 (018,030) /// 通知PM 进行一致性核查 (018,030)
/// </summary> /// </summary>
public class CheckStateChangedToAuditEventConsumer( public class CheckStateChangedToAuditEventConsumer(
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<TrialUser> _trialUseRepository, IRepository<TrialUserRole> _trialUseRoleRepository,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<QCChallenge> _qCChallengeRepository, IRepository<QCChallenge> _qCChallengeRepository,
@@ -544,7 +544,7 @@ public class CheckStateChangedToAuditEventConsumer(
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync(); var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).FirstNotNullAsync();
var trialUser = await _trialUseRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.User).Select(x => x.User).ToListAsync(); var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList(); var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.APM || x.UserTypeEnum == UserTypeEnum.ProjectManager).ToList();
@@ -586,8 +586,8 @@ public class CheckStateChangedToAuditEventConsumer(
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName); var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, subjectVisit.VisitName);
var htmlBodyStr = string.Format( var htmlBodyStr = string.Format(
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr), CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
userinfo.FullName, // 姓名 {0}
trialInfo.ExperimentName, // 项目 {1} trialInfo.ExperimentName, // 项目 {1}
userinfo.FullName, // 用户名 {1}
subjectCode, // 受试者 {2} subjectCode, // 受试者 {2}
subjectVisit.VisitName, // 访视 {3} subjectVisit.VisitName, // 访视 {3}
dictionValue[0], // 核查状态 {4} dictionValue[0], // 核查状态 {4}
@@ -612,8 +612,8 @@ public class CheckStateChangedToAuditEventConsumer(
/// QC 领取了质控任务 (007008) /// QC 领取了质控任务 (007008)
/// </summary> /// </summary>
public class QCClaimTaskEventConsumer( public class QCClaimTaskEventConsumer(
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<TrialUser> _trialUseRepository, IRepository<TrialUserRole> _trialUseRoleRepository,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<QCChallenge> _qCChallengeRepository, IRepository<QCChallenge> _qCChallengeRepository,
@@ -639,7 +639,7 @@ public class QCClaimTaskEventConsumer(
var trialUser = await _trialUseRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.User).Select(x => x.User).ToListAsync(); var trialUser = await _trialUseRoleRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.UserRole).Select(x => x.UserRole).ToListAsync();
@@ -30,13 +30,13 @@ public class MasstransiTestCommand
/// publish 请求流不会先到消费者,发布后,直接执行后续代码 /// publish 请求流不会先到消费者,发布后,直接执行后续代码
/// ///
/// </summary> /// </summary>
/// <param name="_userRepository"></param> /// <param name="_userRoleRepository"></param>
public class MasstransitTestConsumer(IRepository<User> _userRepository) : IConsumer<MasstransiTestCommand> public class MasstransitTestConsumer(IRepository<UserRole> _userRoleRepository) : IConsumer<MasstransiTestCommand>
{ {
public async Task Consume(ConsumeContext<MasstransiTestCommand> context) public async Task Consume(ConsumeContext<MasstransiTestCommand> context)
{ {
Console.WriteLine(_userRepository._dbContext.GetHashCode()); Console.WriteLine(_userRoleRepository._dbContext.GetHashCode());
Console.WriteLine("Now is " + DateTime.Now.ToString()); Console.WriteLine("Now is " + DateTime.Now.ToString());
Console.WriteLine($"MassTransit.Consumer :{context.Message.value}"); Console.WriteLine($"MassTransit.Consumer :{context.Message.value}");
@@ -26,7 +26,7 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository, IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository,
IRepository<VisitTask> _visitTaskRepository, IRepository<VisitTask> _visitTaskRepository,
IRepository<Dictionary> _dictionaryRepository, IRepository<Dictionary> _dictionaryRepository,
IRepository<TrialUser> _trialUserRepository, IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository, IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<UrgentIRUnReadTaskRecurringEvent> IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<UrgentIRUnReadTaskRecurringEvent>
{ {
@@ -52,12 +52,12 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
Expression<Func<VisitTask, bool>> comonTaskFilter = t => t.TrialId == trialId && t.TaskState == TaskState.Effect && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskAllocationState == TaskAllocationState.Allocated; Expression<Func<VisitTask, bool>> comonTaskFilter = t => t.TrialId == trialId && t.TaskState == TaskState.Effect && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskAllocationState == TaskAllocationState.Allocated;
var trialUserList = _trialUserRepository.Where(t => t.TrialId == trialId).Select(t => new var trialUserList = _trialUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialUser.JoinTime != null).Select(t => new
{ {
t.UserId, t.UserId,
t.User.FullName, t.UserRole.FullName,
t.User.EMail, t.UserRole.IdentityUser.EMail,
t.User.UserName, t.UserRole.IdentityUser.UserName,
t.Trial.TrialCode, t.Trial.TrialCode,
t.Trial.ResearchProgramNo t.Trial.ResearchProgramNo
//TrialReadingCriterionList = t.Trial.TrialReadingCriterionList.Select(t => new { t.CriterionName, TrialReadingCriterionId = t.Id }).ToList() //TrialReadingCriterionList = t.Trial.TrialReadingCriterionList.Select(t => new { t.CriterionName, TrialReadingCriterionId = t.Id }).ToList()
@@ -69,7 +69,7 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
var userId = trialUser.UserId; var userId = trialUser.UserId;
var doctorCriterionList = await _trialReadingCriterionRepository.Where(t => t.IsSigned && t.IsConfirm && t.TrialId == trialId && t.Trial.TrialUserList.Any(t => t.UserId == userId)) var doctorCriterionList = await _trialReadingCriterionRepository.Where(t => t.IsSigned && t.IsConfirm && t.TrialId == trialId && t.Trial.TrialUserRoleList.Any(t => t.UserId == userId))
.Select(c => new .Select(c => new
{ {
@@ -22,9 +22,9 @@ public static class OldRecurringEmailHelper
public static async Task SendTrialEmailAsync( public static async Task SendTrialEmailAsync(
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository, IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<TrialUser> _trialUserRepository, IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<VisitTask> _visitTaskRepository, IRepository<VisitTask> _visitTaskRepository,
IRepository<TrialSiteUser> _trialSiteUserRepository, IRepository<TrialSiteUserRole> _trialSiteUserRoleRepository,
Guid trialId, EmailBusinessScenario businessScenario, Guid trialId, EmailBusinessScenario businessScenario,
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc, Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc,
@@ -59,7 +59,7 @@ public static class OldRecurringEmailHelper
var allUserTypeEnumList = toUserTypeEnumList.Union(copyUserTypeEnumList).Distinct().ToList(); var allUserTypeEnumList = toUserTypeEnumList.Union(copyUserTypeEnumList).Distinct().ToList();
var allUserList = await _trialUserRepository.Where(t => t.TrialId == trialId && allUserTypeEnumList.Contains(t.User.UserTypeEnum)).Select(t => new { t.UserId, t.User.EMail, t.User.FullName, t.User.UserTypeEnum }).ToListAsync(); var allUserList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId && allUserTypeEnumList.Contains(t.UserRole.UserTypeEnum)).Select(t => new { t.UserId, t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum }).ToListAsync();
var toUserList = allUserList.Where(t => toUserTypeEnumList.Contains(t.UserTypeEnum)) var toUserList = allUserList.Where(t => toUserTypeEnumList.Contains(t.UserTypeEnum))
@@ -72,7 +72,7 @@ public static class OldRecurringEmailHelper
} }
if (trialSiteId != null && toUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA)) if (trialSiteId != null && toUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA))
{ {
var curentSiteUserIdList = _trialSiteUserRepository.Where(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId).Select(t => t.UserId).ToList(); var curentSiteUserIdList = _trialSiteUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId).Select(t => t.UserId).ToList();
toUserList = toUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList(); toUserList = toUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList();
} }
@@ -86,7 +86,7 @@ public static class OldRecurringEmailHelper
if (trialSiteId != null && copyUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA)) if (trialSiteId != null && copyUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA))
{ {
var curentSiteUserIdList = _trialSiteUserRepository.Where(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId).Select(t => t.UserId).ToList(); var curentSiteUserIdList = _trialSiteUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId).Select(t => t.UserId).ToList();
copyUserList = copyUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList(); copyUserList = copyUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList();
} }
@@ -23,9 +23,9 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer;
public class QCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRepository, public class QCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRepository,
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository, IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository,
IRepository<TrialUser> _trialUserRepository, IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<VisitTask> _visitTaskRepository, IRepository<VisitTask> _visitTaskRepository,
IRepository<TrialSiteUser> _trialSiteUserRepository, IRepository<TrialSiteUserRole> _trialSiteUserRoleRepository,
IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig) : IConsumer<QCImageQuestionRecurringEvent> IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig) : IConsumer<QCImageQuestionRecurringEvent>
{ {
public async Task Consume(ConsumeContext<QCImageQuestionRecurringEvent> context) public async Task Consume(ConsumeContext<QCImageQuestionRecurringEvent> context)
@@ -37,7 +37,7 @@ public class QCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRepo
var trialInfo = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstNotNullAsync(); var trialInfo = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstNotNullAsync();
//找到 该项目的CRC 用户Id //找到 该项目的CRC 用户Id
var userList = await _trialUserRepository.Where(t => t.TrialId == trialId).Where(t => t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { t.UserId, t.User.FullName }).ToListAsync(); var userList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId).Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { t.UserId, t.UserRole.FullName }).ToListAsync();
//判断是否任务可以领取 ,可以的话 发送邮件 //判断是否任务可以领取 ,可以的话 发送邮件
@@ -73,9 +73,9 @@ public class QCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRepo
await OldRecurringEmailHelper.SendTrialEmailAsync( await OldRecurringEmailHelper.SendTrialEmailAsync(
_trialEmailNoticeConfigRepository, _trialEmailNoticeConfigRepository,
_trialRepository, _trialRepository,
_trialUserRepository, _trialUserRoleRepository,
_visitTaskRepository, _visitTaskRepository,
_trialSiteUserRepository, _trialSiteUserRoleRepository,
trialId, EmailBusinessScenario.QCToCRCImageQuestion, topicAndHtmlFunc); trialId, EmailBusinessScenario.QCToCRCImageQuestion, topicAndHtmlFunc);
} }
} }
@@ -88,9 +88,9 @@ public class QCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRepo
/// </summary> /// </summary>
public class CRCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRepository, public class CRCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRepository,
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository, IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository,
IRepository<TrialUser> _trialUserRepository, IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<VisitTask> _visitTaskRepository, IRepository<VisitTask> _visitTaskRepository,
IRepository<TrialSiteUser> _trialSiteUserRepository, IRepository<TrialSiteUserRole> _trialSiteUserRoleRepository,
IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig) : IConsumer<CRCImageQuestionRecurringEvent> IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig) : IConsumer<CRCImageQuestionRecurringEvent>
{ {
public async Task Consume(ConsumeContext<CRCImageQuestionRecurringEvent> context) public async Task Consume(ConsumeContext<CRCImageQuestionRecurringEvent> context)
@@ -101,7 +101,7 @@ public class CRCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRep
var trialInfo = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr, t.DeclarationTypeEnumList }).FirstNotNullAsync(); var trialInfo = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr, t.DeclarationTypeEnumList }).FirstNotNullAsync();
//找到 该项目的IQC 用户Id //找到 该项目的IQC 用户Id
var userList = await _trialUserRepository.Where(t => t.TrialId == trialId).Where(t => t.User.UserTypeEnum == UserTypeEnum.IQC).Select(t => new { t.UserId, t.User.FullName }).ToListAsync(); var userList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId).Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.IQC).Select(t => new { t.UserId, t.UserRole.FullName }).ToListAsync();
//判断是否任务可以领取 ,可以的话 发送邮件 //判断是否任务可以领取 ,可以的话 发送邮件
@@ -141,9 +141,9 @@ public class CRCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRep
await OldRecurringEmailHelper.SendTrialEmailAsync(_trialEmailNoticeConfigRepository, await OldRecurringEmailHelper.SendTrialEmailAsync(_trialEmailNoticeConfigRepository,
_trialRepository, _trialRepository,
_trialUserRepository, _trialUserRoleRepository,
_visitTaskRepository, _visitTaskRepository,
_trialSiteUserRepository, _trialSiteUserRoleRepository,
trialId, EmailBusinessScenario.CRCToQCQuestion, topicAndHtmlFunc); trialId, EmailBusinessScenario.CRCToQCQuestion, topicAndHtmlFunc);
} }
} }
@@ -155,9 +155,9 @@ public class CRCImageQuestionRecurringEventConsumer(IRepository<Trial> _trialRep
/// </summary> /// </summary>
public class ImageQCRecurringEventConsumer(IRepository<Trial> _trialRepository, public class ImageQCRecurringEventConsumer(IRepository<Trial> _trialRepository,
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository, IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository,
IRepository<TrialUser> _trialUserRepository, IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<VisitTask> _visitTaskRepository, IRepository<VisitTask> _visitTaskRepository,
IRepository<TrialSiteUser> _trialSiteUserRepository, IRepository<TrialSiteUserRole> _trialSiteUserRoleRepository,
IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig) : IConsumer<ImageQCRecurringEvent> IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig) : IConsumer<ImageQCRecurringEvent>
{ {
public async Task Consume(ConsumeContext<ImageQCRecurringEvent> context) public async Task Consume(ConsumeContext<ImageQCRecurringEvent> context)
@@ -169,7 +169,7 @@ public class ImageQCRecurringEventConsumer(IRepository<Trial> _trialRepository,
var trialInfo = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstNotNullAsync(); var trialInfo = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstNotNullAsync();
//找到 该项目的IQC 用户Id //找到 该项目的IQC 用户Id
var userList = await _trialUserRepository.Where(t => t.TrialId == trialId).Where(t => t.User.UserTypeEnum == UserTypeEnum.IQC).Select(t => new { t.UserId, t.User.FullName }).ToListAsync(); var userList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId).Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.IQC).Select(t => new { t.UserId, t.UserRole.FullName }).ToListAsync();
//判断是否任务可以领取 ,可以的话 发送邮件 //判断是否任务可以领取 ,可以的话 发送邮件
var userIdList = userList.Select(t => t.UserId).ToList(); var userIdList = userList.Select(t => t.UserId).ToList();
@@ -209,9 +209,9 @@ public class ImageQCRecurringEventConsumer(IRepository<Trial> _trialRepository,
await OldRecurringEmailHelper.SendTrialEmailAsync( await OldRecurringEmailHelper.SendTrialEmailAsync(
_trialEmailNoticeConfigRepository, _trialEmailNoticeConfigRepository,
_trialRepository, _trialRepository,
_trialUserRepository, _trialUserRoleRepository,
_visitTaskRepository, _visitTaskRepository,
_trialSiteUserRepository, _trialSiteUserRoleRepository,
trialId, EmailBusinessScenario.QCTask, topicAndHtmlFunc); trialId, EmailBusinessScenario.QCTask, topicAndHtmlFunc);
} }
} }
@@ -339,6 +339,16 @@ namespace IRaCIS.Core.Application.ViewModel
public int UrgentCount { get; set; } public int UrgentCount { get; set; }
/// <summary>
/// 是否存在未处理的反馈
/// </summary>
public bool IsExistUnprocessedFeedback
{
get
{
return UnReadCanReadTaskList.Any(t => t.IsExistUnprocessedFeedback);
}
}
public List<IRUnreadTaskView> UnReadCanReadTaskList { get; set; } = new List<IRUnreadTaskView>(); public List<IRUnreadTaskView> UnReadCanReadTaskList { get; set; } = new List<IRUnreadTaskView>();
@@ -356,6 +366,11 @@ namespace IRaCIS.Core.Application.ViewModel
/// </summary> /// </summary>
public bool IsAnalysisCreate { get; set; } public bool IsAnalysisCreate { get; set; }
/// <summary>
/// 是否存在未处理的反馈
/// </summary>
public bool IsExistUnprocessedFeedback { get; set; }
public bool IsUrgent { get; set; } public bool IsUrgent { get; set; }
public decimal VisitNum { get; set; } public decimal VisitNum { get; set; }
@@ -14,7 +14,7 @@ namespace IRaCIS.Core.Application.Service
{ {
Task<IResponseOutput> ApplyReReading(ApplyReReadingCommand applyReReadingCommand); Task<IResponseOutput> ApplyReReading(ApplyReReadingCommand applyReReadingCommand);
Task<IResponseOutput> ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService); Task<IResponseOutput> ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand);
Task<PageOutput<IRUnReadSubjectView>> GetSubjectReadingIQueryable(GetReadingIQueryableInDto inDto); Task<PageOutput<IRUnReadSubjectView>> GetSubjectReadingIQueryable(GetReadingIQueryableInDto inDto);
} }
@@ -4,10 +4,12 @@
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//-------------------------------------------------------------------- //--------------------------------------------------------------------
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@@ -18,7 +20,7 @@ namespace IRaCIS.Core.Application.Service
/// </summary> /// </summary>
[ApiExplorerSettings(GroupName = "Trial")] [ApiExplorerSettings(GroupName = "Trial")]
public class TaskAllocationRuleService(IRepository<TaskAllocationRule> _taskAllocationRuleRepository, public class TaskAllocationRuleService(IRepository<TaskAllocationRule> _taskAllocationRuleRepository,
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<Enroll> _enrollRepository, IRepository<Enroll> _enrollRepository,
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository, IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
IRepository<SubjectCanceDoctor> _subjectCanceDoctorRepository, IRepository<SubjectCanceDoctor> _subjectCanceDoctorRepository,
@@ -124,15 +126,15 @@ namespace IRaCIS.Core.Application.Service
public async Task<List<TrialDoctorUserSelectView>> GetDoctorUserSelectList(Guid trialId, [FromServices] IRepository<Enroll> _enrollRepository) public async Task<List<TrialDoctorUserSelectView>> GetDoctorUserSelectList(Guid trialId, [FromServices] IRepository<Enroll> _enrollRepository)
{ {
var query = from enroll in _enrollRepository.Where(t => t.TrialId == trialId && t.EnrollStatus >= EnrollStatus.ConfirmIntoGroup) var query = from enroll in _enrollRepository.Where(t => t.TrialId == trialId && t.EnrollStatus >= EnrollStatus.ConfirmIntoGroup)
join user in _userRepository.AsQueryable() on enroll.DoctorId equals user.DoctorId join user in _userRoleRepository.AsQueryable() on enroll.DoctorId equals user.DoctorId
select new TrialDoctorUserSelectView() select new TrialDoctorUserSelectView()
{ {
TrialId = enroll.TrialId, TrialId = enroll.TrialId,
//ReadingType = enroll.Trial.ReadingType, //ReadingType = enroll.Trial.ReadingType,
DoctorUserId = user.Id, DoctorUserId = user.Id,
FullName = user.FullName, FullName = user.IdentityUser.FullName,
UserCode = user.UserCode, UserCode = user.IdentityUser.UserCode,
UserName = user.UserName, UserName = user.IdentityUser.UserName,
UserTypeEnum = user.UserTypeRole.UserTypeEnum, UserTypeEnum = user.UserTypeRole.UserTypeEnum,
ReadingCategoryList = enroll.EnrollReadingCategoryList.Select(t => t.ReadingCategory).ToList() ReadingCategoryList = enroll.EnrollReadingCategoryList.Select(t => t.ReadingCategory).ToList()
@@ -151,14 +153,14 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory == null, t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId)) .WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory == null, t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId))
.WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory != null, .WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory != null,
t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && t.ReadingCategory == selectQuery.ReadingCategory)) t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && t.ReadingCategory == selectQuery.ReadingCategory))
join user in _userRepository.AsQueryable() on allocationRule.DoctorUserId equals user.Id join user in _userRoleRepository.AsQueryable() on allocationRule.DoctorUserId equals user.Id
select new TrialDoctorUserSelectView() select new TrialDoctorUserSelectView()
{ {
TrialId = allocationRule.TrialId, TrialId = allocationRule.TrialId,
DoctorUserId = user.Id, DoctorUserId = user.Id,
FullName = user.FullName, FullName = user.IdentityUser.FullName,
UserCode = user.UserCode, UserCode = user.IdentityUser.UserCode,
UserName = user.UserName, UserName = user.IdentityUser.UserName,
UserTypeEnum = user.UserTypeRole.UserTypeEnum, UserTypeEnum = user.UserTypeRole.UserTypeEnum,
ReadingCategoryList = selectQuery.TrialReadingCriterionId == null ? ReadingCategoryList = selectQuery.TrialReadingCriterionId == null ?
@@ -30,7 +30,7 @@ namespace IRaCIS.Core.Application.Service
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<TrialSite> _trialSiteRepository, IRepository<TrialSite> _trialSiteRepository,
IRepository<Enroll> _enrollRepository, IRepository<Enroll> _enrollRepository,
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<TrialVirtualSiteCodeUpdate> _trialVirtualSiteCodeUpdateRepository, IRepository<TrialVirtualSiteCodeUpdate> _trialVirtualSiteCodeUpdateRepository,
IVisitTaskHelpeService _visitTaskCommonService, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITaskConsistentRuleService IVisitTaskHelpeService _visitTaskCommonService, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITaskConsistentRuleService
{ {
@@ -369,7 +369,7 @@ namespace IRaCIS.Core.Application.Service
var doctorUserIdQuery = from enroll in _enrollRepository.Where(t => t.TrialId == trialId).Where(t => t.EnrollReadingCategoryList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(c => c.ReadingCategory == ReadingCategory.Global || c.ReadingCategory == ReadingCategory.Visit)) var doctorUserIdQuery = from enroll in _enrollRepository.Where(t => t.TrialId == trialId).Where(t => t.EnrollReadingCategoryList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(c => c.ReadingCategory == ReadingCategory.Global || c.ReadingCategory == ReadingCategory.Visit))
.Where(t => t.EnrollReadingCriteriaList.Any(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsJoinAnalysis == true)) .Where(t => t.EnrollReadingCriteriaList.Any(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsJoinAnalysis == true))
join user in _userRepository.Where() on enroll.DoctorId equals user.DoctorId join user in _userRoleRepository.Where() on enroll.DoctorId equals user.DoctorId
select user.Id; select user.Id;
var configDoctorUserIdList = await doctorUserIdQuery.ToListAsync(); var configDoctorUserIdList = await doctorUserIdQuery.ToListAsync();
@@ -707,9 +707,9 @@ namespace IRaCIS.Core.Application.Service
DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed && t.ArmEnum <= Arm.DoubleReadingArm2).Select(t => new UserSimpleInfo() DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed && t.ArmEnum <= Arm.DoubleReadingArm2).Select(t => new UserSimpleInfo()
{ {
UserId = t.Id, UserId = t.Id,
FullName = t.DoctorUser.FullName, FullName = t.DoctorUser.IdentityUser.FullName,
UserCode = t.DoctorUser.UserCode, UserCode = t.DoctorUser.IdentityUser.UserCode,
UserName = t.DoctorUser.UserName UserName = t.DoctorUser.IdentityUser.UserName
}).ToList(), }).ToList(),
ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count(), ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count(),
@@ -784,7 +784,7 @@ namespace IRaCIS.Core.Application.Service
var taskConsistentRuleQueryable = from enroll in _enrollRepository.Where(t => t.TrialId == trialId && t.EnrollStatus == EnrollStatus.ConfirmIntoGroup var taskConsistentRuleQueryable = from enroll in _enrollRepository.Where(t => t.TrialId == trialId && t.EnrollStatus == EnrollStatus.ConfirmIntoGroup
&& t.EnrollReadingCriteriaList.Any(c => c.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && c.IsJoinAnalysis)) && t.EnrollReadingCriteriaList.Any(c => c.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && c.IsJoinAnalysis))
join user in _userRepository.Where() on enroll.DoctorUserId equals user.Id join user in _userRoleRepository.Where() on enroll.DoctorUserId equals user.Id
join taskConsistentRule in _taskConsistentRuleRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis) on enroll.TrialId equals taskConsistentRule.TrialId join taskConsistentRule in _taskConsistentRuleRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis) on enroll.TrialId equals taskConsistentRule.TrialId
select new TaskConsistentRuleView() select new TaskConsistentRuleView()
{ {
@@ -830,9 +830,9 @@ namespace IRaCIS.Core.Application.Service
AnalysisDoctorUser = new UserSimpleInfo() AnalysisDoctorUser = new UserSimpleInfo()
{ {
UserId = user.Id, UserId = user.Id,
UserCode = user.UserCode, UserCode = user.IdentityUser.UserCode,
FullName = user.FullName, FullName = user.IdentityUser.FullName,
UserName = user.UserName UserName = user.IdentityUser.UserName
} }
}; };
@@ -16,7 +16,7 @@ namespace IRaCIS.Core.Application.Service
/// </summary> /// </summary>
[ApiExplorerSettings(GroupName = "Trial")] [ApiExplorerSettings(GroupName = "Trial")]
public class TaskMedicalReviewRuleService(IRepository<TaskMedicalReviewRule> _taskMedicalReviewRuleRepository, public class TaskMedicalReviewRuleService(IRepository<TaskMedicalReviewRule> _taskMedicalReviewRuleRepository,
IRepository<TrialUser> _trialUserRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITaskMedicalReviewRuleService IRepository<TrialUserRole> _trialUserRoleRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITaskMedicalReviewRuleService
{ {
@@ -29,7 +29,7 @@ namespace IRaCIS.Core.Application.Service
var taskTaskMedicalReviewRuleQueryable = _taskMedicalReviewRuleRepository.Where(t => t.TrialId == inQuery.TrialId) var taskTaskMedicalReviewRuleQueryable = _taskMedicalReviewRuleRepository.Where(t => t.TrialId == inQuery.TrialId)
.ProjectTo<TaskMedicalReviewRuleView>(_mapper.ConfigurationProvider); .ProjectTo<TaskMedicalReviewRuleView>(_mapper.ConfigurationProvider);
var isHaveMIM = await _trialUserRepository.AnyAsync(t => t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MIM && t.TrialId == inQuery.TrialId); var isHaveMIM = await _trialUserRoleRepository.AnyAsync(t => t.UserRole.UserTypeEnum == Domain.Share.UserTypeEnum.MIM && t.TrialId == inQuery.TrialId);
return (await taskTaskMedicalReviewRuleQueryable.ToListAsync(), new { IsHaveMIM = isHaveMIM }); return (await taskTaskMedicalReviewRuleQueryable.ToListAsync(), new { IsHaveMIM = isHaveMIM });
} }
@@ -18,7 +18,7 @@ namespace IRaCIS.Core.Application.Service
/// </summary> /// </summary>
[ApiExplorerSettings(GroupName = "Trial")] [ApiExplorerSettings(GroupName = "Trial")]
public class TaskMedicalReviewService(IRepository<TaskMedicalReview> _taskMedicalReviewRepository, public class TaskMedicalReviewService(IRepository<TaskMedicalReview> _taskMedicalReviewRepository,
IRepository<TrialUser> _trialUserRepository, IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository, IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
IRepository<VisitTask> _visitTaskRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITaskMedicalReviewService IRepository<VisitTask> _visitTaskRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITaskMedicalReviewService
{ {
@@ -196,7 +196,7 @@ namespace IRaCIS.Core.Application.Service
public async Task<IResponseOutput<PageOutput<TaskMedicalReviewView>>> GetMIMMedicalReviewTaskList(TaskMedicalReviewQuery inQuery) public async Task<IResponseOutput<PageOutput<TaskMedicalReviewView>>> GetMIMMedicalReviewTaskList(TaskMedicalReviewQuery inQuery)
{ {
var taskMedicalReviewQueryable = _taskMedicalReviewRepository.Where(t => t.VisitTask.TrialId == inQuery.TrialId && t.MedicalManagerUserId == _userInfo.Id && t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) var taskMedicalReviewQueryable = _taskMedicalReviewRepository.Where(t => t.VisitTask.TrialId == inQuery.TrialId && t.MedicalManagerUserId == _userInfo.UserRoleId && t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.IsGetNextMedicalReviewTask, .WhereIf(inQuery.IsGetNextMedicalReviewTask,
x => ( x => (
@@ -328,7 +328,7 @@ namespace IRaCIS.Core.Application.Service
[HttpGet("{trialId:guid}")] [HttpGet("{trialId:guid}")]
public async Task<List<UserSimpleInfo>> GetMIMUserList(Guid trialId) public async Task<List<UserSimpleInfo>> GetMIMUserList(Guid trialId)
{ {
var query = _trialUserRepository.Where(t => (t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MIM || t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MC) && t.TrialId == trialId).Select(t => t.User).ProjectTo<UserSimpleInfo>(_mapper.ConfigurationProvider); var query = _trialUserRoleRepository.Where(t => (t.UserRole.UserTypeEnum == Domain.Share.UserTypeEnum.MIM || t.UserRole.UserTypeEnum == Domain.Share.UserTypeEnum.MC) && t.TrialId == trialId).Select(t => t.UserRole).ProjectTo<UserSimpleInfo>(_mapper.ConfigurationProvider);
return await query.ToListAsync(); return await query.ToListAsync();
} }
File diff suppressed because it is too large Load Diff
@@ -17,9 +17,9 @@ namespace IRaCIS.Core.Application.Service
CreateMap<TaskAllocationRule, TaskAllocationRuleView>() CreateMap<TaskAllocationRule, TaskAllocationRuleView>()
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode)) .ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.IdentityUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName)) .ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.IdentityUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName)) .ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.IdentityUser.FullName))
.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName)); .ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName));
List<Guid> subjectIdList = new List<Guid>(); List<Guid> subjectIdList = new List<Guid>();
@@ -27,9 +27,9 @@ namespace IRaCIS.Core.Application.Service
CreateMap<TaskAllocationRule, DoctorVisitTaskStatView>() CreateMap<TaskAllocationRule, DoctorVisitTaskStatView>()
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode)) .ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.IdentityUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName)) .ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.IdentityUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName)) .ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.IdentityUser.FullName))
.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName)) .ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName))
//.ForMember(o => o.ArmList, t => t.MapFrom(u => u.DoctorVisitTaskList.Where(c => c.TrialId == u.TrialId).Select(t => t.ArmEnum).Distinct())) //.ForMember(o => o.ArmList, t => t.MapFrom(u => u.DoctorVisitTaskList.Where(c => c.TrialId == u.TrialId).Select(t => t.ArmEnum).Distinct()))
.ForMember(o => o.TotalTaskCount, t => t.MapFrom(u => u.Trial.VisitTaskList.Count())) .ForMember(o => o.TotalTaskCount, t => t.MapFrom(u => u.Trial.VisitTaskList.Count()))
@@ -127,9 +127,9 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindSubjectCode :*/ u.Subject.Code)) .ForMember(o => o.SubjectCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindSubjectCode :*/ u.Subject.Code))
.ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.Subject.MedicalNo)) .ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.Subject.MedicalNo))
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode)) .ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.IdentityUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName)) .ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.IdentityUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName)) .ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.IdentityUser.FullName))
.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName)) .ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName))
//.ForMember(o => o.IsClinicalDataSigned, t => t.MapFrom(u => u.Subject.ClinicalDataList.Any(c => c.IsSign && (c.ReadingId == u.SouceReadModuleId || c.ReadingId == u.SourceSubjectVisitId)))) //.ForMember(o => o.IsClinicalDataSigned, t => t.MapFrom(u => u.Subject.ClinicalDataList.Any(c => c.IsSign && (c.ReadingId == u.SouceReadModuleId || c.ReadingId == u.SourceSubjectVisitId))))
; ;
@@ -176,9 +176,9 @@ namespace IRaCIS.Core.Application.Service
CreateMap<VisitTask, HistoryReadingDoctorUser>() CreateMap<VisitTask, HistoryReadingDoctorUser>()
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode)) .ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.IdentityUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName)) .ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.IdentityUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName)) .ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.IdentityUser.FullName))
.ForMember(o => o.JudgeTaskCode, t => t.MapFrom(u => u.TaskCode)) .ForMember(o => o.JudgeTaskCode, t => t.MapFrom(u => u.TaskCode))
.ForMember(o => o.DoctorUserId, t => t.MapFrom(u => u.DoctorUser.Id)); .ForMember(o => o.DoctorUserId, t => t.MapFrom(u => u.DoctorUser.Id));
@@ -195,9 +195,9 @@ namespace IRaCIS.Core.Application.Service
CreateMap<SubjectUser, AssignDoctorView>() CreateMap<SubjectUser, AssignDoctorView>()
//.ForMember(o => o.AssignTime, t => t.MapFrom(u => u.AssignTime)) //.ForMember(o => o.AssignTime, t => t.MapFrom(u => u.AssignTime))
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode)) .ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.IdentityUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName)) .ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.IdentityUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName)) .ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.IdentityUser.FullName))
.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName)); .ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName));
@@ -205,7 +205,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<TaskAllocationRuleAddOrEdit, TaskAllocationRule>(); CreateMap<TaskAllocationRuleAddOrEdit, TaskAllocationRule>();
CreateMap<User, TrialDoctorUserSelectView>() CreateMap<UserRole, TrialDoctorUserSelectView>()
.ForMember(o => o.DoctorUserId, t => t.MapFrom(u => u.Id)) .ForMember(o => o.DoctorUserId, t => t.MapFrom(u => u.Id))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.FullName)); .ForMember(o => o.FullName, t => t.MapFrom(u => u.FullName));
@@ -250,12 +250,12 @@ namespace IRaCIS.Core.Application.Service
CreateMap<User, UserSimpleInfo>() CreateMap<UserRole, UserSimpleInfo>()
.ForMember(o => o.UserId, t => t.MapFrom(u => u.Id)) .ForMember(o => o.UserId, t => t.MapFrom(u => u.Id))
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.UserCode)) .ForMember(o => o.UserCode, t => t.MapFrom(u => u.IdentityUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.UserName)) .ForMember(o => o.UserName, t => t.MapFrom(u => u.IdentityUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.FullName)); .ForMember(o => o.FullName, t => t.MapFrom(u => u.IdentityUser.FullName));
//.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.UserTypeRole.UserTypeShortName)); //.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.UserTypeRole.UserTypeShortName));
@@ -31,7 +31,7 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(queryCommonDocument.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == queryCommonDocument.BusinessScenarioEnum) .WhereIf(queryCommonDocument.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == queryCommonDocument.BusinessScenarioEnum)
.WhereIf(!string.IsNullOrEmpty(queryCommonDocument.Code), t => t.Code.Contains(queryCommonDocument.Code)) .WhereIf(!string.IsNullOrEmpty(queryCommonDocument.Code), t => t.Code.Contains(queryCommonDocument.Code))
.WhereIf(!string.IsNullOrEmpty(queryCommonDocument.Name), t => t.Name.Contains(queryCommonDocument.Name) || t.NameCN.Contains(queryCommonDocument.Name)) .WhereIf(!string.IsNullOrEmpty(queryCommonDocument.Name), t => t.Name.Contains(queryCommonDocument.Name) || t.NameCN.Contains(queryCommonDocument.Name))
.ProjectTo<CommonDocumentView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken, userId = _userInfo.Id }); .ProjectTo<CommonDocumentView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken, userId = _userInfo.UserRoleId });
return await commonDocumentQueryable.ToPagedListAsync(queryCommonDocument); return await commonDocumentQueryable.ToPagedListAsync(queryCommonDocument);
} }
@@ -110,6 +110,10 @@ namespace IRaCIS.Core.Application.ViewModel
public string Module { get; set; } = string.Empty; public string Module { get; set; } = string.Empty;
public int? State { get; set; }
public int InternationalizationType { get; set; }
} }
public class BatchAddInternationalizationDto : BatchInternationalizationDto public class BatchAddInternationalizationDto : BatchInternationalizationDto
@@ -119,6 +123,9 @@ namespace IRaCIS.Core.Application.ViewModel
public class InternationalizationSimpleDto : BatchInternationalizationDto public class InternationalizationSimpleDto : BatchInternationalizationDto
{ {
public string Version { get; set; }
public DateTime CreateTime { get; set; }
} }
File diff suppressed because it is too large Load Diff
@@ -25,10 +25,10 @@ namespace IRaCIS.Core.Application.Service
var exploreRecommendQueryable = var exploreRecommendQueryable =
_exploreRecommendRepository.Where().IgnoreQueryFilters() _exploreRecommendRepository.Where().IgnoreQueryFilters()
.WhereIf(string.IsNullOrEmpty(inQuery.Title), t => t.Title.Contains(inQuery.Title)) .WhereIf(!string.IsNullOrEmpty(inQuery.Title), t => t.Title.Contains(inQuery.Title))
.WhereIf(string.IsNullOrEmpty(inQuery.FileName), t => t.Title.Contains(inQuery.FileName)) .WhereIf(!string.IsNullOrEmpty(inQuery.FileName), t => t.Title.Contains(inQuery.FileName))
.WhereIf(string.IsNullOrEmpty(inQuery.DownloadUrl), t => t.Title.Contains(inQuery.DownloadUrl)) .WhereIf(!string.IsNullOrEmpty(inQuery.DownloadUrl), t => t.Title.Contains(inQuery.DownloadUrl))
.WhereIf(string.IsNullOrEmpty(inQuery.Version), t => t.Title.Contains(inQuery.Version)) .WhereIf(!string.IsNullOrEmpty(inQuery.Version), t => t.Title.Contains(inQuery.Version))
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == t.IsDeleted) .WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == t.IsDeleted)
.ProjectTo<ExploreRecommendView>(_mapper.ConfigurationProvider); .ProjectTo<ExploreRecommendView>(_mapper.ConfigurationProvider);
@@ -94,7 +94,7 @@ namespace IRaCIS.Core.Application.Service
#region DTO #region DTO
public class DoctorDownloadInfo public class DoctorDownloadInfo
{ {
public Guid Id { get; set; } public Guid? Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string ReviewerCode { get; set; } public string ReviewerCode { get; set; }
@@ -111,7 +111,7 @@ namespace IRaCIS.Core.Application.Service
{ {
public int Language { get; set; } public int Language { get; set; }
public List<Guid> DoctorIdList { get; set; } public List<Guid?> DoctorIdList { get; set; }
} }
public class GetDoctoreAttachPathCommand public class GetDoctoreAttachPathCommand
@@ -18,7 +18,7 @@ namespace IRaCIS.Core.Application.Service
/// </summary> /// </summary>
[ApiExplorerSettings(GroupName = "Common")] [ApiExplorerSettings(GroupName = "Common")]
public class InternationalizationService(IRepository<Internationalization> _internationalizationRepository, public class InternationalizationService(IRepository<Internationalization> _internationalizationRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, IInternationalizationService IMapper _mapper, IRepository<PublishLog> _publishLogRepository, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, IInternationalizationService
{ {
@@ -45,6 +45,11 @@ namespace IRaCIS.Core.Application.Service
ValueCN = t.ValueCN, ValueCN = t.ValueCN,
FrontType = t.FrontType, FrontType = t.FrontType,
Description = t.Description, Description = t.Description,
Module = t.Module,
State = t.State,
Version = t.PublishLog.Version,
CreateTime = t.CreateTime,
InternationalizationType = t.InternationalizationType
}).ToListAsync(); }).ToListAsync();
await _fusionCache.SetAsync<List<InternationalizationSimpleDto>>(CacheKeys.FrontInternational, list, TimeSpan.FromDays(1)); await _fusionCache.SetAsync<List<InternationalizationSimpleDto>>(CacheKeys.FrontInternational, list, TimeSpan.FromDays(1));
@@ -55,15 +60,17 @@ namespace IRaCIS.Core.Application.Service
} }
/// <summary> /// <summary>
/// 前端批量提交,后端判断不存在就添加,存在就更新 /// 前端批量提交,后端查询判断不存在就添加,存在就更新 (这里提交接口也能提交后端的标识,对后端标识进行更新)
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[AllowAnonymous] [AllowAnonymous]
public async Task<IResponseOutput> BatchAddOrUpdateFrontInternationalization(List<BatchInternationalizationDto> batchList) public async Task<IResponseOutput> BatchAddOrUpdateFrontInternationalization(List<BatchInternationalizationDto> batchList)
{ {
var result = (await _publishLogRepository.Where(t => t.IsCurrentVersion == true).ProjectTo<PublishLogView>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
foreach (var item in batchList) foreach (var item in batchList)
{ {
var find = await _internationalizationRepository.FirstOrDefaultAsync(t => t.Code == item.Code && t.Description == item.Description && t.InternationalizationType == 0); var find = await _internationalizationRepository.FirstOrDefaultAsync(t => t.Code == item.Code && t.InternationalizationType == item.InternationalizationType);
if (find != null) if (find != null)
{ {
@@ -71,13 +78,21 @@ namespace IRaCIS.Core.Application.Service
} }
else else
{ {
var frontState = item.State == null ? 0 : (int)item.State;
var mapItem = _mapper.Map<Internationalization>(item); var mapItem = _mapper.Map<Internationalization>(item);
mapItem.InternationalizationType = 0; //mapItem.InternationalizationType = 0;
// 0 是预翻译 1是已确认 2是后端废弃 // 0 是预翻译 1是已确认 2是后端废弃
mapItem.State = 0; mapItem.State = frontState;
await _internationalizationRepository.AddAsync(mapItem); find = await _internationalizationRepository.AddAsync(mapItem);
}
if (find.PublishLogId == null || find.PublishLogId == Guid.Empty)
{
find.PublishLogId = result.Id;
} }
} }
await _internationalizationRepository.SaveChangesAsync(); await _internationalizationRepository.SaveChangesAsync();
@@ -1,11 +1,13 @@
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using MailKit; using MailKit;
using Medallion.Threading; using Medallion.Threading;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using MimeKit; using MimeKit;
@@ -29,11 +31,11 @@ namespace IRaCIS.Core.Application.Service
Task AdminResetPwdSendEmailAsync(Guid userId, string pwdNotMd5 = "123456"); Task AdminResetPwdSendEmailAsync(Guid userId, string pwdNotMd5 = "123456");
Task SiteSurveyUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl); Task SiteSurveyUserJoinEmail(Guid trialId, Guid userId, string userTypes, string baseUrl, string rootUrl);
Task ExternalUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl); Task ExternalUserJoinEmail(Guid trialId, Guid userId, string userTypes, string baseUrl, string rootUrl);
Task<Guid> DoctorJoinTrialEmail(Guid trialId, Guid doctorId, string baseUrl, string rootUrl); Task<(Guid identityUserId, Guid userRoleId)> DoctorJoinTrialEmail(Guid trialId, Guid doctorId, string baseUrl, string rootUrl);
Task UserFeedBackMail(Guid feedBackId); Task UserFeedBackMail(Guid feedBackId);
} }
@@ -42,7 +44,9 @@ namespace IRaCIS.Core.Application.Service
IRepository<SystemBasicData> _systemBasicDatarepository, IRepository<SystemBasicData> _systemBasicDatarepository,
IRepository<VisitTask> _visitTaskRepository, IRepository<VisitTask> _visitTaskRepository,
IRepository<TrialSite> _trialSiteRepository, IRepository<TrialSite> _trialSiteRepository,
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<UserLog> _userLogRepository,
IRepository<IdentityUser> _identityUserRepository,
IRepository<UserFeedBack> _userFeedBackRepository, IRepository<UserFeedBack> _userFeedBackRepository,
ITokenService _tokenService, ITokenService _tokenService,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
@@ -169,83 +173,11 @@ namespace IRaCIS.Core.Application.Service
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle);
} }
//用户重置邮箱
public async Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(userName, emailAddress));
//主题
//---[来自展影IRC] 关于重置邮箱的提醒
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
userName,
//---您正在进行邮箱重置操作
verificationCode
);
return (topicStr, htmlBodyStr);
};
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc);
var sucessHandle = GetEmailSuccessHandle(userId, verificationCode, emailAddress);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle);
}
//不登录 通过邮箱重置密码
public async Task AnolymousSendEmailForResetAccount(string emailAddress, int verificationCode)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
"Sir/Madam",
//---您正在进行邮箱重置密码操作
verificationCode
);
return (topicStr, htmlBodyStr);
};
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc);
////此时不知道用户
var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle);
}
/// <summary> /// <summary>
/// Reviewer简历录入 发送验证码 /// Reviewer简历录入 发送验证码
/// </summary> /// </summary>
@@ -333,12 +265,13 @@ namespace IRaCIS.Core.Application.Service
} }
#region
//添加用户发送邮件 //添加用户发送邮件
public async Task AddUserSendEmailAsync(Guid userId, string baseUrl, string routeUrl) public async Task AddUserSendEmailAsync(Guid userId, string baseUrl, string routeUrl)
{ {
var sysUserInfo = (await _userRepository.Where(t => t.Id == userId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException(); var sysUserInfo = (await _identityUserRepository.Where(t => t.Id == userId).Include(t => t.UserRoleList).ThenInclude(c => c.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
var messageToSend = new MimeMessage(); var messageToSend = new MimeMessage();
@@ -350,11 +283,11 @@ namespace IRaCIS.Core.Application.Service
//---[来自展影IRC] 关于创建账户的提醒 //---[来自展影IRC] 关于创建账户的提醒
var token = _tokenService.GetToken(IRaCISClaims.Create(_mapper.Map<UserBasicInfo>(sysUserInfo))); var token = _tokenService.GetToken(new UserTokenInfo() { IdentityUserId = sysUserInfo.Id });
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token }); await _identityUserRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new IdentityUser() { EmailToken = token });
routeUrl = routeUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token; routeUrl = routeUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login")); var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
@@ -370,8 +303,8 @@ namespace IRaCIS.Core.Application.Service
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
sysUserInfo.FullName, sysUserInfo.FullName,
sysUserInfo.UserName, sysUserInfo.EMail,
sysUserInfo.UserTypeRole.UserTypeShortName, //string.Join(',', sysUserInfo.UserRoleList.Select(t => t.UserTypeRole.UserTypeShortName)),
redirectUrl redirectUrl
); );
@@ -388,7 +321,7 @@ namespace IRaCIS.Core.Application.Service
//管理员重置密码发送邮件 //管理员重置密码发送邮件
public async Task AdminResetPwdSendEmailAsync(Guid userId, string pwdNotMd5 = "123456") public async Task AdminResetPwdSendEmailAsync(Guid userId, string pwdNotMd5 = "123456")
{ {
var sysUserInfo = (await _userRepository.Where(t => t.Id == userId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException(); var sysUserInfo = (await _identityUserRepository.Where(t => t.Id == userId).Include(t => t.UserRoleList).ThenInclude(c => c.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
var messageToSend = new MimeMessage(); var messageToSend = new MimeMessage();
//发件地址 //发件地址
@@ -408,7 +341,7 @@ namespace IRaCIS.Core.Application.Service
sysUserInfo.FullName, sysUserInfo.FullName,
sysUserInfo.UserName, sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName, //string.Join(',', sysUserInfo.UserRoleList.Select(t => t.UserTypeRole.UserTypeShortName)),
pwdNotMd5 pwdNotMd5
); );
@@ -421,73 +354,88 @@ namespace IRaCIS.Core.Application.Service
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
} }
//用户重置邮箱
//Site调研 用户加入项目 public async Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode)
public async Task SiteSurveyUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl)
{ {
var sysUserInfo = (await _userRepository.Where(t => t.Id == userId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
var messageToSend = new MimeMessage(); var messageToSend = new MimeMessage();
//发件地址 //发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail)); messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址 //收件地址
messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail)); messageToSend.To.Add(new MailboxAddress(userName, emailAddress));
//主题 //主题
// $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信"; //---[来自展影IRC] 关于重置邮箱的提醒
var token = _tokenService.GetToken(IRaCISClaims.Create(_mapper.Map<UserBasicInfo>(sysUserInfo)));
if (sysUserInfo.IsFirstAdd)
{
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token });
}
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{ {
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo); var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
sysUserInfo.FullName, userName,
trialInfo.ExperimentName, //---您正在进行邮箱重置操作
trialInfo.ResearchProgramNo, verificationCode
trialInfo.TrialCode,
sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName,
sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl
); );
return (topicStr, htmlBodyStr); return (topicStr, htmlBodyStr);
}; };
await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc); await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig); var sucessHandle = GetEmailSuccessHandle(userId, verificationCode, emailAddress);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle);
} }
//不登录 通过邮箱重置密码
public async Task AnolymousSendEmailForResetAccount(string emailAddress, int verificationCode)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
"Sir/Madam",
//---您正在进行邮箱重置密码操作
verificationCode
);
return (topicStr, htmlBodyStr);
};
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc);
////此时不知道用户
var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle);
}
//外部用户 加入项目 //外部用户 加入项目
public async Task ExternalUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl) public async Task ExternalUserJoinEmail(Guid trialId, Guid userId, string userTypes, string baseUrl, string rootUrl)
{ {
var trialInfo = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId)).IfNullThrowException(); var trialInfo = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId)).IfNullThrowException();
var sysUserInfo = (await _userRepository.Where(t => t.Id == userId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException(); var sysUserInfo = (await _identityUserRepository.Where(t => t.Id == userId).FirstOrDefaultAsync()).IfNullThrowException();
var messageToSend = new MimeMessage(); var messageToSend = new MimeMessage();
//发件地址 //发件地址
@@ -499,15 +447,15 @@ namespace IRaCIS.Core.Application.Service
var token = _tokenService.GetToken(IRaCISClaims.Create(_mapper.Map<UserBasicInfo>(sysUserInfo))); var token = _tokenService.GetToken(new UserTokenInfo() { IdentityUserId = sysUserInfo.Id });
if (sysUserInfo.IsFirstAdd) if (sysUserInfo.IsFirstAdd)
{ {
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token }); await _identityUserRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new Domain.Models.IdentityUser() { EmailToken = token });
} }
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login")); var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token; var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}"; var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
@@ -524,9 +472,9 @@ namespace IRaCIS.Core.Application.Service
trialInfo.ExperimentName, trialInfo.ExperimentName,
trialInfo.ResearchProgramNo, trialInfo.ResearchProgramNo,
trialInfo.TrialCode, trialInfo.TrialCode,
sysUserInfo.UserName, sysUserInfo.IsFirstAdd ? sysUserInfo.EMail : sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName, userTypes,
sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl
); );
return (topicStr, htmlBodyStr); return (topicStr, htmlBodyStr);
@@ -540,26 +488,93 @@ namespace IRaCIS.Core.Application.Service
} }
//Site调研 用户加入项目
public async Task SiteSurveyUserJoinEmail(Guid trialId, Guid userId, string userTypes, string baseUrl, string rootUrl)
{
var sysUserInfo = (await _identityUserRepository.Where(t => t.Id == userId).FirstOrDefaultAsync()).IfNullThrowException();
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail));
//主题
// $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信";
var token = _tokenService.GetToken(new UserTokenInfo() { IdentityUserId = sysUserInfo.Id });
if (sysUserInfo.IsFirstAdd)
{
await _identityUserRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new Domain.Models.IdentityUser() { EmailToken = token });
}
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
sysUserInfo.FullName,
trialInfo.ExperimentName,
trialInfo.ResearchProgramNo,
trialInfo.TrialCode,
sysUserInfo.IsFirstAdd ? sysUserInfo.EMail : sysUserInfo.UserName,
userTypes,
sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl
);
return (topicStr, htmlBodyStr);
};
await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
}
#endregion
//医生生成账号加入 或者已存在账号加入到项目中 //医生生成账号加入 或者已存在账号加入到项目中
public async Task<Guid> DoctorJoinTrialEmail(Guid trialId, Guid doctorId, string baseUrl, string rootUrl) public async Task<(Guid identityUserId, Guid userRoleId)> DoctorJoinTrialEmail(Guid trialId, Guid doctorId, string baseUrl, string rootUrl)
{ {
var doctor = await _doctorTypeRepository.FindAsync(doctorId); var doctor = await _doctorTypeRepository.FindAsync(doctorId);
User sysUserInfo = new User(); var sysUserInfo = new IdentityUser();
var userType = await _userTypeRepository.FirstAsync(t => t.UserTypeEnum == UserTypeEnum.IndependentReviewer); var userType = await _userTypeRepository.FirstAsync(t => t.UserTypeEnum == UserTypeEnum.IndependentReviewer);
//需要创建新的账户
var isNeedCreateNewUser = false;
var @lock = _distributedLockProvider.CreateLock($"UserCode"); var @lock = _distributedLockProvider.CreateLock($"UserCode");
using (await @lock.AcquireAsync()) using (await @lock.AcquireAsync())
{ {
var isDoctorHaveAccount = await _userRepository.AnyAsync(t => t.DoctorId == doctorId); var isDoctorHaveAccount = await _userRoleRepository.AnyAsync(t => t.DoctorId == doctorId || t.IdentityUser.EMail == doctor.EMail);
if (!isDoctorHaveAccount) if (!isDoctorHaveAccount)
{ {
isNeedCreateNewUser = true;
var saveItem = new User() { FirstName = doctor.FirstName, LastName = doctor.LastName, EMail = doctor.EMail }; var saveItem = new IdentityUser() { FirstName = doctor.FirstName, LastName = doctor.LastName, EMail = doctor.EMail };
var trialType = await _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialType).FirstOrDefaultAsync(); var trialType = await _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialType).FirstOrDefaultAsync();
@@ -568,32 +583,43 @@ namespace IRaCIS.Core.Application.Service
saveItem.IsTestUser = true; saveItem.IsTestUser = true;
} }
saveItem.UserCeateSource = UserCeateSource.ReviewerSelect;
saveItem.TrialId = trialId;
saveItem.Code = _userRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1; saveItem.Code = _identityUserRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1;
saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(User)); saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(IdentityUser));
saveItem.UserName = saveItem.UserCode; saveItem.UserRoleList = new List<UserRole>() { new UserRole() { DoctorId = doctorId, UserTypeEnum = UserTypeEnum.IndependentReviewer, UserTypeId = userType.Id } };
saveItem.UserTypeEnum = UserTypeEnum.IndependentReviewer; var savedUser = await _identityUserRepository.AddAsync(saveItem);
saveItem.DoctorId = doctorId;
saveItem.UserTypeId = userType.Id;
var savedUser = await _userRepository.AddAsync(saveItem);
//下面获取Token 需要这部分信息 //下面获取Token 需要这部分信息
sysUserInfo = savedUser.Clone(); sysUserInfo = savedUser;
sysUserInfo.UserTypeRole = userType;
await _userRepository.SaveChangesAsync();
} }
else else
{ {
sysUserInfo = (await _userRepository.Where(t => t.DoctorId == doctorId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException(); sysUserInfo = (await _identityUserRepository.Where(t => t.UserRoleList.Any(t => t.DoctorId == doctorId || t.IdentityUser.EMail == doctor.EMail), true).Include(t => t.UserRoleList).FirstOrDefaultAsync()).IfNullThrowException();
var findRole = sysUserInfo.UserRoleList.FirstOrDefault(t => t.UserTypeId == userType.Id);
//不存在该角色,那么就加入该角色
if (findRole == null)
{
sysUserInfo.UserRoleList.Add(new UserRole() { DoctorId = doctorId, UserTypeEnum = UserTypeEnum.IndependentReviewer, UserTypeId = userType.Id });
}
else
{
findRole.IsUserRoleDisabled = false;
}
sysUserInfo.Status = UserStateEnum.Enable;
} }
//保证能有userRoleId
await _userRoleRepository.SaveChangesAsync();
} }
@@ -607,20 +633,14 @@ namespace IRaCIS.Core.Application.Service
var basicInfo = IRaCISClaims.Create(_mapper.Map<UserBasicInfo>(sysUserInfo)); var token = _tokenService.GetToken(new UserTokenInfo() { IdentityUserId = sysUserInfo.Id });
////第一次添加的时候 注意赋值
//basicInfo.PermissionStr = userType.PermissionStr;
//basicInfo.UserTypeShortName = userType.UserTypeShortName;
var token = _tokenService.GetToken(basicInfo);
if (sysUserInfo.IsFirstAdd) if (sysUserInfo.IsFirstAdd)
{ {
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token }); await _identityUserRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new Domain.Models.IdentityUser() { EmailToken = token });
} }
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + userType.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token; var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login")); var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
@@ -642,8 +662,8 @@ namespace IRaCIS.Core.Application.Service
trialInfo.ExperimentName, trialInfo.ExperimentName,
trialInfo.ResearchProgramNo, trialInfo.ResearchProgramNo,
trialInfo.TrialCode, trialInfo.TrialCode,
sysUserInfo.UserName, sysUserInfo.IsFirstAdd ? sysUserInfo.EMail : sysUserInfo.UserName,
userType.UserTypeShortName, userType.UserTypeName,
sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl
); );
@@ -656,7 +676,15 @@ namespace IRaCIS.Core.Application.Service
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, null); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, null);
return sysUserInfo.Id; //创建账号 和创建角色 一条,更新的时候才记录更新角色
if (isNeedCreateNewUser == false)
{
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = _userInfo.IdentityUserId, ActionUserName = _userInfo.UserName, TargetIdentityUserId = sysUserInfo.Id, OptType = UserOptType.UpdateUserRole }, true);
}
return (sysUserInfo.Id, sysUserInfo.UserRoleList.First(t => t.UserTypeEnum == UserTypeEnum.IndependentReviewer).Id);
} }
@@ -664,7 +692,7 @@ namespace IRaCIS.Core.Application.Service
public async Task UserFeedBackMail(Guid feedBackId) public async Task UserFeedBackMail(Guid feedBackId)
{ {
var feedBack = await _userFeedBackRepository.Where(t => t.Id == feedBackId).Include(t => t.CreateUser).ThenInclude(t => t.UserTypeRole).FirstNotNullAsync(); var feedBack = await _userFeedBackRepository.Where(t => t.Id == feedBackId).Include(t => t.CreateUserRole.UserTypeRole).Include(t => t.CreateUserRole.IdentityUser).FirstNotNullAsync();
var messageToSend = new MimeMessage(); var messageToSend = new MimeMessage();
//发件地址 //发件地址
@@ -680,8 +708,8 @@ namespace IRaCIS.Core.Application.Service
var userTypeEnumList = emailConfigInfo.EmailNoticeUserTypeList.Where(t => t.EmailUserType == EmailUserType.To).Select(t => t.UserType).ToList(); var userTypeEnumList = emailConfigInfo.EmailNoticeUserTypeList.Where(t => t.EmailUserType == EmailUserType.To).Select(t => t.UserType).ToList();
var emailList = await _userRepository.Where(t => userTypeEnumList.Contains(t.UserTypeEnum) && var emailList = await _userRoleRepository.Where(t => userTypeEnumList.Contains(t.UserTypeEnum) && t.IsUserRoleDisabled == false && t.IdentityUser.Status == UserStateEnum.Enable &&
(isHaveTrialId ? t.UserTrials.Any(t => t.TrialId == feedBack.TrialId) : true)).Select(t => new { t.EMail, t.UserTypeEnum, t.FullName }).ToListAsync(); (isHaveTrialId ? t.IdentityUser.UserTrialList.Any(t => t.TrialId == feedBack.TrialId && t.TrialUserRoleList.Any(c => userTypeEnumList.Contains(c.UserRole.UserTypeEnum))) : true)).Select(t => new { t.IdentityUser.EMail, t.UserTypeEnum, t.IdentityUser.FullName }).ToListAsync();
foreach (var email in emailList) foreach (var email in emailList)
@@ -709,8 +737,8 @@ namespace IRaCIS.Core.Application.Service
info.TrialCode, info.TrialCode,
info.SubejctCode, info.SubejctCode,
info.VisitName, info.VisitName,
feedBack.CreateUser.UserTypeRole.UserTypeShortName, feedBack.CreateUserRole.UserTypeRole.UserTypeShortName,
feedBack.CreateUser.FullName, feedBack.CreateUserRole.IdentityUser.FullName,
emailType, emailType,
feedBack.QuestionDescription, feedBack.QuestionDescription,
_systemEmailConfig.SiteUrl _systemEmailConfig.SiteUrl
@@ -739,8 +767,8 @@ namespace IRaCIS.Core.Application.Service
info.TrialCode, info.TrialCode,
info.SubejctCode, info.SubejctCode,
info.VisitName, info.VisitName,
feedBack.CreateUser.UserTypeRole.UserTypeShortName, feedBack.CreateUserRole.UserTypeRole.UserTypeShortName,
feedBack.CreateUser.FullName, feedBack.CreateUserRole.IdentityUser.FullName,
emailType, emailType,
feedBack.QuestionDescription, feedBack.QuestionDescription,
_systemEmailConfig.SiteUrl _systemEmailConfig.SiteUrl
@@ -768,8 +796,8 @@ namespace IRaCIS.Core.Application.Service
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
userNames, userNames,
info.TrialCode, info.TrialCode,
feedBack.CreateUser.UserTypeRole.UserTypeShortName, feedBack.CreateUserRole.UserTypeRole.UserTypeShortName,
feedBack.CreateUser.FullName, feedBack.CreateUserRole.IdentityUser.FullName,
emailType, emailType,
feedBack.QuestionDescription, feedBack.QuestionDescription,
_systemEmailConfig.SiteUrl _systemEmailConfig.SiteUrl
@@ -793,8 +821,8 @@ namespace IRaCIS.Core.Application.Service
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
userNames, userNames,
feedBack.CreateUser.UserTypeRole.UserTypeShortName, feedBack.CreateUserRole.UserTypeRole.UserTypeShortName,
feedBack.CreateUser.FullName, feedBack.CreateUserRole.IdentityUser.FullName,
feedBack.QuestionDescription, feedBack.QuestionDescription,
_systemEmailConfig.SiteUrl _systemEmailConfig.SiteUrl
); );
@@ -42,7 +42,7 @@ namespace IRaCIS.Core.Application.Service
{ {
Version version; Version version;
if (!Version.TryParse(addOrEditPublishLog.Version, out version)|| !Version.TryParse(addOrEditPublishLog.Version_US, out version)) if (!Version.TryParse(addOrEditPublishLog.Version, out version))
{ {
//"版本号不符合要求" //"版本号不符合要求"
return ResponseOutput.NotOk(_localizer["PublishLog_NotValidVersion"]); return ResponseOutput.NotOk(_localizer["PublishLog_NotValidVersion"]);
@@ -50,7 +50,7 @@ namespace IRaCIS.Core.Application.Service
var verifyExp1 = new EntityVerifyExp<PublishLog>() var verifyExp1 = new EntityVerifyExp<PublishLog>()
{ {
VerifyExp = u => u.Version == addOrEditPublishLog.Version || u.Version_US == addOrEditPublishLog.Version_US, VerifyExp = u => u.Version == addOrEditPublishLog.Version ,
//"发布编号不能重复" //"发布编号不能重复"
VerifyMsg = _localizer["PublishLog_RepeatVersion"] VerifyMsg = _localizer["PublishLog_RepeatVersion"]
@@ -5,6 +5,7 @@
//-------------------------------------------------------------------- //--------------------------------------------------------------------
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace IRaCIS.Core.Application.Services namespace IRaCIS.Core.Application.Services
{ {
@@ -25,7 +26,10 @@ namespace IRaCIS.Core.Application.Services
[HttpPost] [HttpPost]
public async Task<PageOutput<SystemBasicDataView>> GetSystemBasicDataList(SystemBasicDataQuery inQuery) public async Task<PageOutput<SystemBasicDataView>> GetSystemBasicDataList(SystemBasicDataQuery inQuery)
{ {
var systemBasicDataQueryable = _systemBasicDataRepository.Where(t => t.ParentId == null) var systemBasicDataQueryable = _systemBasicDataRepository
.Where(t => t.ParentId == null)
.WhereIf(inQuery.Code != null, t => t.Code.Contains(inQuery.Code))
.WhereIf(inQuery.Name != null, t => t.Name.Contains(inQuery.Name))
.ProjectTo<SystemBasicDataView>(_mapper.ConfigurationProvider); .ProjectTo<SystemBasicDataView>(_mapper.ConfigurationProvider);
return await systemBasicDataQueryable.ToPagedListAsync(inQuery, nameof(SystemBasicDataView.Code)); return await systemBasicDataQueryable.ToPagedListAsync(inQuery, nameof(SystemBasicDataView.Code));
@@ -98,9 +98,9 @@ namespace IRaCIS.Core.Application.Service
CreateMap<TrialImageDownload, TrialImageDownloadExportDto>() CreateMap<TrialImageDownload, TrialImageDownloadExportDto>()
.ForMember(d => d.UserFullName, u => u.MapFrom(s => s.CreateUser.FullName)) .ForMember(d => d.UserFullName, u => u.MapFrom(s => s.CreateUserRole.FullName))
.ForMember(d => d.UserTypeEnum, u => u.MapFrom(s => s.CreateUser.UserTypeEnum)) .ForMember(d => d.UserTypeEnum, u => u.MapFrom(s => s.CreateUserRole.UserTypeEnum))
.ForMember(d => d.UserName, u => u.MapFrom(s => s.CreateUser.UserName)) .ForMember(d => d.UserName, u => u.MapFrom(s => s.CreateUserRole.IdentityUser.UserName))
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.Subject.TrialSite.TrialSiteCode)); .ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.Subject.TrialSite.TrialSiteCode));
@@ -1,5 +1,8 @@
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces; using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes; using Panda.DynamicWebApi.Attributes;
@@ -9,7 +12,11 @@ namespace IRaCIS.Core.Application.Service
/// 医生文档关联关系维护 /// 医生文档关联关系维护
/// </summary> /// </summary>
[ApiExplorerSettings(GroupName = "Reviewer")] [ApiExplorerSettings(GroupName = "Reviewer")]
public class AttachmentService(IRepository<Attachment> _attachmentrepository, IRepository<Doctor> _doctorrepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IAttachmentService public class AttachmentService(IRepository<Attachment> _attachmentrepository,
IRepository<Dictionary> _dictionaryRepository,
IRepository<Enroll> _enrollRepository,
IOSSService _oSSService,
IRepository<Doctor> _doctorrepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IAttachmentService
{ {
@@ -89,6 +96,150 @@ namespace IRaCIS.Core.Application.Service
return attachmentList; return attachmentList;
} }
/// <summary>
/// 获取项目医生附件
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<AttachmentDTO>> GetTrialAttachments(GetTrialAttachmentsInDto inDto)
{
var dicList=await _dictionaryRepository.Where(x => x.Parent.Code == "CertificateFileType").Select(x=>x.Code).ToListAsync();
var attachmentList = await _attachmentrepository
.Where(a =>a.Doctor.EnrollList.Any(x=>x.TrialId == inDto.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup)|| a.TrialId == inDto.TrialId)
.WhereIf(inDto.DoctorId!=null,x=>x.DoctorId==inDto.DoctorId)
.WhereIf(inDto.IsAuthorizedView != null, x => x.IsAuthorizedView == inDto.IsAuthorizedView)
.WhereIf(inDto.Type.IsNotNullOrEmpty(), x => x.Type == inDto.Type)
.WhereIf(inDto.FileName.IsNotNullOrEmpty(), x => inDto.FileName.Contains(x.FileName))
.Where(a => dicList.Contains(a.Type)||a.Type==string.Empty)
.ProjectTo<AttachmentDTO>(_mapper.ConfigurationProvider, new { TrialId = inDto.TrialId }).ToPagedListAsync(inDto);
return attachmentList;
}
/// <summary>
/// 获取医生列表
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<GetTrialDoctorListOutDto>> GetTrialDoctorList(GetTrialDoctorSelectInDto inDto)
{
var result= await _enrollRepository.Where(x => x.TrialId == inDto.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup).Select(x => x.Doctor)
.ProjectTo<GetTrialDoctorListOutDto>(_mapper.ConfigurationProvider).OrderBy(x=>x.BlindName).ToListAsync();
return result;
}
/// <summary>
/// 修改稽查状态
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SetAuthorizedView(SetAttachmentAuthorizedView inDto)
{
await _attachmentrepository.UpdatePartialFromQueryAsync(x => inDto.Ids.Contains(x.Id), x => new Attachment() { IsAuthorizedView = inDto.IsAuthorizedView });
await _attachmentrepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> DeleteAttachment(DeleteAttachment inDto)
{
var success = await _attachmentrepository.DeleteFromQueryAsync(t => inDto.Ids.Contains(t.Id));
await _attachmentrepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 上传项目医生
/// </summary>
/// <param name="attachmentList"></param>
/// <returns></returns>
[HttpPost]
public async Task<IEnumerable<AttachmentDTO>> SaveTrialAttachments(IEnumerable<AttachmentDTO> attachmentList)
{
foreach (var item in attachmentList)
{
if (item.DoctorId != null)
{
await _attachmentrepository.BatchDeleteNoTrackingAsync(a => a.DoctorId == item.DoctorId && a.Type == item.Type);
}
}
var attachments = _mapper.Map<IEnumerable<Attachment>>(attachmentList).ToList();
var newAttachment = attachments.Where(t => t.Id == Guid.Empty);
await _attachmentrepository.AddRangeAsync(newAttachment);
await _attachmentrepository.SaveChangesAsync();
var list = _mapper.Map<IEnumerable<AttachmentDTO>>(attachments).ToList();
list.ForEach(t => t.FullPath = t.Path + "?access_token=" + _userInfo.UserToken);
return list;
}
/// <summary>
/// 更新医生资质
/// </summary>
/// <param name="attachment"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> UpdateTrialAttachments(AttachmentDTO attachment)
{
if (!attachment.Path.Contains(attachment.DoctorId.ToString()))
{
var attachmentData= await _attachmentrepository.Where(a => a.Id == attachment.Id).FirstNotNullAsync();
var fileName= attachmentData.Path.Split("/").Last();
attachment.Path = $"/systemData/reviewe/{attachment.Type}/{attachment.DoctorId}/{fileName}";
await _oSSService.MoveObject(attachmentData.Path, attachment.Path);
}
if (attachment.DoctorId != null)
{
await _attachmentrepository.DeleteFromQueryAsync(a =>a.Id!=attachment.Id&& a.DoctorId == attachment.DoctorId && a.Type == attachment.Type);
}
attachment.UpdateTime = DateTime.Now;
await _attachmentrepository.UpdateFromDTOAsync(attachment);
await _attachmentrepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
[NonDynamicMethod] [NonDynamicMethod]
public async Task<AttachmentDTO> GetDetailById(Guid attachmentId) public async Task<AttachmentDTO> GetDetailById(Guid attachmentId)
{ {
@@ -2,19 +2,80 @@
{ {
public class AttachmentDTO public class AttachmentDTO
{ {
public Guid Id { get; set; } public Guid? Id { get; set; }
public Guid DoctorId { get; set; } public Guid? DoctorId { get; set; }
public bool IsOfficial { get; set; } public bool IsOfficial { get; set; }
public string Type { get; set; } = string.Empty; public string Type { get; set; } = string.Empty;
public string Path { get; set; } = string.Empty; public string Path { get; set; } = string.Empty;
public string FullPath { get; set; } = string.Empty; public string FullPath { get; set; } = string.Empty;
public string FileName { get; set; } = string.Empty; public string FileName { get; set; } = string.Empty;
public DateTime? CreateTime { get; set; } public DateTime? CreateTime { get; set; }
public DateTime? UpdateTime { get; set; }
public int Language { get; set; } public int Language { get; set; }
public bool ReUpload { get; set; } = false; public bool ReUpload { get; set; } = false;
public Guid? TrialId { get; set; }
/// <summary>
/// 是否授权
/// </summary>
public bool IsAuthorizedView { get; set; } = false;
public string BlindName { get; set; } = string.Empty;
public string BlindNameCN { get; set; } = string.Empty;
public string ChineseName { get; set; } = string.Empty;
public string FirstName { get; set; } = string.Empty;
public string FullName => LastName + " / " + FirstName;
public string LastName { get; set; } = string.Empty;
public string UserName { get; set; } = string.Empty;
} }
public class SetAttachmentAuthorizedView
{
public List<Guid> Ids { get; set; }
public bool IsAuthorizedView { get; set; }
}
public class DeleteAttachment
{
public List<Guid> Ids { get; set; }
}
public class GetTrialDoctorSelectInDto
{
public Guid TrialId { get; set; }
}
public class GetTrialDoctorListOutDto
{
public Guid Id { get; set; }
public string BlindName { get; set; } = string.Empty;
public string BlindNameCN { get; set; } = string.Empty;
public string ChineseName { get; set; } = string.Empty;
public string FirstName { get; set; } = string.Empty;
public string FullName => LastName + " / " + FirstName;
public string LastName { get; set; } = string.Empty;
}
public class GetTrialAttachmentsInDto:PageInput
{
public Guid TrialId { get; set; }
public string? Type { get; set; }
public Guid? DoctorId { get; set; }
public string? FileName { get; set; }
public bool? IsAuthorizedView { get; set; }
}
public class ReviewerAckDTO public class ReviewerAckDTO
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
@@ -169,6 +169,16 @@ namespace IRaCIS.Application.Contracts
public class ReviewerConfirmationQueryDTO : PageInput public class ReviewerConfirmationQueryDTO : PageInput
{ {
public Guid TrialId { get; set; } = Guid.Empty; public Guid TrialId { get; set; } = Guid.Empty;
public DateTime? OptStartTime{ get; set; }
public DateTime? OptEndTime { get; set; }
public string? Code { get; set; }
public UserTypeEnum? UserTypeEnum { get; set; }
public string? OptUserName { get; set; }
} }
public class SelectionReviewerDTO : DoctorDTO public class SelectionReviewerDTO : DoctorDTO
@@ -194,14 +204,48 @@ namespace IRaCIS.Application.Contracts
public string City { get; set; } = string.Empty; public string City { get; set; } = string.Empty;
public string HospitalName { get; set; } = string.Empty; public string HospitalName { get; set; } = string.Empty;
public string HospitalNameCN { get; set; } = string.Empty;
public string Country { get; set; } = string.Empty; public string Country { get; set; } = string.Empty;
} }
public class GetTrialDoctorListInDto : PageInput
{
public Guid TrialId { get; set; } = Guid.Empty;
/// <summary>
/// 亚专业
/// </summary>
public Guid? SubspecialityId { get; set; }
/// <summary>
/// 专业
/// </summary>
public Guid? SpecialityId { get; set; }
/// <summary>
/// 机构
/// </summary>
public Guid? HospitalId { get; set; }
}
public class TrialDoctorInfo : ConfirmationReviewerDTO
{
public List<string> SubspecialityList => DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).OrderBy(t => t.ShowOrder).Select(t => t.Value).ToList();
public List<string> SubspecialityCNList => DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).OrderBy(t => t.ShowOrder).Select(t => t.ValueCN).ToList();
}
public class ConfirmationReviewerDTO : DoctorOptDTO public class ConfirmationReviewerDTO : DoctorOptDTO
{ {
public int DoctorTrialState { get; set; } public int DoctorTrialState { get; set; }
public string OptUserName { get; set; } = string.Empty; public string OptUserName { get; set; } = string.Empty;
public UserTypeEnum? UserTypeEnum { get; set; }
public DateTime? OptTime { get; set; } public DateTime? OptTime { get; set; }
public string? OptTimeStr => OptTime?.ToString("yyyy-MM-dd HH:mm:ss"); public string? OptTimeStr => OptTime?.ToString("yyyy-MM-dd HH:mm:ss");
@@ -223,6 +267,8 @@ namespace IRaCIS.Application.Contracts
public List<Guid> SubspecialityIds => DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).OrderBy(t => t.ShowOrder).Select(t => t.Id).ToList(); public List<Guid> SubspecialityIds => DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).OrderBy(t => t.ShowOrder).Select(t => t.Id).ToList();
public Guid? HospitalId { get; set; } public Guid? HospitalId { get; set; }
} }
@@ -235,6 +281,10 @@ namespace IRaCIS.Application.Contracts
public string OptUserName { get; set; } = String.Empty; public string OptUserName { get; set; } = String.Empty;
public DateTime? OptTime { get; set; } public DateTime? OptTime { get; set; }
public int OptUserType { get; set; }
public UserTypeEnum UserTypeEnum { get; set; }
} }
#endregion #endregion
@@ -322,6 +372,35 @@ namespace IRaCIS.Application.Contracts
/// </summary> /// </summary>
public string WorkPartTimeEn { get; set; } = string.Empty; public string WorkPartTimeEn { get; set; } = string.Empty;
/// <summary>
/// 大学
/// </summary>
public string UniversityAffiliated { get; set; } = string.Empty;
/// <summary>
/// 大学
/// </summary>
public string UniversityAffiliatedCN { get; set; } = string.Empty;
/// <summary>
/// 城市
/// </summary>
public string City { get; set; } = string.Empty;
/// <summary>
/// 城市
/// </summary>
public string CityCN { get; set; } = string.Empty;
/// <summary>
/// 医院
/// </summary>
public string HospitalName { get; set; } = string.Empty;
/// <summary>
/// 医院
/// </summary>
public string HospitalNameCN { get; set; } = string.Empty;
} }
@@ -494,6 +573,8 @@ namespace IRaCIS.Application.Contracts
{ {
public string BlindName { get; set; } public string BlindName { get; set; }
public bool IsHaveAccount { get; set; } = false;
public string BlindNameCN { get; set; } = string.Empty; public string BlindNameCN { get; set; } = string.Empty;
public List<DicView> DoctorDicViewDtos = new List<DicView>(); public List<DicView> DoctorDicViewDtos = new List<DicView>();
@@ -666,6 +747,55 @@ namespace IRaCIS.Application.Contracts
/// </summary> /// </summary>
public string WorkPartTimeEn { get; set; } = string.Empty; public string WorkPartTimeEn { get; set; } = string.Empty;
/// <summary>
/// 大学
/// </summary>
public string University { get; set; } = string.Empty;
/// <summary>
/// 大学
/// </summary>
public string UniversityCN { get; set; } = string.Empty;
/// <summary>
/// 城市
/// </summary>
public string City { get; set; } = string.Empty;
/// <summary>
/// 城市
/// </summary>
public string CityCN { get; set; } = string.Empty;
/// <summary>
/// 医院
/// </summary>
public string HospitalEn { get; set; } = string.Empty;
/// <summary>
/// 医院
/// </summary>
public string HospitalCN { get; set; } = string.Empty;
/// <summary>
/// 大学
/// </summary>
public string UniversityAffiliated { get; set; } = string.Empty;
/// <summary>
/// 大学
/// </summary>
public string UniversityAffiliatedCN { get; set; } = string.Empty;
/// <summary>
/// 医院
/// </summary>
public string HospitalName { get; set; } = string.Empty;
/// <summary>
/// 医院
/// </summary>
public string HospitalNameCN { get; set; } = string.Empty;
} }
#endregion #endregion
@@ -37,6 +37,7 @@
} }
public class PostgraduateCommand public class PostgraduateCommand
{ {
public Guid? Id { get; set; } public Guid? Id { get; set; }
public Guid DoctorId { get; set; } public Guid DoctorId { get; set; }
@@ -243,11 +243,137 @@ namespace IRaCIS.Core.Application.Service
{ {
#region
//var query = from enroll in _enrollRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup)
// join enrollDetail in _enrollDetailRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup) on new { enroll.DoctorId, enroll.EnrollStatus } equals new { enrollDetail.DoctorId, enrollDetail.EnrollStatus } into enrollDetailtemp
// from leftenrollDetail in enrollDetailtemp.DefaultIfEmpty()
// select new ConfirmationReviewerDTO()
// {
// DoctorTrialState = (int)leftenrollDetail.EnrollStatus,
// OptTime = leftenrollDetail.CreateTime,
// UserTypeEnum = leftenrollDetail.CreateUserRole.UserTypeEnum,
// OptUserName = leftenrollDetail.CreateUserRole.UserName,
// SubmmitTime = leftenrollDetail.CreateTime,
// SubmmitUserName = leftenrollDetail.CreateUserRole.UserName,
// //BlindName= enroll.BlindName,
// //BlindNameCN= enroll.BlindNameCN,
// SpecialityId = enroll.Doctor.SpecialityId,
// SpecialityCN = enroll.Doctor.Speciality.ValueCN,
// Speciality = enroll.Doctor.Speciality.Value,
// //SpecialityOther=enroll.Doctor.Speciality.SpecialityOther,
// //SpecialityOtherCN= enroll.Doctor.Speciality.SpecialityOtherCN,
// DictionaryList = enroll.Doctor.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder).Select(x => new DicView()
// {
// Id = x.Id,
// ParentCode = x.Parent.Code,
// ShowOrder = x.ShowOrder,
// Value = x.Value,
// ValueCN = x.ValueCN
// }).ToList(),
// //HospitalId= enroll.BlindName
// Id = enroll.Doctor.Id,
// Code = enroll.DoctorUser.UserName,
// //FirstName=enroll.FirstName,
// //LastName = enroll.LastName,
// //ChineseName = enroll.ChineseName,
// //City = enroll.City,
// //HospitalName = enroll.HospitalName,
// //Country = enroll.Country,
// };
//var result = await query
// .WhereIf(inQuery.OptStartTime != null, x => x.OptTime >= inQuery.OptStartTime)
// .WhereIf(inQuery.OptEndTime != null, x => x.OptTime <= inQuery.OptEndTime)
// .WhereIf(inQuery.UserTypeEnum != null, x => x.UserTypeEnum == inQuery.UserTypeEnum)
// .WhereIf(inQuery.Code.IsNotNullOrEmpty(), x => x.Code.Contains(inQuery.Code))
// .WhereIf(inQuery.OptUserName.IsNotNullOrEmpty(), x => x.OptUserName.Contains(inQuery.OptUserName))
// .ToPagedListAsync(inQuery);
#endregion
#region
// 这里这样写的原因是因为 要取最新的入组详情 然后还要根据时间筛选 入组信息
var query = _enrollDetailRepository
.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup);
var enrollStateList = await query
.ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
enrollStateList = enrollStateList.GroupBy(e => e.DoctorId)
.Select(g => g.OrderByDescending(e => e.OptTime).FirstOrDefault()).ToList();
enrollStateList = enrollStateList
.WhereIf(inQuery.OptStartTime != null, x => x.OptTime >= inQuery.OptStartTime)
.WhereIf(inQuery.OptEndTime != null, x => x.OptTime <= inQuery.OptEndTime)
.WhereIf(inQuery.UserTypeEnum != null, x => x.UserTypeEnum == inQuery.UserTypeEnum)
.ToList();
#endregion
var doctorids = enrollStateList.Select(x => x.DoctorId).ToList();
var doctorQuery = _enrollRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup) var doctorQuery = _enrollRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup)
.ProjectTo<ConfirmationReviewerDTO>(_mapper.ConfigurationProvider);
.WhereIf(inQuery.OptStartTime != null || inQuery.OptEndTime != null || inQuery.UserTypeEnum != null, x => doctorids.Contains(x.DoctorId))
.ProjectTo<ConfirmationReviewerDTO>(_mapper.ConfigurationProvider)
.WhereIf(inQuery.Code.IsNotNullOrEmpty(), x => x.Code.Contains(inQuery.Code))
.WhereIf(inQuery.OptUserName.IsNotNullOrEmpty(), x => x.OptUserName.Contains(inQuery.OptUserName));
var doctorPageList = await doctorQuery.ToPagedListAsync(inQuery); var doctorPageList = await doctorQuery.ToPagedListAsync(inQuery);
doctorPageList.CurrentPageData.ToList().ForEach(u =>
{
u.DoctorTrialState = (int)EnrollStatus.InviteIntoGroup;
var opt = enrollStateList.OrderByDescending(x=>x.OptTime).FirstOrDefault(t => t.DoctorId == u.Id);
if (opt != null)
{
u.DoctorTrialState = opt.IntoGroupState;
u.OptTime = opt.OptTime;
u.UserTypeEnum = opt.UserTypeEnum;
u.OptUserName = opt.OptUserName;
}
});
return doctorPageList;
}
/// <summary>
/// 获取项目下医生列表
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<TrialDoctorInfo>> GetTrialDoctorList(
GetTrialDoctorListInDto inQuery)
{
var doctorQuery = _enrollRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus == EnrollStatus.ConfirmIntoGroup)
.ProjectTo<TrialDoctorInfo>(_mapper.ConfigurationProvider);
var doctorPageList = await doctorQuery
.WhereIf(inQuery.HospitalId!=null,x=>x.HospitalId==inQuery.HospitalId.Value)
.WhereIf(inQuery.SpecialityId != null, x => x.SpecialityId == inQuery.SpecialityId.Value)
.WhereIf(inQuery.SubspecialityId != null, x => x.DictionaryList.Any(x=>x.Id==inQuery.SubspecialityId.Value))
.ToPagedListAsync(inQuery);
var enrollStateList = await _enrollDetailRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus > EnrollStatus.InviteIntoGroup) var enrollStateList = await _enrollDetailRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus > EnrollStatus.InviteIntoGroup)
.ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync(); .ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
@@ -17,6 +17,8 @@ namespace IRaCIS.Core.Application.Service
IRepository<DoctorDictionary> _doctorDictionaryRepository, IRepository<DoctorDictionary> _doctorDictionaryRepository,
IRepository<DoctorSummarize> _doctorSummarizeRepository, IRepository<DoctorSummarize> _doctorSummarizeRepository,
IRepository<Enroll> _enrollRepository, IRepository<Enroll> _enrollRepository,
IRepository<UserRole> _userRoleRepository,
IRepository<Hospital> _hospitalRepository,
IRepository<Dictionary> _dictionaryRepository, IRepository<Dictionary> _dictionaryRepository,
IRepository<Attachment> _attachmentRepository, IRepository<Attachment> _attachmentRepository,
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository, IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
@@ -229,7 +231,7 @@ namespace IRaCIS.Core.Application.Service
/// <param name="inDto"></param> /// <param name="inDto"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<DoctorSummarize> AddOrUpdateGneralSituation(SummarizeInfoDto inDto) public async Task<(DoctorSummarize,bool)> AddOrUpdateGneralSituation(SummarizeInfoDto inDto)
{ {
if (inDto.TrialId != null&&inDto.Id==null) if (inDto.TrialId != null&&inDto.Id==null)
{ {
@@ -261,6 +263,7 @@ namespace IRaCIS.Core.Application.Service
inDto.IndicationEn = "Default"; inDto.IndicationEn = "Default";
} }
var exists = await _doctorSummarizeRepository var exists = await _doctorSummarizeRepository
.Where(x=> x.IndicationEn!=string.Empty && x.Indication!=string.Empty)
.Where( x => x.IndicationEn == inDto.IndicationEn|| x.Indication == inDto.Indication) .Where( x => x.IndicationEn == inDto.IndicationEn|| x.Indication == inDto.Indication)
.AnyAsync(x => x.DoctorId == inDto.DoctorId && x.TrialId == null&&x.Id!=inDto.Id); .AnyAsync(x => x.DoctorId == inDto.DoctorId && x.TrialId == null&&x.Id!=inDto.Id);
@@ -319,7 +322,7 @@ namespace IRaCIS.Core.Application.Service
var entity = await _doctorSummarizeRepository.InsertOrUpdateAsync(inDto, true); var entity = await _doctorSummarizeRepository.InsertOrUpdateAsync(inDto, true);
return entity; return (entity,true);
} }
/// <summary> /// <summary>
@@ -488,7 +491,7 @@ namespace IRaCIS.Core.Application.Service
var doctorBasicInfo = (await _doctorRepository.Where(t => t.Id == doctorId) var doctorBasicInfo = (await _doctorRepository.Where(t => t.Id == doctorId)
.ProjectTo<DoctorBasicInfoDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); .ProjectTo<DoctorBasicInfoDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
doctorBasicInfo.IsHaveAccount =await _userRoleRepository.AnyAsync(x => x.DoctorId == doctorId);
return doctorBasicInfo; return doctorBasicInfo;
@@ -581,7 +584,7 @@ namespace IRaCIS.Core.Application.Service
[HttpPost] [HttpPost]
public async Task<IResponseOutput> UpdateEmploymentInfo(EmploymentCommand doctorWorkInfoModel) public async Task<IResponseOutput> UpdateEmploymentInfo(EmploymentCommand inDto)
{ {
#region #region
//var success = _doctorRepository.Update(d => d.Id == doctorWorkInfoModel.Id, u => new Doctor() //var success = _doctorRepository.Update(d => d.Id == doctorWorkInfoModel.Id, u => new Doctor()
@@ -611,8 +614,7 @@ namespace IRaCIS.Core.Application.Service
//var success = _doctorRepository.SaveChanges(); //var success = _doctorRepository.SaveChanges();
#endregion #endregion
var entity = await _doctorRepository.InsertOrUpdateAsync(inDto, true);
var entity = await _doctorRepository.InsertOrUpdateAsync(doctorWorkInfoModel, true);
return ResponseOutput.Ok(); return ResponseOutput.Ok();
@@ -721,7 +723,7 @@ namespace IRaCIS.Core.Application.Service
[HttpPost] [HttpPost]
public async Task<IResponseOutput> UpdateAuditResume(ResumeConfirmCommand auditResumeParam) public async Task<IResponseOutput> UpdateAuditResume(ResumeConfirmCommand auditResumeParam)
{ {
var userId = _userInfo.Id; var userId = _userInfo.UserRoleId;
//判断 合作协议、正式简历 是否有。如果没有,显示提示信息,并且不能保存 //判断 合作协议、正式简历 是否有。如果没有,显示提示信息,并且不能保存
var attachmentList = await _attachmentRepository.Where(u => u.DoctorId == auditResumeParam.Id) var attachmentList = await _attachmentRepository.Where(u => u.DoctorId == auditResumeParam.Id)
.Select(u => u.Type).ToListAsync(); .Select(u => u.Type).ToListAsync();
@@ -8,6 +8,7 @@ namespace IRaCIS.Core.Application.Service
{ {
[ApiExplorerSettings(GroupName = "Reviewer")] [ApiExplorerSettings(GroupName = "Reviewer")]
public class EducationService(IRepository<Postgraduate> _postgraduateRepository, public class EducationService(IRepository<Postgraduate> _postgraduateRepository,
IRepository<Hospital> _hospitalRepository,
IRepository<Education> _educationRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IEducationService IRepository<Education> _educationRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IEducationService
{ {
@@ -88,7 +89,7 @@ namespace IRaCIS.Core.Application.Service
/// <summary> 添加/更新医生继续学习经历</summary> /// <summary> 添加/更新医生继续学习经历</summary>
[HttpPost] [HttpPost]
public async Task<IResponseOutput> AddOrUpdatePostgraduateInfo(PostgraduateCommand postgraduateViewModel) public async Task<IResponseOutput> AddOrUpdatePostgraduateInfo(PostgraduateCommand inDto)
{ {
#region #region
@@ -109,8 +110,7 @@ namespace IRaCIS.Core.Application.Service
//} //}
#endregion #endregion
var entity = await _postgraduateRepository.InsertOrUpdateAsync(inDto, true);
var entity = await _postgraduateRepository.InsertOrUpdateAsync(postgraduateViewModel, true);
return ResponseOutput.Ok(entity.Id); return ResponseOutput.Ok(entity.Id);
} }
/// <summary> /// <summary>
@@ -13,6 +13,8 @@ namespace IRaCIS.Core.Application.Service
{ {
var isEn_Us = false; var isEn_Us = false;
Guid TrialId = Guid.Empty;
// 从 DateTime 映射到 DateOnly // 从 DateTime 映射到 DateOnly
CreateMap<DateTime, DateOnly>().ConvertUsing(dt => DateOnly.FromDateTime(dt)); CreateMap<DateTime, DateOnly>().ConvertUsing(dt => DateOnly.FromDateTime(dt));
@@ -67,10 +69,18 @@ namespace IRaCIS.Core.Application.Service
CreateMap<Vacation, VacationCommand>(); CreateMap<Vacation, VacationCommand>();
CreateMap<ResearchPublication, ResearchPublicationDTO>(); CreateMap<ResearchPublication, ResearchPublicationDTO>();
CreateMap<Postgraduate, PostgraduateViewModel>() CreateMap<Postgraduate, PostgraduateViewModel>();
.ForMember(t => t.Hospital, c => c.MapFrom(d => d.HospitalEnt.HospitalName)) // .ForMember(t => t.Hospital, c => c.MapFrom(d => d.HospitalEnt.HospitalName))
.ForMember(t => t.HospitalCN, c => c.MapFrom(d => d.HospitalEnt.HospitalNameCN)); //.ForMember(t => t.HospitalCN, c => c.MapFrom(d => d.HospitalEnt.HospitalNameCN));
CreateMap<Attachment, AttachmentDTO>(); CreateMap<Attachment, AttachmentDTO>()
.ForMember(d => d.BlindName, u => u.MapFrom(t => t.Doctor.BlindName))
.ForMember(d => d.BlindNameCN, u => u.MapFrom(t => t.Doctor.BlindNameCN))
.ForMember(d => d.ChineseName, u => u.MapFrom(t => t.Doctor.ChineseName))
.ForMember(d => d.FirstName, u => u.MapFrom(t => t.Doctor.FirstName))
.ForMember(d => d.LastName, u => u.MapFrom(t => t.Doctor.LastName))
.ForMember(d => d.UserName, u => u.MapFrom(t => t.Doctor.EnrollList.Where(y=>y.TrialId== TrialId).Select(x=>x.DoctorUser.UserName).First()))
;
CreateMap<Doctor, GetTrialDoctorListOutDto>();
CreateMap<Doctor, ResumeConfirmDTO>(); CreateMap<Doctor, ResumeConfirmDTO>();
CreateMap<Doctor, DoctorSelectDTO>(); CreateMap<Doctor, DoctorSelectDTO>();
@@ -99,11 +109,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<DoctorDTO, SelectionReviewerDTO>() CreateMap<DoctorDTO, SelectionReviewerDTO>()
; ;
CreateMap<User, UserBasicInfo>() CreateMap<UserRole, UserBasicInfo>();
.ForMember(d => d.UserTypeShortName, u => u.MapFrom(t => t.UserTypeRole.UserTypeShortName))
.ForMember(d => d.Code, u => u.MapFrom(t => t.UserCode))
.ForMember(d => d.PermissionStr, u => u.MapFrom(t => t.UserTypeRole.PermissionStr))
.ForMember(d => d.RealName, u => u.MapFrom(user => string.IsNullOrEmpty(user.FirstName) ? user.LastName : user.LastName + " / " + user.FirstName));
CreateMap<TrialExperience, TrialExperienceListDTO>() CreateMap<TrialExperience, TrialExperienceListDTO>()
.ForMember(x=>x.VisitReadingCount, u => u.MapFrom(t => (t.ExperienceDataType==ExperienceDataType.TrialAuto||t.ExperienceDataType==ExperienceDataType.SystemAuto)? .ForMember(x=>x.VisitReadingCount, u => u.MapFrom(t => (t.ExperienceDataType==ExperienceDataType.TrialAuto||t.ExperienceDataType==ExperienceDataType.SystemAuto)?
@@ -116,15 +122,17 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.EvaluationCriteriaList, u => u.MapFrom(t => t.ExperienceCriteriaList.Select(t => t.EvaluationCriteria.Value))) .ForMember(d => d.EvaluationCriteriaList, u => u.MapFrom(t => t.ExperienceCriteriaList.Select(t => t.EvaluationCriteria.Value)))
.ForMember(d => d.EvaluationCriteriaIdList, u => u.MapFrom(t => t.ExperienceCriteriaList.Select(t => t.EvaluationCriteriaId))); .ForMember(d => d.EvaluationCriteriaIdList, u => u.MapFrom(t => t.ExperienceCriteriaList.Select(t => t.EvaluationCriteriaId)));
CreateMap<Doctor, UserBasicInfo>() //CreateMap<Doctor, UserBasicInfo>()
.ForMember(d => d.Code, u => u.MapFrom(t => t.ReviewerCode)) // .ForMember(d => d.Code, u => u.MapFrom(t => t.ReviewerCode))
.ForMember(d => d.RealName, u => u.MapFrom(t => t.ChineseName)) // .ForMember(d => d.RealName, u => u.MapFrom(t => t.ChineseName))
.ForMember(d => d.IsReviewer, u => u.MapFrom(t => true)) // .ForMember(d => d.IsReviewer, u => u.MapFrom(t => true))
.ForMember(d => d.UserName, u => u.MapFrom(doctor => doctor.LastName + " / " + doctor.FirstName)); // .ForMember(d => d.UserName, u => u.MapFrom(doctor => doctor.LastName + " / " + doctor.FirstName));
#region #region
CreateMap<Doctor, SelectionReviewerDTO>() CreateMap<Doctor, SelectionReviewerDTO>()
.ForMember(d => d.DoctorUserName, u => u.MapFrom(t => t.User.UserName)); .ForMember(d => d.DoctorUserName, u => u.MapFrom(t => t.UserRole.IdentityUser.UserName));
CreateMap<Doctor, DoctorDTO>().IncludeMembers(t => t.Hospital).Include<Doctor, SelectionReviewerDTO>() CreateMap<Doctor, DoctorDTO>().IncludeMembers(t => t.Hospital).Include<Doctor, SelectionReviewerDTO>()
.ForMember(d => d.AccountUserName, u => u.MapFrom(s => s.EnrollList.Where(t => t.DoctorUserId != null).Select(c => c.DoctorUser.UserName).FirstOrDefault())) .ForMember(d => d.AccountUserName, u => u.MapFrom(s => s.EnrollList.Where(t => t.DoctorUserId != null).Select(c => c.DoctorUser.UserName).FirstOrDefault()))
.ForMember(d => d.Department, u => u.MapFrom(s => s.Department.Value)) .ForMember(d => d.Department, u => u.MapFrom(s => s.Department.Value))
@@ -180,9 +188,21 @@ namespace IRaCIS.Core.Application.Service
CreateMap<Hospital, EmploymentDTO>(); CreateMap<Hospital, EmploymentDTO>();
CreateMap<EnrollDetail, DoctorStateModelDTO>() CreateMap<EnrollDetail, DoctorStateModelDTO>()
.ForMember(d => d.UserTypeEnum, u => u.MapFrom(s => s.CreateUserRole.UserTypeEnum))
.ForMember(d => d.IntoGroupState, u => u.MapFrom(s => s.EnrollStatus)) .ForMember(d => d.IntoGroupState, u => u.MapFrom(s => s.EnrollStatus))
.ForMember(d => d.OptTime, u => u.MapFrom(s => s.CreateTime)) .ForMember(d => d.OptTime, u => u.MapFrom(s => s.CreateTime))
.ForMember(d => d.OptUserName, u => u.MapFrom(s => s.CreateUser.UserName)); .ForMember(d => d.OptUserName, u => u.MapFrom(s => s.CreateUserRole.IdentityUser.UserName));
CreateMap<Enroll, TrialDoctorInfo>().IncludeMembers(t => t.Doctor, t => t.Doctor.Hospital)
.ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.Doctor.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)))
.ForMember(d => d.Speciality, u => u.MapFrom(s => s.Doctor.Speciality.Value))
.ForMember(d => d.SpecialityCN, u => u.MapFrom(s => s.Doctor.Speciality.ValueCN))
.ForMember(d => d.Id, u => u.MapFrom(s => s.Doctor.Id))
.ForMember(d => d.Code, u => u.MapFrom(s => s.DoctorUser.UserName));
CreateMap<Doctor, TrialDoctorInfo>();
CreateMap<Hospital, TrialDoctorInfo>();
CreateMap<Enroll, ConfirmationReviewerDTO>().IncludeMembers(t => t.Doctor, t => t.Doctor.Hospital) CreateMap<Enroll, ConfirmationReviewerDTO>().IncludeMembers(t => t.Doctor, t => t.Doctor.Hospital)
.ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.Doctor.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder))) .ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.Doctor.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)))
@@ -190,6 +210,8 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.SpecialityCN, u => u.MapFrom(s => s.Doctor.Speciality.ValueCN)) .ForMember(d => d.SpecialityCN, u => u.MapFrom(s => s.Doctor.Speciality.ValueCN))
.ForMember(d => d.Id, u => u.MapFrom(s => s.Doctor.Id)) .ForMember(d => d.Id, u => u.MapFrom(s => s.Doctor.Id))
.ForMember(d => d.Code, u => u.MapFrom(s => s.DoctorUser.UserName)) .ForMember(d => d.Code, u => u.MapFrom(s => s.DoctorUser.UserName))
.ForMember(d => d.HospitalName, u => u.MapFrom(s => s.Doctor.HospitalName))
.ForMember(d => d.HospitalNameCN, u => u.MapFrom(s => s.Doctor.HospitalNameCN))
; ;
CreateMap<Doctor, ConfirmationReviewerDTO>(); CreateMap<Doctor, ConfirmationReviewerDTO>();
CreateMap<Hospital, ConfirmationReviewerDTO>(); CreateMap<Hospital, ConfirmationReviewerDTO>();
@@ -0,0 +1,61 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using System;
using IRaCIS.Core.Domain.Share;
using System.Collections.Generic;
namespace IRaCIS.Core.Application.ViewModel;
public class SysFileTypeView : SysFileTypeAddOrEdit
{
public DateTime CreateTime { get; set; }
public DateTime UpdateTime { get; set; }
}
public class SysFileTypeAddOrEdit
{
public Guid? Id { get; set; }
public ArchiveType ArchiveTypeEnum { get; set; }
public bool IsConfirmRecord { get; set; }
public bool IsEnable { get; set; }
public string Name { get; set; }
public string NameCN { get; set; }
/// <summary>
/// 显示顺序
/// </summary>
public int ShowOrder { get; set; }
public SubIdentification SubIdentificationEnum { get; set; }
}
public class SysFileTypeQuery : PageInput
{
public ArchiveType? ArchiveTypeEnum { get; set; }
public bool? IsConfirmRecord { get; set; }
public bool? IsEnable { get; set; }
public string? Name { get; set; }
public string? NameCN { get; set; }
public SubIdentification? SubIdentificationEnum { get; set; }
}
@@ -3,6 +3,7 @@
// 生成时间 2022-01-05 09:17:10 // 生成时间 2022-01-05 09:17:10
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//-------------------------------------------------------------------- //--------------------------------------------------------------------
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace IRaCIS.Core.Application.Contracts namespace IRaCIS.Core.Application.Contracts
@@ -38,6 +39,7 @@ namespace IRaCIS.Core.Application.Contracts
public string ExperimentName { get; set; } public string ExperimentName { get; set; }
} }
@@ -56,8 +58,14 @@ namespace IRaCIS.Core.Application.Contracts
public string RealName { get; set; } = string.Empty; public string RealName { get; set; } = string.Empty;
public Guid UserTypeId { get; set; } public string DocTypeCode { get; set; }
public string UserTypeShortName { get; set; } = string.Empty;
public List<string> UserConfirmedUserTypeList => (DocNeedSignUserTypeList != null && IdentityUserTypeList != null) ? IdentityUserTypeList.Intersect(DocNeedSignUserTypeList).ToList() : new List<string>();
public IEnumerable<string> IdentityUserTypeList { get; set; }
public IEnumerable<string> DocNeedSignUserTypeList { get; set; }
} }
@@ -170,7 +178,25 @@ namespace IRaCIS.Core.Application.Contracts
public bool? IsConfirmed { get; set; } public bool? IsConfirmed { get; set; }
/// <summary>
/// 课时状态
/// </summary>
public bool? IsDeleted { get; set; } public bool? IsDeleted { get; set; }
/// <summary>
/// 用户名
/// </summary>
public string? UserName { get; set; }
/// <summary>
/// 开始时间
/// </summary>
public DateTime? StartConfirmTime { get; set; }
/// <summary>
/// 结束时间
/// </summary>
public DateTime? EndConfirmTime { get; set; }
} }
///<summary> SystemDocumentAddOrEdit 列表查询参数模型</summary> ///<summary> SystemDocumentAddOrEdit 列表查询参数模型</summary>
@@ -0,0 +1,153 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using System;
using IRaCIS.Core.Domain.Share;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Reflection.Metadata;
namespace IRaCIS.Core.Application.ViewModel;
public class TrialFileTypeView : TrialFileTypeAddOrEdit
{
public DateTime CreateTime { get; set; }
public DateTime UpdateTime { get; set; }
}
public class GetTrialFileTypeDataOutDto
{
public List<TrialFileTypeData> TrialFileTypeDataList { get; set; }
}
public class TrialFileTypeData
{
public ArchiveType ArchiveTypeEnum { get; set; }
public List<TrialFileTypeView> TrialFileTypeList { get; set; }
}
public class GetTrialFileTypeFileInDto
{
public Guid TrialFileTypeId { get; set; }
}
public class UploadTrialFileTypeFileInDto
{
public Guid TrialFileTypeId { get; set; }
/// <summary>
/// 文件
/// </summary>
public TrialFileDto? FileRecord { get; set; }
}
public class SetAuthorizedViewInDto
{
public Guid Id { get; set; }
public bool IsEnable { get; set; }
}
public class GetTrialFileTypeDataInDto
{
public Guid TrialId { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public bool IsEnable { get; set; } = false;
}
public class CopySystemFileTypeToTrialInDto
{
public Guid TrialId { get; set; }
}
public class TrialFileTypeSelectView
{
public Guid Id { get; set; }
public string Name { get; set; }
public bool IsEnable { get; set; }
public bool IsSelfDefine { get; set; }
public ArchiveType ArchiveTypeEnum { get; set; }
}
public class TrialFileTypeAddOrEdit
{
public Guid? Id { get; set; }
public ArchiveType ArchiveTypeEnum { get; set; }
public DateOnly? FirstFinalDate { get; set; }
public bool IsConfirmRecord { get; set; }
public bool IsEnable { get; set; }
public bool IsSelfDefine { get; set; }
public string Name { get; set; }
public string NameCN { get; set; }
public SubIdentification SubIdentificationEnum { get; set; }
public Guid? SysFileTypeId { get; set; }
public Guid TrialId { get; set; }
/// <summary>
/// 显示顺序
/// </summary>
public int ShowOrder { get; set; }
}
public class TrialFileTypeQuery : PageInput
{
public ArchiveType? ArchiveTypeEnum { get; set; }
public DateOnly? FirstFinalDate { get; set; }
public bool? IsConfirmRecord { get; set; }
public bool? IsEnable { get; set; }
public bool? IsSelfDefine { get; set; }
public string? Name { get; set; }
public string? NameCN { get; set; }
public SubIdentification? SubIdentificationEnum { get; set; }
[NotDefault]
public Guid TrialId { get; set; }
}
public class TrialFileTypeSelectQuery
{
[NotDefault]
public Guid TrialId { get; set; }
public bool? IsEnable { get; set; }
public bool? IsSelfDefine { get; set; }
public ArchiveType? ArchiveTypeEnum { get; set; }
}
@@ -0,0 +1,115 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using System;
using IRaCIS.Core.Domain.Share;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;
namespace IRaCIS.Core.Application.ViewModel;
public class TrialFinalRecordView : TrialFinalRecordAddOrEdit
{
public DateTime CreateTime { get; set; }
public DateTime UpdateTime { get; set; }
}
public class DeleteTrialNormalRecordListInDto
{
public List<Guid> Ids { get; set; }
}
public class AuthorizedTrialFinalRecordInDto
{
public List<Guid> Ids { get; set; }
public bool IsAuthorizedView { get; set; }
}
public class TrialFinalRecordAddOrEdit
{
public Guid? Id { get; set; }
public bool IsAuthorizedView { get; set; }
public string Name { get; set; }
public int State { get; set; }
public Guid TrialFileTypeId { get; set; }
public Guid TrialId { get; set; }
public string Version { get; set; }
/// <summary>
/// 定稿PDF
/// </summary>
public TrialFileDto? PDFFileRecord { get; set; }
/// <summary>
/// 定稿Word
/// </summary>
public TrialFileDto? WordFileRecord { get; set; }
/// <summary>
/// 签名页
/// </summary>
public TrialFileDto? SignFileRecord { get; set; }
/// <summary>
/// 历史记录
/// </summary>
public TrialFileDto? HistoryFileRecord { get; set; }
}
public class TrialFileDto
{
public Guid TrialFileTypeId { get; set; }
public string FileName { get; set; }
public string FilePath { get; set; }
public string FileSize { get; set; }
public string FileFormat { get; set; }
}
public class TrialFinalRecordQuery : PageInput
{
public Guid? HistoryFileRecordId { get; set; }
public bool? IsAuthorizedView { get; set; }
public string? Name { get; set; }
[NotDefault]
public Guid TrialFileTypeId { get; set; }
public Guid? TrialId { get; set; }
public string? Version { get; set; }
public Guid? WordFileRecordId { get; set; }
}
@@ -0,0 +1,60 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using System;
using IRaCIS.Core.Domain.Share;
using System.Collections.Generic;
namespace IRaCIS.Core.Application.ViewModel;
public class TrialNormalRecordView : TrialNormalRecordAddOrEdit
{
public DateTime CreateTime { get; set; }
public DateTime UpdateTime { get; set; }
public string FileName { get; set; }
}
public class BatchAddTrialNormalRecordInDto
{
public List<TrialNormalRecordAddOrEdit> TrialNormalRecordList { get; set; }
}
public class TrialNormalRecordAddOrEdit
{
public Guid? Id { get; set; }
public bool IsAuthorizedView { get; set; }
public int State { get; set; }
public TrialFileDto? TrialFileRecord { get; set; }
public TrialFileDto? HistoryFileRecord { get; set; }
public Guid TrialFileTypeId { get; set; }
public Guid TrialId { get; set; }
}
public class TrialNormalRecordQuery : PageInput
{
public bool? IsAuthorizedView { get; set; }
public int? State { get; set; }
public string? FileName { get; set; }
public Guid? TrialFileTypeId { get; set; }
public Guid? TrialId { get; set; }
}
@@ -0,0 +1,77 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using System;
using IRaCIS.Core.Domain.Share;
using System.Collections.Generic;
namespace IRaCIS.Core.Application.ViewModel;
public class TrialTrianingRecordView : TrialTrianingRecordAddOrEdit
{
public DateTime CreateTime { get; set; }
public DateTime UpdateTime { get; set; }
public string FileName { get; set; }
}
public class BatchAddTTrianingRecordInDto
{
public List<TrialTrianingRecordAddOrEdit> TrianingRecordList { get; set; }
}
public class TrialTrianingRecordAddOrEdit
{
public Guid? Id { get; set; }
public bool IsAuthorizedView { get; set; }
public string Note { get; set; }=string.Empty;
public int? State { get; set; }
public TrialFileDto? TrialFileRecord { get; set; }
public TrialFileDto? HistoryFileRecord { get; set; }
public Guid TrialFileTypeId { get; set; }
public Guid TrialId { get; set; }
public int? TrianingCount { get; set; }
public DateOnly? TrianingDate { get; set; }
public string? TrianingState { get; set; }
}
public class TrialTrianingRecordQuery : PageInput
{
public bool? IsAuthorizedView { get; set; }
public string? FileName { get; set; }
public Guid? TrialFileTypeId { get; set; }
public Guid? TrialId { get; set; }
public int? TrianingCount { get; set; }
public DateOnly? TrianingDateStartTime { get; set; }
public DateOnly? TrianingDateEndTime { get; set; }
public DateTime? UpdateStartTime { get; set; }
public DateTime? UpdateEndTime { get; set; }
public string? TrianingState { get; set; }
}
@@ -1,4 +1,5 @@
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Consumer;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@@ -15,12 +16,12 @@ namespace IRaCIS.Core.Application.Service
public class EmailSendService(IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository, public class EmailSendService(IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
IRepository<TrialUser> _trialUserRepository, IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<VisitTask> _visitTaskRepository, IRepository<VisitTask> _visitTaskRepository,
IRepository<TrialSiteUser> _trialSiteUserRepository, IRepository<TrialSiteUserRole> _trialSiteUserRoleRepository,
IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IEmailSendService IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IEmailSendService
{ {
private readonly SystemEmailSendConfig _systemEmailConfig = _SystemEmailSendConfig.CurrentValue;
public static string EmailNamePlaceholder => StaticData.EmailSend.EmailNamePlaceholder; public static string EmailNamePlaceholder => StaticData.EmailSend.EmailNamePlaceholder;
@@ -130,6 +131,9 @@ namespace IRaCIS.Core.Application.Service
var (topicStr, htmlBodyStr, isEn_us, onlyToUserId) = topicAndHtmlFunc(trialEmailConfig); var (topicStr, htmlBodyStr, isEn_us, onlyToUserId) = topicAndHtmlFunc(trialEmailConfig);
//处理替换公司名
htmlBodyStr = CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, htmlBodyStr);
sendEmailConfig.TopicDescription = topicStr; sendEmailConfig.TopicDescription = topicStr;
sendEmailConfig.HtmlBodyStr = htmlBodyStr; sendEmailConfig.HtmlBodyStr = htmlBodyStr;
@@ -144,7 +148,7 @@ namespace IRaCIS.Core.Application.Service
var allUserTypeEnumList = toUserTypeEnumList.Union(copyUserTypeEnumList).Distinct().ToList(); var allUserTypeEnumList = toUserTypeEnumList.Union(copyUserTypeEnumList).Distinct().ToList();
var allUserList = await _trialUserRepository.Where(t => t.TrialId == trialId && allUserTypeEnumList.Contains(t.User.UserTypeEnum)).Select(t => new { t.UserId, t.User.EMail, t.User.FullName, t.User.UserTypeEnum }).ToListAsync(); var allUserList = await _trialUserRoleRepository.Where(t => t.TrialId == trialId && allUserTypeEnumList.Contains(t.UserRole.UserTypeEnum)).Select(t => new { t.UserId, t.UserRole.IdentityUser.EMail, t.UserRole.FullName, t.UserRole.UserTypeEnum }).ToListAsync();
var toUserList = allUserList.Where(t => toUserTypeEnumList.Contains(t.UserTypeEnum)) var toUserList = allUserList.Where(t => toUserTypeEnumList.Contains(t.UserTypeEnum))
@@ -157,7 +161,7 @@ namespace IRaCIS.Core.Application.Service
} }
if (trialSiteId != null && toUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA)) if (trialSiteId != null && toUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA))
{ {
var curentSiteUserIdList = _trialSiteUserRepository.Where(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId).Select(t => t.UserId).ToList(); var curentSiteUserIdList = _trialSiteUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId).Select(t => t.UserId).ToList();
toUserList = toUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList(); toUserList = toUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList();
} }
@@ -171,7 +175,7 @@ namespace IRaCIS.Core.Application.Service
if (trialSiteId != null && copyUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA)) if (trialSiteId != null && copyUserTypeEnumList.Any(t => t == UserTypeEnum.ClinicalResearchCoordinator || t == UserTypeEnum.CRA))
{ {
var curentSiteUserIdList = _trialSiteUserRepository.Where(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId).Select(t => t.UserId).ToList(); var curentSiteUserIdList = _trialSiteUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId).Select(t => t.UserId).ToList();
copyUserList = copyUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList(); copyUserList = copyUserList.Where(t => (t.UserTypeEnum != UserTypeEnum.CRA && t.UserTypeEnum != UserTypeEnum.ClinicalResearchCoordinator) || curentSiteUserIdList.Contains(t.UserId)).ToList();
} }
@@ -0,0 +1,23 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using System;
using IRaCIS.Core.Infrastructure.Extention;
using System.Threading.Tasks;
using IRaCIS.Core.Application.ViewModel;
namespace IRaCIS.Core.Application.Interfaces;
public interface ISysFileTypeService
{
Task<PageOutput<SysFileTypeView>> GetSysFileTypeList(SysFileTypeQuery inQuery);
Task<IResponseOutput> AddOrUpdateSysFileType(SysFileTypeAddOrEdit addOrEditSysFileType);
Task<IResponseOutput> DeleteSysFileType(Guid sysFileTypeId);
}
@@ -20,7 +20,7 @@ namespace IRaCIS.Core.Application.Contracts
Task<List<TrialUserDto>> GetTrialUserSelect(Guid trialId); Task<List<TrialUserDto>> GetTrialUserSelect(Guid trialId);
Task<PageOutput<DocumentUnionWithUserStatView>> GetTrialSystemDocumentList(DocumentTrialUnionQuery querySystemDocument); //Task<PageOutput<DocumentUnionWithUserStatView>> GetTrialSystemDocumentList(DocumentTrialUnionQuery querySystemDocument);
List<TrialUserUnionDocumentView> GetTrialUserDocumentList(Guid trialId); //List<TrialUserUnionDocumentView> GetTrialUserDocumentList(Guid trialId);
} }
} }
@@ -0,0 +1,23 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using System;
using IRaCIS.Core.Infrastructure.Extention;
using System.Threading.Tasks;
using IRaCIS.Core.Application.ViewModel;
namespace IRaCIS.Core.Application.Interfaces;
public interface ITrialFileTypeService
{
Task<PageOutput<TrialFileTypeView>> GetTrialFileTypeList(TrialFileTypeQuery inQuery);
Task<IResponseOutput> AddOrUpdateTrialFileType(TrialFileTypeAddOrEdit addOrEditTrialFileType);
Task<IResponseOutput> DeleteTrialFileType(Guid trialFileTypeId);
}
@@ -0,0 +1,23 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using System;
using IRaCIS.Core.Infrastructure.Extention;
using System.Threading.Tasks;
using IRaCIS.Core.Application.ViewModel;
namespace IRaCIS.Core.Application.Interfaces;
public interface ITrialFinalRecordService
{
Task<PageOutput<TrialFinalRecordView>> GetTrialFinalRecordList(TrialFinalRecordQuery inQuery);
Task<IResponseOutput> AddOrUpdateTrialFinalRecord(TrialFinalRecordAddOrEdit addOrEditTrialFinalRecord);
Task<IResponseOutput> DeleteTrialFinalRecord(Guid trialFinalRecordId);
}
@@ -0,0 +1,23 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using System;
using IRaCIS.Core.Infrastructure.Extention;
using System.Threading.Tasks;
using IRaCIS.Core.Application.ViewModel;
namespace IRaCIS.Core.Application.Interfaces;
public interface ITrialNormalRecordService
{
Task<PageOutput<TrialNormalRecordView>> GetTrialNormalRecordList(TrialNormalRecordQuery inQuery);
Task<IResponseOutput> AddOrUpdateTrialNormalRecord(TrialNormalRecordAddOrEdit addOrEditTrialNormalRecord);
Task<IResponseOutput> DeleteTrialNormalRecord(Guid trialNormalRecordId);
}
@@ -0,0 +1,23 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using System;
using IRaCIS.Core.Infrastructure.Extention;
using System.Threading.Tasks;
using IRaCIS.Core.Application.ViewModel;
namespace IRaCIS.Core.Application.Interfaces;
public interface ITrialTrianingRecordService
{
Task<PageOutput<TrialTrianingRecordView>> GetTrialTrianingRecordList(TrialTrianingRecordQuery inQuery);
Task<IResponseOutput> AddOrUpdateTrialTrianingRecord(TrialTrianingRecordAddOrEdit addOrEditTrialTrianingRecord);
Task<IResponseOutput> DeleteTrialTrianingRecord(Guid trialTrianingRecordId);
}
@@ -0,0 +1,87 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:24Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
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;
namespace IRaCIS.Core.Application.Service;
/// <summary>
/// 系统文件类型
/// </summary>
/// <param name="_sysFileTypeRepository"></param>
/// <param name="_mapper"></param>
/// <param name="_userInfo"></param>
/// <param name="_localizer"></param>
[ApiExplorerSettings(GroupName = "FileRecord")]
public class SysFileTypeService(IRepository<SysFileType> _sysFileTypeRepository, IRepository<TrialFileType> _trialFileTypeRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ISysFileTypeService
{
[HttpPost]
public async Task<PageOutput<SysFileTypeView>> GetSysFileTypeList(SysFileTypeQuery inQuery)
{
var sysFileTypeQueryable = _sysFileTypeRepository
.WhereIf(inQuery.ArchiveTypeEnum != null, t => t.ArchiveTypeEnum == inQuery.ArchiveTypeEnum)
.WhereIf(inQuery.IsConfirmRecord != null, t => t.IsConfirmRecord == inQuery.IsConfirmRecord)
.WhereIf(inQuery.SubIdentificationEnum != null, t => t.SubIdentificationEnum == inQuery.SubIdentificationEnum)
.WhereIf(inQuery.IsEnable != null, t => t.IsEnable == inQuery.IsEnable)
.WhereIf(inQuery.Name.IsNotNullOrEmpty(), t => t.Name.Contains(inQuery.Name))
.WhereIf(inQuery.NameCN.IsNotNullOrEmpty(), t => t.NameCN.Contains(inQuery.NameCN))
.ProjectTo<SysFileTypeView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(SysFileTypeView.ArchiveTypeEnum), nameof(SysFileTypeView.ShowOrder)};
var pageList = await sysFileTypeQueryable.ToPagedListAsync(inQuery, defalutSortArray);
return pageList;
}
public async Task<IResponseOutput> AddOrUpdateSysFileType(SysFileTypeAddOrEdit addOrEditSysFileType)
{
var verifyExp = new EntityVerifyExp<SysFileType>()
{
VerifyExp = u => u.IsEnable == addOrEditSysFileType.IsEnable && (u.Name == addOrEditSysFileType.Name || u.NameCN == addOrEditSysFileType.NameCN),
// "当前类型启用的文件类型名称重复"
VerifyMsg = _localizer["SysFileType_NameRepeat"],
IsVerify = addOrEditSysFileType.IsEnable == false
};
var entity = await _sysFileTypeRepository.InsertOrUpdateAsync(addOrEditSysFileType, true, verifyExp);
//启用的才进行更新
if (addOrEditSysFileType.Id != null && addOrEditSysFileType.IsEnable)
{
await _trialFileTypeRepository.BatchUpdateNoTrackingAsync(t => t.SysFileTypeId == addOrEditSysFileType.Id, u => new TrialFileType() { Name = addOrEditSysFileType.Name, NameCN = addOrEditSysFileType.NameCN,ShowOrder=addOrEditSysFileType.ShowOrder });
}
return ResponseOutput.Ok(entity.Id.ToString());
}
[HttpDelete("{sysFileTypeId:guid}")]
public async Task<IResponseOutput> DeleteSysFileType(Guid sysFileTypeId)
{
var success = await _sysFileTypeRepository.DeleteFromQueryAsync(t => t.Id == sysFileTypeId, true);
return ResponseOutput.Ok();
}
}
@@ -6,7 +6,7 @@
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using User = IRaCIS.Core.Domain.Models.User; using UserRole = IRaCIS.Core.Domain.Models.UserRole;
namespace IRaCIS.Core.Application.Services namespace IRaCIS.Core.Application.Services
{ {
@@ -15,8 +15,9 @@ namespace IRaCIS.Core.Application.Services
/// </summary> /// </summary>
[ApiExplorerSettings(GroupName = "Trial")] [ApiExplorerSettings(GroupName = "Trial")]
public class SystemDocumentService(IRepository<SystemDocument> _systemDocumentRepository, public class SystemDocumentService(IRepository<SystemDocument> _systemDocumentRepository,
IRepository<User> _userRepository, IRepository<UserRole> _userRoleRepository,
IRepository<SystemDocConfirmedUser> _systemDocConfirmedUserRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ISystemDocumentService IRepository<IdentityUser> _identityUserRepository,
IRepository<SystemDocConfirmedIdentityUser> _systemDocConfirmedUserRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ISystemDocumentService
{ {
@@ -35,7 +36,7 @@ namespace IRaCIS.Core.Application.Services
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name)) .WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId) .WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted) .WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
.ProjectTo<SystemDocumentView>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us, userId = _userInfo.Id }); .ProjectTo<SystemDocumentView>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us, userId = _userInfo.UserRoleId });
return await systemDocumentQueryable.ToPagedListAsync(inQuery); return await systemDocumentQueryable.ToPagedListAsync(inQuery);
} }
@@ -109,7 +110,7 @@ namespace IRaCIS.Core.Application.Services
await _systemDocumentRepository.UpdatePartialFromQueryAsync(systemDocumentId, u => new SystemDocument() { IsDeleted = true }); await _systemDocumentRepository.UpdatePartialFromQueryAsync(systemDocumentId, u => new SystemDocument() { IsDeleted = true });
await _systemDocConfirmedUserRepository.UpdatePartialFromQueryAsync(x => x.SystemDocumentId == systemDocumentId, x => new SystemDocConfirmedUser() await _systemDocConfirmedUserRepository.UpdatePartialFromQueryAsync(x => x.SystemDocumentId == systemDocumentId, x => new SystemDocConfirmedIdentityUser()
{ {
IsDeleted = true IsDeleted = true
}); });
@@ -146,15 +147,16 @@ namespace IRaCIS.Core.Application.Services
var isInternal = _userInfo.IsZhiZhun; var isInternal = _userInfo.IsZhiZhun;
var query = from sysDoc in _systemDocumentRepository.Where(t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId)) var query = from sysDoc in _systemDocumentRepository.AsQueryable(true)
.Where(t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name)) .WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
//外部人员 只签署 文档类型枚举值有值 //外部人员 只签署 外部需要签署
.WhereIf(isInternal == false, t => t.DocUserSignType == DocUserSignType.InnerAndOuter) .WhereIf(isInternal == false, t => t.DocUserSignType == DocUserSignType.InnerAndOuter)
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId) .WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = _userInfo.Id, SystemDocumentId = sysDoc.Id } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = _userInfo.IdentityUserId, SystemDocumentId = sysDoc.Id } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
from confirm in cc.DefaultIfEmpty() from confirm in cc.DefaultIfEmpty()
join user in _userRepository.Where() on _userInfo.Id equals user.Id join user in _identityUserRepository.Where() on _userInfo.IdentityUserId equals user.Id
select new UnionDocumentWithConfirmInfoView() select new UnionDocumentWithConfirmInfoView()
{ {
@@ -173,15 +175,24 @@ namespace IRaCIS.Core.Application.Services
ConfirmUserId = confirm.ConfirmUserId, ConfirmUserId = confirm.ConfirmUserId,
ConfirmTime = confirm.ConfirmTime, ConfirmTime = confirm.ConfirmTime,
RealName = user.LastName + " / " + user.FirstName, RealName = user.FullName,
UserName = user.UserName, UserName = user.UserName,
UserTypeId = user.UserTypeId,
UserTypeShortName = user.UserTypeRole.UserTypeShortName DocTypeCode=sysDoc.FileType.Code
//UserTypeId = user.UserTypeId,
//UserTypeShortName = user.UserTypeRole.UserTypeShortName
}; };
return await query.WhereIf(inQuery.IsSigned == true, t => t.ConfirmTime != null) var list = await query
//过滤掉删除的,并且没有签名的
.Where(t => !(t.IsDeleted == true && t.ConfirmTime == null))
.WhereIf(inQuery.IsSigned == true, t => t.ConfirmTime != null)
.WhereIf(inQuery.IsSigned == false, t => t.ConfirmTime == null) .WhereIf(inQuery.IsSigned == false, t => t.ConfirmTime == null)
.ToPagedListAsync(inQuery); .ToPagedListAsync(inQuery,nameof(UnionDocumentWithConfirmInfoView.DocTypeCode));
return list;
@@ -6,8 +6,13 @@
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.Formula.Functions;
using System.Linq;
using System.Linq.Dynamic.Core;
namespace IRaCIS.Core.Application.Services namespace IRaCIS.Core.Application.Services
{ {
@@ -16,15 +21,15 @@ namespace IRaCIS.Core.Application.Services
/// </summary> /// </summary>
[ApiExplorerSettings(GroupName = "Trial")] [ApiExplorerSettings(GroupName = "Trial")]
public class TrialDocumentService(IRepository<TrialDocument> _trialDocumentRepository, public class TrialDocumentService(IRepository<TrialDocument> _trialDocumentRepository,
IRepository<TrialDocConfirmedUser> _trialDocUserTypeConfirmedUserRepository,
IRepository<Trial> _trialRepository, IRepository<Trial> _trialRepository,
ISystemDocumentService _systemDocumentService, ISystemDocumentService _systemDocumentService,
IRepository<SystemDocConfirmedUser> _systemDocConfirmedUserRepository, IRepository<SystemDocConfirmedIdentityUser> _systemDocConfirmedUserRepository,
IRepository<SystemDocNeedConfirmedUserType> _systemDocNeedConfirmedUserTypeRepository, IRepository<SystemDocNeedConfirmedUserType> _systemDocNeedConfirmedUserTypeRepository,
IRepository<TrialDocNeedConfirmedUserType> _trialDocNeedConfirmedUserTypeRepository, IRepository<TrialDocNeedConfirmedUserType> _trialDocNeedConfirmedUserTypeRepository,
IRepository<SystemDocument> _systemDocumentRepository, IRepository<SystemDocument> _systemDocumentRepository,
IRepository<TrialUser> _trialUserRepository, IRepository<TrialIdentityUser> _trialIdentityUserRepository,
IRepository<TrialDocConfirmedUser> _trialDocConfirmedUserRepository, IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<TrialDocConfirmedIdentityUser> _trialDocConfirmedUserRepository,
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialDocumentService IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialDocumentService
{ {
@@ -57,9 +62,9 @@ namespace IRaCIS.Core.Application.Services
.WhereIf(inQuery.TrialId != null, t => t.TrialId == inQuery.TrialId) .WhereIf(inQuery.TrialId != null, t => t.TrialId == inQuery.TrialId)
.Where(t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId)) .Where(t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
join trialUser in _trialUserRepository.Where(t => t.UserId == _userInfo.Id) on trialDoc.TrialId equals trialUser.TrialId join trialUser in _trialIdentityUserRepository.Where(t => t.IdentityUserId == _userInfo.IdentityUserId) on trialDoc.TrialId equals trialUser.TrialId
join confirm in _trialDocConfirmedUserRepository.Where() on join confirm in _trialDocConfirmedUserRepository.Where() on
new { trialUser.UserId, TrialDocumentId = trialDoc.Id } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc new { trialUser.IdentityUserId, TrialDocumentId = trialDoc.Id } equals new { IdentityUserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
from confirm in cc.DefaultIfEmpty() from confirm in cc.DefaultIfEmpty()
select new TrialSignDocView() select new TrialSignDocView()
@@ -82,11 +87,12 @@ namespace IRaCIS.Core.Application.Services
//IsConfirmed = confirm.ConfirmTime != null, //IsConfirmed = confirm.ConfirmTime != null,
ConfirmUserId = confirm.ConfirmUserId, ConfirmUserId = confirm.ConfirmUserId,
ConfirmTime = confirm.ConfirmTime, ConfirmTime = confirm.ConfirmTime,
RealName = trialUser.User.FullName, RealName = trialUser.IdentityUser.FullName,
UserName = trialUser.User.UserName, UserName = trialUser.IdentityUser.UserName,
UserTypeId = trialUser.User.UserTypeId,
UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName
IdentityUserTypeList = trialUser.TrialUserRoleList.Select(t => t.UserRole.UserTypeRole.UserTypeShortName).ToList(),
DocNeedSignUserTypeList = trialDoc.NeedConfirmedUserTypeList.Select(t => t.UserTypeRole.UserTypeShortName).ToList(),
}; };
trialDocQueryable = trialDocQueryable.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name)) trialDocQueryable = trialDocQueryable.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
@@ -218,75 +224,183 @@ namespace IRaCIS.Core.Application.Services
var trialInfo = await (_trialRepository.Where(t => t.Id == inQuery.TrialId, ignoreQueryFilters: true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync()); var trialInfo = await (_trialRepository.Where(t => t.Id == inQuery.TrialId, ignoreQueryFilters: true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync());
//系统文档查询 var isInternal = _userInfo.IsZhiZhun;
var systemDocumentQueryable = from needConfirmedUserType in _systemDocNeedConfirmedUserTypeRepository.Where(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId, ignoreQueryFilters: true)
.WhereIf(trialInfo.TrialFinishedTime != null, u => u.SystemDocument.CreateTime < trialInfo.TrialFinishedTime)
.WhereIf(!_userInfo.IsAdmin, t => t.SystemDocument.IsDeleted == false || (t.SystemDocument.IsDeleted == true && t.SystemDocument.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
join trialUser in _trialUserRepository.Where(t => t.TrialId == inQuery.TrialId && t.UserId == _userInfo.Id) #region
on needConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId
join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = trialUser.UserId, SystemDocumentId = needConfirmedUserType.SystemDocumentId } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
from confirm in cc.DefaultIfEmpty()
select new UnionDocumentWithConfirmInfoView()
{
IsSystemDoc = true,
Id = needConfirmedUserType.SystemDocument.Id, var systemDocQuery =
CreateTime = needConfirmedUserType.SystemDocument.CreateTime, from sysDoc in _systemDocumentRepository.AsQueryable(true).Where(t => t.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == _userInfo.UserTypeId))
IsDeleted = needConfirmedUserType.SystemDocument.IsDeleted, //外部人员 只签署 外部需要签署的
SignViewMinimumMinutes = needConfirmedUserType.SystemDocument.SignViewMinimumMinutes, .WhereIf(isInternal == false, t => t.DocUserSignType == DocUserSignType.InnerAndOuter)
Name = needConfirmedUserType.SystemDocument.Name, from trialUser in _trialIdentityUserRepository.AsQueryable(false)
Path = needConfirmedUserType.SystemDocument.Path, .Where(t => t.TrialId == inQuery.TrialId && t.IdentityUserId == _userInfo.IdentityUserId
FileTypeId = needConfirmedUserType.SystemDocument.FileTypeId, && t.TrialUserRoleList.Any(t => sysDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == t.UserRole.UserTypeId)))
FileType = _userInfo.IsEn_Us ? needConfirmedUserType.SystemDocument.FileType.Value : needConfirmedUserType.SystemDocument.FileType.ValueCN,
UpdateTime = needConfirmedUserType.SystemDocument.UpdateTime,
FullFilePath = needConfirmedUserType.SystemDocument.Path, join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = trialUser.IdentityUserId, SystemDocumentId = sysDoc.Id } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
from confirm in cc.DefaultIfEmpty()
select new UnionDocumentWithConfirmInfoView()
{
IsSystemDoc = true,
Id = sysDoc.Id,
CreateTime = sysDoc.CreateTime,
IsDeleted = sysDoc.IsDeleted,
SignViewMinimumMinutes = sysDoc.SignViewMinimumMinutes,
Name = sysDoc.Name,
Path = sysDoc.Path,
FileType = _userInfo.IsEn_Us ? sysDoc.FileType.Value : sysDoc.FileType.ValueCN,
FileTypeId = sysDoc.FileTypeId,
UpdateTime = sysDoc.UpdateTime,
//IsConfirmed = confirm.ConfirmTime != null,
ConfirmUserId = confirm.ConfirmUserId,
ConfirmTime = confirm.ConfirmTime,
RealName = trialUser.IdentityUser.FullName,
UserName = trialUser.IdentityUser.UserName,
//UserTypeId = trialUser.UserRole.UserTypeId,
//UserTypeShortName = trialUser.UserRole.UserTypeRole.UserTypeShortName,
//DocNeedSignUserTypeList = sysDoc.NeedConfirmedUserTypeList.Select(t => t.UserTypeRole.UserTypeName),
FullFilePath = sysDoc.Path
};
//IsConfirmed = confirm.ConfirmTime != null,
ConfirmUserId = confirm.ConfirmUserId,
ConfirmTime = confirm.ConfirmTime,
RealName = trialUser.User.FullName,
UserName = trialUser.User.UserName,
UserTypeId = trialUser.User.UserTypeId,
UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName
};
//项目文档查询 //项目文档查询
var trialDocQueryable = from trialDoc in _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == inQuery.TrialId) var trialDocQuery =
.WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId)) from trialDoc in _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == inQuery.TrialId).Where(t => t.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == _userInfo.UserTypeId))
.WhereIf(!_userInfo.IsAdmin, t => t.IsDeleted == false || (t.IsDeleted == true && t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id))) from trialUser in _trialIdentityUserRepository.AsQueryable(false).Where(t => t.TrialId == inQuery.TrialId && t.IdentityUserId == _userInfo.IdentityUserId
&& t.TrialUserRoleList.Any(t => trialDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == t.UserRole.UserTypeId)))
join trialUser in _trialUserRepository.Where(t => t.TrialId == inQuery.TrialId && t.UserId == _userInfo.Id) on trialDoc.TrialId equals trialUser.TrialId join confirm in _trialDocConfirmedUserRepository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) on
join confirm in _trialDocConfirmedUserRepository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) on new { trialUser.IdentityUserId, TrialDocumentId = trialDoc.Id } equals new { IdentityUserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
new { trialUser.UserId, TrialDocumentId = trialDoc.Id } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc from confirm in cc.DefaultIfEmpty()
from confirm in cc.DefaultIfEmpty() select new UnionDocumentWithConfirmInfoView()
select new UnionDocumentWithConfirmInfoView() {
{ IsSystemDoc = false,
Id = trialDoc.Id,
IsSystemDoc = false,
CreateTime = trialDoc.CreateTime,
FullFilePath = trialDoc.Path,
IsDeleted = trialDoc.IsDeleted,
Name = trialDoc.Name,
Path = trialDoc.Path,
FileTypeId = trialDoc.FileTypeId,
FileType = _userInfo.IsEn_Us ? trialDoc.FileType.Value : trialDoc.FileType.ValueCN,
UpdateTime = trialDoc.UpdateTime,
SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes,
//IsConfirmed = confirm.ConfirmTime != null, Id = trialDoc.Id,
ConfirmUserId = confirm.ConfirmUserId, CreateTime = trialDoc.CreateTime,
ConfirmTime = confirm.ConfirmTime, IsDeleted = trialDoc.IsDeleted,
RealName = trialUser.User.FullName, SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes,
UserName = trialUser.User.UserName, Name = trialDoc.Name,
UserTypeId = trialUser.User.UserTypeId, Path = trialDoc.Path,
UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName FileTypeId = trialDoc.FileTypeId,
FileType = _userInfo.IsEn_Us ? trialDoc.FileType.Value : trialDoc.FileType.ValueCN,
UpdateTime = trialDoc.UpdateTime,
//IsConfirmed= confirm.ConfirmTime!=null,
};
ConfirmUserId = confirm.ConfirmUserId,
ConfirmTime = confirm.ConfirmTime,
RealName = trialUser.IdentityUser.FullName,
UserName = trialUser.IdentityUser.UserName,
//DocNeedSignUserTypeList = trialDoc.NeedConfirmedUserTypeList.Select(t => t.UserTypeRole.UserTypeName),
//UserTypeId = trialUser.UserRole.UserTypeId,
//UserTypeShortName = trialUser.UserRole.UserTypeRole.UserTypeShortName,
FullFilePath = trialDoc.Path
};
#endregion
#region
////系统文档查询
//var systemDocQuery = from needConfirmedUserType in _systemDocNeedConfirmedUserTypeRepository.Where(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId, ignoreQueryFilters: true)
// .WhereIf(trialInfo.TrialFinishedTime != null, u => u.SystemDocument.CreateTime < trialInfo.TrialFinishedTime)
// .WhereIf(!_userInfo.IsAdmin, t => t.SystemDocument.IsDeleted == false || (t.SystemDocument.IsDeleted == true && t.SystemDocument.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId)))
// join trialUser in _trialUserRoleRepository.Where(t => t.TrialId == inQuery.TrialId && t.UserRole.IdentityUserId == _userInfo.IdentityUserId)
// on needConfirmedUserType.NeedConfirmUserTypeId equals trialUser.UserRole.UserTypeId
// join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = trialUser.UserId, SystemDocumentId = needConfirmedUserType.SystemDocumentId } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
// from confirm in cc.DefaultIfEmpty()
// select new UnionDocumentWithConfirmInfoView()
// {
// IsSystemDoc = true,
// Id = needConfirmedUserType.SystemDocument.Id,
// CreateTime = needConfirmedUserType.SystemDocument.CreateTime,
// IsDeleted = needConfirmedUserType.SystemDocument.IsDeleted,
// SignViewMinimumMinutes = needConfirmedUserType.SystemDocument.SignViewMinimumMinutes,
// Name = needConfirmedUserType.SystemDocument.Name,
// Path = needConfirmedUserType.SystemDocument.Path,
// FileTypeId = needConfirmedUserType.SystemDocument.FileTypeId,
// FileType = _userInfo.IsEn_Us ? needConfirmedUserType.SystemDocument.FileType.Value : needConfirmedUserType.SystemDocument.FileType.ValueCN,
// UpdateTime = needConfirmedUserType.SystemDocument.UpdateTime,
// FullFilePath = needConfirmedUserType.SystemDocument.Path,
// //IsConfirmed = confirm.ConfirmTime != null,
// ConfirmUserId = confirm.ConfirmUserId,
// ConfirmTime = confirm.ConfirmTime,
// RealName = trialUser.UserRole.FullName,
// UserName = trialUser.UserRole.IdentityUser.UserName,
// //IdentityUserTypeList = trialUser.TrialUser.TrialUserRoleList.Select(t => t.UserRole.UserTypeRole.UserTypeShortName),
// //DocNeedSignUserTypeList = needConfirmedUserType.SystemDocument.NeedConfirmedUserTypeList.Select(t => t.UserTypeRole.UserTypeShortName).ToList(),
// //UserTypeId = trialUser.UserRole.UserTypeId,
// //UserTypeShortName = trialUser.UserRole.UserTypeRole.UserTypeShortName
// };
////项目文档查询
//var trialDocQuery = from trialDoc in _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == inQuery.TrialId)
// .WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
// .WhereIf(!_userInfo.IsAdmin, t => t.IsDeleted == false || (t.IsDeleted == true && t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId)))
// join trialUser in _trialUserRoleRepository.Where(t => t.TrialId == inQuery.TrialId && t.UserRole.IdentityUserId == _userInfo.IdentityUserId) on trialDoc.TrialId equals trialUser.TrialId
// join confirm in _trialDocConfirmedUserRepository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) on
// new { trialUser.UserId, TrialDocumentId = trialDoc.Id } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
// from confirm in cc.DefaultIfEmpty()
// select new UnionDocumentWithConfirmInfoView()
// {
// Id = trialDoc.Id,
// IsSystemDoc = false,
// CreateTime = trialDoc.CreateTime,
// FullFilePath = trialDoc.Path,
// IsDeleted = trialDoc.IsDeleted,
// Name = trialDoc.Name,
// Path = trialDoc.Path,
// FileTypeId = trialDoc.FileTypeId,
// FileType = _userInfo.IsEn_Us ? trialDoc.FileType.Value : trialDoc.FileType.ValueCN,
// UpdateTime = trialDoc.UpdateTime,
// SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes,
// //IsConfirmed = confirm.ConfirmTime != null,
// ConfirmUserId = confirm.ConfirmUserId,
// ConfirmTime = confirm.ConfirmTime,
// RealName = trialUser.UserRole.FullName,
// UserName = trialUser.UserRole.IdentityUser.UserName,
// //UserTypeId = trialUser.UserRole.UserTypeId,
// //UserTypeShortName = trialUser.UserRole.UserTypeRole.UserTypeShortName
// //IdentityUserTypeList = trialUser.TrialUser.TrialUserRoleList.Select(t => t.UserRole.UserTypeRole.UserTypeShortName).ToList(),
// //DocNeedSignUserTypeList = trialDoc.NeedConfirmedUserTypeList.Select(t => t.UserTypeRole.UserTypeShortName).ToList(),
// };
#endregion
#region bug #region bug
var unionQuery = systemDocumentQueryable.Union(trialDocQueryable)
var unionQuery = systemDocQuery.Concat(trialDocQuery)
//过滤掉删除的,并且没有签名的
.Where(t => !(t.IsDeleted == true && t.ConfirmTime == null))
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name)) .WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId) .WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
.WhereIf(inQuery.IsSign == true, t => t.ConfirmTime != null) .WhereIf(inQuery.IsSign == true, t => t.ConfirmTime != null)
@@ -318,16 +432,15 @@ namespace IRaCIS.Core.Application.Services
#endregion #endregion
var needSignTrialDocCount = await _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == inQuery.TrialId && t.Trial.TrialStatusStr != StaticData.TrialState.TrialStopped) var needSignTrialDocCount = await _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == inQuery.TrialId && t.Trial.TrialStatusStr != StaticData.TrialState.TrialStopped)
.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .Where(t => t.Trial.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId && t.TrialUserRoleList.Any(t => t.UserRole.UserTypeId == _userInfo.UserTypeId)))
.Where(t => t.IsDeleted == false && !t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id && t.ConfirmTime != null) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId)) .Where(t => t.IsDeleted == false && !t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId && t.ConfirmTime != null) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId))
.CountAsync(); .CountAsync();
var needSignSystemDocCount = await _systemDocumentRepository var needSignSystemDocCount = await _systemDocumentRepository.AsQueryable(true)
.Where(t => t.IsDeleted == false && !t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id && t.ConfirmTime != null) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId)) .WhereIf(isInternal == false, t => t.DocUserSignType == DocUserSignType.InnerAndOuter)
.Where(t => t.IsDeleted == false && !t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId && t.ConfirmTime != null) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId))
.CountAsync(); .CountAsync();
var trialTaskConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo<TrialProcessConfigDTO>(_mapper.ConfigurationProvider).FirstOrDefault(); var trialTaskConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo<TrialProcessConfigDTO>(_mapper.ConfigurationProvider).FirstOrDefault();
@@ -338,7 +451,7 @@ namespace IRaCIS.Core.Application.Services
var isAdditionalAssessment = _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsSigned && t.IsAdditionalAssessment == true var isAdditionalAssessment = _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsSigned && t.IsAdditionalAssessment == true
&& t.TrialCriterionAdditionalAssessmentTypeList.Any(c =>/*c.AdditionalAssessmentType==Domain.Share.Reading.AdditionalAssessmentType.BrainMetastasis &&*/ c.IsSelected == true)).Any(); && t.TrialCriterionAdditionalAssessmentTypeList.Any(c =>/*c.AdditionalAssessmentType==Domain.Share.Reading.AdditionalAssessmentType.BrainMetastasis &&*/ c.IsSelected == true)).Any();
return ResponseOutput.Ok<PageOutput<UnionDocumentWithConfirmInfoView>>(result, new { NeedSignCount = needSignTrialDocCount + needSignSystemDocCount, NeedSignTrialDocCount = needSignTrialDocCount, NeedSignSystemDocCount = needSignSystemDocCount, IsAdditionalAssessment = isAdditionalAssessment && isManualGenerateTask, TrialStatusStr = trialInfo.TrialStatusStr, TrialConfig = trialTaskConfig }); return ResponseOutput.Ok(result, new { NeedSignCount = needSignTrialDocCount + needSignSystemDocCount, NeedSignTrialDocCount = needSignTrialDocCount, NeedSignSystemDocCount = needSignSystemDocCount, IsAdditionalAssessment = isAdditionalAssessment && isManualGenerateTask, TrialStatusStr = trialInfo.TrialStatusStr, TrialConfig = trialTaskConfig });
} }
@@ -353,10 +466,157 @@ namespace IRaCIS.Core.Application.Services
public async Task<IResponseOutput<PageOutput<UnionDocumentWithConfirmInfoView>>> GetDocumentConfirmList(DocumentTrialUnionQuery inQuery) public async Task<IResponseOutput<PageOutput<UnionDocumentWithConfirmInfoView>>> GetDocumentConfirmList(DocumentTrialUnionQuery inQuery)
{ {
#region
var trialInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId, ignoreQueryFilters: true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync());
var trialDocQuery =
from trialDoc in _trialDocumentRepository.AsQueryable(false).Where(t => t.TrialId == inQuery.TrialId)
.Where(t => inQuery.UserTypeId != null ? t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == inQuery.UserTypeId) : true)
from trialUser in _trialIdentityUserRepository.AsQueryable(false).Where(t => t.TrialId == inQuery.TrialId
&& t.TrialUserRoleList.AsQueryable().Any(t => trialDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == t.UserRole.UserTypeId))
)
.Where(t => inQuery.UserId != null ? t.IdentityUserId == inQuery.UserId : true)
.Where(t => inQuery.UserTypeId != null ? t.TrialUserRoleList.Any(t => t.UserRole.UserTypeId == inQuery.UserTypeId) : true)
join confirm in _trialDocConfirmedUserRepository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) on
new { trialUser.IdentityUserId, TrialDocumentId = trialDoc.Id } equals new { IdentityUserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
from confirm in cc.DefaultIfEmpty()
select new UnionDocumentWithConfirmInfoView()
{
IsSystemDoc = false,
Id = trialDoc.Id,
CreateTime = trialDoc.CreateTime,
IsDeleted = trialDoc.IsDeleted,
SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes,
Name = trialDoc.Name,
Path = trialDoc.Path,
FileTypeId = trialDoc.FileTypeId,
FileType = _userInfo.IsEn_Us ? trialDoc.FileType.Value : trialDoc.FileType.ValueCN,
UpdateTime = trialDoc.UpdateTime,
//IsConfirmed= confirm.ConfirmTime!=null,
ConfirmUserId = trialUser.IdentityUserId,
ConfirmTime = confirm.ConfirmTime,
RealName = trialUser.IdentityUser.FullName,
UserName = trialUser.IdentityUser.UserName,
//UserTypeId = trialUser.UserRole.UserTypeId,
//UserTypeShortName = trialUser.UserRole.UserTypeRole.UserTypeShortName,
//DocNeedSignUserTypeList = trialDoc.NeedConfirmedUserTypeList.Select(t => t.UserTypeRole.UserTypeName),
FullFilePath = trialDoc.Path
};
var systemDocQuery =
from sysDoc in _systemDocumentRepository.AsQueryable(false).Where(u => trialInfo.TrialFinishedTime != null ? u.CreateTime < trialInfo.TrialFinishedTime : true)
.Where(t => inQuery.UserTypeId != null ? t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == inQuery.UserTypeId) : true)
from trialUser in _trialIdentityUserRepository.AsQueryable(false).Where(t => t.TrialId == inQuery.TrialId
&& t.TrialUserRoleList.Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserRole.UserTypeId)))
.Where(t => inQuery.UserId != null ? t.IdentityUserId == inQuery.UserId : true)
.Where(t => inQuery.UserTypeId != null ? t.TrialUserRoleList.Any(t => t.UserRole.UserTypeId == inQuery.UserTypeId) : true)
join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = trialUser.IdentityUserId, SystemDocumentId = sysDoc.Id } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
from confirm in cc.DefaultIfEmpty()
select new UnionDocumentWithConfirmInfoView()
{
IsSystemDoc = true,
Id = sysDoc.Id,
CreateTime = sysDoc.CreateTime,
IsDeleted = sysDoc.IsDeleted,
SignViewMinimumMinutes = sysDoc.SignViewMinimumMinutes,
Name = sysDoc.Name,
Path = sysDoc.Path,
FileType = _userInfo.IsEn_Us ? sysDoc.FileType.Value : sysDoc.FileType.ValueCN,
FileTypeId = sysDoc.FileTypeId,
UpdateTime = sysDoc.UpdateTime,
//IsConfirmed = confirm.ConfirmTime != null,
ConfirmUserId = trialUser.IdentityUserId,
ConfirmTime = confirm.ConfirmTime,
RealName = trialUser.IdentityUser.FullName,
UserName = trialUser.IdentityUser.UserName,
//UserTypeId = trialUser.UserRole.UserTypeId,
//UserTypeShortName = trialUser.UserRole.UserTypeRole.UserTypeShortName,
FullFilePath = sysDoc.Path
};
//var tt = await trialDocQuery.ToPagedListAsync(inQuery);
var unionQuery = trialDocQuery.Union(systemDocQuery).IgnoreQueryFilters().Where(t => !(t.IsDeleted == true && t.ConfirmTime == null))
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
.WhereIf(inQuery.IsConfirmed == true, t => t.ConfirmTime != null)
.WhereIf(inQuery.IsConfirmed == false, t => t.ConfirmTime == null)
.WhereIf(inQuery.StartConfirmTime != null, t => t.ConfirmTime >= inQuery.StartConfirmTime.Value)
.WhereIf(inQuery.EndConfirmTime != null, t => t.ConfirmTime <= inQuery.EndConfirmTime.Value)
.WhereIf(!string.IsNullOrEmpty(inQuery.UserName), t => t.UserName.Contains(inQuery.UserName))
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted);
var result = await unionQuery.ToPagedListAsync(inQuery);
#region
var trialDocIdList = result.CurrentPageData.Where(t => t.IsSystemDoc == false).Select(t => t.Id).ToList();
var sysDocIdList = result.CurrentPageData.Where(t => t.IsSystemDoc == true).Select(t => t.Id).ToList();
var trialIdentityUserIdList = result.CurrentPageData.Select(t => t.ConfirmUserId).Distinct().ToList();
var trialDocUserTypeList = _trialDocNeedConfirmedUserTypeRepository.Where(t => trialDocIdList.Contains(t.TrialDocumentId)).Select(t => new { t.TrialDocumentId, t.UserTypeRole.UserTypeShortName }).ToList();
var sysDocUserTypeList = _systemDocNeedConfirmedUserTypeRepository.Where(t => sysDocIdList.Contains(t.SystemDocumentId)).Select(t => new { t.SystemDocumentId, t.UserTypeRole.UserTypeShortName }).ToList();
var trialUserUserTypeList = _trialIdentityUserRepository.Where(t => t.TrialId == inQuery.TrialId && trialIdentityUserIdList.Contains(t.IdentityUserId)).IgnoreQueryFilters().Select(t => new { t.IdentityUserId, UserTypeList = t.TrialUserRoleList.Select(c => c.UserRole.UserTypeRole.UserTypeShortName).ToList() });
foreach (var item in result.CurrentPageData)
{
if (item.IsSystemDoc)
{
item.DocNeedSignUserTypeList = sysDocUserTypeList.Where(t => t.SystemDocumentId == item.Id).Select(t => t.UserTypeShortName).ToList();
}
else
{
item.DocNeedSignUserTypeList = trialDocUserTypeList.Where(t => t.TrialDocumentId == item.Id).Select(t => t.UserTypeShortName).ToList();
}
item.IdentityUserTypeList = trialUserUserTypeList.Where(t => t.IdentityUserId == item.ConfirmUserId).SelectMany(c => c.UserTypeList).ToList();
}
#endregion
var needSignTrialDocCount = await _trialDocumentRepository.AsQueryable(true)
.Where(t => t.Trial.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId && t.TrialUserRoleList.Any(t => t.UserRole.UserTypeId == _userInfo.UserTypeId)))
.Where(t => t.IsDeleted == false && !t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId))
.CountAsync();
var needSignSystemDocCount = await _systemDocumentRepository
.Where(t => t.IsDeleted == false && !t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId))
.CountAsync();
return ResponseOutput.Ok(result, new { NeedSignCount = needSignTrialDocCount + needSignSystemDocCount, NeedSignTrialDocCount = needSignTrialDocCount, NeedSignSystemDocCount = needSignSystemDocCount, TrialStatusStr = trialInfo.TrialStatusStr });
#endregion
#region linq join #region linq join
//var trialDocQuery = from trialDocumentNeedConfirmedUserType in _trialDocumentNeedConfirmedUserTypeRepository.Where(t => t.TrialDocument.TrialId == querySystemDocument.TrialId) //var trialDocQuery = from trialDocumentNeedConfirmedUserType in _trialDocumentNeedConfirmedUserTypeRepository.Where(t => t.TrialDocument.TrialId == querySystemDocument.TrialId)
// join trialUser in _trialUserRepository.Where(t => t.TrialId == querySystemDocument.TrialId) // join trialUser in _trialUserRoleRepository.Where(t => t.TrialId == querySystemDocument.TrialId)
// .WhereIf(querySystemDocument.UserId != null, t => t.UserId == querySystemDocument.UserId) // .WhereIf(querySystemDocument.UserId != null, t => t.UserId == querySystemDocument.UserId)
// on trialDocumentNeedConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId // on trialDocumentNeedConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId
@@ -387,100 +647,106 @@ namespace IRaCIS.Core.Application.Services
#endregion #endregion
var trialInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId, ignoreQueryFilters: true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync()); #region
//var trialInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId, ignoreQueryFilters: true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync());
var trialDocQuery = from trialDocumentNeedConfirmedUserType in _trialDocNeedConfirmedUserTypeRepository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) //var trialDocQuery = from trialDocumentNeedConfirmedUserType in _trialDocNeedConfirmedUserTypeRepository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId)
join trialUser in _trialUserRepository.Where(t => t.TrialId == inQuery.TrialId) // join trialUser in _trialUserRoleRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(inQuery.UserId != null, t => t.UserId == inQuery.UserId) // .WhereIf(inQuery.UserId != null, t => t.UserRole.IdentityUserId == inQuery.UserId)
.WhereIf(inQuery.UserTypeId != null, t => t.User.UserTypeId == inQuery.UserTypeId) // .WhereIf(inQuery.UserTypeId != null, t => t.UserRole.UserTypeId == inQuery.UserTypeId)
on trialDocumentNeedConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId // on trialDocumentNeedConfirmedUserType.NeedConfirmUserTypeId equals trialUser.UserRole.UserTypeId
join confirm in _trialDocConfirmedUserRepository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) on // join confirm in _trialDocConfirmedUserRepository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) on
new { trialUser.UserId, TrialDocumentId = trialDocumentNeedConfirmedUserType.TrialDocumentId } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc // new { trialUser.UserRole.IdentityUserId, TrialDocumentId = trialDocumentNeedConfirmedUserType.TrialDocumentId } equals new { IdentityUserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
from confirm in cc.DefaultIfEmpty() // from confirm in cc.DefaultIfEmpty()
select new UnionDocumentWithConfirmInfoView() // select new UnionDocumentWithConfirmInfoView()
{ // {
IsSystemDoc = false, // IsSystemDoc = false,
Id = trialDocumentNeedConfirmedUserType.TrialDocument.Id, // Id = trialDocumentNeedConfirmedUserType.TrialDocument.Id,
CreateTime = trialDocumentNeedConfirmedUserType.TrialDocument.CreateTime, // CreateTime = trialDocumentNeedConfirmedUserType.TrialDocument.CreateTime,
IsDeleted = trialDocumentNeedConfirmedUserType.TrialDocument.IsDeleted, // IsDeleted = trialDocumentNeedConfirmedUserType.TrialDocument.IsDeleted,
SignViewMinimumMinutes = trialDocumentNeedConfirmedUserType.TrialDocument.SignViewMinimumMinutes, // SignViewMinimumMinutes = trialDocumentNeedConfirmedUserType.TrialDocument.SignViewMinimumMinutes,
Name = trialDocumentNeedConfirmedUserType.TrialDocument.Name, // Name = trialDocumentNeedConfirmedUserType.TrialDocument.Name,
Path = trialDocumentNeedConfirmedUserType.TrialDocument.Path, // Path = trialDocumentNeedConfirmedUserType.TrialDocument.Path,
FileTypeId = trialDocumentNeedConfirmedUserType.TrialDocument.FileTypeId, // FileTypeId = trialDocumentNeedConfirmedUserType.TrialDocument.FileTypeId,
FileType = _userInfo.IsEn_Us ? trialDocumentNeedConfirmedUserType.TrialDocument.FileType.Value : trialDocumentNeedConfirmedUserType.TrialDocument.FileType.ValueCN, // FileType = _userInfo.IsEn_Us ? trialDocumentNeedConfirmedUserType.TrialDocument.FileType.Value : trialDocumentNeedConfirmedUserType.TrialDocument.FileType.ValueCN,
UpdateTime = trialDocumentNeedConfirmedUserType.TrialDocument.UpdateTime, // UpdateTime = trialDocumentNeedConfirmedUserType.TrialDocument.UpdateTime,
//IsConfirmed= confirm.ConfirmTime!=null, // //IsConfirmed= confirm.ConfirmTime!=null,
ConfirmUserId = confirm.ConfirmUserId, // ConfirmUserId = confirm.ConfirmUserId,
ConfirmTime = confirm.ConfirmTime, // ConfirmTime = confirm.ConfirmTime,
RealName = trialUser.User.FullName, // RealName = trialUser.UserRole.FullName,
UserName = trialUser.User.UserName, // UserName = trialUser.UserRole.IdentityUser.UserName,
UserTypeId = trialUser.User.UserTypeId,
UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName,
FullFilePath = trialDocumentNeedConfirmedUserType.TrialDocument.Path // //UserTypeId = trialUser.UserRole.UserTypeId,
}; // //UserTypeShortName = trialUser.UserRole.UserTypeRole.UserTypeShortName,
// FullFilePath = trialDocumentNeedConfirmedUserType.TrialDocument.Path
// };
var systemDocQuery = from needConfirmEdUserType in _systemDocNeedConfirmedUserTypeRepository.WhereIf(trialInfo.TrialFinishedTime != null, u => u.SystemDocument.CreateTime < trialInfo.TrialFinishedTime) //var systemDocQuery = from needConfirmEdUserType in _systemDocNeedConfirmedUserTypeRepository.WhereIf(trialInfo.TrialFinishedTime != null, u => u.SystemDocument.CreateTime < trialInfo.TrialFinishedTime)
join trialUser in _trialUserRepository.Where(t => t.TrialId == inQuery.TrialId) // join trialUser in _trialUserRoleRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(inQuery.UserId != null, t => t.UserId == inQuery.UserId) // .WhereIf(inQuery.UserId != null, t => t.UserRole.IdentityUserId == inQuery.UserId)
on needConfirmEdUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId // on needConfirmEdUserType.NeedConfirmUserTypeId equals trialUser.UserRole.UserTypeId
join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = trialUser.UserId, SystemDocumentId = needConfirmEdUserType.SystemDocumentId } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc // join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = trialUser.UserId, SystemDocumentId = needConfirmEdUserType.SystemDocumentId } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
from confirm in cc.DefaultIfEmpty() // from confirm in cc.DefaultIfEmpty()
select new UnionDocumentWithConfirmInfoView() // select new UnionDocumentWithConfirmInfoView()
{ // {
IsSystemDoc = true, // IsSystemDoc = true,
Id = needConfirmEdUserType.SystemDocument.Id, // Id = needConfirmEdUserType.SystemDocument.Id,
CreateTime = needConfirmEdUserType.SystemDocument.CreateTime, // CreateTime = needConfirmEdUserType.SystemDocument.CreateTime,
IsDeleted = needConfirmEdUserType.SystemDocument.IsDeleted, // IsDeleted = needConfirmEdUserType.SystemDocument.IsDeleted,
SignViewMinimumMinutes = needConfirmEdUserType.SystemDocument.SignViewMinimumMinutes, // SignViewMinimumMinutes = needConfirmEdUserType.SystemDocument.SignViewMinimumMinutes,
Name = needConfirmEdUserType.SystemDocument.Name, // Name = needConfirmEdUserType.SystemDocument.Name,
Path = needConfirmEdUserType.SystemDocument.Path, // Path = needConfirmEdUserType.SystemDocument.Path,
FileType = _userInfo.IsEn_Us ? needConfirmEdUserType.SystemDocument.FileType.Value : needConfirmEdUserType.SystemDocument.FileType.ValueCN, // FileType = _userInfo.IsEn_Us ? needConfirmEdUserType.SystemDocument.FileType.Value : needConfirmEdUserType.SystemDocument.FileType.ValueCN,
FileTypeId = needConfirmEdUserType.SystemDocument.FileTypeId, // FileTypeId = needConfirmEdUserType.SystemDocument.FileTypeId,
UpdateTime = needConfirmEdUserType.SystemDocument.UpdateTime, // UpdateTime = needConfirmEdUserType.SystemDocument.UpdateTime,
//IsConfirmed = confirm.ConfirmTime != null, // //IsConfirmed = confirm.ConfirmTime != null,
ConfirmUserId = confirm.ConfirmUserId, // ConfirmUserId = confirm.ConfirmUserId,
ConfirmTime = confirm.ConfirmTime, // ConfirmTime = confirm.ConfirmTime,
RealName = trialUser.User.FullName, // RealName = trialUser.UserRole.FullName,
UserName = trialUser.User.UserName, // UserName = trialUser.UserRole.IdentityUser.UserName,
UserTypeId = trialUser.User.UserTypeId,
UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName,
FullFilePath = needConfirmEdUserType.SystemDocument.Path // //UserTypeId = trialUser.UserRole.UserTypeId,
}; // //UserTypeShortName = trialUser.UserRole.UserTypeRole.UserTypeShortName,
var unionQuery = trialDocQuery.Union(systemDocQuery).IgnoreQueryFilters().Where(t => !(t.IsDeleted == true && t.ConfirmUserId == null)) // FullFilePath = needConfirmEdUserType.SystemDocument.Path
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name)) // };
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
.WhereIf(inQuery.IsConfirmed == true, t => t.ConfirmTime != null)
.WhereIf(inQuery.IsConfirmed == false, t => t.ConfirmTime == null)
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
.WhereIf(inQuery.UserTypeId != null, t => t.UserTypeId == inQuery.UserTypeId);
var result = await unionQuery.ToPagedListAsync(inQuery); //var unionQuery = trialDocQuery.Union(systemDocQuery).IgnoreQueryFilters().Where(t => !(t.IsDeleted == true && t.ConfirmUserId == null))
// .WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
// .WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId)
// .WhereIf(inQuery.IsConfirmed == true, t => t.ConfirmTime != null)
// .WhereIf(inQuery.IsConfirmed == false, t => t.ConfirmTime == null)
// .WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
// /*.Distinct()*/;
var needSignTrialDocCount = await _trialDocumentRepository.AsQueryable(true) //var result = await unionQuery.ToPagedListAsync(inQuery);
.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.Where(t => t.IsDeleted == false && !t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId)) //var needSignTrialDocCount = await _trialDocumentRepository.AsQueryable(true)
.CountAsync(); // .Where(t => t.Trial.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId))
// .Where(t => t.IsDeleted == false && !t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId))
// .CountAsync();
var needSignSystemDocCount = await _systemDocumentRepository //var needSignSystemDocCount = await _systemDocumentRepository
.Where(t => t.IsDeleted == false && !t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId)) // .Where(t => t.IsDeleted == false && !t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId))
.CountAsync(); // .CountAsync();
return ResponseOutput.Ok(result, new { NeedSignCount = needSignTrialDocCount + needSignSystemDocCount, NeedSignTrialDocCount = needSignTrialDocCount, NeedSignSystemDocCount = needSignSystemDocCount, TrialStatusStr = trialInfo.TrialStatusStr }); //return ResponseOutput.Ok(result, new { NeedSignCount = needSignTrialDocCount + needSignSystemDocCount, NeedSignTrialDocCount = needSignTrialDocCount, NeedSignSystemDocCount = needSignSystemDocCount, TrialStatusStr = trialInfo.TrialStatusStr });
#endregion
} }
@@ -492,8 +758,8 @@ namespace IRaCIS.Core.Application.Services
[HttpGet("{trialId:guid}")] [HttpGet("{trialId:guid}")]
public async Task<List<TrialUserDto>> GetTrialUserSelect(Guid trialId) public async Task<List<TrialUserDto>> GetTrialUserSelect(Guid trialId)
{ {
return await _trialUserRepository.Where(t => t.TrialId == trialId) return await _trialIdentityUserRepository.Where(t => t.TrialId == trialId)
.Select(t => new TrialUserDto() { UserId = t.UserId, RealName = t.User.FullName, UserName = t.User.UserName }) .Select(t => new TrialUserDto() { UserId = t.IdentityUserId, RealName = t.IdentityUser.FullName, UserName = t.IdentityUser.UserName })
.ToListAsync(); .ToListAsync();
} }
@@ -513,7 +779,7 @@ namespace IRaCIS.Core.Application.Services
return ResponseOutput.Ok(result); return ResponseOutput.Ok(result);
} }
[TrialGlobalLimit( "BeforeOngoingCantOpt", "AfterStopCannNotOpt" )] [TrialGlobalLimit("BeforeOngoingCantOpt", "AfterStopCannNotOpt")]
//[Authorize(Policy = IRaCISPolicy.PM)] //[Authorize(Policy = IRaCISPolicy.PM)]
public async Task<IResponseOutput> AddOrUpdateTrialDocument(AddOrEditTrialDocument addOrEditTrialDocument) public async Task<IResponseOutput> AddOrUpdateTrialDocument(AddOrEditTrialDocument addOrEditTrialDocument)
{ {
@@ -585,7 +851,7 @@ namespace IRaCIS.Core.Application.Services
/// <returns></returns> /// <returns></returns>
[HttpDelete("{trialId:guid}/{trialDocumentId:guid}")] [HttpDelete("{trialId:guid}/{trialDocumentId:guid}")]
//[Authorize(Policy = IRaCISPolicy.PM)] //[Authorize(Policy = IRaCISPolicy.PM)]
[TrialGlobalLimit( "BeforeOngoingCantOpt", "AfterStopCannNotOpt" )] [TrialGlobalLimit("BeforeOngoingCantOpt", "AfterStopCannNotOpt")]
public async Task<IResponseOutput> DeleteTrialDocument(Guid trialDocumentId, Guid trialId) public async Task<IResponseOutput> DeleteTrialDocument(Guid trialDocumentId, Guid trialId)
{ {
if (await _trialDocumentRepository.AsQueryable(true).Where(t => t.Id == trialDocumentId).AnyAsync(t => t.TrialDocConfirmedUserList.Any())) if (await _trialDocumentRepository.AsQueryable(true).Where(t => t.Id == trialDocumentId).AnyAsync(t => t.TrialDocConfirmedUserList.Any()))
@@ -614,9 +880,9 @@ namespace IRaCIS.Core.Application.Services
var success = false; var success = false;
if (isSystemDoc) if (isSystemDoc)
{ {
if (!await _systemDocConfirmedUserRepository.AnyAsync(t => t.SystemDocumentId == documentId && t.ConfirmUserId == _userInfo.Id)) if (!await _systemDocConfirmedUserRepository.AnyAsync(t => t.SystemDocumentId == documentId && t.ConfirmUserId == _userInfo.IdentityUserId))
{ {
await _systemDocConfirmedUserRepository.AddAsync(new SystemDocConfirmedUser() { SystemDocumentId = documentId, ConfirmUserId = _userInfo.Id, SignFirstViewTime = DateTime.Now }); await _systemDocConfirmedUserRepository.AddAsync(new SystemDocConfirmedIdentityUser() { SystemDocumentId = documentId, ConfirmUserId = _userInfo.IdentityUserId, SignFirstViewTime = DateTime.Now });
} }
@@ -624,10 +890,10 @@ namespace IRaCIS.Core.Application.Services
else else
{ {
if (!await _trialDocUserTypeConfirmedUserRepository.AnyAsync(t => t.TrialDocumentId == documentId && t.ConfirmUserId == _userInfo.Id)) if (!await _trialDocConfirmedUserRepository.AnyAsync(t => t.TrialDocumentId == documentId && t.ConfirmUserId == _userInfo.IdentityUserId))
{ {
await _trialDocConfirmedUserRepository.AddAsync(new TrialDocConfirmedUser() { TrialDocumentId = documentId, ConfirmUserId = _userInfo.Id, SignFirstViewTime = DateTime.Now }); await _trialDocConfirmedUserRepository.AddAsync(new TrialDocConfirmedIdentityUser() { TrialDocumentId = documentId, ConfirmUserId = _userInfo.IdentityUserId, SignFirstViewTime = DateTime.Now });
} }
@@ -642,9 +908,9 @@ namespace IRaCIS.Core.Application.Services
[HttpPut("{documentId:guid}")] [HttpPut("{documentId:guid}")]
public async Task<IResponseOutput> SetSystemDocFirstViewTime(Guid documentId) public async Task<IResponseOutput> SetSystemDocFirstViewTime(Guid documentId)
{ {
if (!await _systemDocConfirmedUserRepository.AnyAsync(t => t.SystemDocumentId == documentId && t.ConfirmUserId == _userInfo.Id)) if (!await _systemDocConfirmedUserRepository.AnyAsync(t => t.SystemDocumentId == documentId && t.ConfirmUserId == _userInfo.IdentityUserId))
{ {
await _systemDocConfirmedUserRepository.AddAsync(new SystemDocConfirmedUser() { SystemDocumentId = documentId, ConfirmUserId = _userInfo.Id, SignFirstViewTime = DateTime.Now }); await _systemDocConfirmedUserRepository.AddAsync(new SystemDocConfirmedIdentityUser() { SystemDocumentId = documentId, ConfirmUserId = _userInfo.IdentityUserId, SignFirstViewTime = DateTime.Now });
} }
@@ -656,10 +922,10 @@ namespace IRaCIS.Core.Application.Services
[HttpPut("{trialId:guid}/{documentId:guid}")] [HttpPut("{trialId:guid}/{documentId:guid}")]
public async Task<IResponseOutput> SetTrialDocFirstViewTime(Guid documentId) public async Task<IResponseOutput> SetTrialDocFirstViewTime(Guid documentId)
{ {
if (!await _trialDocUserTypeConfirmedUserRepository.AnyAsync(t => t.TrialDocumentId == documentId && t.ConfirmUserId == _userInfo.Id)) if (!await _trialDocConfirmedUserRepository.AnyAsync(t => t.TrialDocumentId == documentId && t.ConfirmUserId == _userInfo.IdentityUserId))
{ {
await _trialDocConfirmedUserRepository.AddAsync(new TrialDocConfirmedUser() { TrialDocumentId = documentId, ConfirmUserId = _userInfo.Id, SignFirstViewTime = DateTime.Now }); await _trialDocConfirmedUserRepository.AddAsync(new TrialDocConfirmedIdentityUser() { TrialDocumentId = documentId, ConfirmUserId = _userInfo.IdentityUserId, SignFirstViewTime = DateTime.Now });
} }
var success = await _trialDocConfirmedUserRepository.SaveChangesAsync(); var success = await _trialDocConfirmedUserRepository.SaveChangesAsync();
@@ -671,14 +937,14 @@ namespace IRaCIS.Core.Application.Services
/// 用户 签名某个文档 可能是系统的,也可能是项目的 /// 用户 签名某个文档 可能是系统的,也可能是项目的
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[TrialGlobalLimit( "BeforeOngoingCantOpt", "AfterStopCannNotOpt" )] [TrialGlobalLimit("BeforeOngoingCantOpt", "AfterStopCannNotOpt")]
public async Task<IResponseOutput> UserConfirm(UserConfirmCommand userConfirmCommand) public async Task<IResponseOutput> UserConfirm(UserConfirmCommand userConfirmCommand)
{ {
if (userConfirmCommand.isSystemDoc) if (userConfirmCommand.isSystemDoc)
{ {
var sysDocConfirm = await _systemDocConfirmedUserRepository.FirstOrDefaultAsync(t => t.SystemDocumentId == userConfirmCommand.DocumentId && t.ConfirmUserId == _userInfo.Id, true); var sysDocConfirm = await _systemDocConfirmedUserRepository.FirstOrDefaultAsync(t => t.SystemDocumentId == userConfirmCommand.DocumentId && t.ConfirmUserId == _userInfo.IdentityUserId, true);
if (sysDocConfirm.ConfirmTime != null) if (sysDocConfirm.ConfirmTime != null)
{ {
@@ -705,7 +971,7 @@ namespace IRaCIS.Core.Application.Services
else else
{ {
var trialDocConfirm = await _trialDocUserTypeConfirmedUserRepository.FirstOrDefaultAsync(t => t.TrialDocumentId == userConfirmCommand.DocumentId && t.ConfirmUserId == _userInfo.Id, true); var trialDocConfirm = await _trialDocConfirmedUserRepository.FirstOrDefaultAsync(t => t.TrialDocumentId == userConfirmCommand.DocumentId && t.ConfirmUserId == _userInfo.IdentityUserId, true);
if (trialDocConfirm.ConfirmTime != null) if (trialDocConfirm.ConfirmTime != null)
{ {
@@ -722,7 +988,7 @@ namespace IRaCIS.Core.Application.Services
trialDocConfirm.ConfirmTime = DateTime.Now; trialDocConfirm.ConfirmTime = DateTime.Now;
trialDocConfirm.SignText = userConfirmCommand.SignText; trialDocConfirm.SignText = userConfirmCommand.SignText;
await _trialDocUserTypeConfirmedUserRepository.SaveChangesAsync(); await _trialDocConfirmedUserRepository.SaveChangesAsync();
} }
@@ -738,13 +1004,13 @@ namespace IRaCIS.Core.Application.Services
/// <param name="isSystemDoc"></param> /// <param name="isSystemDoc"></param>
/// <returns></returns> /// <returns></returns>
[HttpPut("{documentId:guid}/{isSystemDoc:bool}")] [HttpPut("{documentId:guid}/{isSystemDoc:bool}")]
[TrialGlobalLimit( "BeforeOngoingCantOpt", "AfterStopCannNotOpt", "SignSystemDocNoTrialId" )] [TrialGlobalLimit("BeforeOngoingCantOpt", "AfterStopCannNotOpt", "SignSystemDocNoTrialId")]
public async Task<IResponseOutput> UserAbandonDoc(Guid documentId, bool isSystemDoc) public async Task<IResponseOutput> UserAbandonDoc(Guid documentId, bool isSystemDoc)
{ {
if (isSystemDoc) if (isSystemDoc)
{ {
await _systemDocumentRepository.UpdatePartialFromQueryAsync(documentId, u => new SystemDocument() { IsDeleted = true }); await _systemDocumentRepository.UpdatePartialFromQueryAsync(documentId, u => new SystemDocument() { IsDeleted = true });
await _systemDocConfirmedUserRepository.UpdatePartialFromQueryAsync(x => x.SystemDocumentId == documentId, x => new SystemDocConfirmedUser() await _systemDocConfirmedUserRepository.UpdatePartialFromQueryAsync(x => x.SystemDocumentId == documentId, x => new SystemDocConfirmedIdentityUser()
{ {
IsDeleted = true IsDeleted = true
}); });
@@ -752,7 +1018,7 @@ namespace IRaCIS.Core.Application.Services
else else
{ {
await _trialDocumentRepository.UpdatePartialFromQueryAsync(documentId, u => new TrialDocument() { IsDeleted = true }); await _trialDocumentRepository.UpdatePartialFromQueryAsync(documentId, u => new TrialDocument() { IsDeleted = true });
await _trialDocUserTypeConfirmedUserRepository.UpdatePartialFromQueryAsync(x => x.TrialDocumentId == documentId, x => new TrialDocConfirmedUser() await _trialDocConfirmedUserRepository.UpdatePartialFromQueryAsync(x => x.TrialDocumentId == documentId, x => new TrialDocConfirmedIdentityUser()
{ {
IsDeleted = true IsDeleted = true
}); });
@@ -762,93 +1028,8 @@ namespace IRaCIS.Core.Application.Services
} }
#region
/// <summary>
/// 从项目下参与者的维度 先看人员列表(展示统计数字) 点击数字 再看人员具体签署的 系统文档+项目文档(共用上面与人相关的具体文档列表)
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
[HttpGet("{trialId:guid}")]
[Obsolete]
public List<TrialUserUnionDocumentView> GetTrialUserDocumentList(Guid trialId)
{
var query = _trialUserRepository.Where(t => t.TrialId == trialId)
.Select(t => new TrialUserUnionDocumentView()
{
UserId = t.UserId,
UserName = t.User.UserName,
RealName = t.User.FullName,
UserTypeShortName = t.User.UserTypeRole.UserTypeShortName,
TrialDocumentCount = t.Trial.TrialDocumentList.Count(u => u.NeedConfirmedUserTypeList.Any(k => k.NeedConfirmUserTypeId == t.User.UserTypeId)),
TrialDocumentConfirmedCount = t.Trial.TrialDocumentList.SelectMany(u => u.TrialDocConfirmedUserList).Count(k => k.ConfirmUserId == t.UserId),
SystemDocumentConfirmedCount = t.User.SystemDocConfirmedList.Count(),
//这样写不行
//SystemDocumentCount = _systemDocumentRepository.Where(s => s.NeedConfirmedUserTypeList.Any(kk => kk.NeedConfirmUserTypeId == t.User.UserTypeId))
// .WhereIf(!_userInfo.IsAdmin, s => s.IsAbandon == false || (s.IsAbandon == true && s.SystemDocConfirmedUserList.Any(uu => uu.ConfirmUserId == t.UserId))).Count()
SystemDocumentCount = t.User.UserTypeRole.SystemDocNeedConfirmedUserTypeList.Where(cc => cc.NeedConfirmUserTypeId == t.User.UserTypeId).Select(y => y.SystemDocument).Count()
});
return query.ToList();
}
/// <summary>
/// 从 文档的维度 先看到文档列表(系统文档+项目文档 以及需要确认的人数 和已经确认人数) 点击数字查看某文档下面人确认情况
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
[Obsolete]
public async Task<PageOutput<DocumentUnionWithUserStatView>> GetTrialSystemDocumentList(DocumentTrialUnionQuery inQuery)
{
var systemDocumentQueryable = _systemDocumentRepository
.WhereIf(!_userInfo.IsAdmin, t => t.IsDeleted == false)
.Select(t => new DocumentUnionWithUserStatView()
{
Id = t.Id,
IsSystemDoc = true,
CreateTime = t.CreateTime,
FullFilePath = t.Path,
IsDeleted = t.IsDeleted,
Name = t.Name,
Path = t.Path,
FileType = t.FileType.Value,
UpdateTime = t.UpdateTime,
SignViewMinimumMinutes = t.SignViewMinimumMinutes,
DocumentConfirmedUserCount = t.SystemDocConfirmedUserList.Count(),
//DocumentUserCount= _trialUserRepository.Where(tu=>tu.TrialId== querySystemDocument.TrialId).Count(u=>t.NeedConfirmedUserTypeList.Any(cc=>cc.NeedConfirmUserTypeId== u.User.UserTypeId ))
DocumentUserCount = t.NeedConfirmedUserTypeList.SelectMany(u => u.UserTypeRole.UserList.SelectMany(b => b.UserTrials.Where(r => r.TrialId == inQuery.TrialId))).Count()
});
var trialDocQueryable = _trialDocumentRepository.Where(t => t.TrialId == inQuery.TrialId).Select(t => new DocumentUnionWithUserStatView()
{
Id = t.Id,
IsSystemDoc = false,
CreateTime = t.CreateTime,
FullFilePath = t.Path,
IsDeleted = t.IsDeleted,
Name = t.Name,
Path = t.Path,
FileType = t.FileType.Value,
UpdateTime = t.UpdateTime,
SignViewMinimumMinutes = t.SignViewMinimumMinutes,
DocumentConfirmedUserCount = t.TrialDocConfirmedUserList.Count(),
DocumentUserCount = t.Trial.TrialUserList.Count(cc => t.NeedConfirmedUserTypeList.Any(k => k.NeedConfirmUserTypeId == cc.User.UserTypeId))
});
var unionQuery = systemDocumentQueryable.Union(trialDocQueryable)
.WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name))
.WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId);
return await unionQuery.ToPagedListAsync(inQuery);
}
#endregion
} }
@@ -8,6 +8,7 @@ using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.MassTransit.Consumer;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Domain.Share.Common; using IRaCIS.Core.Domain.Share.Common;
@@ -33,7 +34,7 @@ namespace IRaCIS.Core.Application.Service
IRepository<TaskMedicalReview> _taskMedicalReviewRepository, IRepository<TaskMedicalReview> _taskMedicalReviewRepository,
IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository, IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository,
IRepository<VisitTask> _visitTaskRepository, IRepository<VisitTask> _visitTaskRepository,
IRepository<TrialUser> _trialUserRepository, IRepository<TrialUserRole> _trialUserRoleRepository,
IRepository<TrialEmailNoticeUser> _trialEmailNoticeUserRepository, IRepository<TrialEmailNoticeUser> _trialEmailNoticeUserRepository,
IRepository<Subject> _subjectRepository, IRepository<Subject> _subjectRepository,
IRepository<ReadModule> _readModuleRepository, IRepository<ReadModule> _readModuleRepository,
@@ -280,8 +281,7 @@ namespace IRaCIS.Core.Application.Service
{ {
var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode); var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode);
var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN, var htmlBodyStr = isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN;
StaticData.EmailSend.EmailNamePlaceholder, taskInfo.ResearchProgramNo, taskInfo.SubjectCode);
return (topicStr, htmlBodyStr, isEn_us, null); return (topicStr, htmlBodyStr, isEn_us, null);
@@ -300,7 +300,7 @@ namespace IRaCIS.Core.Application.Service
var answer = "否"; var answer = "否";
var isNeedSend = true; var isNeedSend = true;
var minUserIdList = _trialUserRepository.Where(t => t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MIM && t.TrialId == taskInfo.TrialId).Select(t => t.UserId).ToList(); var minUserIdList = _trialUserRoleRepository.Where(t => t.UserRole.UserTypeEnum == Domain.Share.UserTypeEnum.MIM && t.TrialId == taskInfo.TrialId).Select(t => t.UserId).ToList();
@@ -1199,7 +1199,7 @@ namespace IRaCIS.Core.Application.Service
public async Task<List<TrialUserType>> GetTrialUserTypeSelectList(Guid trialId) public async Task<List<TrialUserType>> GetTrialUserTypeSelectList(Guid trialId)
{ {
var query = _trialUserRepository.Where(t => t.TrialId == trialId, false, true).IgnoreQueryFilters().Select(t => t.User.UserTypeRole).Distinct() var query = _trialUserRoleRepository.Where(t => t.TrialId == trialId, false, true).IgnoreQueryFilters().Select(t => t.UserRole.UserTypeRole).Distinct()
.ProjectTo<TrialUserType>(_mapper.ConfigurationProvider); .ProjectTo<TrialUserType>(_mapper.ConfigurationProvider);
@@ -1222,13 +1222,13 @@ namespace IRaCIS.Core.Application.Service
var userTypeList = trialEmailNoticeConfig.TrialEmailNoticeUserList.Select(t => t.UserType).ToList(); var userTypeList = trialEmailNoticeConfig.TrialEmailNoticeUserList.Select(t => t.UserType).ToList();
var query = _trialUserRepository.Where(t => t.TrialId == trialId && userTypeList.Contains(t.User.UserTypeEnum), false, true).IgnoreQueryFilters() var query = _trialUserRoleRepository.Where(t => t.TrialId == trialId && userTypeList.Contains(t.UserRole.UserTypeEnum), false, true).IgnoreQueryFilters()
.Select(t => new TrialSelectUser() .Select(t => new TrialSelectUser()
{ {
UserId = t.UserId, UserId = t.UserId,
UserName = t.User.UserName, UserName = t.UserRole.IdentityUser.UserName,
RealName = t.User.FullName, RealName = t.UserRole.FullName,
UserTypeEnum = t.User.UserTypeEnum UserTypeEnum = t.UserRole.UserTypeEnum
}).Distinct(); }).Distinct();
return await query.ToListAsync(); return await query.ToListAsync();
@@ -1525,7 +1525,7 @@ namespace IRaCIS.Core.Application.Service
#region #region
//var toUserList = await _trialUserRepository.Where(t => t.TrialId == config.TrialId) //var toUserList = await _trialUserRoleRepository.Where(t => t.TrialId == config.TrialId)
// .WhereIf(config.ToUserTypeList != null, t => config.ToUserTypeList.Contains(t.User.UserTypeEnum)) // .WhereIf(config.ToUserTypeList != null, t => config.ToUserTypeList.Contains(t.User.UserTypeEnum))
// .Select(t => new { t.User.EMail, t.User.FullName }).ToListAsync(); // .Select(t => new { t.User.EMail, t.User.FullName }).ToListAsync();
@@ -0,0 +1,241 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
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 MassTransit;
using IRaCIS.Core.Infrastructure;
namespace IRaCIS.Core.Application.Service;
/// <summary>
/// 项目文件类型
/// </summary>
/// <param name="_trialFileTypeRepository"></param>
/// <param name="_mapper"></param>
/// <param name="_userInfo"></param>
/// <param name="_localizer"></param>
[ApiExplorerSettings(GroupName = "FileRecord")]
public class TrialFileTypeService(IRepository<TrialFileType> _trialFileTypeRepository,
IRepository<TrialFile> _trialFileRepository,
IRepository<SysFileType> _sysFileTypeRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialFileTypeService
{
[HttpPost]
public async Task<PageOutput<TrialFileTypeView>> GetTrialFileTypeList(TrialFileTypeQuery inQuery)
{
var trialFileTypeQueryable = _trialFileTypeRepository
.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(inQuery.ArchiveTypeEnum != null, t => t.ArchiveTypeEnum == inQuery.ArchiveTypeEnum)
.WhereIf(inQuery.IsConfirmRecord != null, t => t.IsConfirmRecord == inQuery.IsConfirmRecord)
.WhereIf(inQuery.SubIdentificationEnum != null, t => t.SubIdentificationEnum == inQuery.SubIdentificationEnum)
.WhereIf(inQuery.IsEnable != null, t => t.IsEnable == inQuery.IsEnable)
.WhereIf(inQuery.Name.IsNotNullOrEmpty(), t => t.Name.Contains(inQuery.Name))
.WhereIf(inQuery.NameCN.IsNotNullOrEmpty(), t => t.NameCN.Contains(inQuery.NameCN))
.WhereIf(inQuery.IsSelfDefine != null, t => t.IsSelfDefine == inQuery.IsSelfDefine)
.ProjectTo<TrialFileTypeView>(_mapper.ConfigurationProvider);
var pageList = await trialFileTypeQueryable.ToPagedListAsync(inQuery);
return pageList;
}
/// <summary>
/// 获取项目文件类型下拉框
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
public async Task<List<TrialFileTypeSelectView>> GetTrialFileTypeSelectList(TrialFileTypeSelectQuery inQuery)
{
var list = _trialFileTypeRepository
.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(inQuery.ArchiveTypeEnum != null, t => t.ArchiveTypeEnum == inQuery.ArchiveTypeEnum)
.WhereIf(inQuery.IsSelfDefine != null, t => t.IsSelfDefine == inQuery.IsSelfDefine)
.WhereIf(inQuery.IsEnable != null, t => t.IsEnable == inQuery.IsEnable)
.Select(t => new TrialFileTypeSelectView()
{
Id = t.Id,
IsEnable = t.IsEnable,
Name = _userInfo.IsEn_Us ? t.Name : t.NameCN,
IsSelfDefine = t.IsSelfDefine,
ArchiveTypeEnum = t.ArchiveTypeEnum,
}).ToList();
return list;
}
public async Task<IResponseOutput> AddOrUpdateTrialFileType(TrialFileTypeAddOrEdit addOrEditTrialFileType)
{
if (await _trialFileTypeRepository.AnyAsync(u => u.TrialId == addOrEditTrialFileType.TrialId && u.Id != addOrEditTrialFileType.Id && u.IsEnable == addOrEditTrialFileType.IsEnable && (u.Name == addOrEditTrialFileType.Name || u.NameCN == addOrEditTrialFileType.NameCN)))
{
throw new BusinessValidationFailedException(_localizer["TrialFileType_NameRepeat"]);
}
var entity = await _trialFileTypeRepository.InsertOrUpdateAsync(addOrEditTrialFileType, true);
return ResponseOutput.Ok(entity.Id.ToString());
}
[HttpDelete("{trialFileTypeId:guid}")]
public async Task<IResponseOutput> DeleteTrialFileType(Guid trialFileTypeId)
{
var success = await _trialFileTypeRepository.DeleteFromQueryAsync(t => t.Id == trialFileTypeId, true);
return ResponseOutput.Ok();
}
/// <summary>
/// 复制系统数据到项目
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<IResponseOutput> CopySystemFileTypeToTrial(CopySystemFileTypeToTrialInDto inDto)
{
if (!(await _trialFileTypeRepository.AnyAsync(x => x.TrialId == inDto.TrialId)))
{
var trialFileTypeList = await _sysFileTypeRepository
.ProjectTo<TrialFileType>(_mapper.ConfigurationProvider)
.ToListAsync();
trialFileTypeList.ForEach(x => {
x.TrialId = inDto.TrialId;
x.Id = NewId.NextGuid();
});
await _trialFileTypeRepository.AddRangeAsync(trialFileTypeList, true);
}
return ResponseOutput.Ok();
}
/// <summary>
/// 获取项目文件类型数据
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<GetTrialFileTypeDataOutDto> GetTrialFileTypeData(GetTrialFileTypeDataInDto inDto)
{
await this.CopySystemFileTypeToTrial(new CopySystemFileTypeToTrialInDto()
{
TrialId = inDto.TrialId
});
var trialFileTypeList = await _trialFileTypeRepository.Where(x => x.TrialId == inDto.TrialId)
.WhereIf(inDto.IsEnable, x => x.IsEnable)
.OrderBy(x => x.ShowOrder)
.ProjectTo<TrialFileTypeView>(_mapper.ConfigurationProvider)
.ToListAsync();
List<TrialFileTypeData> result = new List<TrialFileTypeData>();
foreach (ArchiveType type in Enum.GetValues(typeof(ArchiveType)))
{
result.Add(new TrialFileTypeData()
{
ArchiveTypeEnum = type,
TrialFileTypeList = trialFileTypeList.Where(x => x.ArchiveTypeEnum == type).OrderBy(x => x.SysFileTypeId == null).ThenBy(x => x.ShowOrder).ToList()
});
}
return new GetTrialFileTypeDataOutDto() { TrialFileTypeDataList = result };
}
/// <summary>
/// 修改授权状态
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SetAuthorizedView(SetAuthorizedViewInDto inDto)
{
await _trialFileTypeRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.Id, x => new TrialFileType() { IsEnable = inDto.IsEnable }, true);
return ResponseOutput.Ok();
}
/// <summary>
/// 上传同意入项记录
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> UploadTrialFileTypeFile(UploadTrialFileTypeFileInDto inDto)
{
var trialFileType = await _trialFileTypeRepository.Where(x => x.Id == inDto.TrialFileTypeId).FirstNotNullAsync();
if (trialFileType.FileRecordId != null)
{
await _trialFileRepository.BatchDeleteNoTrackingAsync(x => x.Id == trialFileType.FileRecordId);
}
inDto.FileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
var entity = await _trialFileRepository.InsertFromDTOAsync(inDto.FileRecord, true);
await _trialFileTypeRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.TrialFileTypeId, x => new TrialFileType()
{
FileRecordId = entity.Id
});
await _trialFileTypeRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 获取入项记录
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<TrialFileDto> GetTrialFileTypeFile(GetTrialFileTypeFileInDto inDto)
{
var trialFileType = await _trialFileTypeRepository.Where(x => x.Id == inDto.TrialFileTypeId).FirstNotNullAsync();
if (trialFileType.FileRecordId == null)
{
return new TrialFileDto() { };
}
var file = await _trialFileRepository.Where(x => x.Id == trialFileType.FileRecordId).ProjectTo<TrialFileDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
return file;
}
/// <summary>
/// 删除入项记录
/// </summary>
/// <param name="trialFileTypeId"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> DeleteTrialTypeFile(Guid trialFileTypeId)
{
var trialFileType = await _trialFileTypeRepository.Where(x => x.Id == trialFileTypeId).FirstNotNullAsync();
await _trialFileRepository.DeleteFromQueryAsync(x => x.Id == trialFileType.FileRecordId, true);
await _trialFileTypeRepository.UpdatePartialFromQueryAsync(x => x.Id == trialFileTypeId, x => new TrialFileType() { FileRecordId = null }, true);
return ResponseOutput.Ok();
}
}
@@ -0,0 +1,119 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
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 IRaCIS.Core.Infrastructure;
namespace IRaCIS.Core.Application.Service;
/// <summary>
/// 项目定稿记录
/// </summary>
/// <param name="_trialFinalRecordRepository"></param>
/// <param name="_mapper"></param>
/// <param name="_userInfo"></param>
/// <param name="_localizer"></param>
[ApiExplorerSettings(GroupName = "FileRecord")]
public class TrialFinalRecordService(IRepository<TrialFinalRecord> _trialFinalRecordRepository,
IRepository<TrialFile> _trialFileRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialFinalRecordService
{
[HttpPost]
public async Task<PageOutput<TrialFinalRecordView>> GetTrialFinalRecordList(TrialFinalRecordQuery inDto)
{
var trialFinalRecordQueryable = _trialFinalRecordRepository
.Where(x=>x.TrialFileTypeId==inDto.TrialFileTypeId)
.WhereIf(inDto.Name.IsNotNullOrEmpty(),x=>x.Name.Contains(inDto.Name))
.WhereIf(inDto.Version.IsNotNullOrEmpty(), x => x.Version.Contains(inDto.Version))
.WhereIf(inDto.IsAuthorizedView!=null, x => x.IsAuthorizedView==inDto.IsAuthorizedView)
// .Include(x=>x.PDFFileRecord).Include(x => x.WordFileRecord).Include(x => x.SignFileRecord).Include(x => x.HistoryFileRecord)
.ProjectTo<TrialFinalRecordView>(_mapper.ConfigurationProvider);
var pageList = await trialFinalRecordQueryable.ToPagedListAsync(inDto);
return pageList;
}
/// <summary>
/// 新增或者修改文档
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<IResponseOutput> AddOrUpdateTrialFinalRecord(TrialFinalRecordAddOrEdit inDto)
{
// 在此处拷贝automapper 映射
if (inDto.PDFFileRecord != null) inDto.PDFFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
if (inDto.WordFileRecord != null) inDto.WordFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
if (inDto.SignFileRecord != null) inDto.SignFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
if (inDto.HistoryFileRecord != null) inDto.HistoryFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
if (await _trialFinalRecordRepository.AnyAsync(x => x.Id != inDto.Id && x.TrialFileTypeId == inDto.TrialFileTypeId && x.Name == inDto.Name && x.Version == inDto.Version))
{
throw new BusinessValidationFailedException(_localizer["TrialFinalRecord_NameRepeat"]);
}
if (inDto.Id != null)
{
var trialFinalRecord = await _trialFinalRecordRepository.Where(x => x.Id == inDto.Id.Value).FirstNotNullAsync();
List<Guid?> ids= new List<Guid?>() {
trialFinalRecord.WordFileRecordId,
trialFinalRecord.PDFFileRecordId,
trialFinalRecord.SignFileRecordId,
trialFinalRecord.HistoryFileRecordId
};
var fileIds = ids.Where(x => x != null).Select(x => (Guid)x).ToList();
await _trialFileRepository.BatchDeleteNoTrackingAsync(x => fileIds.Contains(x.Id));
}
var entity = await _trialFinalRecordRepository.InsertOrUpdateAsync(inDto, true);
return ResponseOutput.Ok(entity.Id.ToString());
}
/// <summary>
/// 授权文档
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<IResponseOutput> AuthorizedTrialFinalRecord(AuthorizedTrialFinalRecordInDto inDto)
{
await _trialFinalRecordRepository.UpdatePartialFromQueryAsync(t =>inDto.Ids.Contains(t.Id), t => new TrialFinalRecord() { IsAuthorizedView = inDto.IsAuthorizedView });
await _trialFinalRecordRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 删除文档
/// </summary>
/// <param name="trialFinalRecordId"></param>
/// <returns></returns>
[HttpDelete("{trialFinalRecordId:guid}")]
public async Task<IResponseOutput> DeleteTrialFinalRecord(Guid trialFinalRecordId)
{
var success = await _trialFinalRecordRepository.DeleteFromQueryAsync(t => t.Id == trialFinalRecordId, true);
return ResponseOutput.Ok();
}
}
@@ -0,0 +1,130 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
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;
namespace IRaCIS.Core.Application.Service;
/// <summary>
/// 项目-一般文件记录
/// </summary>
/// <param name="_trialNormalRecordRepository"></param>
/// <param name="_mapper"></param>
/// <param name="_userInfo"></param>
/// <param name="_localizer"></param>
[ApiExplorerSettings(GroupName = "FileRecord")]
public class TrialNormalRecordService(IRepository<TrialNormalRecord> _trialNormalRecordRepository,
IRepository<TrialFile> _trialFileRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialNormalRecordService
{
[HttpPost]
public async Task<PageOutput<TrialNormalRecordView>> GetTrialNormalRecordList(TrialNormalRecordQuery inDto)
{
var trialNormalRecordQueryable = _trialNormalRecordRepository
.Where(x => x.TrialFileTypeId == inDto.TrialFileTypeId)
.WhereIf(inDto.IsAuthorizedView != null, x => x.IsAuthorizedView == inDto.IsAuthorizedView)
.WhereIf(inDto.FileName.IsNotNullOrEmpty(), x => x.TrialFileRecord.FileName.Contains(inDto.FileName))
.ProjectTo<TrialNormalRecordView>(_mapper.ConfigurationProvider);
var pageList = await trialNormalRecordQueryable.ToPagedListAsync(inDto);
return pageList;
}
public async Task<IResponseOutput> AddOrUpdateTrialNormalRecord(TrialNormalRecordAddOrEdit inDto)
{
if (inDto.TrialFileRecord != null) inDto.TrialFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
if (inDto.HistoryFileRecord != null) inDto.HistoryFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
if (inDto.Id != null)
{
var trialFinalRecord = await _trialNormalRecordRepository.Where(x => x.Id == inDto.Id.Value).FirstNotNullAsync();
List<Guid?> ids = new List<Guid?>() {
trialFinalRecord.TrialFileRecordId,
trialFinalRecord.HistoryFileRecordId,
};
var fileIds = ids.Where(x => x != null).Select(x => (Guid)x).ToList();
await _trialFileRepository.BatchDeleteNoTrackingAsync(x => fileIds.Contains(x.Id));
}
var entity = await _trialNormalRecordRepository.InsertOrUpdateAsync(inDto, true);
return ResponseOutput.Ok(entity.Id.ToString());
}
/// <summary>
/// 批量新增一般文件记录
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> BatchAddTrialNormalRecord(BatchAddTrialNormalRecordInDto inDto)
{
foreach (var item in inDto.TrialNormalRecordList)
{
if (item.TrialFileRecord != null) item.TrialFileRecord.TrialFileTypeId = item.TrialFileTypeId;
if (item.HistoryFileRecord != null) item.HistoryFileRecord.TrialFileTypeId = item.TrialFileTypeId;
var entity = await _trialNormalRecordRepository.InsertFromDTOAsync(item);
}
var result= await _trialNormalRecordRepository.SaveChangesAsync();
return ResponseOutput.Ok(result);
}
/// <summary>
/// 授权文档
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<IResponseOutput> AuthorizedTTrialNormalRecord(AuthorizedTrialFinalRecordInDto inDto)
{
await _trialNormalRecordRepository.UpdatePartialFromQueryAsync(t => inDto.Ids.Contains(t.Id), t => new TrialNormalRecord() { IsAuthorizedView = inDto.IsAuthorizedView });
await _trialNormalRecordRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
[HttpDelete("{trialNormalRecordId:guid}")]
public async Task<IResponseOutput> DeleteTrialNormalRecord(Guid trialNormalRecordId)
{
var success = await _trialNormalRecordRepository.DeleteFromQueryAsync(t => t.Id == trialNormalRecordId, true);
return ResponseOutput.Ok();
}
/// <summary>
/// 批量删除一般文件记录
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> DeleteTrialNormalRecordList(DeleteTrialNormalRecordListInDto inDto)
{
var success = await _trialNormalRecordRepository.DeleteFromQueryAsync(t => inDto.Ids.Contains(t.Id), true);
return ResponseOutput.Ok();
}
}
@@ -0,0 +1,140 @@
//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-02-21 07:47:30Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
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;
namespace IRaCIS.Core.Application.Service;
/// <summary>
/// 项目-培训记录
/// </summary>
/// <param name="_trialTrianingRecordRepository"></param>
/// <param name="_mapper"></param>
/// <param name="_userInfo"></param>
/// <param name="_localizer"></param>
[ApiExplorerSettings(GroupName = "FileRecord")]
public class TrialTrianingRecordService(IRepository<
TrialTrianingRecord> _trialTrianingRecordRepository,
IRepository<TrialFile> _trialFileRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialTrianingRecordService
{
/// <summary>
/// 获取培训记录列表
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<TrialTrianingRecordView>> GetTrialTrianingRecordList(TrialTrianingRecordQuery inDto)
{
var trialTrianingRecordQueryable = _trialTrianingRecordRepository
.Where(x => x.TrialFileTypeId == inDto.TrialFileTypeId)
.WhereIf(inDto.IsAuthorizedView != null, x => x.IsAuthorizedView == inDto.IsAuthorizedView)
.WhereIf(inDto.FileName.IsNotNullOrEmpty(), x => x.TrialFileRecord.FileName.Contains(inDto.FileName))
.WhereIf(inDto.TrianingDateStartTime != null, x => x.TrianingDate >= inDto.TrianingDateStartTime)
.WhereIf(inDto.TrianingDateEndTime != null, x => x.TrianingDate <= inDto.TrianingDateEndTime)
.WhereIf(inDto.UpdateStartTime != null, x => x.UpdateTime >= inDto.UpdateStartTime)
.WhereIf(inDto.UpdateEndTime != null, x => x.UpdateTime < inDto.UpdateEndTime.Value.AddDays(1))
.ProjectTo<TrialTrianingRecordView>(_mapper.ConfigurationProvider);
var pageList = await trialTrianingRecordQueryable.ToPagedListAsync(inDto);
return pageList;
}
public async Task<IResponseOutput> AddOrUpdateTrialTrianingRecord(TrialTrianingRecordAddOrEdit inDto)
{
// 在此处拷贝automapper 映射
if (inDto.TrialFileRecord != null) inDto.TrialFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
if (inDto.HistoryFileRecord != null) inDto.HistoryFileRecord.TrialFileTypeId = inDto.TrialFileTypeId;
if (inDto.Id != null)
{
var trialFinalRecord = await _trialTrianingRecordRepository.Where(x => x.Id == inDto.Id.Value).FirstNotNullAsync();
List<Guid?> ids = new List<Guid?>() {
trialFinalRecord.TrialFileRecordId,
trialFinalRecord.HistoryFileRecordId,
};
var fileIds = ids.Where(x => x != null).Select(x => (Guid)x).ToList();
await _trialFileRepository.BatchDeleteNoTrackingAsync(x => fileIds.Contains(x.Id));
}
var entity = await _trialTrianingRecordRepository.InsertOrUpdateAsync(inDto, true);
return ResponseOutput.Ok(entity.Id.ToString());
}
/// <summary>
/// 批量新增培训记录
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> BatchAddTrialTrianingRecord(BatchAddTTrianingRecordInDto inDto)
{
foreach (var item in inDto.TrianingRecordList)
{
if (item.TrialFileRecord != null) item.TrialFileRecord.TrialFileTypeId = item.TrialFileTypeId;
if (item.HistoryFileRecord != null) item.HistoryFileRecord.TrialFileTypeId = item.TrialFileTypeId;
var entity = await _trialTrianingRecordRepository.InsertFromDTOAsync(item);
}
var result = await _trialTrianingRecordRepository.SaveChangesAsync();
return ResponseOutput.Ok(result);
}
/// <summary>
/// 授权文档
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> AuthorizedTrialTrianingRecord(AuthorizedTrialFinalRecordInDto inDto)
{
await _trialTrianingRecordRepository.UpdatePartialFromQueryAsync(t => inDto.Ids.Contains(t.Id), t => new TrialTrianingRecord() { IsAuthorizedView = inDto.IsAuthorizedView });
await _trialTrianingRecordRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
[HttpDelete("{trialTrianingRecordId:guid}")]
public async Task<IResponseOutput> DeleteTrialTrianingRecord(Guid trialTrianingRecordId)
{
var success = await _trialTrianingRecordRepository.DeleteFromQueryAsync(t => t.Id == trialTrianingRecordId, true);
return ResponseOutput.Ok();
}
/// <summary>
/// 批量删除培训记录
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> DeleteTrialTrianingRecordList(DeleteTrialNormalRecordListInDto inDto)
{
var success = await _trialTrianingRecordRepository.DeleteFromQueryAsync(t => inDto.Ids.Contains(t.Id), true);
return ResponseOutput.Ok();
}
}
@@ -3,6 +3,7 @@ using AutoMapper.EquivalencyExpression;
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Core.Application.Service namespace IRaCIS.Core.Application.Service
{ {
@@ -18,6 +19,12 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.FileType, u => u.MapFrom(s => isEn_Us ? s.FileType.Value : s.FileType.ValueCN)) .ForMember(d => d.FileType, u => u.MapFrom(s => isEn_Us ? s.FileType.Value : s.FileType.ValueCN))
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path)); .ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path));
CreateMap<SysFileType, TrialFileType>()
.ForMember(d => d.SysFileTypeId, u => u.MapFrom(s => s.Id))
.ForMember(d => d.IsSelfDefine, u => u.MapFrom(s => false))
.ForMember(dest => dest.CreateUserRole, opt => opt.Ignore());
CreateMap<TrialDocument, TrialDocumentView>() CreateMap<TrialDocument, TrialDocumentView>()
.ForMember(d => d.FileType, u => u.MapFrom(s => isEn_Us ? s.FileType.Value : s.FileType.ValueCN)) .ForMember(d => d.FileType, u => u.MapFrom(s => isEn_Us ? s.FileType.Value : s.FileType.ValueCN))
.ForMember(d => d.IsSomeUserSigned, u => u.MapFrom(s => s.TrialDocConfirmedUserList.Any(t => t.ConfirmTime != null))) .ForMember(d => d.IsSomeUserSigned, u => u.MapFrom(s => s.TrialDocConfirmedUserList.Any(t => t.ConfirmTime != null)))
@@ -40,7 +47,7 @@ namespace IRaCIS.Core.Application.Service
// .ForMember(t => t.UserConfirmInfo, c => c.MapFrom(t => t.TrialDocConfirmedUserList.Where(u => u.ConfirmUserId == userId).FirstOrDefault())) // .ForMember(t => t.UserConfirmInfo, c => c.MapFrom(t => t.TrialDocConfirmedUserList.Where(u => u.ConfirmUserId == userId).FirstOrDefault()))
// .ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token)); ; // .ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token)); ;
CreateMap<TrialDocConfirmedUser, TrialDocumentUserConfirmView>() CreateMap<TrialDocConfirmedIdentityUser, TrialDocumentUserConfirmView>()
.ForMember(d => d.UserName, c => c.MapFrom(t => t.User.UserName)) .ForMember(d => d.UserName, c => c.MapFrom(t => t.User.UserName))
.ForMember(d => d.RealName, c => c.MapFrom(t => t.User.FullName)); .ForMember(d => d.RealName, c => c.MapFrom(t => t.User.FullName));
@@ -49,7 +56,10 @@ namespace IRaCIS.Core.Application.Service
// .ForMember(d => d.RealName, c => c.MapFrom(t => t.User.LastName + " / " + t.User.FirstName)); // .ForMember(d => d.RealName, c => c.MapFrom(t => t.User.LastName + " / " + t.User.FirstName));
CreateMap<TrialUser, TrialDocumentUserConfirmView>(); CreateMap<TrialUserRole, TrialDocumentUserConfirmView>();
CreateMap<TrialFileDto, TrialFile>();
CreateMap<TrialFile, TrialFileDto>();
CreateMap<BatchAddTrialEmailNoticeConfig, TrialEmailNoticeConfig>(); CreateMap<BatchAddTrialEmailNoticeConfig, TrialEmailNoticeConfig>();
@@ -78,15 +88,42 @@ namespace IRaCIS.Core.Application.Service
CreateMap<TrialEmailNoticeConfigAddOrEdit, TrialEmailNoticeConfig>(); CreateMap<TrialEmailNoticeConfigAddOrEdit, TrialEmailNoticeConfig>();
CreateMap<TrialUser, TrialUserSelct>() CreateMap<TrialUserRole, TrialUserSelct>()
.ForMember(d => d.Phone, c => c.MapFrom(t => t.User.Phone)) .ForMember(d => d.Phone, c => c.MapFrom(t => t.UserRole.IdentityUser.Phone))
.ForMember(d => d.Email, c => c.MapFrom(t => t.User.EMail)) .ForMember(d => d.Email, c => c.MapFrom(t => t.UserRole.IdentityUser.EMail))
.ForMember(d => d.RealName, c => c.MapFrom(t => t.User.FullName)) .ForMember(d => d.RealName, c => c.MapFrom(t => t.UserRole.IdentityUser.FullName))
.ForMember(d => d.UserName, c => c.MapFrom(t => t.User.UserName)); .ForMember(d => d.UserName, c => c.MapFrom(t => t.UserRole.IdentityUser.UserName));
CreateMap<TrialEmailNoticeUser, EmailUserInfoDto>(); CreateMap<TrialEmailNoticeUser, EmailUserInfoDto>();
CreateMap<SysFileType, SysFileTypeView>();
CreateMap<SysFileType, SysFileTypeAddOrEdit>().ReverseMap();
CreateMap<TrialFileType, TrialFileTypeView>();
CreateMap<TrialFileType, TrialFileTypeAddOrEdit>().ReverseMap();
CreateMap<TrialFinalRecord, TrialFinalRecordView>();
CreateMap<TrialFinalRecordAddOrEdit, TrialFinalRecord>();
//.ForMember(d => d.HistoryFileRecord.TrialFileTypeId, c => c.MapFrom(t => t.TrialFileTypeId))
//.ForMember(d => d.SignFileRecord.TrialFileTypeId, c => c.MapFrom(t => t.TrialFileTypeId))
//.ForMember(d => d.WordFileRecord.TrialFileTypeId, c => c.MapFrom(t => t.TrialFileTypeId))
//.ForMember(d => d.PDFFileRecord.TrialFileTypeId, c => c.MapFrom(t => t.TrialFileTypeId));
CreateMap<TrialNormalRecord, TrialNormalRecordView>()
.ForMember(d => d.FileName, c => c.MapFrom(t => t.TrialFileRecord.FileName));
CreateMap<TrialNormalRecord, TrialNormalRecordAddOrEdit>().ReverseMap();
CreateMap<TrialTrianingRecord, TrialTrianingRecordView>()
.ForMember(d => d.FileName, c => c.MapFrom(t => t.TrialFileRecord.FileName));
CreateMap<TrialTrianingRecord, TrialTrianingRecordAddOrEdit>().ReverseMap();
} }
} }
@@ -66,7 +66,7 @@ namespace IRaCIS.Core.Application.Service
SowPath = "", SowPath = "",
SowName = "", SowName = "",
UpdateTime = DateTime.Now, UpdateTime = DateTime.Now,
UpdateUserId = _userInfo.Id UpdateUserId = _userInfo.UserRoleId
}); });
return ResponseOutput.Result(success); return ResponseOutput.Result(success);
@@ -79,6 +79,11 @@ namespace IRaCIS.Core.Application.Contracts.Dicom.DTO
public int InstanceNumber { get; set; } public int InstanceNumber { get; set; }
public bool IsReading { get; set; }
public bool IsDeleted { get; set; }
public Guid? StudyId { get; set; } public Guid? StudyId { get; set; }
public List<int?> KeyFramesList { get; set; } = new List<int?> { }; public List<int?> KeyFramesList { get; set; } = new List<int?> { };
@@ -37,7 +37,7 @@
public bool SoftDelete { get; set; } = false; public bool SoftDelete { get; set; } = false;
public string InstitutionName { get; set; } = string.Empty; //public string InstitutionName { get; set; } = string.Empty;
public string PatientId { get; set; } = string.Empty; public string PatientId { get; set; } = string.Empty;
public string PatientName { get; set; } = string.Empty; public string PatientName { get; set; } = string.Empty;
public string PatientAge { get; set; } = string.Empty; public string PatientAge { get; set; } = string.Empty;
@@ -65,19 +65,19 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
(t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.Random && t.TrialReadingCriterion.ImageUploadEnum != ReadingImageUpload.None)))) (t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.Random && t.TrialReadingCriterion.ImageUploadEnum != ReadingImageUpload.None))))
{ {
//找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务 //找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务
var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.UserRoleId
&& t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskBlindName == "Timepoint" && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskBlindName == "Timepoint" && t.ReadingCategory == ReadingCategory.Visit
&& (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze), true).ToListAsync(); && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze), true).ToListAsync();
if (needDealTaskList.Count > 0) if (needDealTaskList.Count > 0)
{ {
//已完成的访视任务数量(包含重阅的) //已完成的访视任务数量(包含重阅的)
var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.UserRoleId
&& t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit); && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit);
//已经处理过的任务名称的数量 //已经处理过的任务名称的数量
var haveDealedTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id var haveDealedTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.UserRoleId
&& t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint").Select(t => new { t.TaskBlindName, t.SourceSubjectVisitId, t.SouceReadModuleId }).ToListAsync(); && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint").Select(t => new { t.TaskBlindName, t.SourceSubjectVisitId, t.SouceReadModuleId }).ToListAsync();
@@ -153,7 +153,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var query = _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SourceSubjectVisitId != null var query = _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SourceSubjectVisitId != null
&& t.DoctorUserId == _userInfo.Id && t.TaskState == TaskState.Effect) && t.DoctorUserId == _userInfo.UserRoleId && t.TaskState == TaskState.Effect)
//满足 有序,或者随机只看到当前任务的dicom 非dicom检查 //满足 有序,或者随机只看到当前任务的dicom 非dicom检查
.WhereIf(criterionInfo.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId) .WhereIf(criterionInfo.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)
.Select(u => new SubjectImageUploadDTO() .Select(u => new SubjectImageUploadDTO()
@@ -257,7 +257,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
} }
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> PreArchiveDicomStudy(PriArchiveTaskStudyCommand preArchiveStudyCommand) public async Task<IResponseOutput> PreArchiveDicomStudy(PriArchiveTaskStudyCommand preArchiveStudyCommand)
{ {
@@ -356,7 +356,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
} }
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> AddOrUpdateArchiveTaskStudy(TaskArchiveStudyCommand incommand) public async Task<IResponseOutput> AddOrUpdateArchiveTaskStudy(TaskArchiveStudyCommand incommand)
{ {
#region subject 访 #region subject 访
@@ -402,7 +402,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
else else
{ {
//在事务未完成前 防止前端重复提交 //在事务未完成前 防止前端重复提交
await _fusionCache.SetAsync(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid), _userInfo.Id, TimeSpan.FromMinutes(1)); await _fusionCache.SetAsync(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid), _userInfo.UserRoleId, TimeSpan.FromMinutes(1));
} }
} }
@@ -620,12 +620,25 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{ {
if (dicomStudyId == null) if (dicomStudyId == null)
{ {
var deleteStudyPathList = await _taskInstanceRepository.Where(t => t.VisitTaskId == visitTaskId).GroupBy(t => t.StudyId).Select(g => g.First().Path).ToListAsync();
foreach (var fisrtPath in deleteStudyPathList)
{
var prefix = fisrtPath.Substring(1, fisrtPath.LastIndexOf('/') - 1);
await _oSSService.DeleteFromPrefix(prefix, true);
}
await _taskStudyRepository.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId); await _taskStudyRepository.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId);
await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId); await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId);
await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId); await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId);
} }
else else
{ {
var fisrtPath = await _taskInstanceRepository.Where(t => t.VisitTaskId == visitTaskId && t.StudyId == dicomStudyId).Select(t => t.Path).FirstOrDefaultAsync();
var prefix = fisrtPath.Substring(1, fisrtPath.LastIndexOf('/') - 1);
await _oSSService.DeleteFromPrefix(prefix, true);
await _taskStudyRepository.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId); await _taskStudyRepository.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId); await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId); await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
@@ -653,7 +666,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{ {
var subjectCode = inQuery.SubjectCode; var subjectCode = inQuery.SubjectCode;
var subjectId = inQuery.SubjectId; var subjectId = inQuery.SubjectId;
var doctorUserId = _userInfo.Id; var doctorUserId = _userInfo.UserRoleId;
if (inQuery.VisitTaskId != null) if (inQuery.VisitTaskId != null)
{ {
@@ -689,7 +702,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
SubjectCode = u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code, SubjectCode = u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code,
TaskBlindName = u.TaskBlindName, TaskBlindName = u.TaskBlindName,
TaskName = u.TaskName, TaskName = u.TaskName,
ReadingTaskState=u.ReadingTaskState, ReadingTaskState = u.ReadingTaskState,
SourceSubjectVisitId = u.SourceSubjectVisitId, SourceSubjectVisitId = u.SourceSubjectVisitId,
VisitTaskId = u.Id, VisitTaskId = u.Id,
@@ -761,9 +774,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
select new select new
{ {
TrialId = sv.TrialId, TrialId = sv.TrialId,
SubjectId=sv.SubjectId, SubjectId = sv.SubjectId,
SubjectCode = sv.Subject.Code, SubjectCode = sv.Subject.Code,
TrialSiteCode=sv.TrialSite.TrialSiteCode, TrialSiteCode = sv.TrialSite.TrialSiteCode,
VisitName = sv.VisitName, VisitName = sv.VisitName,
StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false) StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
@@ -839,7 +852,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
public async Task<List<SubjectCRCImageUploadedStudyDto>> GetSubjectImageDownloadSelectList(IRReadingDownloadQuery inQuery) public async Task<List<SubjectCRCImageUploadedStudyDto>> GetSubjectImageDownloadSelectList(IRReadingDownloadQuery inQuery)
{ {
var doctorUserId = _userInfo.Id; var doctorUserId = _userInfo.UserRoleId;
var isAnalysisCreate = false; var isAnalysisCreate = false;
//要根据标准阅片顺序,确定是否查询单个任务的,还是查询所有的 //要根据标准阅片顺序,确定是否查询单个任务的,还是查询所有的
@@ -971,7 +984,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var subjectVisitIdList = inQuery.SubjectVisitTaskList.Select(t => t.SubjectVisitId).ToList(); var subjectVisitIdList = inQuery.SubjectVisitTaskList.Select(t => t.SubjectVisitId).ToList();
var trialSiteCode = _visitTaskRepository.Where(t => t.Id == taskIdList.FirstOrDefault()).Select(t => t.IsAnalysisCreate ? t.BlindTrialSiteCode : t.Subject.TrialSite.TrialSiteCode).FirstOrDefault()??string.Empty; var trialSiteCode = _visitTaskRepository.Where(t => t.Id == taskIdList.FirstOrDefault()).Select(t => t.IsAnalysisCreate ? t.BlindTrialSiteCode : t.Subject.TrialSite.TrialSiteCode).FirstOrDefault() ?? string.Empty;
var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id))) var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id)))
//一致性分析,导致查询出来两条数据 //一致性分析,导致查询出来两条数据
@@ -1032,9 +1045,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{ {
Id = NewId.NextSequentialGuid(), Id = NewId.NextSequentialGuid(),
TrialId = info.TrialId, TrialId = info.TrialId,
SubjectId=inQuery.SubjectId, SubjectId = inQuery.SubjectId,
SubjectCode = inQuery.SubjectCode, SubjectCode = inQuery.SubjectCode,
TrialSiteCode= trialSiteCode, TrialSiteCode = trialSiteCode,
IP = _userInfo.IP, IP = _userInfo.IP,
DownloadStartTime = DateTime.Now, DownloadStartTime = DateTime.Now,
IsSuccess = false, IsSuccess = false,
@@ -1129,9 +1142,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var query = _trialImageDownloadRepository.Where(t => t.TrialId == inQuery.TrialId) var query = _trialImageDownloadRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(inQuery.SubjectCode.IsNotNullOrEmpty(), t => t.SubjectCode.Contains(inQuery.SubjectCode)) .WhereIf(inQuery.SubjectCode.IsNotNullOrEmpty(), t => t.SubjectCode.Contains(inQuery.SubjectCode))
.WhereIf(inQuery.IP.IsNotNullOrEmpty(), t => t.IP.Contains(inQuery.IP)) .WhereIf(inQuery.IP.IsNotNullOrEmpty(), t => t.IP.Contains(inQuery.IP))
.WhereIf(inQuery.Name.IsNotNullOrEmpty(), t => t.CreateUser.UserName.Contains(inQuery.Name) || t.CreateUser.FullName.Contains(inQuery.Name)) .WhereIf(inQuery.Name.IsNotNullOrEmpty(), t => t.CreateUserRole.IdentityUser.UserName.Contains(inQuery.Name) || t.CreateUserRole.FullName.Contains(inQuery.Name))
.WhereIf(inQuery.ImageType != null, t => t.ImageType == inQuery.ImageType) .WhereIf(inQuery.ImageType != null, t => t.ImageType == inQuery.ImageType)
.WhereIf(inQuery.UserType != null, t => t.CreateUser.UserTypeEnum == inQuery.UserType) .WhereIf(inQuery.UserType != null, t => t.CreateUserRole.UserTypeEnum == inQuery.UserType)
.WhereIf(inQuery.IsSuccess != null, t => t.IsSuccess == inQuery.IsSuccess) .WhereIf(inQuery.IsSuccess != null, t => t.IsSuccess == inQuery.IsSuccess)
.WhereIf(inQuery.DownloadStartTime != null, t => t.DownloadStartTime >= inQuery.DownloadStartTime) .WhereIf(inQuery.DownloadStartTime != null, t => t.DownloadStartTime >= inQuery.DownloadStartTime)
.WhereIf(inQuery.DownloadEndTime != null, t => t.DownloadEndTime <= inQuery.DownloadEndTime) .WhereIf(inQuery.DownloadEndTime != null, t => t.DownloadEndTime <= inQuery.DownloadEndTime)
@@ -1538,7 +1551,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
public async Task<List<SubjectUploadTaskInfo>> GetIRUploadTaskList_Old(CRCUploadTaskQuery inQuery) public async Task<List<SubjectUploadTaskInfo>> GetIRUploadTaskList_Old(CRCUploadTaskQuery inQuery)
{ {
var query = _visitTaskRepository.Where(t => t.SubjectId == inQuery.SubjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId var query = _visitTaskRepository.Where(t => t.SubjectId == inQuery.SubjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId
&& t.SourceSubjectVisitId != null && t.DoctorUserId == _userInfo.Id && t.TaskState == TaskState.Effect) && t.SourceSubjectVisitId != null && t.DoctorUserId == _userInfo.UserRoleId && t.TaskState == TaskState.Effect)
.ProjectTo<SubjectUploadTaskInfo>(_mapper.ConfigurationProvider); .ProjectTo<SubjectUploadTaskInfo>(_mapper.ConfigurationProvider);
@@ -102,18 +102,13 @@ namespace IRaCIS.Core.Application.Services
var resource = new ResourceInfo() var resource = new ResourceInfo()
{ {
StudyId = imageShare.StudyId, StudyId = imageShare.StudyId,
Token = _tokenService.GetToken(IRaCISClaims.Create(new UserBasicInfo() Token = _tokenService.GetToken(new UserTokenInfo()
{ {
Id = Guid.Empty, IdentityUserId = Guid.NewGuid(),
IsReviewer = false, FullName = "Share001",
IsAdmin = false,
RealName = "Share001",
UserName = "Share001", UserName = "Share001",
Sex = 0,
//UserType = "ShareType",
UserTypeEnum = UserTypeEnum.ShareImage, UserTypeEnum = UserTypeEnum.ShareImage,
Code = "ShareCode001", })
}))
}; };
@@ -19,13 +19,19 @@ namespace IRaCIS.Core.Application.Services
[HttpGet("{seriesId:guid}")] [HttpGet("{seriesId:guid}")]
public async Task<IResponseOutput<List<DicomInstanceDTO>>> List(Guid seriesId) public async Task<IResponseOutput<List<DicomInstanceDTO>>> List(Guid seriesId)
{ {
var list = await _instanceRepository.Where(s => s.SeriesId == seriesId)/*.OrderBy(s => s.SliceLocation)*/.OrderBy(s => s.InstanceNumber). var qcAuditState = await _instanceRepository.Where(s => s.SeriesId == seriesId).Select(t => t.DicomStudy.SubjectVisit.AuditState).FirstOrDefaultAsync();
ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
//质控通过以后,过滤删除的 质控之前的不过滤
var isQCFinished = qcAuditState == AuditStateEnum.QCPassed;
var list = await _instanceRepository.Where(s => s.SeriesId == seriesId).IgnoreQueryFilters()
.WhereIf(isQCFinished, t => t.IsDeleted == false)
.OrderBy(s => s.InstanceNumber).ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
.ProjectTo<DicomInstanceDTO>(_mapper.ConfigurationProvider).ToListAsync(); .ProjectTo<DicomInstanceDTO>(_mapper.ConfigurationProvider).ToListAsync();
var imageResizePath = await _instanceRepository.Where(s => s.SeriesId == seriesId).Select(t => t.DicomSerie.ImageResizePath).FirstOrDefaultAsync(); var seriesInfo = await _instanceRepository.Where(s => s.SeriesId == seriesId).Select(t => new { t.DicomSerie.ImageResizePath,t.DicomSerie.IsDeleted,t.DicomSerie.IsReading }).FirstOrDefaultAsync();
return ResponseOutput.Ok(list, new { ImageResizePath = imageResizePath }); return ResponseOutput.Ok(list, seriesInfo);
} }
@@ -4,9 +4,11 @@
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//-------------------------------------------------------------------- //--------------------------------------------------------------------
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using Medallion.Threading; using Medallion.Threading;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NPOI.SS.Formula.Functions;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace IRaCIS.Core.Application.Contracts namespace IRaCIS.Core.Application.Contracts
@@ -27,38 +29,54 @@ namespace IRaCIS.Core.Application.Contracts
[HttpGet] [HttpGet]
public async Task<List<NoneDicomStudyView>> GetNoneDicomStudyList( public async Task<IResponseOutput<List<NoneDicomStudyView>>> GetNoneDicomStudyList(
[FromQuery, NotDefault] Guid subjectVisitId, [FromQuery, NotDefault] Guid subjectVisitId,
[FromQuery] Guid? nonedicomStudyId, [FromQuery] Guid? nonedicomStudyId,
[FromQuery] bool isFilterZip, [FromQuery] bool isFilterZip,
[FromQuery] Guid? visitTaskId) [FromQuery] Guid? visitTaskId,
[FromQuery] bool isReading)
{ {
var qcAuditState = await _subjectVisitRepository.Where(s => s.Id == subjectVisitId).Select(t => t.AuditState).FirstOrDefaultAsync();
//质控过程中,因为会修改统计数字,但是此时其他人看,应该看到完整的影像
var isQCFinished = qcAuditState == AuditStateEnum.QCPassed;
//质控过程中并且不是IQC时,可以看到删除的(不需要忽略过滤器) 质控中iqc 也需要看到删除的
var isViewDelete = !isQCFinished;
IQueryable<NoneDicomStudyView> noneDicomStudyQueryable = default; IQueryable<NoneDicomStudyView> noneDicomStudyQueryable = default;
if (visitTaskId == null) if (visitTaskId == null)
{ {
noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId).WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) //质控过程中,需要忽略过滤质控设置删除的检查,以及设置删除的文件,质控通过后才
noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId, ignoreQueryFilters: isViewDelete)
.WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId)
.WhereIf(isReading, t => t.IsReading && t.IsDeleted==false)
.ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip });
.ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, isReading= isReading });
} }
else else
{ {
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(t => new { t.BlindSubjectCode, t.TrialReadingCriterionId, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync(); var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(t => new { t.BlindSubjectCode, t.TrialReadingCriterionId, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync();
noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.TaskNoneDicomFileList.Any(t => t.VisitTaskId == visitTaskId)) noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.TaskNoneDicomFileList.Any(t => t.VisitTaskId == visitTaskId), ignoreQueryFilters: isViewDelete)
.WhereIf(isReading, t => t.IsReading && t.IsDeleted == false)
.Where(t => taskinfo.IsImageFilter ? ("|" + taskinfo.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true) .Where(t => taskinfo.IsImageFilter ? ("|" + taskinfo.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true)
.WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) .WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId)
.ProjectTo<TaskDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, visiTaskId = visitTaskId }); .ProjectTo<TaskDicomStudyView>(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, visiTaskId = visitTaskId, isReading = isReading });
} }
return await noneDicomStudyQueryable.ToListAsync(); var list = await noneDicomStudyQueryable.OrderBy(x => x.ImageDate).ThenBy(x => x.CreateTime).ToListAsync();
var config = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => new { t.Trial.ImageFormatList, t.Trial.StudyNameList, t.Trial.IsShowStudyName, AuditState = qcAuditState }).FirstOrDefaultAsync();
return ResponseOutput.Ok(list, config);
} }
[UnitOfWork] [UnitOfWork]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput<NoneDicomStudyAddReturnDto>> AddOrUpdateNoneDicomStudy(NoneDicomStudyAddOrEdit addOrEditNoneDicomStudy) public async Task<IResponseOutput<NoneDicomStudyAddReturnDto>> AddOrUpdateNoneDicomStudy(NoneDicomStudyAddOrEdit addOrEditNoneDicomStudy)
{ {
@@ -70,6 +88,8 @@ namespace IRaCIS.Core.Application.Contracts
} }
NoneDicomStudy? optEntity = null; NoneDicomStudy? optEntity = null;
var @lock = _distributedLockProvider.CreateLock($"NoneDicomCode"); var @lock = _distributedLockProvider.CreateLock($"NoneDicomCode");
@@ -80,11 +100,14 @@ namespace IRaCIS.Core.Application.Contracts
//默认会是0 //默认会是0
var code = await _noneDicomStudyRepository.Where(t => t.TrialId == addOrEditNoneDicomStudy.TrialId).Select(x => x.Code).DefaultIfEmpty().MaxAsync(); var code = await _noneDicomStudyRepository.Where(t => t.TrialId == addOrEditNoneDicomStudy.TrialId).Select(x => x.Code).DefaultIfEmpty().MaxAsync();
addOrEditNoneDicomStudy.Code = code + 1;
optEntity = await _noneDicomStudyRepository.InsertFromDTOAsync(addOrEditNoneDicomStudy); optEntity = await _noneDicomStudyRepository.InsertFromDTOAsync(addOrEditNoneDicomStudy);
optEntity.Code = code + 1;
optEntity.StudyCode = AppSettings.GetCodeStr(optEntity.Code, nameof(NoneDicomStudy)); optEntity.StudyCode = AppSettings.GetCodeStr(optEntity.Code, nameof(NoneDicomStudy));
} }
else else
{ {
@@ -105,7 +128,7 @@ namespace IRaCIS.Core.Application.Contracts
} }
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[HttpDelete("{trialId:guid}/{subjectVisitId:guid}/{noneDicomStudyId:guid}")] [HttpDelete("{trialId:guid}/{subjectVisitId:guid}/{noneDicomStudyId:guid}")]
public async Task<IResponseOutput> DeleteNoneDicomStudy(Guid noneDicomStudyId, Guid subjectVisitId) public async Task<IResponseOutput> DeleteNoneDicomStudy(Guid noneDicomStudyId, Guid subjectVisitId)
{ {
@@ -128,7 +151,7 @@ namespace IRaCIS.Core.Application.Contracts
[HttpDelete("{trialId:guid}/{subjectVisitId:guid}/{noneDicomStudyFileId:guid}")] [HttpDelete("{trialId:guid}/{subjectVisitId:guid}/{noneDicomStudyFileId:guid}")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> DeleteNoneDicomStudyFile(Guid noneDicomStudyFileId, Guid subjectVisitId) public async Task<IResponseOutput> DeleteNoneDicomStudyFile(Guid noneDicomStudyFileId, Guid subjectVisitId)
{ {
//提交了 但是IQC同意的时候 是可以删除的 | 普通提交后也不能删除 //提交了 但是IQC同意的时候 是可以删除的 | 普通提交后也不能删除
@@ -154,18 +177,35 @@ namespace IRaCIS.Core.Application.Contracts
[HttpGet("{noneDicomStudyId:guid}")] [HttpGet("{noneDicomStudyId:guid}")]
public async Task<List<NoneDicomStudyFileView>> GetNoneDicomStudyFileList(Guid noneDicomStudyId) public async Task<List<NoneDicomStudyFileView>> GetNoneDicomStudyFileList(Guid noneDicomStudyId)
{ {
return await _noneDicomStudyFileRepository.Where(t => t.NoneDicomStudyId == noneDicomStudyId) var qcAuditState = await _noneDicomStudyFileRepository.Where(t => t.NoneDicomStudyId == noneDicomStudyId).Select(t => t.NoneDicomStudy.SubjectVisit.AuditState).FirstOrDefaultAsync();
.ProjectTo<NoneDicomStudyFileView>(_mapper.ConfigurationProvider).ToListAsync();
//质控过程中,因为会修改统计数字,但是此时其他人看,应该看到完整的影像
var isQCFinished = qcAuditState == AuditStateEnum.QCPassed;
//质控过程中并且不是IQC时,可以看到删除的(不需要忽略过滤器)
var isViewDelete = !isQCFinished;
return await _noneDicomStudyFileRepository.Where(t => t.NoneDicomStudyId == noneDicomStudyId, ignoreQueryFilters: isViewDelete)
.ProjectTo<NoneDicomStudyFileView>(_mapper.ConfigurationProvider).OrderBy(t => t.CreateTime).ToListAsync();
} }
[HttpGet("{subjectVisitId:guid}")] [HttpGet("{subjectVisitId:guid}")]
public async Task<List<NoneDicomStudyFileView>> GetVisitNoneDicomStudyFileList(Guid subjectVisitId) public async Task<List<NoneDicomStudyFileView>> GetVisitNoneDicomStudyFileList(Guid subjectVisitId)
{ {
return await _noneDicomStudyFileRepository.Where(t => t.NoneDicomStudy.SubjectVisitId == subjectVisitId) var qcAuditState = await _subjectVisitRepository.Where(s => s.Id == subjectVisitId).Select(t => t.AuditState).FirstOrDefaultAsync();
//质控过程中,因为会修改统计数字,但是此时其他人看,应该看到完整的影像
var isQCFinished = qcAuditState == AuditStateEnum.QCPassed;
//质控过程中并且不是IQC时, 不需要忽略过滤器+质控设置删除的
var isViewDelete = !isQCFinished;
return await _noneDicomStudyFileRepository.Where(t => t.NoneDicomStudy.SubjectVisitId == subjectVisitId, ignoreQueryFilters: isViewDelete)
.ProjectTo<NoneDicomStudyFileView>(_mapper.ConfigurationProvider).ToListAsync(); .ProjectTo<NoneDicomStudyFileView>(_mapper.ConfigurationProvider).ToListAsync();
} }
} }
} }
@@ -22,14 +22,25 @@ namespace IRaCIS.Core.Application.Services
[HttpGet, Route("{studyId:guid}")] [HttpGet, Route("{studyId:guid}")]
public async Task<IResponseOutput<List<DicomSeriesDTO>>> List(Guid studyId) public async Task<IResponseOutput<List<DicomSeriesDTO>>> List(Guid studyId)
{ {
//质控的时候,要标记序列,和instance 删除 ,所以要返回全部,但是 质控通过后,pm 进去看的时候要看过滤后的
var seriesList = await _seriesRepository.Where(s => s.StudyId == studyId).OrderBy(s => s.SeriesNumber). var qcAuditState = await _seriesRepository.Where(s => s.StudyId == studyId).Select(t => t.DicomStudy.SubjectVisit.AuditState).FirstOrDefaultAsync();
ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime)
//质控通过以后,预览过滤删除的 质控之前的不过滤
var isQCFinished = qcAuditState == AuditStateEnum.QCPassed;
//断点
var seriesList = await _seriesRepository.Where(s => s.StudyId == studyId).IgnoreQueryFilters()
.WhereIf(isQCFinished, t => t.IsDeleted == false)
.OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime)
.ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync(); .ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();
var instanceList = await _instanceRepository.Where(s => s.StudyId == studyId).OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber) var instanceList = await _instanceRepository.Where(s => s.StudyId == studyId).IgnoreQueryFilters()
.ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime) .WhereIf(isQCFinished, t => t.IsDeleted == false)
.Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber, t.HtmlPath }).ToListAsync();//.GroupBy(u => u.SeriesId); .OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber)
.ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
.Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber, t.HtmlPath, t.IsReading, t.IsDeleted }).ToListAsync();//.GroupBy(u => u.SeriesId);
foreach (var series in seriesList) foreach (var series in seriesList)
{ {
@@ -42,8 +53,12 @@ namespace IRaCIS.Core.Application.Services
HtmlPath = k.HtmlPath, HtmlPath = k.HtmlPath,
Path = k.Path, Path = k.Path,
InstanceNumber = k.InstanceNumber, InstanceNumber = k.InstanceNumber,
IsReading = k.IsReading,
IsDeleted = k.IsDeleted
}).ToList(); }).ToList();
series.InstanceCount = series.InstanceInfoList.Count;
} }
#region #region
@@ -65,7 +65,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
} }
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> PreArchiveDicomStudy(PreArchiveDicomStudyCommand preArchiveStudyCommand) public async Task<IResponseOutput> PreArchiveDicomStudy(PreArchiveDicomStudyCommand preArchiveStudyCommand)
{ {
@@ -99,20 +99,20 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
if (visitTaskId != null) if (visitTaskId != null)
{ {
var cacheValue = _fusionCache.GetOrDefault<Guid>(CacheKeys.TrialTaskStudyUidUploading(trialId, visitTaskId.Value, studyInstanceUid)); var cacheValue = _fusionCache.GetOrDefault<Guid>(CacheKeys.TrialTaskStudyUidUploading(trialId, visitTaskId.Value, studyInstanceUid));
if (cacheValue != Guid.Empty && cacheValue != _userInfo.Id) if (cacheValue != Guid.Empty && cacheValue != _userInfo.UserRoleId)
{ {
//---当前已有人正在上传和归档该检查! //---当前已有人正在上传和归档该检查!
return ResponseOutput.NotOk(I18n.T("UploadDownLoad_ArchiveInProgress")); return ResponseOutput.NotOk(I18n.T("UploadDownLoad_ArchiveInProgress"));
} }
else else
{ {
await _fusionCache.SetAsync(CacheKeys.TrialTaskStudyUidUploading(trialId, visitTaskId.Value, studyInstanceUid), _userInfo.Id, TimeSpan.FromSeconds(15)); await _fusionCache.SetAsync(CacheKeys.TrialTaskStudyUidUploading(trialId, visitTaskId.Value, studyInstanceUid), _userInfo.UserRoleId, TimeSpan.FromSeconds(15));
} }
} }
else else
{ {
await _fusionCache.SetAsync(CacheKeys.TrialStudyUidUploading(trialId, studyInstanceUid), _userInfo.Id, TimeSpan.FromSeconds(15)); await _fusionCache.SetAsync(CacheKeys.TrialStudyUidUploading(trialId, studyInstanceUid), _userInfo.UserRoleId, TimeSpan.FromSeconds(15));
} }
@@ -122,7 +122,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> AddOrUpdateArchiveStudy(NewArchiveStudyCommand incommand) public async Task<IResponseOutput> AddOrUpdateArchiveStudy(NewArchiveStudyCommand incommand)
{ {
@@ -139,7 +139,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
else else
{ {
//在事务未完成前 防止前端重复提交 //在事务未完成前 防止前端重复提交
await _fusionCache.SetAsync(CacheKeys.TrialStudyUidDBLock(incommand.TrialId, incommand.Study.StudyInstanceUid), _userInfo.Id, TimeSpan.FromMinutes(3)); await _fusionCache.SetAsync(CacheKeys.TrialStudyUidDBLock(incommand.TrialId, incommand.Study.StudyInstanceUid), _userInfo.UserRoleId, TimeSpan.FromMinutes(3));
} }
} }
@@ -254,6 +254,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
} }
} }
findStudy = addStudy;
} }
else else
{ {
@@ -321,6 +323,20 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
} }
#region
//项目配置的影像部位
var trialBodyParts = _trialRepository.Where(t => t.Id == trialId).Select(t => t.BodyPartTypes).FirstOrDefault();
var trialBodyPartList = trialBodyParts.Split('|', StringSplitOptions.RemoveEmptyEntries);
if (trialBodyPartList.Count() == 1)
{
var first = trialBodyPartList.First();
findStudy.BodyPartForEdit = first;
}
#endregion
var @lock2 = _distributedLockProvider.CreateLock($"StudyCommit"); var @lock2 = _distributedLockProvider.CreateLock($"StudyCommit");
using (await @lock2.AcquireAsync()) using (await @lock2.AcquireAsync())
@@ -357,7 +373,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var svExpression = QCCommon.GetDicomStudySubjectVisitFilter(inQuery.VisitPlanArray); var svExpression = QCCommon.GetDicomStudySubjectVisitFilter(inQuery.VisitPlanArray);
var dicomStudyQuery = _dicomStudyRepository.Where(t => t.TrialId == inQuery.TrialId) var dicomStudyQuery = _dicomStudyRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.Subject.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.Subject.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.UserRoleId))
//.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) //.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo))
.WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression) .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectInfo), t => t.Subject.Code.Contains(inQuery.SubjectInfo)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectInfo), t => t.Subject.Code.Contains(inQuery.SubjectInfo))
@@ -394,7 +410,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
TrialSiteCode = t.Subject.TrialSite.TrialSiteCode, TrialSiteCode = t.Subject.TrialSite.TrialSiteCode,
Uploader = t.CreateUser.UserName, Uploader = t.CreateUserRole.IdentityUser.UserName,
UploadTime = t.CreateTime UploadTime = t.CreateTime
@@ -406,7 +422,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var nodeDicomStudyQuery = _noneDicomStudyRepository.Where(t => t.TrialId == inQuery.TrialId) var nodeDicomStudyQuery = _noneDicomStudyRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.Subject.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.Subject.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.UserRoleId))
//.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) //.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo))
.WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression2) .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression2)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectInfo), t => t.Subject.Code.Contains(inQuery.SubjectInfo)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectInfo), t => t.Subject.Code.Contains(inQuery.SubjectInfo))
@@ -444,7 +460,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
TrialSiteCode = t.Subject.TrialSite.TrialSiteCode, TrialSiteCode = t.Subject.TrialSite.TrialSiteCode,
Uploader = t.CreateUser.UserName, Uploader = t.CreateUserRole.IdentityUser.UserName,
UploadTime = t.CreateTime UploadTime = t.CreateTime
@@ -468,7 +484,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{ {
var svExpression = QCCommon.GetStudyMonitorSubjectVisitFilter(inQuery.VisitPlanArray); var svExpression = QCCommon.GetStudyMonitorSubjectVisitFilter(inQuery.VisitPlanArray);
var StudyMonitorQuery = _studyMonitorRepository.Where(t => t.TrialId == inQuery.TrialId, ignoreQueryFilters: true) var StudyMonitorQuery = _studyMonitorRepository.Where(t => t.TrialId == inQuery.TrialId, ignoreQueryFilters: true)
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.Subject.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.Subject.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.UserRoleId))
//.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) //.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo))
.WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression) .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectInfo), t => t.Subject.Code.Contains(inQuery.SubjectInfo)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectInfo), t => t.Subject.Code.Contains(inQuery.SubjectInfo))
@@ -476,7 +492,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
.WhereIf(inQuery.SubjectVisitId != null, t => t.SubjectId == inQuery.SubjectVisitId) .WhereIf(inQuery.SubjectVisitId != null, t => t.SubjectId == inQuery.SubjectVisitId)
.WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.IsDicom != null, t => t.IsDicom == inQuery.IsDicom) .WhereIf(inQuery.IsDicom != null, t => t.IsDicom == inQuery.IsDicom)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.Uploader), t => t.CreateUser.UserName.Contains(inQuery.Uploader)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Uploader), t => t.CreateUserRole.IdentityUser.UserName.Contains(inQuery.Uploader))
.WhereIf(inQuery.IsSuccess != null, t => t.IsSuccess == inQuery.IsSuccess) .WhereIf(inQuery.IsSuccess != null, t => t.IsSuccess == inQuery.IsSuccess)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.StudyCode), t => t.StudyCode.Contains(inQuery.StudyCode)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.StudyCode), t => t.StudyCode.Contains(inQuery.StudyCode))
.WhereIf(inQuery.UploadStartTime != null, t => t.UploadStartTime >= inQuery.UploadStartTime) .WhereIf(inQuery.UploadStartTime != null, t => t.UploadStartTime >= inQuery.UploadStartTime)
@@ -499,7 +515,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
TrialSiteCode = t.Subject.TrialSite.TrialSiteCode, TrialSiteCode = t.Subject.TrialSite.TrialSiteCode,
Uploader = t.CreateUser.UserName, Uploader = t.CreateUserRole.IdentityUser.UserName,
UploadTime = t.CreateTime, UploadTime = t.CreateTime,
@@ -615,7 +631,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
public async Task<IResponseOutput<List<VerifyStudyUploadResult>>> VerifyTaskStudyAllowUploadAsync(VerifyTaskUploadOrReupload verifyInfo) public async Task<IResponseOutput<List<VerifyStudyUploadResult>>> VerifyTaskStudyAllowUploadAsync(VerifyTaskUploadOrReupload verifyInfo)
{ {
var queryStudy = _visitTaskRepository.Where(t => t.SubjectId == verifyInfo.SubjectId && t.SourceSubjectVisitId != null && t.DoctorUserId == _userInfo.Id).Select(u => new var queryStudy = _visitTaskRepository.Where(t => t.SubjectId == verifyInfo.SubjectId && t.SourceSubjectVisitId != null && t.DoctorUserId == _userInfo.UserRoleId).Select(u => new
{ {
VisitTaskId = u.Id, VisitTaskId = u.Id,
SourceSubjectVisitId = u.SourceSubjectVisitId, SourceSubjectVisitId = u.SourceSubjectVisitId,
@@ -654,7 +670,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var result = new VerifyStudyUploadResult(); var result = new VerifyStudyUploadResult();
if (_fusionCache.GetOrDefault<Guid>($"StudyUid_{trialId}_{studyInstanceUid}") != _userInfo.Id) if (_fusionCache.GetOrDefault<Guid>($"StudyUid_{trialId}_{studyInstanceUid}") != _userInfo.UserRoleId)
{ {
result.AllowUpload = false; result.AllowUpload = false;
@@ -704,7 +720,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{ {
if (result.AllowReUpload || result.AllowUpload) if (result.AllowReUpload || result.AllowUpload)
{ {
await _fusionCache.SetAsync($"StudyUid_{trialId}_{studyInstanceUid}", _userInfo.Id, TimeSpan.FromSeconds(30)); await _fusionCache.SetAsync($"StudyUid_{trialId}_{studyInstanceUid}", _userInfo.UserRoleId, TimeSpan.FromSeconds(30));
} }
else else
@@ -800,7 +816,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var result = new VerifyStudyUploadResult(); var result = new VerifyStudyUploadResult();
if (cacheUserId.GetValueOrDefault() != _userInfo.Id && cacheUserId.HasValue) if (cacheUserId.GetValueOrDefault() != _userInfo.UserRoleId && cacheUserId.HasValue)
{ {
result.AllowUpload = false; result.AllowUpload = false;
@@ -869,7 +885,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{ {
if (result.AllowReUpload || result.AllowUpload) if (result.AllowReUpload || result.AllowUpload)
{ {
_fusionCache.Set(CacheKeys.TrialStudyUidUploading(trialId, studyInstanceUid), _userInfo.Id, TimeSpan.FromSeconds(30)); _fusionCache.Set(CacheKeys.TrialStudyUidUploading(trialId, studyInstanceUid), _userInfo.UserRoleId, TimeSpan.FromSeconds(30));
} }
else else
{ {

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