Compare commits

..

661 Commits

Author SHA1 Message Date
hang 845c532134 [修改subject 查询 不依赖系统site] 2024-01-31 11:04:36 +08:00
hang 8615c90ebe 【修改 查询写入dicom的信息】 2024-01-31 11:04:29 +08:00
hang 88f015183d [赋值study code dicom]
continuous-integration/drone/push Build is passing
2024-01-26 12:36:42 +08:00
hang 4f9560c3a6 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-26 11:11:59 +08:00
hang 9abb78400a [site搜索三个名字] 2024-01-26 09:41:03 +08:00
he 8f5e2c5b0c 添加LimitShow 限制显示
continuous-integration/drone/push Build is passing
2024-01-25 16:03:35 +08:00
he efe96203d9 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-25 16:00:35 +08:00
hang 65de94079a Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-25 15:52:57 +08:00
hang 6e706c4fc9 [上传监控增加字段] 2024-01-25 15:52:31 +08:00
hang 84e2e14b73 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-24 14:20:22 +08:00
hang 49d4a71f36 [修改回退] 2024-01-24 14:20:20 +08:00
hang 7dcf73176c 去掉内存缓存
continuous-integration/drone/push Build is passing
2024-01-24 12:28:33 +08:00
hang f9bf9d752c 测试
continuous-integration/drone/push Build is passing
2024-01-24 12:20:38 +08:00
hang acac7ec995 升级net8 准备
continuous-integration/drone/push Build is passing
2024-01-24 12:17:02 +08:00
hang 6cfcb9bfe1 修改测试
continuous-integration/drone/push Build is passing
2024-01-24 11:22:20 +08:00
hang 9adf2ad52b 请求前端国际化增加缓存-需要迁移 2024-01-24 11:21:47 +08:00
hang 403885ef3f 修改国际化取消权限限制 2024-01-24 11:21:43 +08:00
hang 7b1a0affbe 增加前端国际化修改 2024-01-24 11:21:32 +08:00
hang 85897f990d [邮件模板启用与否没用bug修复]
continuous-integration/drone/push Build is passing
2024-01-24 10:14:18 +08:00
hang be477818d7 [AWS 对接上传 需要传递文件大小] 2024-01-24 10:13:22 +08:00
hang 41bbb75407 [修改重传没有检查id] 2024-01-24 10:13:13 +08:00
hang fd9fdcb8be [修改医生bug 和site bug] 2024-01-24 10:13:06 +08:00
hang 0e8ecdaf46 [上传失败过,返回标志] 2024-01-24 10:12:22 +08:00
hang 81b033885e [上传监控增加字段] 2024-01-24 10:11:06 +08:00
hang fca2a81c66 [遗漏 get set] 2024-01-24 10:10:59 +08:00
hang 353f5df217 [修改上传,失败数量传递不准问题] 2024-01-24 10:10:54 +08:00
hang 4874533804 [增加默认值] 2024-01-24 10:10:48 +08:00
hang 025a8e7af1 [上传增加稽查字段]迁移 2024-01-24 10:10:40 +08:00
hang 79c5824051 统一日志记录信息 2024-01-24 10:08:32 +08:00
hang 2c47842e13 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study 2024-01-24 10:03:24 +08:00
hang 39d9cefda9 [上传监控修改,增加搜索条件] 2024-01-24 09:58:51 +08:00
hang 2c0d1cdc82 [邮件模板启用与否没用bug修复] 2024-01-24 09:55:22 +08:00
hang af77d5be56 修改邮件模板
continuous-integration/drone/push Build is passing
2024-01-22 11:09:19 +08:00
he f662a988e0 修改 2024-01-16 10:27:48 +08:00
hang b9cace17b2 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-15 16:10:46 +08:00
hang c8d0ef9043 修改study 配置文件 2024-01-15 16:10:44 +08:00
hang 2491fd1fff 请求前端国际化增加缓存-需要迁移 2024-01-11 18:03:25 +08:00
hang 7cc9731edf 修改国际化取消权限限制 2024-01-11 18:03:21 +08:00
hang ff333219d4 增加前端国际化修改 2024-01-11 18:03:16 +08:00
hang 0eae520f0d 适配AWS 和MinIO
continuous-integration/drone/push Build is passing
2024-01-11 17:59:49 +08:00
hang 0a2513245c 升级net8 模型要求严格了 2024-01-05 17:09:25 +08:00
hang f10cc0adbf 修改稽查上传文件路径
continuous-integration/drone/push Build is passing
2024-01-05 12:56:26 +08:00
hang 58b2f9c7a9 修改配置文件
continuous-integration/drone/push Build is passing
2024-01-05 12:40:13 +08:00
hang 472e744b6c 修改生产数据库
continuous-integration/drone/push Build is passing
2024-01-05 12:27:11 +08:00
hang 699df338c1 修改待阅列表 临床数据未签名但是可以做后续访视,生成任务逻辑遗漏
continuous-integration/drone/push Build is passing
2024-01-04 15:20:00 +08:00
hang a64127537e Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-04 12:16:39 +08:00
hang 2287c8869d 修改导表错误 2024-01-04 12:16:31 +08:00
he 0d8319feaa 代码修改
continuous-integration/drone/push Build is passing
2024-01-03 17:28:15 +08:00
he 676c5b0e74 再次修改
continuous-integration/drone/push Build is passing
2024-01-03 17:17:33 +08:00
he a76654c210 修改状态
continuous-integration/drone/push Build is passing
2024-01-03 17:08:39 +08:00
he 0a29d431dc 修改状态
continuous-integration/drone/push Build is passing
2024-01-03 16:58:43 +08:00
he 86562b39e3 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-03 16:47:51 +08:00
he 86fe43aa93 代码修改 修改阅片状态 2024-01-03 16:47:49 +08:00
hang 082998da09 修改监控导出
continuous-integration/drone/push Build is passing
2024-01-03 15:39:43 +08:00
hang d209a8de4d 修改中心调研导表
continuous-integration/drone/push Build is passing
2024-01-03 15:26:40 +08:00
he b1608812ec Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-03 14:24:57 +08:00
he 20c18d957a 阅片状态修改 2024-01-03 14:24:55 +08:00
hang 7a7011e7ef 打开文件修改监控
continuous-integration/drone/push Build is passing
2024-01-03 13:43:31 +08:00
hang 24a395f8c8 增加真实名字
continuous-integration/drone/push Build is passing
2024-01-03 13:42:01 +08:00
hang df2f179917 xx
continuous-integration/drone/push Build is passing
2024-01-03 13:39:17 +08:00
hang 1bcc831937 不监测修改
continuous-integration/drone/push Build is passing
2024-01-03 13:32:03 +08:00
hang 75bf85997a 禁止热更新
continuous-integration/drone/push Build is passing
2024-01-03 13:20:27 +08:00
hang 074cba906c xx
continuous-integration/drone/push Build is passing
2024-01-03 13:18:11 +08:00
hang 86db676df8 必须在镜像里面修改
continuous-integration/drone/push Build is passing
2024-01-03 13:12:36 +08:00
hang bc67f16735 docker 部署方式解决
continuous-integration/drone/push Build is passing
2024-01-03 12:13:47 +08:00
hang 3e046e24e9 增加上传人
continuous-integration/drone/push Build is passing
2024-01-03 11:43:04 +08:00
hang c971161d31 修改utf-8
continuous-integration/drone/push Build is passing
2024-01-03 11:19:07 +08:00
hang a63904c0bb 暂时屏蔽
continuous-integration/drone/push Build is passing
2024-01-03 11:11:57 +08:00
hang 572d4ea4b8 修改docker-compose 文件打开文件修改跟踪
continuous-integration/drone/push Build is passing
2024-01-03 11:05:19 +08:00
hang ae4345cfcc x 监控文件错误 测试
continuous-integration/drone/push Build is passing
2024-01-03 10:06:30 +08:00
hang a536c33302 自动打包修改
continuous-integration/drone/push Build is passing
2024-01-03 09:29:07 +08:00
hang be5c9b636e 修改国际化邮件代码 2024-01-03 09:23:55 +08:00
hang c71bf65cd9 系统签名文档废除
continuous-integration/drone/push Build encountered an error
2023-12-29 17:36:08 +08:00
he 69c5ce9841 代码统计修改 查询数量 2023-12-29 17:36:00 +08:00
hang 2139193df4 清理裁判任务Id
continuous-integration/drone/push Build encountered an error
2023-12-29 17:35:11 +08:00
he 9aa2f23a67 修改代码 需要发study
continuous-integration/drone/push Build encountered an error
2023-12-28 13:25:02 +08:00
he 531e0fa228 计算小数位修改 需要同步study 2023-12-28 13:24:35 +08:00
hang 250c478687 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build encountered an error
2023-12-27 11:13:29 +08:00
hang 09ba37ec6d 修改测试环境数据库地址 2023-12-27 11:13:27 +08:00
hang 913b673b72 迁移修改
continuous-integration/drone/push Build is passing
2023-12-23 11:30:15 +08:00
hang 5ee8a3db21 迁移修改数据库连接地址
continuous-integration/drone/push Build is failing
2023-12-22 18:01:29 +08:00
hang 3c41789ba9 修改导表 5 2023-12-20 16:44:40 +08:00
hang d2268f0706 裁判任务失效的时候,清理裁判任务id 需要迁移 2023-12-20 16:44:36 +08:00
hang e8496df81a 修改模板文件位置 4 2023-12-20 16:43:49 +08:00
hang 3e24fe9461 修改路径bug 3 2023-12-20 16:43:45 +08:00
hang d771ab0f6f 修改文档删除2 2023-12-20 16:43:39 +08:00
hang 29dfa03d0f 修改导表时间格式2 2023-12-20 16:43:34 +08:00
hang 44e9b211c2 更新模板的时候,清理之前的文档,需要迁移 2023-12-20 16:43:29 +08:00
hang b1154ea594 修改导表时间格式 2023-12-20 16:43:25 +08:00
he 6dd12b419b 临床数据查询修改
continuous-integration/drone/push Build is passing
2023-12-13 09:57:18 +08:00
he bce7c1cc99 临床数据查询修改
continuous-integration/drone/push Build is failing
2023-12-13 09:51:24 +08:00
he a660eb4f37 临床数据修改 2023-12-13 09:51:17 +08:00
he 3ade13a922 临床数据修改
continuous-integration/drone/push Build is passing
2023-12-13 09:47:51 +08:00
he a5fed78c19 临床数据修改 2023-12-13 09:47:18 +08:00
he 5207fef130 医学审核加是否有临床数据 2023-12-13 09:47:07 +08:00
he b8ad8085cd Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-12-13 09:45:48 +08:00
hang dc8451f55c windows linux 环境路径修改 迁移
continuous-integration/drone/push Build is passing
2023-12-08 12:45:02 +08:00
hang dd9ec3d8fe 用户登录国际化
continuous-integration/drone/push Build is passing
2023-12-08 09:01:06 +08:00
hang 589cd83576 修改编码格式
continuous-integration/drone/push Build is passing
2023-12-07 10:27:59 +08:00
hang 6c2a1e0a4b 修改文件格式
continuous-integration/drone/push Build is passing
2023-12-07 10:02:32 +08:00
hang 7a927b3133 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-12-06 17:14:13 +08:00
hang 3dbf6dc897 修改为utf8 测试 2023-12-06 17:14:11 +08:00
he bb5401f78c 代码修改
continuous-integration/drone/push Build is passing
2023-12-06 16:55:49 +08:00
he 59e9d9df69 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-12-06 16:53:56 +08:00
hang 9a70193e7a hospital修改 需要迁移
continuous-integration/drone/push Build is passing
2023-12-06 16:12:59 +08:00
hang b44a9ecc63 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-12-06 11:48:25 +08:00
hang fb45173106 修改trigger 注入服务异常 2023-12-06 11:47:46 +08:00
hang bf2996bd1c 修改合并bug
continuous-integration/drone/push Build is passing
2023-12-05 17:33:28 +08:00
hang d840f14a2f x
continuous-integration/drone/push Build is passing
2023-12-05 16:11:24 +08:00
hang 4101c68d37 修改国际化
continuous-integration/drone/push Build is passing
2023-12-05 14:56:45 +08:00
hang 91503dc599 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study 2023-12-05 14:53:09 +08:00
hang debe22fdc3 清理无用的文件 2023-12-05 14:41:00 +08:00
hang 8f4f9a91c2 修改一致性核查国际化
continuous-integration/drone/push Build is passing
2023-12-05 13:59:21 +08:00
hang a53e306427 修改调研表 增加SR
continuous-integration/drone/push Build is passing
2023-12-05 11:03:58 +08:00
hang 02183affc3 修改study 生成用户类型
continuous-integration/drone/push Build is passing
2023-12-05 10:50:45 +08:00
hang e81c97037a 修改 验证 和生产配置文件
continuous-integration/drone/push Build is passing
2023-12-04 17:07:58 +08:00
hang 1fd02cbbc5 修改后端上传OSS 解析
continuous-integration/drone/push Build is passing
2023-12-04 15:32:25 +08:00
hang 55cbbffba6 oss 直接返回secret
continuous-integration/drone/push Build is passing
2023-12-04 11:35:34 +08:00
hang 4a1bf759cf OSS 大写改为小写 2023-12-04 11:31:22 +08:00
hang 703ab03b7f 阿里云临时token改为直接返回token和秘钥 2023-12-04 11:29:42 +08:00
he 0582390b2c 代码修改
continuous-integration/drone/push Build is passing
2023-12-04 09:27:43 +08:00
he cdf1119764 缓存时间修改 需要同步 2023-12-04 09:27:32 +08:00
hang 72cb407766 删除无用的服务
continuous-integration/drone/push Build is passing
2023-12-01 14:15:20 +08:00
hang 9f80386a19 修改警告4 2023-12-01 14:13:22 +08:00
hang 3a96710210 修改警告7 2023-12-01 14:12:45 +08:00
hang b8b63e33b8 修改警告6 2023-12-01 14:12:05 +08:00
hang 98d09886de 修改警告5 2023-12-01 14:11:10 +08:00
hang 91671c5003 修改警告4 2023-12-01 14:09:56 +08:00
hang 35ef014391 修改警告4 2023-12-01 14:07:43 +08:00
hang 82fc9bfc75 警告修改2 2023-12-01 14:05:31 +08:00
hang d6d47a6f85 修改警告 1 2023-12-01 14:03:22 +08:00
hang 32d6cce33e 服务循环依赖
continuous-integration/drone/push Build is passing
2023-12-01 13:59:28 +08:00
hang 06ca624886 x
continuous-integration/drone/push Build is passing
2023-11-30 15:29:59 +08:00
hang 88231fffb4 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-11-30 15:29:11 +08:00
hang 12ab0d3eb4 合并代码修改 2023-11-30 15:29:09 +08:00
hang 6faeecebb0 修改统计,需要迁移 2023-11-30 15:13:15 +08:00
hang 48b778c95a linux 下适配 转换pdf 2023-11-30 15:13:09 +08:00
hang dee286cc90 验证环境发布 2023-11-30 15:09:53 +08:00
hang 2e96f7a936 日志提示当前部署平台 2023-11-30 15:07:52 +08:00
he ebb33f45ba 临床数据修改
continuous-integration/drone/push Build is passing
2023-11-30 15:00:04 +08:00
he 9d32be658c Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-11-30 14:24:33 +08:00
he 27fd819c9c 临床数据维护 2023-11-30 14:24:12 +08:00
he 937f8a5b66 临床数据问题修改 2023-11-30 14:24:09 +08:00
hang 53544001a7 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-11-28 13:25:20 +08:00
hang f08cd1c818 1127 稽查修改 2023-11-28 13:24:34 +08:00
hang 2c377d02f9 中心调研修改 需要迁移 2023-11-28 13:23:03 +08:00
hang 29f8648287 修改OSS 配置
continuous-integration/drone/push Build is passing
2023-11-24 14:47:12 +08:00
hang f0725873e1 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-11-24 11:25:17 +08:00
hang dc12e57494 迁移提交 2023-11-24 11:25:15 +08:00
hang d4a731d544 OSS 稽查修改 ,新增健康检查
continuous-integration/drone/push Build is passing
2023-11-24 11:23:39 +08:00
hang 6e22515603 迁移修改
continuous-integration/drone/push Build is passing
2023-11-24 09:51:50 +08:00
hang abd5c8942d 上传文件到OSS 需要迁移 2023-11-24 09:37:12 +08:00
hang 3decef7693 修改统计bug,医学审核增加最新回复人 2023-11-24 09:29:30 +08:00
hang ae83c753cb 统计排序 03
continuous-integration/drone/push Build is failing
2023-11-24 09:20:29 +08:00
hang 53ae0527ff 修改稽查和界面统计 需要迁移02 2023-11-24 09:20:21 +08:00
hang a234e0746d 修改重阅稽查 2023-11-24 09:18:20 +08:00
hang c88d927c4b 稽查修改 2023-11-24 09:18:04 +08:00
hang 245898e22e 医学审核稽查修改 2023-11-24 09:16:41 +08:00
he 93d3024b0f 修改
continuous-integration/drone/push Build is passing
2023-11-21 13:12:31 +08:00
he 35be7f3144 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2023-11-21 13:11:57 +08:00
hang 62ac9418b5 修改统计bug,
continuous-integration/drone/push Build is passing
2023-11-21 11:13:56 +08:00
hang ea5de83364 修改统计03 -需迁移 2023-11-21 11:13:00 +08:00
hang cf5a8b20e4 CRC 影像质疑 2023-11-21 11:12:55 +08:00
hang ea95ece331 修改页面查询结果显示 2023-11-21 11:12:51 +08:00
hang 894b9eb67b Merge branch 'Test.Study' of http://192.168.3.69:2000/XCKJ/irc-netcore-api into Test.Study 2023-11-08 18:28:02 +08:00
hang d7e5b3f57c 没有建议完成时间 2023-11-08 18:27:58 +08:00
hang 29a47e7351 修改邮件 2023-11-08 16:43:52 +08:00
he 6d2cddfcfc 修改 2023-11-08 16:07:31 +08:00
he 60b2978deb Merge branch 'Test.Study' of http://192.168.3.69:2000/XCKJ/irc-netcore-api into Test.Study 2023-11-08 16:06:30 +08:00
hang 79187772a6 Merge branch 'Test.Study' of http://192.168.3.69:2000/XCKJ/irc-netcore-api into Test.Study 2023-11-07 11:59:56 +08:00
hang 105da818a8 修改删除 2023-11-07 11:59:19 +08:00
hang 584516f936 修改项目列表 2023-11-07 11:46:47 +08:00
hang a7429c1739 通用文档下载 2023-11-06 13:58:34 +08:00
hang 75f227e547 增加权限 2023-11-06 13:39:30 +08:00
hang 60c31b470c 导表bug 2023-11-06 13:32:06 +08:00
hang 731f049fc0 修改国际化,导表,增加查看角色类型 2023-11-06 13:10:13 +08:00
hang 201c24238c 权限增加 2023-11-06 11:14:41 +08:00
hang 71e28f1a37 x 2023-11-03 15:44:39 +08:00
he 375e50bab7 Merge branch 'Test.Study' of http://192.168.3.69:2000/XCKJ/irc-netcore-api into Test.Study 2023-11-03 12:27:57 +08:00
he 39e2651edf 修改 2023-11-03 12:27:54 +08:00
hang b461216d87 修改配置文件 2023-11-03 12:15:13 +08:00
he dc6ae39130 修改 2023-11-03 09:55:05 +08:00
he 4b65f1e922 Merge branch 'Test.Study' of http://192.168.3.69:2000/XCKJ/irc-netcore-api into Test.Study 2023-11-03 09:51:44 +08:00
hang 99439a4809 容器真实ip 2023-11-02 15:53:09 +08:00
hang 419d5de7f1 admin 项目列表查看 2023-11-02 10:06:53 +08:00
hang a56ffaee58 admin 可以看到项目列表 2023-11-01 13:21:17 +08:00
hang e925d5bdb2 x 2023-11-01 11:18:53 +08:00
hang 9ec97f7d37 拷贝病灶修改 2023-10-31 15:21:35 +08:00
hang 3c532389d9 项目默认邮件配置 2023-10-30 16:20:33 +08:00
hang 1094f318f9 预留项目配置系统邮件配置 2023-10-30 16:13:26 +08:00
hang 56f261b8ce 拷贝表单屏蔽 2023-10-30 15:26:59 +08:00
hang 34b12b89e4 访视拷贝表单测试 2023-10-30 14:43:36 +08:00
hang bca8f2ddb9 数据库保存异常提示 2023-10-18 10:41:20 +08:00
hang 4023a59097 Merge branch 'Test.Study' of http://192.168.3.69:2000/XCKJ/irc-netcore-api into Test.Study 2023-10-16 09:21:59 +08:00
hang 8afcbf3d5e 打开分布式锁 2023-10-16 09:21:58 +08:00
hang 69c2cd339c 打开分布式锁 2023-10-16 09:20:44 +08:00
hang 4c7ce217da nuget 包确认 2023-10-13 23:38:04 +08:00
hang d66209452c 升级EF core 7 2023-10-13 22:48:00 +08:00
hang 77352245fc 测试 升级nuget包ok 2023-10-13 22:38:28 +08:00
hang 17ebdce96e 移除废弃的包 2023-10-13 22:17:11 +08:00
hang 3962178c68 efcore 6 升级到6版本最新,同时EFCore.BulkExtensions 也是6版本最新,但是projectable 不能升级 2023-10-13 21:28:10 +08:00
hang 7c6dcbbe38 回退包,查询临时方案 2023-10-13 18:02:33 +08:00
hang 75ed6375c2 修改nuget包位置 2023-10-13 11:53:52 +08:00
hang 290578d824 删除没用的文件 2023-10-13 11:34:55 +08:00
hang cd2f5aa1e1 Merge branch 'Test.Study' of http://192.168.3.69:2000/XCKJ/irc-netcore-api into Test.Study 2023-10-13 11:27:21 +08:00
hang 79d150829a EntityFrameworkCore.Projectables 包问题 导致更新出错 2023-10-13 11:21:21 +08:00
hang 270de86658 批量删除修改 2023-10-12 17:28:34 +08:00
hang edefc8f3e7 修改nuget 2023-10-12 15:16:52 +08:00
hang f1b3ec7d7c 更新nuget 2023-10-12 14:20:03 +08:00
hang 5171af975d nuget 包升级,清理没用的包,预备net8 2023-10-12 14:07:33 +08:00
hang 33b9113993 nuget 包升级,清理没用的包,预备net8 2023-10-12 14:03:30 +08:00
he a53626b66c 修改缓存 2023-10-12 13:56:39 +08:00
hang a27dcd6399 升级efcore 清理之前的写法 2023-10-12 13:31:52 +08:00
hang 14908c4eed 分布式锁 sqlserver 05 项目迁移修改 2023-10-12 09:34:09 +08:00
hang dfef88d663 分布式锁 sqlserver 测试 04 增加日志 2023-10-11 17:44:13 +08:00
hang 1afe020e83 分布式锁 sqlserver 测试 03 2023-10-11 17:38:34 +08:00
hang 7544e0c2e9 引入分布式组件 redis 2023-10-11 16:29:57 +08:00
hang 68d72fce53 引入 EasyCaching redis 准备工作完毕 2023-10-11 13:16:57 +08:00
hang 423f2fcb7c 修改PI 审核 2023-10-07 10:55:04 +08:00
hang 92b715de3a Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-10-07 10:53:28 +08:00
hang 912bc2edb8 修改pi 审核 2023-10-07 10:53:26 +08:00
hang a5f6c24aec 修改pi 审核 2023-10-07 10:49:20 +08:00
hang 8fc886a1db 修改异常提示 2023-09-28 11:37:49 +08:00
hang 5832610d3d x 2023-09-27 13:19:52 +08:00
hang e675542136 x 2023-09-27 13:19:30 +08:00
hang 8f7a3ab713 删除表 2023-09-27 11:42:10 +08:00
hang 02d98cfa75 x 2023-09-26 15:31:38 +08:00
hang 8bb1e8cf43 x 2023-09-26 14:20:35 +08:00
hang b3e37c7ea4 测试oss 改为1分钟 2023-09-26 14:13:07 +08:00
he 5bdb89df7d 维护临床数据 2023-09-26 11:25:21 +08:00
hang 10d50f3b5a 修改 2023-09-26 11:23:45 +08:00
hang bb6d36c8be 修改site 2023-09-25 17:25:59 +08:00
hang d91f4dc728 CRA 签名权限 以及Site 列表 2023-09-25 16:58:33 +08:00
hang f01e5335d6 增加地址 2023-09-22 15:32:26 +08:00
hang 3e8794b335 邮件发送 2023-09-22 15:23:42 +08:00
hang 79375f7106 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-22 15:22:35 +08:00
hang 72b2047862 修改site 查询 2023-09-22 15:22:29 +08:00
he 8b124e1c60 关键序列修改 2023-09-21 13:14:02 +08:00
he 5b2449b607 预览新增ParentTriggerValueList
RelevanceValueList 字段
2023-09-21 11:43:22 +08:00
he 3f4a5e3040 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-21 11:41:57 +08:00
hang 75a24b8aef Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-19 13:38:22 +08:00
hang 493c46ed15 修改数据库配置 2023-09-19 13:38:20 +08:00
he 5c2467bdbb Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-19 11:19:53 +08:00
he 0777ea830c 修改端口 2023-09-19 11:19:46 +08:00
hang b75223f8a0 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-18 11:42:15 +08:00
hang 6a4e42f9dc 修改cookie 测试 2023-09-18 11:42:14 +08:00
he f7eec6327a 两个问题bug修改 2023-09-18 10:24:42 +08:00
he 1a4301233c 临床数据排序 自定义标准关键序列 2023-09-18 10:16:26 +08:00
he b6b5a5d0de Revert "添加问题分类字段"
This reverts commit da9a7affa9.
2023-09-14 15:45:32 +08:00
he 92c435cf23 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-14 15:45:13 +08:00
hang 8697ec952c Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-14 14:17:16 +08:00
hang c6d3ae7c8b VisitBaseDataDes 遗漏 2023-09-14 14:17:13 +08:00
he 376c02f44c Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-14 14:02:34 +08:00
he da9a7affa9 添加问题分类字段 2023-09-14 14:02:23 +08:00
hang ac62f48a71 给默认值 2023-09-14 11:44:15 +08:00
hang 3d8cdd6ac6 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-14 10:37:14 +08:00
hang 9380b40c28 增加访视基准日期说明 2023-09-14 10:37:11 +08:00
he cc823daee5 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-13 14:08:24 +08:00
he b4594a4c47 获取下一个质控任务 2023-09-13 14:08:22 +08:00
hang c8660c0426 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-12 10:36:19 +08:00
hang 375a724169 修改邮件 2023-09-12 10:36:06 +08:00
he 67375c3cbd 去掉doctor筛选 2023-09-07 17:59:52 +08:00
he 1645aaf69a Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-07 17:39:05 +08:00
hang 99b7d3a4f8 x 2023-09-07 14:32:21 +08:00
hang eac77e45d2 x 2023-09-07 14:22:09 +08:00
hang ebf05df568 修改下拉框 2023-09-07 14:21:38 +08:00
hang f464b25c2b 修改下拉框 2023-09-07 14:20:50 +08:00
hang b0dbe1442c 修改json 2023-09-07 10:27:51 +08:00
hang 5ae3220e67 修改稽查查询 2023-09-06 14:39:31 +08:00
hang f31a6408ac 修改已阅片任务 2023-09-06 11:06:49 +08:00
hang 9234e7ebe9 x 2023-09-05 15:52:49 +08:00
hang 609a7fb427 修改配置 2023-09-05 13:38:34 +08:00
hang a92bbbb275 x 2023-09-05 13:17:32 +08:00
hang c2bf16e1ff 稽查查询 2023-09-05 11:49:35 +08:00
hang dce2509613 oss 2023-09-05 11:11:57 +08:00
hang 1ac336220e oss 权限修改 2023-09-05 10:45:01 +08:00
hang a47f2fd496 x 2023-09-04 17:25:42 +08:00
hang 45c0704b40 修改邮件发送逻辑 2023-09-04 17:23:03 +08:00
hang 97cf5ce93c 邮件用户名修改 2023-09-04 16:35:26 +08:00
hang 786367f9fe x 2023-09-04 16:31:17 +08:00
hang f8c9cb1564 x 2023-09-04 16:20:22 +08:00
hang ee11290037 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-04 16:05:38 +08:00
hang 42f3f6fb67 修改PI 审核发送邮件 2023-09-04 16:05:35 +08:00
he 2a844b11bd Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-04 15:47:28 +08:00
hang 5579fe4e95 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-04 09:21:36 +08:00
hang ee96435379 object 参数会必传 2023-09-04 09:21:34 +08:00
he 4fce96db0e 代码修改 2023-09-04 09:21:01 +08:00
he 14e7ecd171 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-04 09:13:26 +08:00
hang ffeece79fe 修改中心查询 2023-09-01 17:36:04 +08:00
hang 5c86989dfa x 2023-09-01 17:18:28 +08:00
hang c6a8c4d24f Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-01 15:53:18 +08:00
hang 477691ec70 修改中心 2023-09-01 15:53:17 +08:00
he 5518609d54 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-09-01 15:47:02 +08:00
he 9f706d3123 临床数据表格问题添加依赖父问题 2023-09-01 15:46:56 +08:00
hang 5956d32c36 修改中心 2023-09-01 15:45:20 +08:00
hang a60e00159d 邮件发送翻译 2023-09-01 15:16:25 +08:00
hang 47277086ac xx 2023-09-01 14:29:54 +08:00
hang c7571570e9 x 2023-09-01 14:23:16 +08:00
hang 83d6859347 修改问题 2023-09-01 14:19:39 +08:00
hang a42986dcab 修改 2023-09-01 14:10:45 +08:00
hang 13fbf36de0 修改查询 2023-09-01 14:00:54 +08:00
hang 4ba2aa4769 修改PI 审核 2023-09-01 11:54:52 +08:00
hang 6b1a6a81eb 修改邮件--034 2023-09-01 10:35:13 +08:00
hang 62f8d5823f 调研表 2023-08-31 17:00:01 +08:00
hang 5cbefec0b0 修改提示 2023-08-31 16:33:34 +08:00
hang b154540885 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-08-31 16:20:50 +08:00
hang 9eda07b253 修改启动 2023-08-31 16:20:47 +08:00
he 2995d2273a Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-08-31 16:14:06 +08:00
he 8fffdb244d oos 上传 2023-08-31 16:14:00 +08:00
hang 657da0c554 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-08-31 16:04:21 +08:00
hang 1912e1cfcd 一致性核查文件名修改 2023-08-31 16:04:19 +08:00
he 3313c0223d Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-08-31 15:46:31 +08:00
hang 3c9b87ba01 修改上传bug 2023-08-31 13:30:39 +08:00
hang 65b52a1836 修改稽查 2023-08-31 10:10:29 +08:00
hang 684dbbd8e1 修改日志查询 2023-08-31 10:10:22 +08:00
hang 5a3127bb8e x 2023-08-30 16:42:45 +08:00
hang 0b9cf600ba 加 看内存缓存数据接口 2023-08-30 16:34:24 +08:00
hang b2f4fa3fb9 修改邮件--033 2023-08-30 15:14:08 +08:00
hang ecae4f663a 修改邮件--032 2023-08-30 15:08:38 +08:00
he 200da3375b Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-08-30 14:45:30 +08:00
he a3cedaa7b8 OSS上传 2023-08-30 14:45:25 +08:00
hang 37fc48c64d Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-08-30 14:40:17 +08:00
hang 1e4ee0a5e9 修改邮件--031 2023-08-30 14:40:13 +08:00
he bc383d9b23 OOS上传 2023-08-30 11:11:22 +08:00
he 27634b5aac Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-08-30 11:10:47 +08:00
he 2d479a15ec OOS 上传 2023-08-30 11:10:37 +08:00
hang a719ca752f 调研表--30 2023-08-29 17:47:08 +08:00
hang 089e329e4c Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-08-29 17:33:49 +08:00
hang b84abaa0a9 修改医学审核 2023-08-29 17:33:46 +08:00
he 6f4d85ea2b Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-08-29 16:54:48 +08:00
he 0f47a14e69 国际化修改 2023-08-29 16:54:38 +08:00
hang 788c24a6f3 修改邮件发送和稽查 2023-08-29 14:31:11 +08:00
hang a6c0bc7a21 Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-08-28 18:05:43 +08:00
hang 661140ebf8 邮件发送逻辑修改--029 项目邮件配置增加是否启用 2023-08-28 18:05:40 +08:00
he 9692ae569e Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-08-28 14:09:10 +08:00
he f6d46bcf12 国际化修改 2023-08-28 14:09:08 +08:00
he 595635d93d 国际化修改 2023-08-28 14:08:23 +08:00
hang 89d92baf56 邮件发送逻辑修改--028 2023-08-25 19:21:43 +08:00
hang 995605a2b6 邮件修改 2023-08-25 18:59:11 +08:00
hang 749c123229 x 2023-08-25 18:50:05 +08:00
hang f24f60cdef 修改映射 2023-08-25 18:46:58 +08:00
hang 451ffec65b 邮件发送逻辑修改--028 2023-08-25 18:36:27 +08:00
hang 033ac555f2 邮件发送逻辑修改--027 2023-08-25 18:05:01 +08:00
hang 14b57769d3 中心调研--026 2023-08-25 17:27:20 +08:00
hang 7c5b1b6fd1 x 2023-08-25 17:26:58 +08:00
hang 14bc9f4429 修改邮件发送枚举--026 2023-08-25 17:16:09 +08:00
hang b72b13509b xx 2023-08-25 11:25:26 +08:00
hang daaf4540a4 修改邮件发送枚举--025 2023-08-25 10:28:43 +08:00
hang eee828ca46 hangfire授权--025 2023-08-25 09:56:23 +08:00
hang a084a6b49b 测试路径 2023-08-24 16:36:47 +08:00
hang 1676056e43 测试路径 2023-08-24 16:04:58 +08:00
hang a601cf3ef8 虚拟路径测试 2023-08-24 15:34:38 +08:00
hang 3a7ddab1f3 修改访问路径 2023-08-24 15:23:42 +08:00
hang d1634d0813 继续测试 2023-08-24 14:55:49 +08:00
hang 31ccf4cefa x 2023-08-24 14:44:26 +08:00
hang f528b7ff5e 访问路径测试 2023-08-24 14:38:31 +08:00
hang d48333e71e 项目邮件配置修改--024 2023-08-24 13:09:28 +08:00
hang 7c0c096be4 项目邮件配置修改--023 2023-08-24 11:38:51 +08:00
hang b23befe18c x 2023-08-24 11:38:37 +08:00
hang ea48a57f95 x 2023-08-23 18:20:26 +08:00
hang c7faf920db 项目邮件配置修改--022 2023-08-23 18:12:58 +08:00
hang 6f722a43f5 修改定时任务 2023-08-23 18:06:07 +08:00
hang cbe66ac397 项目邮件配置修改--021 2023-08-23 17:54:48 +08:00
hang 0006f12151 修改定时任务 2023-08-23 17:49:06 +08:00
hang 8a3db78cd0 项目邮件配置修改--020 2023-08-23 17:48:56 +08:00
hang 3dfe229024 项目邮件配置修改--019 2023-08-23 17:46:31 +08:00
hang a8e4d6285d 项目邮件配置修改--018 修改邮件查询条件 2023-08-23 10:48:41 +08:00
hang bfe82bd322 修改发送邮件的方式test 2023-08-23 10:46:02 +08:00
hang e0ebd083b9 临床数据质询 增加新的表和回复接口 2023-08-23 09:46:59 +08:00
hang 6c6b18818a 项目邮件配置修改--017 2023-08-23 09:46:29 +08:00
hang 4338481f9f 项目邮件配置修改--016 2023-08-22 17:12:41 +08:00
hang e05f43b0b8 项目邮件配置修改--015 2023-08-22 14:54:30 +08:00
hang a4e26f9895 项目邮件配置修改--014 2023-08-22 14:14:31 +08:00
hang bc1e39450d 项目邮件配置修改--013 2023-08-22 13:31:40 +08:00
hang 87aa2cd8da 项目邮件配置修改--012 2023-08-22 11:07:01 +08:00
hang 9fa9896f0a 项目邮件配置修改--011 2023-08-22 11:06:16 +08:00
hang c4c034f2bb 修改字典表bug 2023-08-22 10:38:23 +08:00
hang aaed933eb9 项目邮件配置修改--010 2023-08-22 10:36:08 +08:00
hang c7b541dec6 项目邮件配置修改--009 2023-08-21 17:30:08 +08:00
hang e24933f0dd 项目邮件配置修改--008 2023-08-21 17:18:17 +08:00
hang e46b51d6a1 项目邮件配置修改--007 2023-08-21 16:15:44 +08:00
hang f3f00e3d0f Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study 2023-08-21 15:47:04 +08:00
hang 5a71e3eb25 系统邮件配置预先修改-005 2023-08-21 15:47:02 +08:00
hang d9b108553a 系统邮件配置预先修改-004 2023-08-21 15:43:07 +08:00
hang b9a99cef90 修改名称 2023-08-21 15:41:42 +08:00
hang 2f366b55d9 系统邮件配置预先修改-003 2023-08-21 15:34:18 +08:00
hang 13263cf39c 系统邮件配置预先修改-002 2023-08-21 15:28:26 +08:00
hang e03e93b0f5 修改上传路径 2023-08-21 15:13:56 +08:00
hang d62d1f2047 修改上传 2023-08-21 15:04:42 +08:00
hang ca3f3b6f9d 系统邮件配置预先修改-001 2023-08-21 15:04:30 +08:00
hang 96e1a2c393 修改中心调研,引入hangfire 2023-08-18 17:55:43 +08:00
hang b6403580de 修改退出改为加入 2023-08-18 14:44:36 +08:00
hang 8c5cca7ba5 修改中心调研限制条件 2023-08-18 13:19:51 +08:00
hang 4200daa1b9 修改调研表 2023-08-18 10:27:49 +08:00
hang 1a5cfa8bbd 修改废除状态 2023-08-18 09:23:35 +08:00
hang c371c4b127 OK 2023-08-18 08:57:39 +08:00
hang bd8123af59 修改调研表限制 2023-08-18 08:56:57 +08:00
hang 00cb2fc67c 修改调研表限制 2023-08-18 08:56:44 +08:00
hang ea157cdb71 修改调研表查询和提交 2023-08-17 18:07:34 +08:00
hang aa343ade2e xx 2023-08-17 17:11:02 +08:00
hang 536e9ef262 修改更新后的状态 2023-08-17 16:44:55 +08:00
hang d200f12fa8 修改人员状态变更 2023-08-17 16:42:05 +08:00
hang c85bb7f22b 修改调研验证提示 2023-08-17 16:21:34 +08:00
hang d575d8ac73 修改中心调研拷贝数据逻辑错误 2023-08-17 15:59:11 +08:00
hang 585b665b53 继续test 2023-08-17 15:17:06 +08:00
hang 8ffe69d38e 修改服务器时间,自动发布测试 2023-08-17 15:03:40 +08:00
hang 5e743b162d 提交中心调研 2023-08-17 14:54:44 +08:00
hang b9ccf4bb12 中心调研临时提交 2023-08-17 11:18:01 +08:00
hang 4bc2c3107a 前端限制查询配置增加 2023-08-16 13:10:51 +08:00
hang 008f5203c0 外部用户修改 2023-08-15 16:40:36 +08:00
hang 5d2acf44c1 修改中心调研 isJoin 2023-08-15 15:25:18 +08:00
hang c04d3a3fe4 修改PI 审核 2023-08-14 18:24:45 +08:00
hang 33ef76ad98 返回字段控制界面tab显示与否 2023-08-14 17:48:44 +08:00
hang c77cf1bf1e 废除的也可以看到调研信息 2023-08-10 17:44:10 +08:00
hang f9274c8fda 修改锁定废除 2023-08-10 17:21:32 +08:00
hang 5ae02e0d1f 修改调研查询trialId 2023-08-10 16:56:22 +08:00
hang dcdf03ca8e x 2023-08-10 16:40:01 +08:00
hang 775927c484 修改 Test.Study 2023-08-10 13:54:36 +08:00
hang bf230924d7 显示指定缓存发布尝试 2023-08-10 11:52:33 +08:00
hang d81fee17ba bat 执行一部分 测试时间 2023-08-10 11:36:28 +08:00
hang 0a398bd712 增加Test.IRC发布配置 2023-08-10 10:56:39 +08:00
hang a7d41772f7 ps 等待执行结束测试 2023-08-09 18:18:40 +08:00
hang 08754b9a24 尝试call 2023-08-09 18:15:25 +08:00
hang 133120e8c0 修改自动发布配置文件 2023-08-09 18:05:48 +08:00
hang ce3bfaeb5c 修改中心调研 2023-08-09 17:18:21 +08:00
hang 7e518bf3ab 修改中心调研 2023-08-08 14:53:07 +08:00
hang 106cbfacce 修改 参数可传与否 2023-08-08 13:14:38 +08:00
hang eb58745f19 增加Uat环境 2023-08-08 09:27:35 +08:00
hang cf0fa32101 Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-08-07 17:28:57 +08:00
hang d8894e92c0 修改邮件模板 2023-08-07 17:28:21 +08:00
he fc800672e1 代码修改 2023-08-07 16:44:32 +08:00
he 462ef4671e Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-08-07 16:31:46 +08:00
hang 212701fa8c 修改阅片任务 2023-08-07 14:57:27 +08:00
hang 75ccbe9bfb 删除多余的配置文件 2023-08-07 14:06:49 +08:00
hang 56e3bf64f2 任务阅片修改 2023-08-07 12:22:17 +08:00
hang 228254db09 调研表修改 2023-08-07 12:22:03 +08:00
hang 711c3f3639 修改退回 2023-08-03 13:53:42 +08:00
hang 5aa4c81c0d Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-08-03 11:49:08 +08:00
hang db9ce69594 修改引用包 2023-08-03 11:48:59 +08:00
he 891044eaf7 S-102 自定义标记 2023-08-03 10:53:13 +08:00
he 2e84fb8063 S-101 自定义标记 2023-08-03 10:52:40 +08:00
he d0e6f06f38 S-100 国际化修改 2023-08-03 10:52:14 +08:00
he 32a7fc3239 Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-08-03 10:51:11 +08:00
hang 29e4df9792 修改任务生成 2023-08-03 10:19:33 +08:00
hang 447bc6cb13 修改查询 2023-08-03 09:38:21 +08:00
hang dbb23132b3 修改instanceId 2023-08-01 13:02:41 +08:00
hang 179c283d75 修改DTO 2023-07-31 17:04:01 +08:00
hang 427cb38f39 修改非dicom 上传 2023-07-31 13:20:04 +08:00
hang ca9193438b Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-07-31 09:25:32 +08:00
hang d3d991cb3a 修改领取逻辑 2023-07-31 09:24:42 +08:00
he d8ea93dcd6 提示语言修改 2023-07-28 13:32:43 +08:00
he 3a649cfcfc S-99 临床数据 2023-07-27 16:04:58 +08:00
he 446d47167b Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-07-27 15:41:10 +08:00
he 7b10424238 修改 2023-07-27 15:40:46 +08:00
hang 9bfca25044 修改退回逻辑 2023-07-27 09:50:44 +08:00
hang 2bde5d1309 暂存修改 2023-07-27 09:38:41 +08:00
hang 93646d8f58 Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-07-27 09:23:23 +08:00
hang 9162f6ec99 删除没用的数据 2023-07-27 09:23:13 +08:00
he e413191bf4 S-98 时间修改 2023-07-26 11:14:42 +08:00
he 36cb770a86 S-97 添加分组 2023-07-26 11:01:25 +08:00
he 7a383a3fa5 Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-07-26 10:50:35 +08:00
he c9342b6ad1 S-96 添加时间 2023-07-26 10:50:14 +08:00
hang aadbc191a8 Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-07-25 18:06:24 +08:00
hang 4c9b46a20c 序列bug 2023-07-25 18:06:16 +08:00
he 0bde983ae9 Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-07-25 10:38:59 +08:00
he f55e295c01 添加映射 2023-07-25 10:38:37 +08:00
hang e06f564905 修改退回重阅片 2023-07-24 17:20:31 +08:00
he 1a64de066e 修改映射关系 2023-07-24 17:19:42 +08:00
he 53251e53a0 删除不要的功能 2023-07-24 14:40:31 +08:00
he f0cde942fb Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-07-24 13:30:44 +08:00
hang 7c9a07f384 Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-07-24 10:52:07 +08:00
hang 96b9d264a9 hang-清除工作量脏数据 2023-07-24 10:51:55 +08:00
he 0f3802474d 阅片关联去掉DoctorId 2023-07-24 10:12:24 +08:00
he f4c8d6c999 S-95 2023-07-21 15:56:27 +08:00
he fd25c99609 S-94 2023-07-21 15:56:22 +08:00
he 79da2c0adc S-93 2023-07-21 15:56:16 +08:00
he 7ec682668c S-92 2023-07-21 15:56:10 +08:00
he 93df8b81b7 S-91 2023-07-21 15:56:03 +08:00
he a089807bf0 S-90 2023-07-21 15:55:58 +08:00
he f97956c181 S-90 2023-07-21 15:55:53 +08:00
he 8bc59c53b6 S-89 2023-07-21 15:55:48 +08:00
he a136ed3f87 S-88 2023-07-21 15:55:42 +08:00
he d903e76d7a S-87 2023-07-21 15:55:37 +08:00
he ac1c0e6baa S-86 2023-07-21 15:55:32 +08:00
he e57617c305 S-85 2023-07-21 15:55:27 +08:00
he 4d307bc6fa S-84 2023-07-21 15:55:20 +08:00
he f3f3eb463b S-83 2023-07-21 15:55:12 +08:00
he a8232341dd S-82 2023-07-21 15:55:04 +08:00
he 4e2b03000d S-81 2023-07-21 15:54:56 +08:00
he 4e777e05db S-80 2023-07-21 15:54:49 +08:00
he 1f7fe0d854 S-79 2023-07-21 15:54:43 +08:00
he a58d7c9314 S-78 2023-07-21 15:54:37 +08:00
he 22d66ce856 S-77 2023-07-21 15:54:31 +08:00
he 546d7e7280 S-76 2023-07-21 15:54:25 +08:00
he 9f2d241d87 S-75 2023-07-21 15:54:19 +08:00
he bcdd8b7e2b S-74 2023-07-21 15:54:12 +08:00
he 11ad8f8d5f S-73 2023-07-21 15:54:04 +08:00
he 24b2067f50 S-72 2023-07-21 15:53:58 +08:00
he f85c51f7de S-71 2023-07-21 15:53:51 +08:00
he 449098ad72 S-70 2023-07-21 15:53:46 +08:00
he d8c1f9ee6f S-69 2023-07-21 15:53:42 +08:00
he 05bc298cfc S-68 2023-07-21 15:53:36 +08:00
he d03c405d54 S-67 2023-07-21 15:53:29 +08:00
he be786c2cbe S-66 同步 2023-07-21 15:53:23 +08:00
he 3a32825642 S-65 确认就同步标准 2023-07-21 15:53:17 +08:00
he 72e6bcc297 S-64 2023-07-21 15:53:12 +08:00
he 586000a98d S-63 2023-07-21 15:53:06 +08:00
he eae14095c0 S-62 2023-07-21 15:53:01 +08:00
he f7027d3fe6 S-61 2023-07-21 15:52:55 +08:00
he ca0a29b033 S-60 VisitHelper 任务临床状态维护 2023-07-21 15:52:50 +08:00
he 9e695dcfe8 S-59 2023-07-21 15:52:44 +08:00
he 4a8fd956ff S-58 2023-07-21 15:52:39 +08:00
he 284495700a S-57 2023-07-21 15:52:31 +08:00
he 1ba147009b S-56 2023-07-21 15:52:24 +08:00
he 2c541e68e1 S-55 2023-07-21 15:52:19 +08:00
he 95b39ea5e7 S-54 2023-07-21 15:52:12 +08:00
he 44e109cefa S-53 2023-07-21 15:52:05 +08:00
he 48763989d9 S-52 2023-07-21 15:52:00 +08:00
he f88bbee37b S-51 2023-07-21 15:51:55 +08:00
he fa3e1a6c35 S-50 2023-07-21 15:51:49 +08:00
he 6a5ce9aaa6 S-50 2023-07-21 15:51:43 +08:00
he bd7f840536 S-49 任务的临床状态维护 2023-07-21 15:51:35 +08:00
he 53fab12535 S-48 2023-07-21 15:51:30 +08:00
he 77745cfae6 S-47 2023-07-21 15:51:25 +08:00
he 73cb05956f S-46 2023-07-21 15:51:17 +08:00
he b3386c20ab S-45 2023-07-21 15:51:10 +08:00
he 83f419bff1 S-44 2023-07-21 15:50:55 +08:00
he c6a4a2dd0b S-43 2023-07-21 15:50:48 +08:00
he de3c59b7f5 S-42 2023-07-21 15:50:42 +08:00
he 28c89ce51d S-41 2023-07-21 15:50:36 +08:00
he a6fcf3421c S-40 2023-07-21 15:50:31 +08:00
he 2fcb2493d1 S-39 2023-07-21 15:50:25 +08:00
he 64b2b7850f S-38 2023-07-21 15:50:18 +08:00
he 429b53feba S-37 2023-07-21 15:50:11 +08:00
he a7042ba8a6 S-36 2023-07-21 15:50:05 +08:00
he f4c0413360 S-35 2023-07-21 15:49:57 +08:00
he 216b14663c S-34 2023-07-21 15:49:51 +08:00
he 895bda2e3f S-33 2023-07-21 15:49:45 +08:00
he 459866e924 S-32 2023-07-21 15:49:38 +08:00
he bdada76518 S-31 2023-07-21 15:49:33 +08:00
he 53129d2fcb S-30 2023-07-21 15:49:28 +08:00
he f174a555dd S-29 2023-07-21 15:49:23 +08:00
he 21da76f493 S-28 2023-07-21 15:49:17 +08:00
he 4d74de93ba S-27 2023-07-21 15:49:12 +08:00
he 92780b7152 S-26 2023-07-21 15:49:07 +08:00
he 0d73d19e44 S-25 2023-07-21 15:49:01 +08:00
he 689511a130 S-24 2023-07-21 15:48:55 +08:00
he d22d4d01c5 S-23 2023-07-21 15:48:49 +08:00
he fe691c2460 S-22 2023-07-21 15:48:44 +08:00
he f0d3c787d9 S-21 2023-07-21 15:48:37 +08:00
he 6b0945dc6f S-20 2023-07-21 15:48:31 +08:00
he d84358db3a S-19 2023-07-21 15:48:25 +08:00
he 5bb90e6f15 S-18 2023-07-21 15:48:18 +08:00
he 0840ac2c8b S-17 2023-07-21 15:48:13 +08:00
he 44a153ebb0 S-16 2023-07-21 15:48:07 +08:00
he 2214bdc1ad S-15 2023-07-21 15:45:38 +08:00
he c958e49118 S_014 2023-07-21 15:45:08 +08:00
he f7ae01ddc1 S-13 2023-07-21 15:44:56 +08:00
he 71b68f3354 修改 2023-07-21 15:44:49 +08:00
he a7e2e56175 S-011 2023-07-21 15:44:42 +08:00
he 7f4e82c27c S-010 2023-07-21 15:44:32 +08:00
he 6e2013f0c7 S-009 2023-07-21 15:44:26 +08:00
he 438e0947ac S-008 2023-07-21 15:44:19 +08:00
he 2e2d912aeb S-007 2023-07-21 15:44:13 +08:00
he 44d0f67e18 S-006 临床数据 2023-07-21 15:44:06 +08:00
he 22225dd841 修改 2023-07-21 15:43:53 +08:00
he 650d1e9647 S-004 临床数据 2023-07-21 15:43:42 +08:00
he 9265147e12 S-003 临床数据 2023-07-21 15:43:34 +08:00
he 8358d67f3e S-002 临床数据修改 2023-07-21 15:43:16 +08:00
he 2930c2b640 S-01临床数据 2023-07-21 15:32:08 +08:00
he 42e64d77cb Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-07-21 15:30:36 +08:00
hang 440fc103b1 修改医学审核返回字段 2023-07-21 08:48:59 +08:00
hang 128e3c747e 修改角色 2023-07-20 14:30:18 +08:00
hang a9439758c9 修改查询 2023-07-20 14:01:19 +08:00
hang 1247baaa36 修改未读任务查询 2023-07-20 13:43:25 +08:00
hang 59239060a6 修改中心调研 2023-07-20 11:41:56 +08:00
hang 42eae556e8 修改中心调研 2023-07-20 09:25:09 +08:00
hang a61b20ace6 修改PI 审核空数组 2023-07-19 16:38:13 +08:00
hang 9425fc521e 自动发送邮件代码屏蔽 2023-07-18 14:23:55 +08:00
hang 47c629f9a1 hang- 修改CRC 看到的检查列表 2023-07-18 11:14:20 +08:00
hang 11a669bf99 国际化修改 2023-07-17 14:26:02 +08:00
hang 366aba68ce 前端限制 界面显示,加字段 2023-07-17 10:41:46 +08:00
hang 2f5a4d5515 修改查询 2023-07-17 10:17:47 +08:00
hang f7c41d1b9a 修改中心调研 2023-07-14 13:39:15 +08:00
hang fbd24fd059 修改中心调研 2023-07-14 12:43:43 +08:00
hang cc6994e238 修改中心调研 2023-07-14 11:29:30 +08:00
hang 96c07f86b5 发送邮件修改 2023-07-14 09:30:16 +08:00
hang e502721d13 发布修改 2023-07-13 16:06:31 +08:00
hang a3b52dc9ff hang-用户登录日志 -04 2023-07-13 14:07:13 +08:00
hang e07fe76e39 修改任务 2023-07-13 14:06:56 +08:00
hang a4ee90ca5c hang-用户登录日志 -03 2023-07-13 11:29:16 +08:00
hang c016187498 hang-用户登录日志 -02 2023-07-13 11:12:05 +08:00
hang b0d74d31de hang - 用户登录日志修改-01 2023-07-13 10:49:09 +08:00
hang a85255b5fd PI 审核 2023-07-13 09:34:23 +08:00
hang 888dfbcafb 修改解决方案依赖 2023-07-12 15:07:04 +08:00
hang 5de4745303 发送邮件 2023-07-12 14:03:57 +08:00
hang 6883e3b5fa 修改查询 2023-07-12 13:18:24 +08:00
hang ef15b96f15 修改查询列表 2023-07-12 11:41:58 +08:00
hang 03810e0093 国际化 2023-07-12 09:03:50 +08:00
hang bbbc9da76e 修改审核 2023-07-11 16:23:08 +08:00
hang 11b4cf0351 PI 审核接口提交 2023-07-11 11:06:16 +08:00
hang 6df64d68af 修改中心调研 2023-07-11 09:58:09 +08:00
hang 3925fe74af 修改中心调研 2023-07-07 17:59:22 +08:00
hang edb48d8364 修改查询 2023-07-07 17:16:56 +08:00
hang 1d6b67658e 国际化修改 2023-07-07 16:24:37 +08:00
hang bcd1476d2d 修改阅片 2023-07-07 16:18:11 +08:00
hang d2251e4cb2 修改重阅列表 2023-07-07 11:21:38 +08:00
hang bd275539d1 修改定时任务 2023-07-06 16:39:39 +08:00
hang 6042909915 修改默认值 2023-07-06 16:03:24 +08:00
hang 38fc05e0d9 定时任务 2023-07-06 15:10:50 +08:00
hang 3ddbd59995 修改中心调研 2023-07-06 10:23:19 +08:00
hang 0a2a5bdd7a 修改查询条件 2023-07-05 14:39:50 +08:00
hang 088aa83fea 重阅跟踪修改 2023-07-05 14:36:43 +08:00
hang 0797b8b262 中心调研两个版本修改 2023-07-05 11:43:32 +08:00
hang 54a9db2acb 修改调研下拉框 2023-07-05 11:40:04 +08:00
hang e9f88a9c92 修改中心调研 2023-07-05 11:35:31 +08:00
hang 311d651ba7 修改用户类型筛选 2023-07-05 11:24:49 +08:00
hang 7789252f76 修改用户过滤 2023-07-05 10:47:17 +08:00
hang c58e96bce7 修改用户登录日志 2023-07-05 10:35:08 +08:00
hang 2a0ee12780 修改过滤查询 2023-07-05 10:27:26 +08:00
hang e7bc9168ae TA筛选人员,PM 根据标准筛选人员 2023-07-05 10:00:09 +08:00
he 98e5cb4979 修改 2023-07-05 09:37:50 +08:00
hang 6fc6829bc8 hang-S-002增加枚举,修改密码,重置密码,记录日志 2023-07-05 09:37:42 +08:00
hang 516f0fa1b4 hang_S_1_可逆加密算法增加 2023-07-05 09:37:37 +08:00
hang 6f556c45df 用户日志修改 2023-07-04 17:02:51 +08:00
hang e237d58906 修改用户类型 2023-07-04 15:53:38 +08:00
hang cc9807846e Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-07-04 15:04:54 +08:00
hang df7f9dbaeb 编译错误 2023-07-04 15:04:50 +08:00
he dee350742f 修改 2023-07-04 14:35:12 +08:00
he 735f9a9534 修改 2023-07-04 14:35:08 +08:00
he 859f10ee1f 修改 2023-07-04 14:35:06 +08:00
he a002eeed25 修改 2023-07-04 14:35:04 +08:00
he c9c5e5658f 修改 2023-07-04 14:35:01 +08:00
he edfcb53491 修改 2023-07-04 14:34:58 +08:00
he d158c13c7c 修改 2023-07-04 14:34:52 +08:00
he f2dc43b47f 修改 2023-07-04 14:34:47 +08:00
he e7cb246639 修改 2023-07-04 14:34:32 +08:00
he 19d109b3bf 修改 2023-07-04 14:33:46 +08:00
he b2fc4b9886 修改 2023-07-04 14:33:31 +08:00
he e6dd0f0abe 修改 2023-07-04 14:33:27 +08:00
he 6f4186ae07 修改 2023-07-04 14:33:26 +08:00
hang 44a3d03974 修改接口名字 2023-07-04 14:11:50 +08:00
hang 649f6897a4 Merge branch '中心影像_Test环境' of http://192.168.1.2:8033/IRaCIS_Core_Api into 中心影像_Test环境 2023-07-04 14:04:56 +08:00
hang 9edc30cef0 修改限制配置时间 2023-07-04 14:03:06 +08:00
he b0aaa2b791 修改 2023-07-04 13:58:24 +08:00
hang 108a4ee2bf 修改用户类型角色 2023-07-04 13:57:05 +08:00
hang 1083b80849 测试环境修改配置环境,同步中心影像测试 2023-07-04 13:48:05 +08:00
hang a2ff420f89 医学审核修改,暂时不让报错,需要修改之前的接口,待定 2023-07-04 13:34:16 +08:00
hang 5d718f7621 医学审核修改,暂时不让报错,需要修改之前的接口,待定 2023-07-04 13:32:17 +08:00
hang 63096d5919 测试挑拣 2023-07-03 17:13:07 +08:00
hang b80f1794e2 修改配置文件 2023-07-03 17:05:40 +08:00
hang 166c64798e 暂时不让统计报错 2023-07-03 16:58:37 +08:00
hang 150b51b327 修改阅片单元配置 2023-07-03 15:16:52 +08:00
hang 878e9541da 角色列表查询增加展示具体的枚举值 2023-07-03 14:01:18 +08:00
hang 8b416b113c 修改冲突 2023-07-03 13:58:09 +08:00
hang b8dd85c88f 新增配置,加字段,修改查询、编辑接口 2023-07-03 13:57:30 +08:00
hang 7098b15d0d 新增配置,加字段,修改查询、编辑接口 2023-07-03 13:56:51 +08:00
hang 1bd796cd94 项目表增加字段 2023-07-03 13:32:32 +08:00
hang cd41f8f060 模拟提交2 2023-07-03 11:34:43 +08:00
hang 2e117d6641 去掉添加修改项目里面写死的权限控制 2023-07-03 11:21:59 +08:00
hang 70513ff8b8 中心影像首次提交 2023-07-03 11:03:09 +08:00
490 changed files with 11076 additions and 39128 deletions
+1 -6
View File
@@ -22,9 +22,4 @@
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
!**/.gitignore
!.git/HEAD
!.git/config
!.git/packed-refs
!.git/refs/heads/**
README.md
+37 -5
View File
@@ -126,14 +126,46 @@ csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
# SA0001: XML comment analysis disabled
dotnet_diagnostic.SA0001.severity = suggestion
dotnet_diagnostic.CS1570.severity = none
dotnet_diagnostic.CS1587.severity = none
dotnet_diagnostic.CS8619.severity = none
dotnet_diagnostic.CS8620.severity = none
dotnet_diagnostic.CS8632.severity = none
# SA1002: Semicolons should be spaced correctly
dotnet_diagnostic.SA1002.severity = suggestion
# SA1005: Single line comments should begin with single space
dotnet_diagnostic.SA1005.severity = none
dotnet_diagnostic.CS8618.severity = none
dotnet_diagnostic.CS8604.severity = none
dotnet_diagnostic.CS8600.severity = none
dotnet_diagnostic.CS1570.severity = none
dotnet_diagnostic.CS8601.severity = none
dotnet_diagnostic.CS8632.severity = none
dotnet_diagnostic.CS8625.severity = none
dotnet_diagnostic.CS8603.severity = none
dotnet_diagnostic.CS8602.severity = none
dotnet_diagnostic.CS1998.severity = none
dotnet_diagnostic.CS0168.severity = none
dotnet_diagnostic.CS0219.severity = none
dotnet_diagnostic.CS0108.severity = none
dotnet_diagnostic.CS0120.severity = none
dotnet_diagnostic.CS8620.severity = none
dotnet_diagnostic.CS8619.severity = none
dotnet_diagnostic.CS0162.severity = none
dotnet_diagnostic.CS0472.severity = none
dotnet_diagnostic.CS8629.severity = none
dotnet_diagnostic.CS8073.severity = none
dotnet_diagnostic.CS0414.severity = none
dotnet_diagnostic.CS1573.severity = none
dotnet_diagnostic.CS0109.severity = none
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_top_level_statements = true:silent
dotnet_diagnostic.SA1003.severity = silent
dotnet_diagnostic.SA1108.severity = silent
dotnet_diagnostic.SA1107.severity = silent
[*.vb]
#### 命名样式 ####
+26
View File
@@ -0,0 +1,26 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["IRaCIS.Core.API/IRaCIS.Core.API.csproj", "IRaCIS.Core.API/"]
COPY ["IRaCIS.Core.Application/IRaCIS.Core.Application.csproj", "IRaCIS.Core.Application/"]
COPY ["IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj", "IRaCIS.Core.Infra.EFCore/"]
COPY ["IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj", "IRaCIS.Core.Domain/"]
COPY ["IRaCIS.Core.Domain.Share/IRaCIS.Core.Domain.Share.csproj", "IRaCIS.Core.Domain.Share/"]
COPY ["IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj", "IRaCIS.Core.Infrastructure/"]
RUN dotnet restore "IRaCIS.Core.API/IRaCIS.Core.API.csproj"
COPY . .
WORKDIR "/src/IRaCIS.Core.API"
RUN dotnet build "IRaCIS.Core.API.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "IRaCIS.Core.API.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "IRaCIS.Core.API.dll"]
-99
View File
@@ -1,99 +0,0 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace EFSaving.Concurrency
{
public class Sample
{
public static void Run()
{
// Ensure database is created and has a person in it
using (var setupContext = new PersonContext())
{
setupContext.Database.EnsureDeleted();
setupContext.Database.EnsureCreated();
setupContext.People.Add(new Person { FirstName = "John", LastName = "Doe" });
setupContext.SaveChanges();
}
#region ConcurrencyHandlingCode
using var context = new PersonContext();
// Fetch a person from database and change phone number
var person = context.People.Single(p => p.PersonId == 1);
person.PhoneNumber = "555-555-5555";
// Change the person's name in the database to simulate a concurrency conflict
context.Database.ExecuteSqlRaw(
"UPDATE dbo.People SET FirstName = 'Jane' WHERE PersonId = 1");
var saved = false;
while (!saved)
{
try
{
// Attempt to save changes to the database
context.SaveChanges();
saved = true;
}
catch (DbUpdateConcurrencyException ex)
{
foreach (var entry in ex.Entries)
{
if (entry.Entity is Person)
{
var proposedValues = entry.CurrentValues;
var databaseValues = entry.GetDatabaseValues();
foreach (var property in proposedValues.Properties)
{
var proposedValue = proposedValues[property];
var databaseValue = databaseValues[property];
// TODO: decide which value should be written to database
// proposedValues[property] = <value to be saved>;
}
// Refresh original values to bypass next concurrency check
entry.OriginalValues.SetValues(databaseValues);
}
else
{
throw new NotSupportedException(
"Don't know how to handle concurrency conflicts for "
+ entry.Metadata.Name);
}
}
}
}
#endregion
}
public class PersonContext : DbContext
{
public DbSet<Person> People { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// Requires NuGet package Microsoft.EntityFrameworkCore.SqlServer
optionsBuilder.UseSqlServer(
@"Server=(localdb)\mssqllocaldb;Database=EFSaving.Concurrency;Trusted_Connection=True");
}
}
public class Person
{
public int PersonId { get; set; }
[ConcurrencyCheck]
public string FirstName { get; set; }
[ConcurrencyCheck]
public string LastName { get; set; }
public string PhoneNumber { get; set; }
}
}
}
+231
View File
@@ -0,0 +1,231 @@
//using Autofac;
//using Autofac.Extensions.DependencyInjection;
//using IRaCIS.Core.API;
//using IRaCIS.Core.Application.Filter;
//using IRaCIS.Core.Application.MediatR.Handlers;
//using LogDashboard;
//using MassTransit;
//using MassTransit.NewIdProviders;
//using MediatR;
//using Microsoft.AspNetCore.Builder;
//using Microsoft.AspNetCore.Http.Features;
//using Microsoft.AspNetCore.HttpOverrides;
//using Microsoft.AspNetCore.SignalR;
//using Microsoft.Extensions.Configuration;
//using Microsoft.Extensions.DependencyInjection;
//using Microsoft.Extensions.Hosting;
//using Serilog;
//using System;
//var builder = WebApplication.CreateBuilder(args);
// //以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数)
// var config = new ConfigurationBuilder()
// .AddEnvironmentVariables()
// .Build();
// var enviromentName = config["ASPNETCORE_ENVIRONMENT"];
// if (string.IsNullOrWhiteSpace(enviromentName))
// {
// var index = Array.IndexOf(args, "--env");
// enviromentName = index > -1
// ? args[index + 1]
// : "Development";
// }
// NewId.SetProcessIdProvider(new CurrentProcessIdProvider());
//builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
// .ConfigureContainer<ContainerBuilder>(containerBuilder =>
// {
// containerBuilder.RegisterModule<AutofacModuleSetup>();
// })
// .UseWindowsService().UseSerilog();
//// Add services to the container.
////本地化
//builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
//// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
//builder.Services.AddControllers(options =>
//{
// //options.Filters.Add<LogActionFilter>();
// options.Filters.Add<ModelActionFilter>();
// options.Filters.Add<ProjectExceptionFilter>();
// //options.Filters.Add<UnitOfWorkFilter>();
// //if (_configuration.GetSection("BasicSystemConfig").GetValue<bool>("OpenLoginLimit"))
// //{
// // options.Filters.Add<LimitUserRequestAuthorization>();
// //}
//}).AddNewtonsoftJsonSetup(); // NewtonsoftJson 序列化 处理
////动态WebApi + UnifiedApiResultFilter 省掉控制器代码
//builder.Services.AddDynamicWebApiSetup();
////AutoMapper
//builder.Services.AddAutoMapperSetup();
////EF ORM QueryWithNoLock
//builder.Services.AddEFSetup(builder.Configuration);
////Http 响应压缩
//builder.Services.AddResponseCompressionSetup();
////Swagger Api 文档
//builder.Services.AddSwaggerSetup();
////JWT Token 验证
//builder.Services.AddJWTAuthSetup(builder.Configuration);
//// MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系
//builder.Services.AddMediatR(typeof(ConsistencyVerificationHandler).Assembly);
//// EasyCaching 缓存
//builder.Services.AddEasyCachingSetup();
////services.AddDistributedMemoryCache();
////// hangfire 定时任务框架 有界面,更友好~
//builder.Services.AddhangfireSetup(builder.Configuration);
////// QuartZ 定时任务框架 使用了hangfire 暂时不用,后续需要可以打开,已经配好
////builder.Services.AddQuartZSetup(_configuration);
//// 保护上传文件
////services.AddStaticFileAuthorizationSetup();
//////HttpReports 暂时废弃
////services.AddHttpReports().AddHttpTransport();
////Serilog 日志可视化 LogDashboard日志
//builder.Services.AddLogDashboardSetup();
////上传限制 配置
//builder.Services.Configure<FormOptions>(options =>
//{
// options.MultipartBodyLengthLimit = int.MaxValue;
// options.ValueCountLimit = int.MaxValue;
// options.ValueLengthLimit = int.MaxValue;
//});
////IP 限流 可设置白名单 或者黑名单
////services.AddIpPolicyRateLimitSetup(_configuration);
////用户类型 策略授权
//builder.Services.AddAuthorizationPolicySetup(builder.Configuration);
//builder.Services.AddJsonConfigSetup(builder.Configuration);
////转发头设置 获取真实IP
//builder.Services.Configure<ForwardedHeadersOptions>(options =>
//{
// options.ForwardedHeaders =
// ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
//});
////Dicom影像渲染图片 跨平台
//builder.Services.AddDicomSetup();
//// 实时应用
//builder.Services.AddSignalR();
//builder.Services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
//builder.Services.AddControllers();
//// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
////builder.Services.AddEndpointsApiExplorer();
////builder.Services.AddSwaggerGen();
////SerilogExtension.AddSerilogSetup(enviromentName, builder.Host.confi);
//var app = builder.Build();
//// Configure the HTTP request pipeline.
////本地化
//app.UseLocalization();
//app.UseForwardedHeaders();
////不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
//app.UseStaticFiles();
//app.UseIRacisHostStaticFileStore(app.Environment);
////LogDashboard
//app.UseLogDashboard("/LogDashboard");
////hangfire
////app.UseHangfireConfig(app.Environment);
//////暂时废弃
////app.UseHttpReports();
//////限流 中间件
////app.UseIpRateLimiting();
////响应压缩
//app.UseResponseCompression();
//if (app.Environment.IsDevelopment())
//{
// app.UseDeveloperExceptionPage();
//}
//else
//{
// //app.UseHsts();
//}
//SwaggerSetup.Configure(app, app.Environment);
//Console.WriteLine("当前环境: " + builder.Environment.EnvironmentName);
////app.UseMiddleware<AuthMiddleware>();
//// 特殊异常处理 比如 404
//app.UseStatusCodePagesWithReExecute("/Error/{0}");
//////serilog 记录请求的用户信息
//app.UseSerilogConfig(app.Environment);
//app.UseRouting();
//app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
//app.UseAuthentication();
////app.UseJwtBearerQueryString();
//app.UseAuthorization();
//////文件伺服 必须带Token 访问
//////app.UseIRacisHostStaticFileStore(env);
////app.UseEndpoints(endpoints =>
////{
//// endpoints.MapControllers();
//// endpoints.MapHub<UploadHub>("/UploadHub")/*.RequireCors(t=>t.WithOrigins(new string[] {"null"}).AllowAnyMethod().AllowAnyHeader().AllowCredentials())*/;
////});
//app.MapControllers();
//app.MapHub<UploadHub>("/UploadHub")/*.RequireCors(t=>t.WithOrigins(new string[] {"null"}).AllowAnyMethod().AllowAnyHeader().AllowCredentials())*/;
//app.Run();
//测试同步
+106
View File
@@ -0,0 +1,106 @@
{
"needAnonymizeTag": [
{ //PatientsName
"Group": "0010",
"Element": "0010",
"ReplaceValue": "",
"Enable": true
},
{ // PatientID
"Group": "0010",
"Element": "0020",
"ReplaceValue": "",
"Enable": true
},
{ // IssuerOfPatientID
"Group": "0010",
"Element": "0021",
"ReplaceValue": "",
"Enable": true
},
{ // PatientsBirthDate
"Group": "0010",
"Element": "0030",
"ReplaceValue": "",
"Enable": true
},
{ // PatientsBirthTime
"Group": "0010",
"Element": "0032",
"ReplaceValue": "",
"Enable": false
},
{ // PatientsSex
"Group": "0010",
"Element": "0040",
"ReplaceValue": "",
"Enable": false
},
{ // OtherPatientIDs
"Group": "0010",
"Element": "1000",
"ReplaceValue": "",
"Enable": false
},
{ // OtherPatientNames
"Group": "0010",
"Element": "1001",
"ReplaceValue": "",
"Enable": false
},
{ // OtherPatientNames
"Group": "0010",
"Element": "1005",
"ReplaceValue": "",
"Enable": true
},
{ // PatientBirthName
"Group": "0010",
"Element": "1005",
"ReplaceValue": "",
"Enable": true
},
{ // PatientsAge
"Group": "0010",
"Element": "1010",
"ReplaceValue": "",
"Enable": true
},
{ // PatientsAddress
"Group": "0010",
"Element": "1040",
"ReplaceValue": "",
"Enable": true
},
{ // PatientsMothersBirthName
"Group": "0010",
"Element": "1060",
"ReplaceValue": "",
"Enable": true
},
{
"Group": "0010",
"Element": "2150",
"ReplaceValue": "",
"Enable": true
},
{
"Group": "0010",
"Element": "2152",
"ReplaceValue": "",
"Enable": true
},
{
"Group": "0010",
"Element": "2154",
"ReplaceValue": "",
"Enable": true
},
{
"Group": "0012",
"Element": "0040",
"ReplaceValue": "XXX",
"Enable": true
}
]
}
+101 -248
View File
@@ -21,17 +21,13 @@ using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure;
using System.Linq;
using Microsoft.Extensions.Logging;
using MassTransit;
using Microsoft.AspNetCore.Hosting;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Core.Auth.Sts;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Sts.Model.V20150401;
using Microsoft.AspNetCore.Hosting;
using MassTransit;
using IRaCIS.Core.Application.Helper;
using Microsoft.Extensions.Options;
using IRaCIS.Core.Application.Contracts;
using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO;
using DocumentFormat.OpenXml.Spreadsheet;
using AutoMapper.QueryableExtensions;
namespace IRaCIS.Api.Controllers
{
@@ -43,268 +39,101 @@ namespace IRaCIS.Api.Controllers
{
/// <summary>
/// 获取医生详情
/// </summary>
/// <param name="attachmentService"></param>
/// <param name="_doctorService"></param>
/// <param name="_educationService"></param>
/// <param name="_trialExperienceService"></param>
/// <param name="_researchPublicationService"></param>
/// <param name="_vacationService"></param>
/// <param name="doctorId"></param>
/// <returns></returns>
[HttpGet, Route("doctor/getDetail/{doctorId:guid}")]
public async Task<IResponseOutput<DoctorDetailDTO>> GetDoctorDetail([FromServices] IAttachmentService attachmentService, [FromServices] IDoctorService _doctorService,
[FromServices] IEducationService _educationService, [FromServices] ITrialExperienceService _trialExperienceService,
[FromServices] IResearchPublicationService _researchPublicationService, [FromServices] IVacationService _vacationService, Guid doctorId)
{
var education = await _educationService.GetEducation(doctorId);
var sowList = _doctorService.GetDoctorSowList(doctorId);
var ackSowList = _doctorService.GetDoctorAckSowList(doctorId);
var doctorDetail = new DoctorDetailDTO
{
AuditView = await _doctorService.GetAuditState(doctorId),
BasicInfoView = await _doctorService.GetBasicInfo(doctorId),
EmploymentView = await _doctorService.GetEmploymentInfo(doctorId),
AttachmentList = await attachmentService.GetAttachments(doctorId),
EducationList = education.EducationList,
PostgraduateList = education.PostgraduateList,
TrialExperienceView = await _trialExperienceService.GetTrialExperience(doctorId),
ResearchPublicationView = await _researchPublicationService.GetResearchPublication(doctorId),
SpecialtyView = await _doctorService.GetSpecialtyInfo(doctorId),
InHoliday = (await _vacationService.OnVacation(doctorId)).IsSuccess,
IntoGroupInfo = _doctorService.GetDoctorIntoGroupInfo(doctorId),
SowList = sowList,
AckSowList = ackSowList
};
return ResponseOutput.Ok(doctorDetail);
}
/// <summary> 系统用户登录接口[New] </summary>
[HttpPost, Route("user/login")]
[AllowAnonymous]
public async Task<IResponseOutput> Login(UserLoginDTO loginUser,
[FromServices] IEasyCachingProvider provider,
[FromServices] IUserService _userService,
[FromServices] ITokenService _tokenService,
[FromServices] IReadingImageTaskService readingImageTaskService,
IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig,
IMailVerificationService _mailVerificationService)
public async Task<IResponseOutput<LoginReturnDTO>> Login(UserLoginDTO loginUser, [FromServices] IEasyCachingProvider provider, [FromServices] IUserService _userService,
[FromServices] ITokenService _tokenService, [FromServices] IConfiguration configuration)
{
//MFA 邮箱验证 前端传递用户Id 和MFACode
if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA)
var returnModel = await _userService.Login(loginUser.UserName, loginUser.Password);
if (returnModel.IsSuccess)
{
Guid userId = (Guid)loginUser.UserId;
#region GRPC IIS问题 http/2 使
//验证MFA 编码是否有问题 ,前端要拆开,自己调用验证的逻辑
//await _userService.VerifyMFACodeAsync(userId, loginUser.MFACode);
////重试策略
//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 }
// }
//};
//var loginUser = await _userRepository.Where(u => u.UserName.Equals(userName) && u.Password == password).ProjectTo<UserBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
//#region unable to trust the certificate then the gRPC client can be configured to ignore the invalid certificate
var basicInfo = await _userService.GetUserBasicInfo(userId, loginUser.Password);
//var httpHandler = new HttpClientHandler();
//// Return `true` to allow certificates that are untrusted/invalid
//httpHandler.ServerCertificateCustomValidationCallback =
// HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var loginReturn = new LoginReturnDTO() { BasicInfo = basicInfo };
loginReturn.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(loginReturn.BasicInfo));
//////这一句是让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
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 属性
Expires = DateTime.Now.AddMonths(1),
HttpOnly = true, // 确保 cookie 只能通过 HTTP 访问
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Unspecified, // 设置 SameSite 属性
Secure = false // 确保 cookie 只能通过 HTTPS 访问
};
HttpContext.Response.Cookies.Append("access_token", loginReturn.JWTStr, option);
// 验证阅片休息时间
await readingImageTaskService.ResetReadingRestTime(userId);
await provider.SetAsync(userId.ToString(), loginReturn.JWTStr, TimeSpan.FromDays(7));
await provider.SetAsync($"{userId.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
return ResponseOutput.Ok(loginReturn);
}
else
{
var returnModel = await _userService.Login(loginUser.UserName, loginUser.Password);
if (returnModel.IsSuccess)
{
#region GRPC IIS问题 http/2 使
////重试策略
//var defaultMethodConfig = new MethodConfig
//{
// Names = { MethodName.Default },
// RetryPolicy = new RetryPolicy
// {
// MaxAttempts = 3,
// InitialBackoff = TimeSpan.FromSeconds(1),
// MaxBackoff = TimeSpan.FromSeconds(5),
// BackoffMultiplier = 1.5,
// RetryableStatusCodes = { Grpc.Core.StatusCode.Unavailable }
// }
//};
//#region unable to trust the certificate then the gRPC client can be configured to ignore the invalid certificate
//var httpHandler = new HttpClientHandler();
//// Return `true` to allow certificates that are untrusted/invalid
//httpHandler.ServerCertificateCustomValidationCallback =
// HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
//////这一句是让grpc支持本地 http 如果本地访问部署在服务器上,那么是访问不成功的
//AppContext.SetSwitch(
// "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
//#endregion
//var grpcAdress = configuration.GetValue<string>("GrpcAddress");
////var grpcAdress = "http://localhost:7200";
//var channel = GrpcChannel.ForAddress(grpcAdress, new GrpcChannelOptions
//{
// HttpHandler = httpHandler,
// ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }
//});
////var channel = GrpcChannel.ForAddress(grpcAdress);
//var grpcClient = new TokenGrpcService.TokenGrpcServiceClient(channel);
//var userInfo = returnModel.Data.BasicInfo;
//var tokenResponse = grpcClient.GetUserToken(new GetTokenReuqest()
//{
// Id = userInfo.Id.ToString(),
// ReviewerCode = userInfo.ReviewerCode,
// IsAdmin = userInfo.IsAdmin,
// RealName = userInfo.RealName,
// UserTypeEnumInt = (int)userInfo.UserTypeEnum,
// UserTypeShortName = userInfo.UserTypeShortName,
// UserName = userInfo.UserName
//});
//returnModel.Data.JWTStr = tokenResponse.Token;
#endregion
var userId = returnModel.Data.BasicInfo.Id;
if (_verifyConfig.CurrentValue.OpenLoginMFA)
{
//发版屏蔽
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
//MFA 发送邮件
returnModel.Data.IsMFA = true;
var email = returnModel.Data.BasicInfo.EMail;
#region Email
// 找到 "@" 符号的位置
int atIndex = email.IndexOf('@');
// 替换 "@" 符号前的中间两位为星号
string visiblePart = email.Substring(0, atIndex);
int startIndex = (visiblePart.Length - 2) / 2;
// 替换中间两位字符为星号
string hiddenPartBeforeAt = visiblePart.Substring(0, startIndex) + "**" + visiblePart.Substring(startIndex + 2);
string afterAt = email.Substring(atIndex + 1);
// 组合隐藏和可见部分
string hiddenEmail = hiddenPartBeforeAt + "@" + afterAt;
#endregion
returnModel.Data.BasicInfo.EMail = hiddenEmail;
await _userService.SendMFAEmail(userId);
}
else
{
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
// 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
var option = new CookieOptions
{
Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
HttpOnly = false, // 确保 cookie 只能通过 HTTP 访问
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None, // 设置 SameSite 属性
Secure = false // 确保 cookie 只能通过 HTTPS 访问
};
HttpContext.Response.Cookies.Append("access_token", returnModel.Data.JWTStr, option);
// 验证阅片休息时间
await readingImageTaskService.ResetReadingRestTime(returnModel.Data.BasicInfo.Id);
await provider.SetAsync(userId.ToString(), returnModel.Data.JWTStr, TimeSpan.FromDays(7));
await provider.SetAsync($"{userId.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
}
}
return returnModel;
HttpContext.Response.Cookies.Append("access_token", returnModel.Data.JWTStr, option);
}
var userId = returnModel.Data.BasicInfo.Id.ToString();
//provider.Set(userId, userId, TimeSpan.FromMinutes(AppSettings.LoginExpiredTimeSpan));
}
[HttpGet, Route("imageShare/ShareImage")]
[AllowAnonymous]
public IResponseOutput ShareImage([FromServices] ITokenService _tokenService)
{
var token = _tokenService.GetToken(IRaCISClaims.Create(new UserBasicInfo()
{
Id = Guid.Empty,
IsReviewer = false,
IsAdmin = false,
RealName = "Share001",
UserName = "Share001",
Sex = 0,
//UserType = "ShareType",
UserTypeEnum = UserTypeEnum.ShareImage,
Code = "ShareCode001",
}));
return ResponseOutput.Ok("/showdicom?studyId=f7b67793-8155-0223-2f15-118f2642efb8&type=Share&token=" + token);
await provider.SetAsync(userId.ToString(), returnModel.Data.JWTStr, TimeSpan.FromDays(7));
return returnModel;
}
[HttpGet("user/GetObjectStoreToken")]
@@ -398,9 +227,9 @@ namespace IRaCIS.Api.Controllers
SecurityToken = response.Credentials.SecurityToken,
Expiration = response.Credentials.Expiration,
Region = ossOptions.region,
BucketName = ossOptions.bucketName,
ViewEndpoint = ossOptions.viewEndpoint,
Region = ossOptions.region ,
BucketName = ossOptions.bucketName ,
ViewEndpoint = ossOptions.viewEndpoint ,
};
@@ -410,6 +239,30 @@ namespace IRaCIS.Api.Controllers
[HttpGet, Route("imageShare/ShareImage")]
[AllowAnonymous]
public IResponseOutput ShareImage([FromServices] ITokenService _tokenService)
{
var token = _tokenService.GetToken(IRaCISClaims.Create(new UserBasicInfo()
{
Id = Guid.Empty,
IsReviewer = false,
IsAdmin = false,
RealName = "Share001",
UserName = "Share001",
Sex = 0,
//UserType = "ShareType",
UserTypeEnum = UserTypeEnum.ShareImage,
Code = "ShareCode001",
}));
return ResponseOutput.Ok("/showdicom?studyId=f7b67793-8155-0223-2f15-118f2642efb8&type=Share&token=" + token);
}
[HttpGet("User/UserRedirect")]
[AllowAnonymous]
public async Task<IActionResult> UserRedirect([FromServices] IRepository<User> _userRepository, string url, [FromServices] ILogger<ExtraController> _logger)
@@ -22,14 +22,14 @@ namespace IRaCIS.Core.API.Controllers.Special
public class FinancialChangeController : ControllerBase
{
private readonly ITrialService _trialService;
private readonly ICalculateService _calculateService;
private IStringLocalizer _localizer { get; set; }
public FinancialChangeController(ITrialService trialService, ICalculateService calculateService, IStringLocalizer localizer
public FinancialChangeController(ITrialService trialService, IStringLocalizer localizer
)
{
_localizer = localizer;
_trialService = trialService;
_calculateService = calculateService;
}
@@ -60,268 +60,28 @@ namespace IRaCIS.Core.API.Controllers.Special
var userId = Guid.Parse(User.FindFirst("id").Value);
var result = await _trialService.AddOrUpdateTrial(param);
if (_trialService.TrialExpeditedChange)
{
var needCalReviewerIds = await _trialService.GetTrialEnrollmentReviewerIds(param.Id.Value);
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty);
calcList.ForEach(t =>
{
if (needCalReviewerIds.Contains(t.DoctorId))
{
_calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
t.DoctorId
},
CalculateMonth = DateTime.Parse(t.YearMonth)
}, User.FindFirst("id").Value);
}
});
}
return result;
}
/// <summary>
/// 添加或更新工作量[AUTH]
/// </summary>
/// <param name="_trialWorkloadService"></param>
/// <param name="workLoadAddOrUpdateModel"></param>
/// <returns></returns>
[HttpPost, Route("doctorWorkload/workLoadAddOrUpdate")]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> WorkLoadAddOrUpdate([FromServices] IDoctorWorkloadService _trialWorkloadService, WorkloadCommand workLoadAddOrUpdateModel)
{
var userId = Guid.Parse(User.FindFirst("id").Value);
var result = await _trialWorkloadService.AddOrUpdateWorkload(workLoadAddOrUpdateModel, userId);
if (result.IsSuccess && workLoadAddOrUpdateModel.DataFrom == 2)
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
workLoadAddOrUpdateModel.DoctorId
},
CalculateMonth = workLoadAddOrUpdateModel.WorkTime
}, User.FindFirst("id").Value);
}
return result;
}
[HttpDelete, Route("doctorWorkload/deleteWorkLoad/{id:guid}/{trialId:guid}")]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> DeleteWorkLoad([FromServices] IDoctorWorkloadService _trialWorkloadService, Guid id)
{
//先判断该工作量的费用是否被锁定,如果被锁定,则不能删除
var workload = await _trialWorkloadService.GetWorkloadDetailById(id);
var yearMonth = workload.WorkTime.ToString("yyyy-MM");
var isLock = await _calculateService.IsLock(workload.DoctorId, yearMonth);
if (isLock)
{
//---Expenses have been settled and workload can not be reset.
return ResponseOutput.NotOk(_localizer["Financial_ChargeSettled"]);
}
var deleteResult = await _trialWorkloadService.DeleteWorkload(id);
if (workload.DataFrom == (int)Domain.Share.WorkLoadFromStatus.FinalConfirm)
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
workload.DoctorId
},
CalculateMonth = workload.WorkTime
}, User.FindFirst("id").Value);
}
return deleteResult;
}
/// <summary>
/// 添加或更新汇率(会触发没有对锁定的费用计算)
/// </summary>
[HttpPost, Route("exchangeRate/addOrUpdateExchangeRate")]
public async Task<IResponseOutput> AddOrUpdateExchangeRate([FromServices] IExchangeRateService _exchangeRateService, [FromServices] IPaymentAdjustmentService _costAdjustmentService, ExchangeRateCommand addOrUpdateModel)
{
var result = await _exchangeRateService.AddOrUpdateExchangeRate(addOrUpdateModel);
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, addOrUpdateModel.YearMonth);
foreach (var item in calcList)
{
if (item != null)
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
item.DoctorId
},
CalculateMonth = DateTime.Parse(item.YearMonth)
}, User.FindFirst("id").Value);
}
}
await _costAdjustmentService.CalculateCNY(addOrUpdateModel.YearMonth, addOrUpdateModel.Rate);
return result;
}
/// <summary>
/// 添加或更新 职称单价[AUTH]
/// </summary>
[HttpPost, Route("rankPrice/addOrUpdateRankPrice")]
public async Task<IResponseOutput> AddOrUpdateRankPrice([FromServices] IReviewerPayInfoService _reviewerPayInfoService, [FromServices] IRankPriceService _rankPriceService, RankPriceCommand addOrUpdateModel)
{
if (addOrUpdateModel.Id != Guid.Empty && addOrUpdateModel.Id != null)
{
var needCalReviewerIds =await _reviewerPayInfoService.GetReviewerIdByRankId(Guid.Parse(addOrUpdateModel.Id.ToString()));
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty);
foreach (var item in calcList)
{
if (item != null && needCalReviewerIds.Contains(item.DoctorId))
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
item.DoctorId
},
CalculateMonth = DateTime.Parse(item.YearMonth)
}, User.FindFirst("id").Value);
}
}
}
var userId = Guid.Parse(User.FindFirst("id").Value);
return await _rankPriceService.AddOrUpdateRankPrice(addOrUpdateModel, userId);
}
/// <summary>
/// 添加或更新(替换)医生支付展信息[AUTH]
/// </summary>
[HttpPost, Route("reviewerPayInfo/addOrUpdateReviewerPayInfo")]
public async Task<IResponseOutput> AddOrUpdateReviewerPayInfo([FromServices] IReviewerPayInfoService _doctorPayInfoService, ReviewerPayInfoCommand addOrUpdateModel)
{
var userId = Guid.Parse(User.FindFirst("id").Value);
var result =await _doctorPayInfoService.AddOrUpdateReviewerPayInfo(addOrUpdateModel, userId);
var calcList = await _calculateService.GetNeedCalculateReviewerList(addOrUpdateModel.DoctorId, string.Empty);
foreach (var item in calcList)
{
if (item != null)
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
item.DoctorId
},
CalculateMonth = DateTime.Parse(item.YearMonth)
}, User.FindFirst("id").Value);
}
}
return result;
}
/// <summary>
/// 保存(替换)项目支付价格信息(会触发没有被锁定的费用计算)[AUTH]
/// </summary>
[HttpPost, Route("trialPaymentPrice/addOrUpdateTrialPaymentPrice")]
public async Task<IResponseOutput> AddOrUpdateTrialPaymentPrice([FromServices] ITrialPaymentPriceService _trialPaymentPriceService, TrialPaymentPriceCommand addOrUpdateModel)
{
var userId = Guid.Parse(User.FindFirst("id").Value);
var result =await _trialPaymentPriceService.AddOrUpdateTrialPaymentPrice(addOrUpdateModel);
var needCalReviewerIds = await _trialService.GetTrialEnrollmentReviewerIds(addOrUpdateModel.TrialId);
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty);
foreach (var item in calcList)
{
if (item != null && needCalReviewerIds.Contains(item.DoctorId))
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
item.DoctorId
},
CalculateMonth = DateTime.Parse(item.YearMonth)
}, User.FindFirst("id").Value);
}
}
return result;
}
/// <summary>
/// 批量更新奖励费用[AUTH]
/// </summary>
[HttpPost, Route("volumeReward/addOrUpdatevolumeRewardPriceList")]
public async Task<IResponseOutput> AddOrUpdateAwardPriceList([FromServices] IVolumeRewardService _volumeRewardService, IEnumerable<AwardPriceCommand> addOrUpdateModel)
{
var result =await _volumeRewardService.AddOrUpdateVolumeRewardPriceList(addOrUpdateModel);
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty);
foreach (var item in calcList)
{
if (item != null)
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
item.DoctorId
},
CalculateMonth = DateTime.Parse(item.YearMonth)
}, User.FindFirst("id").Value);
}
}
return result;
}
/// <summary>
/// 计算医生月度费用,并将计算的结果存入费用表
/// </summary>
[HttpPost, Route("financial/calculateMonthlyPayment")]
public async Task<IResponseOutput> CalculateMonthlyPayment(CalculateDoctorAndMonthDTO param)
{
if (!ModelState.IsValid)
{
//---Invalid parameter.
return ResponseOutput.NotOk(_localizer["Financial_InvalidParameter"]);
}
return await _calculateService.CalculateMonthlyPayment(param, User.FindFirst("id").Value);
}
/// <summary>
/// Financials /Monthly Payment 列表查询接口
/// </summary>
[HttpPost, Route("financial/getMonthlyPaymentList")]
public async Task<IResponseOutput<PaymentDTO>> GetMonthlyPaymentList([FromServices] IPaymentService _paymentService, [FromServices] IExchangeRateService _exchangeRateService, MonthlyPaymentQueryDTO queryParam)
{
return ResponseOutput.Ok(new PaymentDTO
{
CostList = await _paymentService.GetMonthlyPaymentList(queryParam),
ExchangeRate = await _exchangeRateService.GetExchangeRateByMonth(queryParam.StatisticsDate.ToString("yyyy-MM"))
});
}
}
}
@@ -419,30 +419,13 @@ namespace IRaCIS.Core.API.Controllers
}
/// <summary>
/// 重置并同步项目阅片标准
/// </summary>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingCriterion/ResetAndAsyncCriterion")]
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> ResetAndAsyncCriterion(DataInspectionDto<ResetAndAsyncCriterionInDto> opt)
{
var singid = await _inspectionService.RecordSing(opt.SignInfo);
var result = await _trialConfigService.ResetAndAsyncCriterion(opt.Data);
await _inspectionService.CompletedSign(singid, result);
return result;
}
/// <summary>
/// CRC RequestToQC 批量提交
/// </summary>
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/QCOperation/CRCRequestToQC")]
/// <summary>
/// CRC RequestToQC 批量提交
/// </summary>
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/QCOperation/CRCRequestToQC")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[UnitOfWork]
public async Task<IResponseOutput> CRCRequestToQC(DataInspectionDto<CRCRequestToQCCommand> opt)
@@ -20,6 +20,7 @@ using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using Magicodes.ExporterAndImporter.Excel;
using MassTransit;
using MediatR;
using Microsoft.AspNetCore.Authorization;
@@ -32,12 +33,12 @@ using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
using MiniExcelLibs;
using Newtonsoft.Json;
using SharpCompress.Archives;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Data;
@@ -234,17 +235,13 @@ namespace IRaCIS.Core.API.Controllers
public IUserInfo _userInfo { get; set; }
private readonly IMediator _mediator;
public IStringLocalizer _localizer { get; set; }
private readonly IWebHostEnvironment _hostEnvironment;
private readonly IRepository _repository;
private readonly IEasyCachingProvider _provider;
private readonly QCCommon _qCCommon;
public StudyController(IMapper mapper, IStringLocalizer localizer, IUserInfo userInfo, IWebHostEnvironment hostEnvironment, IMediator mediator, IEasyCachingProvider provider,
public StudyController(IMapper mapper, IUserInfo userInfo, IWebHostEnvironment hostEnvironment, IMediator mediator, IEasyCachingProvider provider,
QCCommon qCCommon,
IRepository repository)
{
@@ -252,13 +249,12 @@ namespace IRaCIS.Core.API.Controllers
_provider = provider;
_hostEnvironment = hostEnvironment;
_mediator = mediator;
_localizer = localizer;
_mapper = mapper;
_userInfo = userInfo;
_repository = repository;
}
[HttpPost, Route("Study/PreArchiveStudy")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> PreArchiveStudy(PreArchiveStudyCommand preArchiveStudyCommand,
@@ -276,6 +272,7 @@ namespace IRaCIS.Core.API.Controllers
var studyMonitor = new StudyMonitor()
{
TrialId = savedInfo.TrialId,
SiteId = savedInfo.SiteId,
SubjectId = savedInfo.SubjectId,
SubjectVisitId = savedInfo.SubjectVisitId,
@@ -315,7 +312,7 @@ namespace IRaCIS.Core.API.Controllers
string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
{
//---不支持的MediaType
return ResponseOutput.NotOk(_localizer["UploadDownLoad_UnsupportedMedia"]);
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_UnsupportedMedia"));
}
var archiveStudyCommand = new ArchiveStudyCommand() { AbandonStudyId = abandonStudyId, StudyInstanceUid = studyInstanceUid, SubjectVisitId = subjectVisitId };
@@ -404,12 +401,12 @@ namespace IRaCIS.Core.API.Controllers
}
catch (Exception)
catch (Exception ex)
{
_provider.Remove($"StudyUid_{trialId}_{archiveStudyCommand.StudyInstanceUid}");
//---请求异常,请重试!
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_RequestError"]);
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_RequestError"));
}
studyMonitor.FileSize = (decimal)HttpContext.Request.ContentLength;
@@ -463,6 +460,248 @@ namespace IRaCIS.Core.API.Controllers
}
#region
///// <summary>
///// 上传临床数据 多文件
///// </summary>
///// <param name="subjectVisitId"></param>
///// <returns></returns>
//[HttpPost("ClinicalData/UploadVisitClinicalData/{trialId:guid}/{subjectVisitId:guid}")]
//[DisableRequestSizeLimit]
////[Authorize(Policy = IRaCISPolicy.CRC)]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//public async Task<IResponseOutput> UploadVisitClinicalData(Guid subjectVisitId)
//{
// await _qCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
// var sv = _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.SiteId, t.SubjectId }).FirstOrDefault().IfNullThrowException();
// await FileUploadAsync(async (fileName) =>
// {
// var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetClinicalDataPath(_hostEnvironment, fileName, sv.TrialId, sv.SiteId, sv.SubjectId, subjectVisitId);
// //插入临床pdf 路径
// await _repository.AddAsync(new PreviousPDF()
// {
// SubjectVisitId = subjectVisitId,
// IsVisist = true,
// DataType = ClinicalDataType.MedicalHistory,
// UploadType = ClinicalUploadType.PDF,
// SubjectId = sv.SubjectId,
// TrialId = sv.TrialId,
// ClinicalLevel = ClinicalLevel.Subject,
// Path = relativePath,
// FileName = fileRealName
// });
// return serverFilePath;
// });
// await _repository.SaveChangesAsync();
// return ResponseOutput.Ok();
//}
///// <summary>
///// 上传临床数据模板
///// </summary>
///// <param name="trialId"></param>
///// <returns></returns>
//[HttpPost("ClinicalData/UploadClinicalTemplate")]
//[DisableRequestSizeLimit]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })]
//public async Task<IResponseOutput<List<FileDto>>> UploadClinicalTemplate(Guid? trialId)
//{
// if (trialId == null)
// trialId = default(Guid);
// var filerelativePath = string.Empty;
// List<FileDto> fileDtos = new List<FileDto>();
// await FileUploadAsync(async (fileName) =>
// {
// var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetClinicalTemplatePath(_hostEnvironment, fileName, trialId.Value);
// //插入临床pdf 路径
// filerelativePath = relativePath;
// fileDtos.Add(new FileDto()
// {
// FileName = fileName,
// Path = relativePath
// });
// await Task.CompletedTask;
// return serverFilePath;
// });
// return ResponseOutput.Ok(fileDtos);
//}
///// <summary>
///// 上传阅片临床数据
///// </summary>
///// <param name="trialId"></param>
///// <param name="subjectId"></param>
///// <param name="readingId"></param>
///// <returns></returns>
//[HttpPost("ClinicalData/UploadClinicalData/{trialId:guid}/{subjectId:guid}/{readingId:guid}")]
//[DisableRequestSizeLimit]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//public async Task<IResponseOutput<List<FileDto>>> UploadReadClinicalData(Guid trialId, Guid subjectId, Guid readingId)
//{
// var filerelativePath = string.Empty;
// List<FileDto> fileDtos = new List<FileDto>();
// var siteid = await _repository.Where<Subject>(x => x.Id == subjectId).Select(x => x.SiteId).FirstOrDefaultAsync();
// await FileUploadAsync(async (fileName) =>
// {
// var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetReadClinicalDataPath(_hostEnvironment, fileName, trialId, siteid, subjectId, readingId);
// //插入临床pdf 路径
// filerelativePath = relativePath;
// fileDtos.Add(new FileDto()
// {
// FileName = fileName,
// Path = relativePath
// });
// await Task.CompletedTask;
// return serverFilePath;
// });
// return ResponseOutput.Ok(fileDtos);
//}
///// <summary>
///// 上传截图
///// </summary>
///// <param name="subjectId"></param>
///// <returns></returns>
//[HttpPost("Printscreen/UploadPrintscreen/{subjectId:guid}")]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//public async Task<IResponseOutput<FileDto>> UploadPrintscreen(Guid subjectId)
//{
// var subjectInfo = await this._repository.Where<Subject>(x => x.Id == subjectId).FirstNotNullAsync();
// FileDto fileDto = new FileDto();
// await FileUploadAsync(async (fileName) =>
// {
// var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetUploadPrintscreenFilePath(_hostEnvironment, fileName, subjectInfo.TrialId, subjectInfo.SiteId, subjectInfo.Id);
// fileDto.Path = relativePath;
// fileDto.FileName = fileName;
// await Task.CompletedTask;
// return serverFilePath;
// });
// return ResponseOutput.Ok(fileDto);
//}
///// <summary>
///// 上传Reading问题的图像
///// </summary>
///// <param name="trialId"></param>
///// <param name="visitTaskId"></param>
///// <returns></returns>
//[HttpPost("VisitTask/UploadReadingAnswerImage/{trialId:guid}/{visitTaskId:guid}")]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//public async Task<IResponseOutput<FileDto>> UploadReadingAnswerImage(Guid trialId, Guid visitTaskId)
//{
// FileDto fileDto = new FileDto();
// await FileUploadAsync(async (fileName) =>
// {
// var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetFilePath(_hostEnvironment, fileName, trialId, visitTaskId, StaticData.Folder.JudgeTask);
// fileDto.Path = relativePath;
// fileDto.FileName = fileName;
// await Task.CompletedTask;
// return serverFilePath;
// });
// return ResponseOutput.Ok(fileDto);
//}
///// <summary>
///// 上传裁判任务的图像
///// </summary>
///// <param name="trialId"></param>
///// <param name="visitTaskId"></param>
///// <returns></returns>
//[HttpPost("VisitTask/UploadJudgeTaskImage/{trialId:guid}/{visitTaskId:guid}")]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//public async Task<IResponseOutput<FileDto>> UploadJudgeTaskImage(Guid trialId, Guid visitTaskId)
//{
// FileDto fileDto = new FileDto();
// await FileUploadAsync(async (fileName) =>
// {
// var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetFilePath(_hostEnvironment, fileName, trialId, visitTaskId, StaticData.Folder.JudgeTask);
// fileDto.Path = relativePath;
// fileDto.FileName = fileName;
// await Task.CompletedTask;
// return serverFilePath;
// });
// return ResponseOutput.Ok(fileDto);
//}
///// <summary>
///// 上传医学审核图片
///// </summary>
///// <param name="trialId"></param>
///// <param name="taskMedicalReviewId"></param>
///// <returns></returns>
//[HttpPost("TaskMedicalReview/UploadMedicalReviewImage/{trialId:guid}/{taskMedicalReviewId:guid}")]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//public async Task<IResponseOutput<FileDto>> UploadMedicalReviewImage(Guid trialId, Guid taskMedicalReviewId)
//{
// string path = string.Empty;
// FileDto fileDto = new FileDto();
// await FileUploadAsync(async (fileName) =>
// {
// var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetMedicalReviewImage(_hostEnvironment, fileName, trialId, taskMedicalReviewId);
// //await _repository.UpdatePartialFromQueryAsync<TaskMedicalReview>(x => x.Id == taskMedicalReviewId, x => new TaskMedicalReview()
// //{
// // ImagePath = relativePath,
// // FileName = fileName,
// //});
// path = relativePath;
// fileDto.Path = relativePath;
// fileDto.FileName = fileName;
// return serverFilePath;
// });
// await _repository.SaveChangesAsync();
// return ResponseOutput.Ok(fileDto);
//}
#endregion
public class UploadNoneDicomFileCommand
{
public Guid TrialId { get; set; }
@@ -485,13 +724,12 @@ namespace IRaCIS.Core.API.Controllers
/// <summary>
/// 上传非Dicom 文件 支持压缩包 多文件上传
/// </summary>
/// <param name="incommand"></param>
/// <param name="_noneDicomStudyRepository"></param>
/// <param name="_studyMonitorRepository"></param>
/// <returns></returns>
//[DisableRequestSizeLimit]
[HttpPost("NoneDicomStudy/UploadNoneDicomFile")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//[Authorize(Policy = IRaCISPolicy.CRC)]
public async Task<IResponseOutput> UploadNoneDicomFile(UploadNoneDicomFileCommand incommand,
[FromServices] IRepository<NoneDicomStudy> _noneDicomStudyRepository, [FromServices] IRepository<StudyMonitor> _studyMonitorRepository)
{
@@ -503,7 +741,7 @@ namespace IRaCIS.Core.API.Controllers
await _qCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
var sv = (await _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.TrialSiteId, t.SubjectId }).FirstOrDefaultAsync()).IfNullThrowConvertException();
var sv = (await _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.SiteId, t.SubjectId }).FirstOrDefaultAsync()).IfNullThrowConvertException();
var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == studyMonitorId);
@@ -534,20 +772,14 @@ namespace IRaCIS.Core.API.Controllers
return ResponseOutput.Ok();
}
/// <summary>
/// 一致性核查 excel上传 支持三种格式
/// </summary>
/// <param name="trialId"></param>
/// <param name="oSSService"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
[HttpPost("QCOperation/UploadVisitCheckExcel/{trialId:guid}")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> UploadVisitCheckExcel(Guid trialId, [FromServices] IOSSService oSSService)
{
@@ -561,14 +793,14 @@ namespace IRaCIS.Core.API.Controllers
if (!fileName.EndsWith(".xlsx") && !fileName.EndsWith(".csv") && !fileName.EndsWith(".xls"))
{
//---支持.xlsx、.xls、.csv格式的文件上传。
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_SupportedFormats"]);
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_SupportedFormats"));
}
fileStream.CopyTo(templateFileStream);
templateFileStream.Seek(0, SeekOrigin.Begin);
var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/Check", realFileName);
var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/Check", realFileName);
await _repository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId });
@@ -582,22 +814,9 @@ namespace IRaCIS.Core.API.Controllers
var etcCheckList = new List<CheckViewModel>();
#region MiniExcel
if (fileName.EndsWith(".xlsx"))
{
etcCheckList = MiniExcel.Query<CheckViewModel>(templateFileStream, excelType: ExcelType.XLSX).ToList();
}
else if (fileName.EndsWith(".csv"))
{
//因为csv 需要加配置文件 不然都是null
etcCheckList = MiniExcel.Query<CheckViewModel>(templateFileStream, null, configuration: new MiniExcelLibs.Csv.CsvConfiguration()
{
StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312"))
}).ToList();
}
//if (fileName.EndsWith(".csv"))
//{
// //因为csv 需要加配置文件 不然都是null
@@ -613,72 +832,67 @@ namespace IRaCIS.Core.API.Controllers
#endregion
#region net8
//Magicodes 支持自定义特性验证
// if (fileName.EndsWith(".xlsx"))
//{
// var Importer = new ExcelImporter();
if (fileName.EndsWith(".xlsx"))
{
var Importer = new ExcelImporter();
// var import = await Importer.Import<CheckViewModel>(templateFileStream);
var import = await Importer.Import<CheckViewModel>(templateFileStream);
// if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
// //if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
//if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
// if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(_localizer["UploadDownLoad_TemplateErrors"]);
if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors));
// etcCheckList = import.Data.ToList();
//}
//else if (fileName.EndsWith(".csv"))
//{
// #region 临时方案 MiniExcel读取 然后保存为xlsx 再用 Magicodes验证数据
etcCheckList = import.Data.ToList();
}
else if (fileName.EndsWith(".csv"))
{
#region MiniExcel读取 xlsx Magicodes验证数据
// //因为csv 需要加配置文件 不然都是null
// etcCheckList = MiniExcel.Query<CheckViewModel>(templateFileStream, null, configuration: new MiniExcelLibs.Csv.CsvConfiguration()
// {
// StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312"))
// }).ToList();
//因为csv 需要加配置文件 不然都是null
etcCheckList = MiniExcel.Query<CheckViewModel>(templateFileStream, null, configuration: new MiniExcelLibs.Csv.CsvConfiguration()
{
StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312"))
}).ToList();
// var (csVToXlsxPath, csVToXlsxRelativePath) = FileStoreHelper.GetTrialCheckFilePath(_hostEnvironment, Path.GetFileNameWithoutExtension(fileName) + ".xlsx", trialId);
var (csVToXlsxPath, csVToXlsxRelativePath) = FileStoreHelper.GetTrialCheckFilePath(_hostEnvironment, Path.GetFileNameWithoutExtension(fileName) + ".xlsx", trialId);
// await MiniExcel.SaveAsAsync(csVToXlsxPath, etcCheckList, excelType: ExcelType.XLSX);
await MiniExcel.SaveAsAsync(csVToXlsxPath, etcCheckList, excelType: ExcelType.XLSX);
// var Importer = new ExcelImporter();
var Importer = new ExcelImporter();
// var import = await Importer.Import<CheckViewModel>(System.IO.File.OpenRead(csVToXlsxPath));
var import = await Importer.Import<CheckViewModel>(System.IO.File.OpenRead(csVToXlsxPath));
// if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
// //if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
//if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
// if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors));
if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors));
// etcCheckList = import.Data.ToList();
etcCheckList = import.Data.ToList();
// #endregion
#endregion
// #region 导入组件有问题 excel编码格式
// //var Importer = new CsvImporter();
#region excel编码格式
//var Importer = new CsvImporter();
// //var import = await Importer.Import<CheckViewModel>(File.OpenRead(filePath));
//var import = await Importer.Import<CheckViewModel>(File.OpenRead(filePath));
// //if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
//if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
// //if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
//if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
// //if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors));
//if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors));
// //etcCheckList = import.Data.ToList();
// #endregion
//etcCheckList = import.Data.ToList();
#endregion
//}
#endregion
}
//ExcelReaderFactory 需要自己验证数据 并且从固定列取数据
else
{
@@ -717,7 +931,7 @@ namespace IRaCIS.Core.API.Controllers
if (etcCheckList == null || etcCheckList.Count == 0)
{
//---请保证上传数据符合模板文件中的样式,且存在有效数据。
return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]);
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_InvalidData"));
}
else
{
@@ -738,7 +952,7 @@ namespace IRaCIS.Core.API.Controllers
if (etcCheckList.Count == 0)
{
//---请保证上传数据符合模板文件中的样式,且存在有效数据。
return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]);
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_InvalidData"));
}
}
@@ -754,223 +968,8 @@ namespace IRaCIS.Core.API.Controllers
#endregion
#region
#region DTO
public class DoctorDownloadInfo
{
public Guid Id { get; set; }
public string Name { get; set; }
public string ReviewerCode { get; set; }
public List<DownloadFileInfo> FileList { get; set; }
}
public class DownloadFileInfo
{
public string FileName { get; set; }
public string Path { get; set; }
}
public class GetDoctorPathCommand
{
public int Language { get; set; }
public List<Guid> DoctorIdList { get; set; }
}
public class GetDoctoreAttachPathCommand
{
public Guid DoctorId { get; set; }
public List<Guid> AttachmentIdList { get; set; }
}
#endregion
/// <summary>医生文件上传下载</summary>
[ApiExplorerSettings(GroupName = "Common")]
[ApiController]
public class FileController : UploadBaseController
{
public IMapper _mapper { get; set; }
public IUserInfo _userInfo { get; set; }
private readonly IWebHostEnvironment _hostEnvironment;
private readonly IFileService _fileService;
public FileController(IMapper mapper, IUserInfo userInfo, IWebHostEnvironment hostEnvironment, IFileService fileService)
{
_fileService = fileService;
_hostEnvironment = hostEnvironment;
_mapper = mapper;
_userInfo = userInfo;
}
/// <summary>
/// New 医生首页 多选 获取多个医生信息+文件路径列表 医生压缩包名称 doctorCode + "_" + doctorName _(时间戳或者随机的Guid)
/// </summary>
/// <returns></returns>
[HttpPost, Route("file/GetOfficialResume")]
public async Task<IResponseOutput<List<DoctorDownloadInfo>>> GetOfficialResume(GetDoctorPathCommand command,
[FromServices] IRepository<Attachment> _attachmentrepository)
{
var list = await _attachmentrepository.Where(t => command.DoctorIdList.Contains(t.DoctorId) && command.Language == t.Language).GroupBy(t => new { Name = t.Doctor.FirstName + "_" + t.Doctor.LastName, ReviewerCode = t.Doctor.ReviewerCode, t.DoctorId })
.Select(g => new DoctorDownloadInfo()
{
Id = g.Key.DoctorId,
Name = g.Key.Name,
ReviewerCode = g.Key.ReviewerCode,
FileList = g.Select(t => new DownloadFileInfo() { FileName = t.FileName, Path = t.Path }).ToList()
}).ToListAsync();
return ResponseOutput.Ok(list);
}
/// <summary>
/// New 项目入组 勾选获取简历路径
/// </summary>
/// <param name="command"></param>
/// <param name="_doctorService"></param>
/// <param name="_attachmentrepository"></param>
/// <returns></returns>
[HttpPost, Route("file/GetTrialDoctorOfficialResume")]
public async Task<IResponseOutput<List<DoctorDownloadInfo>>> GetTrialDoctorOfficialResume(GetDoctorPathCommand command,
[FromServices] IDoctorService _doctorService,
[FromServices] IRepository<Attachment> _attachmentrepository)
{
var list = await _attachmentrepository.Where(t => command.DoctorIdList.Contains(t.DoctorId) && command.Language == t.Language && t.IsOfficial && t.Type.Equals("Resume")).GroupBy(t => new { Name = t.Doctor.FirstName + "_" + t.Doctor.LastName, ReviewerCode = t.Doctor.ReviewerCode, t.DoctorId })
.Select(g => new DoctorDownloadInfo()
{
Id = g.Key.DoctorId,
Name = g.Key.Name,
ReviewerCode = g.Key.ReviewerCode,
FileList = g.Select(t => new DownloadFileInfo() { FileName = t.FileName, Path = t.Path }).ToList()
}).ToListAsync();
return ResponseOutput.Ok(list);
}
/// <summary>
/// new 医生详情 勾选或者下载文件路径
/// </summary>
/// <param name="command"></param>
/// <param name="_doctorService"></param>
/// <param name="_attachmentrepository"></param>
/// <returns></returns>
[HttpPost, Route("file/GetDoctorAttachment")]
public async Task<IResponseOutput<DoctorDownloadInfo>> GetDoctorAttachment(GetDoctoreAttachPathCommand command,
[FromServices] IDoctorService _doctorService,
[FromServices] IRepository<Attachment> _attachmentrepository)
{
var find = await _attachmentrepository.Where(t => command.DoctorId == t.DoctorId && command.AttachmentIdList.Contains(t.Id)).GroupBy(t => new { Name = t.Doctor.FirstName + "_" + t.Doctor.LastName, ReviewerCode = t.Doctor.ReviewerCode, t.DoctorId })
.Select(g => new DoctorDownloadInfo()
{
Id = g.Key.DoctorId,
Name = g.Key.Name,
ReviewerCode = g.Key.ReviewerCode,
FileList = g.Select(t => new DownloadFileInfo() { FileName = t.FileName, Path = t.Path }).ToList()
}).FirstOrDefaultAsync();
return ResponseOutput.Ok(find);
}
#region
/// <summary>
/// 下载多个医生的所有附件
/// </summary>
/// <param name="doctorIds"></param>
/// <returns></returns>
[Obsolete]
[HttpPost, Route("file/downloadDoctorAttachments")]
public async Task<IResponseOutput<UploadFileInfoDTO>> DownloadAttachment(Guid[] doctorIds)
{
var path = await _fileService.CreateDoctorsAllAttachmentZip(doctorIds);
return ResponseOutput.Ok(new UploadFileInfoDTO
{
FilePath = path,
FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7)
});
}
/// <summary>
/// 下载指定医生的指定附件
/// </summary>
/// <param name="doctorId">医生Id</param>
/// <param name="attachmentIds">要下载的附件Id</param>
/// <returns></returns>
[HttpPost, Route("file/downloadByAttachmentId/{doctorId}")]
[Obsolete]
public async Task<IResponseOutput<UploadFileInfoDTO>> DownloadAttachmentById(Guid doctorId, Guid[] attachmentIds)
{
var path = await _fileService.CreateZipPackageByAttachment(doctorId, attachmentIds);
return ResponseOutput.Ok(new UploadFileInfoDTO
{
FilePath = await _fileService.CreateZipPackageByAttachment(doctorId, attachmentIds),
FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7)
});
}
/// <summary>
/// 下载医生官方简历 首页 区分 中文和英文
/// </summary>
/// <param name="language"></param>
/// <param name="doctorIds"></param>
/// <returns></returns>
[HttpPost, Route("file/downloadOfficialCV/{language}")]
[Obsolete]
public async Task<IResponseOutput<UploadFileInfoDTO>> DownloadOfficialResume(int language, Guid[] doctorIds)
{
var path = await _fileService.CreateDoctorsAllAttachmentZip(doctorIds);
return ResponseOutput.Ok(new UploadFileInfoDTO
{
FilePath = await _fileService.CreateOfficialResumeZip(language, doctorIds),
FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7)
});
}
/// <summary>
/// 入组 项目下载简历
/// </summary>
/// <param name="language"></param>
/// <param name="trialId"></param>
/// <param name="doctorIdArray"></param>
/// <returns></returns>
[HttpPost, Route("enroll/downloadResume/{trialId:guid}/{language}")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[AllowAnonymous]
[Obsolete]
public async Task<IResponseOutput<string>> DownloadResume(int language, Guid trialId, Guid[] doctorIdArray)
{
var zipPath = await _fileService.CreateOfficialResumeZip(language, doctorIdArray);
return ResponseOutput.Ok(zipPath);
}
#endregion
}
#endregion
#region
@@ -982,18 +981,25 @@ namespace IRaCIS.Core.API.Controllers
public IMapper _mapper { get; set; }
public IUserInfo _userInfo { get; set; }
private readonly IMediator _mediator;
public IStringLocalizer _localizer { get; set; }
private readonly IWebHostEnvironment _hostEnvironment;
public UploadDownLoadController(IMapper mapper, IUserInfo userInfo, IStringLocalizer localizer, IMediator mediator, IWebHostEnvironment hostEnvironment)
public UploadDownLoadController(IMapper mapper, IUserInfo userInfo, IMediator mediator, IWebHostEnvironment hostEnvironment)
{
_hostEnvironment = hostEnvironment;
_localizer = localizer;
_mediator = mediator;
_mapper = mapper;
_userInfo = userInfo;
}
[HttpPost, Route("TrialSiteSurvey/TestOOS")]
public string TestUploadFileToOOS(string path)
{
return FileStoreHelper.UploadOOS(path, "testc/test", true);
}
[HttpPost, Route("TrialSiteSurvey/UploadTrialSiteSurveyUser")]
[DisableFormValueModelBinding]
[UnitOfWork]
@@ -1015,28 +1021,28 @@ namespace IRaCIS.Core.API.Controllers
if (!realFileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase))
{
// 请用提供格式的模板excel上传需要处理的数据
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_TemplateUploadData"]);
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_TemplateUploadData"));
}
var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/SiteSurvey", realFileName);
var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/SiteSurvey", realFileName);
await _inspectionFileRepository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId });
return ossRelativePath;
});
//去掉空白行
var excelList = MiniExcel.Query<SiteSurveyUserImportDto>(templateFileStream, excelType: ExcelType.XLSX).ToList()
var excelList = MiniExcel.Query<SiteSurveyUserImportDto>(templateFileStream,excelType:ExcelType.XLSX).ToList()
.Where(t => !(string.IsNullOrWhiteSpace(t.TrialSiteCode) && string.IsNullOrWhiteSpace(t.FirstName) && string.IsNullOrWhiteSpace(t.LastName) && string.IsNullOrWhiteSpace(t.Email)
&& string.IsNullOrWhiteSpace(t.Phone) && string.IsNullOrWhiteSpace(t.UserTypeStr) && string.IsNullOrWhiteSpace(t.OrganizationName))).ToList();
if (excelList.Any(t => string.IsNullOrWhiteSpace(t.TrialSiteCode) || string.IsNullOrWhiteSpace(t.FirstName) || string.IsNullOrWhiteSpace(t.LastName) || string.IsNullOrWhiteSpace(t.Email) || string.IsNullOrWhiteSpace(t.UserTypeStr)))
{
//请确保Excel中 每一行的 中心编号,姓名,邮箱,用户类型数据记录完整再进行上传
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_EnsureCompleteData"]);
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_EnsureCompleteData"));
}
var siteCodeList = excelList.Select(t => t.TrialSiteCode.Trim().ToUpper()).Distinct().ToList();
@@ -1044,35 +1050,35 @@ namespace IRaCIS.Core.API.Controllers
if (_trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode.ToUpper())).Count() != siteCodeList.Count)
{
//在项目中未找到该Excel中部分或全部中心
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidCenters"]);
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidCenters"));
}
if (excelList.GroupBy(t => new { t.TrialSiteCode, t.UserTypeStr, t.Email }).Any(g => g.Count() > 1))
if (excelList.GroupBy(t => new {t.TrialSiteCode, t.UserTypeStr, t.Email }).Any(g => g.Count() > 1))
{
// 同一邮箱,同一用户类型,只能生成一个账户,请核查Excel数据
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_CheckDuplicateAccounts"]);
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_CheckDuplicateAccounts"));
}
if (excelList.Any(t => !t.Email.Contains("@")))
{
//有邮箱不符合邮箱格式,请核查Excel数据
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidEmail"]);
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidEmail"));
}
var generateUserTypeList = new List<string>() { "CRC", "CRA" };
var generateUserTypeList = new List<string>() { "CRC", "CRA","SR" };
if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper())))
{
//用户类型仅能为 CRC,SR,CRA 请核查Excel数据
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidUserType"]);
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidUserType"));
}
if (excelList.Count == 0)
{
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_NoValiddata"]);
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_NoValiddata"));
}
//处理好 用户类型 和用户类型枚举
var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList();
var siteList = _trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode)).Select(t => new { t.TrialSiteCode, TrialSiteId= t.Id }).ToList();
var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.SR).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList();
var siteList = _trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode)).Select(t => new { t.TrialSiteCode, t.SiteId }).ToList();
foreach (var item in excelList)
{
@@ -1089,11 +1095,14 @@ namespace IRaCIS.Core.API.Controllers
item.UserTypeEnum = UserTypeEnum.CRA;
break;
case "SR":
item.UserTypeId = sysUserTypeList.FirstOrDefault(t => t.UserTypeEnum == UserTypeEnum.SR).UserTypeId;
item.UserTypeEnum = UserTypeEnum.SR;
break;
}
item.TrialSiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.ToUpper() == item.TrialSiteCode.ToUpper()).TrialSiteId;
item.SiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.ToUpper() == item.TrialSiteCode.ToUpper()).SiteId;
}
@@ -1128,12 +1137,12 @@ namespace IRaCIS.Core.API.Controllers
[DisableFormValueModelBinding]
public async Task<IResponseOutput> UploadCommonDoc()
{
return await SingleFileUploadAsync((fileName) => FileStoreHelper.GetCommonDocPath(_hostEnvironment, fileName));
}
public enum UploadFileType
{
DataUpload = 1,
@@ -1187,6 +1196,8 @@ namespace IRaCIS.Core.API.Controllers
}
}
#endregion
+38 -19
View File
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<SignAssembly>false</SignAssembly>
<UserSecretsId>354572d4-9e15-4099-807c-63a2d29ff9f2</UserSecretsId>
<LangVersion>default</LangVersion>
@@ -14,7 +14,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>.\IRaCIS.Core.API.xml</DocumentationFile>
<NoWarn>1701;1702;1591;1570;</NoWarn>
<NoWarn>1701;1702;1591;</NoWarn>
<OutputPath>..\bin\</OutputPath>
</PropertyGroup>
@@ -24,7 +24,12 @@
<NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Remove="wwwroot\**" />
<EmbeddedResource Remove="UploadFile\**" />
<EmbeddedResource Remove="wwwroot\**" />
</ItemGroup>
<ItemGroup>
<Content Remove="web.config" />
@@ -63,25 +68,26 @@
<ItemGroup>
<PackageReference Include="aliyun-net-sdk-sts" Version="3.1.2" />
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="EasyCaching.Interceptor.Castle" Version="1.9.1" />
<PackageReference Include="EasyCaching.Serialization.MessagePack" Version="1.9.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="EasyCaching.Interceptor.Castle" Version="1.9.2" />
<PackageReference Include="EasyCaching.Serialization.MessagePack" Version="1.9.2">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.12" />
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
<PackageReference Include="Hangfire.SqlServer" Version="1.8.12" />
<PackageReference Include="EasyCaching.InMemory" Version="1.9.1" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.5" />
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
<PackageReference Include="Hangfire.SqlServer" Version="1.8.5" />
<PackageReference Include="Invio.Extensions.Authentication.JwtBearer" Version="2.0.1" />
<PackageReference Include="LogDashboard" Version="1.4.8" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.5" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.0.3" />
<PackageReference Include="Serilog.Sinks.Email" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.23" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.2" />
<PackageReference Include="Quartz.Extensions.DependencyInjection" Version="3.7.0" />
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.7.0" />
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.0.1" />
<PackageReference Include="Serilog.Sinks.Email" Version="2.4.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.6.2" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.5.0" />
</ItemGroup>
<ItemGroup>
@@ -94,6 +100,11 @@
</ItemGroup>
<ItemGroup>
<Content Update="appsettings.Uat_Study.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\EmailTemplate\AdminAddUser_US.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
@@ -154,7 +165,15 @@
<Folder Include="Properties\PublishProfiles\" />
</ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties properties_4launchsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
<ProjectExtensions><VisualStudio><UserProperties anonymizetagsetting_1json__JsonSchema="http://json.schemastore.org/jovo-language-model" properties_4launchsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
<ItemGroup>
<None Remove="..\.dockerignore" />
</ItemGroup>
<ItemGroup>
<None Remove="..\.dockerignore" />
</ItemGroup>
</Project>
+1 -136
View File
@@ -16,20 +16,7 @@
医生基本信息 、工作信息 专业信息、审核状态
</summary>
</member>
<member name="M:IRaCIS.Api.Controllers.ExtraController.GetDoctorDetail(IRaCIS.Application.Interfaces.IAttachmentService,IRaCIS.Application.Interfaces.IDoctorService,IRaCIS.Application.Interfaces.IEducationService,IRaCIS.Application.Interfaces.ITrialExperienceService,IRaCIS.Application.Interfaces.IResearchPublicationService,IRaCIS.Application.Interfaces.IVacationService,System.Guid)">
<summary>
获取医生详情
</summary>
<param name="attachmentService"></param>
<param name="_doctorService"></param>
<param name="_educationService"></param>
<param name="_trialExperienceService"></param>
<param name="_researchPublicationService"></param>
<param name="_vacationService"></param>
<param name="doctorId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,EasyCaching.Core.IEasyCachingProvider,IRaCIS.Application.Services.IUserService,IRaCIS.Core.Application.Auth.ITokenService,IRaCIS.Core.Application.Contracts.IReadingImageTaskService,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},IRaCIS.Application.Services.IMailVerificationService)">
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,EasyCaching.Core.IEasyCachingProvider,IRaCIS.Application.Services.IUserService,IRaCIS.Core.Application.Auth.ITokenService,Microsoft.Extensions.Configuration.IConfiguration)">
<summary> 系统用户登录接口[New] </summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateTrialInspection(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Application.Contracts.TrialCommand})">
@@ -41,49 +28,6 @@
<param name="param"></param>
<returns>新记录Id</returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.WorkLoadAddOrUpdate(IRaCIS.Application.Services.IDoctorWorkloadService,IRaCIS.Application.Contracts.WorkloadCommand)">
<summary>
添加或更新工作量[AUTH]
</summary>
<param name="_trialWorkloadService"></param>
<param name="workLoadAddOrUpdateModel"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateExchangeRate(IRaCIS.Application.Interfaces.IExchangeRateService,IRaCIS.Application.Interfaces.IPaymentAdjustmentService,IRaCIS.Application.Contracts.ExchangeRateCommand)">
<summary>
添加或更新汇率(会触发没有对锁定的费用计算)
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateRankPrice(IRaCIS.Application.Interfaces.IReviewerPayInfoService,IRaCIS.Application.Interfaces.IRankPriceService,IRaCIS.Application.Contracts.RankPriceCommand)">
<summary>
添加或更新 职称单价[AUTH]
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateReviewerPayInfo(IRaCIS.Application.Interfaces.IReviewerPayInfoService,IRaCIS.Application.Contracts.ReviewerPayInfoCommand)">
<summary>
添加或更新(替换)医生支付展信息[AUTH]
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateTrialPaymentPrice(IRaCIS.Application.Interfaces.ITrialPaymentPriceService,IRaCIS.Application.Contracts.TrialPaymentPriceCommand)">
<summary>
保存(替换)项目支付价格信息(会触发没有被锁定的费用计算)[AUTH]
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateAwardPriceList(IRaCIS.Application.Interfaces.IVolumeRewardService,System.Collections.Generic.IEnumerable{IRaCIS.Application.Interfaces.AwardPriceCommand})">
<summary>
批量更新奖励费用[AUTH]
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.CalculateMonthlyPayment(IRaCIS.Application.Contracts.CalculateDoctorAndMonthDTO)">
<summary>
计算医生月度费用,并将计算的结果存入费用表
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.GetMonthlyPaymentList(IRaCIS.Application.Interfaces.IPaymentService,IRaCIS.Application.Interfaces.IExchangeRateService,IRaCIS.Application.Contracts.MonthlyPaymentQueryDTO)">
<summary>
Financials /Monthly Payment 列表查询接口
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.GetInspectionList(IRaCIS.Core.Application.Service.Inspection.DTO.GetDataInspectionDto)">
<summary>
获取稽查数据
@@ -208,12 +152,6 @@
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.ResetAndAsyncCriterion(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Service.Reading.Dto.ResetAndAsyncCriterionInDto})">
<summary>
重置并同步项目阅片标准
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.CRCRequestToQC(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Contracts.CRCRequestToQCCommand})">
<summary>
CRC RequestToQC 批量提交
@@ -278,9 +216,7 @@
<summary>
上传非Dicom 文件 支持压缩包 多文件上传
</summary>
<param name="incommand"></param>
<param name="_noneDicomStudyRepository"></param>
<param name="_studyMonitorRepository"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadVisitCheckExcel(System.Guid,IRaCIS.Core.Application.Helper.IOSSService)">
@@ -288,67 +224,6 @@
一致性核查 excel上传 支持三种格式
</summary>
<param name="trialId"></param>
<param name="oSSService"></param>
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>
<member name="T:IRaCIS.Core.API.Controllers.FileController">
<summary>医生文件上传下载</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.GetOfficialResume(IRaCIS.Core.API.Controllers.GetDoctorPathCommand,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Attachment})">
<summary>
New 医生首页 多选 获取多个医生信息+文件路径列表 医生压缩包名称 doctorCode + "_" + doctorName _(时间戳或者随机的Guid)
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.GetTrialDoctorOfficialResume(IRaCIS.Core.API.Controllers.GetDoctorPathCommand,IRaCIS.Application.Interfaces.IDoctorService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Attachment})">
<summary>
New 项目入组 勾选获取简历路径
</summary>
<param name="command"></param>
<param name="_doctorService"></param>
<param name="_attachmentrepository"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.GetDoctorAttachment(IRaCIS.Core.API.Controllers.GetDoctoreAttachPathCommand,IRaCIS.Application.Interfaces.IDoctorService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Attachment})">
<summary>
new 医生详情 勾选或者下载文件路径
</summary>
<param name="command"></param>
<param name="_doctorService"></param>
<param name="_attachmentrepository"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadAttachment(System.Guid[])">
<summary>
下载多个医生的所有附件
</summary>
<param name="doctorIds"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadAttachmentById(System.Guid,System.Guid[])">
<summary>
下载指定医生的指定附件
</summary>
<param name="doctorId">医生Id</param>
<param name="attachmentIds">要下载的附件Id</param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadOfficialResume(System.Int32,System.Guid[])">
<summary>
下载医生官方简历 首页 区分 中文和英文
</summary>
<param name="language"></param>
<param name="doctorIds"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadResume(System.Int32,System.Guid,System.Guid[])">
<summary>
入组 项目下载简历
</summary>
<param name="language"></param>
<param name="trialId"></param>
<param name="doctorIdArray"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.DownloadCommonFile(System.String,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument})">
@@ -371,11 +246,6 @@
IPLimit限流 启动服务
</summary>
</member>
<member name="T:IRaCIS.Core.API.JSONTimeZoneConverter">
<summary>
序列化,反序列化的时候,处理时间 时区转换
</summary>
</member>
<member name="M:IRaCIS.Core.API.NullToEmptyStringResolver.CreateProperties(System.Type,Newtonsoft.Json.MemberSerialization)">
<summary>
创建属性
@@ -391,11 +261,6 @@
<param name="httpContext"></param>
<returns></returns>
</member>
<member name="T:TimeZoneAdjustmentMiddleware">
<summary>
废弃,没用
</summary>
</member>
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
<summary>
对称可逆加密
@@ -1,118 +0,0 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
/// <summary>
/// 废弃,没用
/// </summary>
public class TimeZoneAdjustmentMiddleware
{
private readonly RequestDelegate _next;
public TimeZoneAdjustmentMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (string.IsNullOrEmpty(context.Request.ContentType))
{
// 请求没有内容体,可能是一个没有请求体的请求,比如 GET 请求
await _next(context);
return;
}
var timeZoneId = "Asia/Shanghai"; // 客户端默认时区
var timeZoneIdHeaderValue = context.Request.Headers["TimeZoneId"];
if (!string.IsNullOrEmpty(timeZoneIdHeaderValue))
{
timeZoneId = timeZoneIdHeaderValue;
}
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
// 处理 JSON 请求体中的时间字段
if (context.Request.ContentType.StartsWith("application/json"))
{
var requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync();
// 使用 JSON.NET 或 System.Text.Json 解析 JSON 请求体
// 假设请求体中有一个名为 "dateTime" 的时间字段
dynamic jsonData = JsonConvert.DeserializeObject(requestBody);
if (jsonData.dateTime != null)
{
if (DateTime.TryParse((string)jsonData.dateTime, out DateTime dateTime))
{
// 将 JSON 请求体中的时间字段转换为服务器时区的时间
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
jsonData.dateTime = serverTime;
}
}
// 将修改后的 JSON 请求体重新写入请求流中
var jsonBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jsonData));
context.Request.Body = new MemoryStream(jsonBytes);
context.Request.ContentLength = jsonBytes.Length;
}
// 处理 URL 表单参数
var modifiedQuery = new Dictionary<string, StringValues>();
foreach (var key in context.Request.Query.Keys)
{
if (DateTime.TryParse(context.Request.Query[key], out DateTime dateTime))
{
// 将 URL 表单参数中的时间转换为服务器时区的时间
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
modifiedQuery[key] = new StringValues(serverTime.ToString());
}
else
{
modifiedQuery[key] = context.Request.Query[key];
}
}
context.Request.Query = new QueryCollection(modifiedQuery);
// 处理Form请求体中的参数
if (context.Request.HasFormContentType)
{
var modifiedForm = new Dictionary<string, StringValues>();
foreach (var key in context.Request.Form.Keys)
{
if (DateTime.TryParse(context.Request.Form[key], out DateTime dateTime))
{
// 将请求体中的时间转换为服务器时区的时间
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
modifiedForm[key] = new StringValues(serverTime.ToString());
}
else
{
modifiedForm[key] = context.Request.Form[key];
}
}
var newFormCollection = new FormCollection(modifiedForm);
// 将新的表单集合设置回请求对象
context.Request.Form = newFormCollection;
}
await _next(context);
}
}
+8 -14
View File
@@ -24,10 +24,8 @@ using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.HttpOverrides;
using IRaCIS.Application.Services.BackGroundJob;
using LogDashboard;
using FellowOakDicom.Network;
using IRaCIS.Core.Application.Service.ImageAndDoc;
using IP2Region.Net.Abstractions;
using IP2Region.Net.XDB;
using OfficeOpenXml.Utils;
#region
@@ -111,7 +109,7 @@ builder.Services.AddControllers(options =>
}
})
.AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化 处理
.AddNewtonsoftJsonSetup(); // NewtonsoftJson 序列化 处理
builder.Services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig"));
builder.Services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
@@ -140,6 +138,8 @@ builder.Services.AddEasyCachingSetup(_configuration);
// hangfire 定时任务框架 有界面,更友好~
builder.Services.AddhangfireSetup(_configuration);
//
builder.Services.AddQuartZSetup(_configuration);
//Serilog 日志可视化 LogDashboard日志
builder.Services.AddLogDashboardSetup();
@@ -160,12 +160,12 @@ builder.Services.AddSignalR();
builder.Services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
//builder.Services.AddMemoryCache();
builder.Services.AddSingleton<ISearcher>(new Searcher(CachePolicy.Content, Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, "ip2region.xdb")));
#region
//builder.Services.AddMemoryCache();
////上传限制 配置
//builder.Services.Configure<FormOptions>(options =>
//{
@@ -202,7 +202,7 @@ app.UseResponseCompression();
//不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();
app.UseMiddleware<MultiDiskStaticFilesMiddleware>();
//app.UseMiddleware<MultiDiskStaticFilesMiddleware>();
//LogDashboard
app.UseLogDashboard("/LogDashboard");
@@ -258,7 +258,6 @@ var hangfireJobService = app.Services.GetRequiredService<IIRaCISHangfireJob>();
await hangfireJobService.InitHangfireJobTaskAsync();
#endregion
try
@@ -294,11 +293,6 @@ try
//Log.Logger.Warning($"ContentRootPath——GetParent{Directory.GetParent(env.ContentRootPath).Parent.FullName}");
//Log.Logger.Warning($"ContentRootPath——xx{Path.GetDirectoryName(Path.GetDirectoryName(env.ContentRootPath))}");
var server = DicomServerFactory.Create<CStoreSCPService>(11112,userState: app.Services);
app.Run();
}
+4 -50
View File
@@ -1,67 +1,21 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:3305",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Test_IRC"
}
},
"IRaCIS.Test_IRC": {
"Test_Study": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Test_IRC"
"ASPNETCORE_ENVIRONMENT": "Test_Study"
},
"applicationUrl": "http://localhost:6100"
},
"IRaCIS.Event_IRC": {
"Uat_Study": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Event_IRC"
},
"applicationUrl": "http://localhost:6101"
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
"publishAllPorts": true
},
"IRaCIS.Uat_IRC": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Uat_IRC"
},
"applicationUrl": "http://localhost:6100"
},
"IRaCIS.Prod_IRC": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Prod_IRC"
},
"applicationUrl": "http://localhost:6100"
},
"IRaCIS.US_IRC": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "US_IRC"
"ASPNETCORE_ENVIRONMENT": "Uat_Study"
},
"applicationUrl": "http://localhost:6100"
}
}
}
@@ -0,0 +1,39 @@
using Hangfire.Dashboard;
using System.IdentityModel.Tokens.Jwt;
using System;
using System.Linq;
using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.API.Filter
{
//从cookie 中取值
public class hangfireAuthorizationFilter : IDashboardAuthorizationFilter
{
public bool Authorize(DashboardContext context)
{
var httpContext = context.GetHttpContext();
// Allow all authenticated users to see the Dashboard (potentially dangerous).
//return httpContext.User.Identity.IsAuthenticated;
var jwtToken = httpContext.Request.Cookies["access_token"]?.ToString();
var handler = new JwtSecurityTokenHandler();
if (handler.CanReadToken(jwtToken))
{
var jwtSecurityToken = handler.ReadJwtToken(jwtToken);
return jwtSecurityToken.Claims.Any(t => t.Type == JwtIRaCISClaimType.UserTypeEnum && (t.Value == UserTypeEnum.Admin.ToString()|| t.Value== UserTypeEnum.SuperAdmin.ToString()));
}
else
{
return false;
}
}
}
}
@@ -1,17 +0,0 @@
using Hangfire.Dashboard;
namespace IRaCIS.Core.API.Filter
{
public class hangfireAuthorizationFilter : IDashboardAuthorizationFilter
{
public bool Authorize(DashboardContext context)
{
var httpContext = context.GetHttpContext();
// Allow all authenticated users to see the Dashboard (potentially dangerous).
return httpContext.User.Identity.IsAuthenticated;
//return true;
}
}
}
@@ -1,11 +1,8 @@
using Azure;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.FileProviders.Physical;
@@ -14,7 +11,6 @@ using Microsoft.Extensions.Hosting.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.VisualBasic;
using Newtonsoft.Json;
using SharpCompress.Common;
using System.IO;
using System.Linq;
@@ -51,7 +47,7 @@ namespace IRaCIS.Core.API
var path = context.Request.Path.Value;
var isIRacisFile = path.StartsWith($"/{StaticData.Folder.IRaCISDataFolder}");
var isDicomFile = isIRacisFile && path.Contains($"{StaticData.Folder.DicomFolder}");
var isDicomFile = path.Contains($"{StaticData.Folder.DicomFolder}");
@@ -151,12 +147,6 @@ namespace IRaCIS.Core.API
return;
}
}
// 如果没有找到文件,返回404
context.Response.StatusCode = 404;
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk("File not found")));
}
@@ -1,6 +1,4 @@
using Hangfire;
using Hangfire.Dashboard;
using IRaCIS.Core.API._PipelineExtensions.Serilog;
using IRaCIS.Core.API._PipelineExtensions.Serilog;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Serilog;
@@ -21,7 +21,7 @@ namespace IRaCIS.Core.API
diagnosticContext.Set("Host", request.Host);
//这种获取的Ip不准 配置服务才行
//diagnosticContext.Set("RequestIP", httpContext.Connection.RemoteIpAddress.ToString());
diagnosticContext.Set("RequestIP", httpContext.Connection.RemoteIpAddress.ToString());
//这种方式可以,但是serilog提供了 就不用了
//diagnosticContext.Set("TestIP", httpContext.GetUserIp());
@@ -16,7 +16,7 @@ namespace IRaCIS.Core.API
public IStringLocalizer _localizer;
public ApiResponseHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
IStringLocalizer localizer,
ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder)
ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
{
_localizer = localizer;
@@ -1,86 +0,0 @@
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Domain.Share;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace IRaCIS.Core.API
{
public static class AuthorizationPolicySetup
{
public static void AddAuthorizationPolicySetup(this IServiceCollection services, IConfiguration configuration)
{
services.AddAuthorization(options =>
{
//影像质控策略 只允许 CRC IQC进行操作
options.AddPolicy(IRaCISPolicy.CRC_IQC, policyBuilder =>
{
policyBuilder.RequireClaim("userTypeEnumInt", ((int)UserTypeEnum.ClinicalResearchCoordinator).ToString(), ((int)UserTypeEnum.IQC).ToString());
});
//一致性核查策略 只允许 CRC PM APM 进行操作
options.AddPolicy(IRaCISPolicy.PM_APM_CRC, policyBuilder =>
{
policyBuilder.RequireClaim("userTypeEnumInt", ((int)UserTypeEnum.ProjectManager).ToString(), ((int)UserTypeEnum.ClinicalResearchCoordinator).ToString(), ((int)UserTypeEnum.APM).ToString());
});
options.AddPolicy(IRaCISPolicy.PM_APM, policyBuilder =>
{
policyBuilder.RequireClaim("userTypeEnumInt", ((int)UserTypeEnum.ProjectManager).ToString(), ((int)UserTypeEnum.APM).ToString());
});
options.AddPolicy(IRaCISPolicy.PM_IQC, policyBuilder =>
{
policyBuilder.RequireClaim("userTypeEnumInt", ((int)UserTypeEnum.ProjectManager).ToString(), ((int)UserTypeEnum.IQC).ToString());
});
options.AddPolicy(IRaCISPolicy.PM, policyBuilder =>
{
policyBuilder.RequireClaim("userTypeEnumInt", ((int)UserTypeEnum.ProjectManager).ToString());
});
options.AddPolicy(IRaCISPolicy.IQC, policyBuilder =>
{
policyBuilder.RequireClaim("userTypeEnumInt", ((int)UserTypeEnum.IQC).ToString());
});
options.AddPolicy(IRaCISPolicy.CRC, policyBuilder =>
{
policyBuilder.RequireClaim("userTypeEnumInt", ((int)UserTypeEnum.ClinicalResearchCoordinator).ToString());
});
options.AddPolicy(IRaCISPolicy.PM_APM_CRC_QC, policyBuilder =>
{
policyBuilder.RequireClaim("userTypeEnumInt", ((int)UserTypeEnum.ProjectManager).ToString(),((int)UserTypeEnum.ClinicalResearchCoordinator).ToString(), ((int)UserTypeEnum.APM).ToString(), ((int)UserTypeEnum.IQC).ToString());
});
options.AddPolicy(IRaCISPolicy.SPM_CPM, policyBuilder =>
{
policyBuilder.RequireClaim("userTypeEnumInt", ((int)UserTypeEnum.SPM).ToString(), ((int)UserTypeEnum.CPM).ToString());
});
options.AddPolicy(IRaCISPolicy.PM_APM_SPM_CPM, policyBuilder =>
{
policyBuilder.RequireClaim("userTypeEnumInt", ((int)UserTypeEnum.ProjectManager).ToString(), ((int)UserTypeEnum.APM).ToString(),((int)UserTypeEnum.SPM).ToString(), ((int)UserTypeEnum.CPM).ToString());
});
options.AddPolicy(IRaCISPolicy.PM_APM_SPM_CPM_SMM_CMM, policyBuilder =>
{
policyBuilder.RequireClaim("userTypeEnumInt", ((int)UserTypeEnum.ProjectManager).ToString(), ((int)UserTypeEnum.APM).ToString(), ((int)UserTypeEnum.SPM).ToString(),
((int)UserTypeEnum.CPM).ToString(), ((int)UserTypeEnum.SMM).ToString(), ((int)UserTypeEnum.CMM).ToString());
});
});
}
}
}
@@ -14,6 +14,7 @@ using MediatR;
using IRaCIS.Application.Services;
using IRaCIS.Application.Interfaces;
using AutoMapper;
using Quartz;
namespace IRaCIS.Core.API
{
@@ -30,6 +31,10 @@ namespace IRaCIS.Core.API
containerBuilder.RegisterType<Repository>().As<IRepository>().InstancePerLifetimeScope();
//containerBuilder.RegisterType<Mapper>().As<IMapper>().InstancePerLifetimeScope();
//containerBuilder.RegisterGeneric(typeof(EFUnitOfWork<>))
// .As(typeof(IEFUnitOfWork<>)).InstancePerLifetimeScope();//注册仓储
#endregion
@@ -45,7 +50,8 @@ namespace IRaCIS.Core.API
#endregion
//containerBuilder.RegisterType<BaseService>().As<IBaseService>().PropertiesAutowired().InstancePerLifetimeScope();
//containerBuilder.RegisterType<DictionaryService>().As<IDictionaryService>().InstancePerLifetimeScope();
@@ -53,13 +59,21 @@ namespace IRaCIS.Core.API
containerBuilder.RegisterAssemblyTypes(application).Where(t => t.FullName.Contains("Service"))
.PropertiesAutowired().AsImplementedInterfaces().EnableClassInterceptors();
//Assembly infrastructure = Assembly.Load("IRaCIS.Core.Infra.EFCore");
//containerBuilder.RegisterAssemblyTypes(infrastructure).AsImplementedInterfaces();
containerBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
containerBuilder.RegisterType<UserInfo>().As<IUserInfo>().InstancePerLifetimeScope();
//containerBuilder.RegisterType<Dictionary>().InstancePerLifetimeScope();
//Autofac 注册拦截器 需要注意的是生成api上服务上的动态代理AOP失效 间接掉用不影响
//containerBuilder.RegisterType<TrialStatusAutofacAOP>();
//containerBuilder.RegisterType<UserAddAOP>();
//containerBuilder.RegisterType<QANoticeAOP>();
//containerBuilder.RegisterType<LogService>().As<ILogService>().SingleInstance();
//注册hangfire任务 依赖注入
//注册hangfire任务 依赖注入
containerBuilder.RegisterType<ObtainTaskAutoCancelJob>().As<IObtainTaskAutoCancelJob>().InstancePerDependency();
@@ -49,14 +49,8 @@ namespace IRaCIS.Core.API
triggerOptions.AddTrigger<TableQuestionRowTrigger>();
//triggerOptions.AddTrigger<AddlTrialUserTrigger>();
triggerOptions.AddTrigger<VisitTaskIsFrontTaskNeedSignButNotSignTrigger>();
triggerOptions.AddTrigger<VisitTaskIbeforeTrigger>();
triggerOptions.AddTrigger<UserLogTrigger>();
triggerOptions.AddTrigger<VisitTaskIAfterSignTrigger>();
});
@@ -6,7 +6,7 @@ using Microsoft.Extensions.DependencyInjection;
namespace IRaCIS.Core.API
{
public static class EasyCachingSetup
public static class EasyCachingSetup
{
public static void AddEasyCachingSetup(this IServiceCollection services, IConfiguration configuration)
{
@@ -16,7 +16,7 @@ namespace IRaCIS.Core.API
//options.UseRedis(configuration, EasyCachingConstValue.DefaultRedisName).WithMessagePack(EasyCachingConstValue.DefaultRedisName);
});
//services.ConfigureCastleInterceptor(options => options.CacheProviderName = EasyCachingConstValue.DefaultRedisName);
@@ -13,12 +13,14 @@ namespace IRaCIS.Core.API
services.AddLogDashboard(opt =>
{
//opt.PathMatch = "/api/LogDashboard";
opt.PathMatch = "/LogDashboard";
opt.PathMatch = "/back/logs";
//opt.AddAuthorizationFilter(new LogDashboardBasicAuthFilter("admin", "zhizhun2018"));
//opt.AddAuthorizationFilter(new LogDashBoardAuthFilter());
});
}
@@ -0,0 +1,81 @@
//using System;
//using Microsoft.Extensions.DependencyInjection;
//using StackExchange.Profiling.Storage;
//namespace IRaCIS.Core.API
//{
// public class MiniProfilerConfigure
// {
// public static void ConfigureMiniProfiler(IServiceCollection services)
// {
// services.AddMiniProfiler(options =>
// {
// // All of this is optional. You can simply call .AddMiniProfiler() for all defaults
// // (Optional) Path to use for profiler URLs, default is /mini-profiler-resources
// options.RouteBasePath = "/profiler";
// //// (Optional) Control storage
// //// (default is 30 minutes in MemoryCacheStorage)
// (options.Storage as MemoryCacheStorage).CacheDuration = TimeSpan.FromMinutes(10);
// //// (Optional) Control which SQL formatter to use, InlineFormatter is the default
// //options.SqlFormatter = new StackExchange.Profiling.SqlFormatters.InlineFormatter();
// //// (Optional) To control authorization, you can use the Func<HttpRequest, bool> options:
// //// (default is everyone can access profilers)
// //options.ResultsAuthorize = request => MyGetUserFunction(request).CanSeeMiniProfiler;
// //options.ResultsListAuthorize = request => MyGetUserFunction(request).CanSeeMiniProfiler;
// //// Or, there are async versions available:
// //options.ResultsAuthorizeAsync = async request => (await MyGetUserFunctionAsync(request)).CanSeeMiniProfiler;
// //options.ResultsAuthorizeListAsync = async request => (await MyGetUserFunctionAsync(request)).CanSeeMiniProfilerLists;
// //// (Optional) To control which requests are profiled, use the Func<HttpRequest, bool> option:
// //// (default is everything should be profiled)
// //options.ShouldProfile = request => MyShouldThisBeProfiledFunction(request);
// //// (Optional) Profiles are stored under a user ID, function to get it:
// //// (default is null, since above methods don't use it by default)
// //options.UserIdProvider = request => MyGetUserIdFunction(request);
// //// (Optional) Swap out the entire profiler provider, if you want
// //// (default handles async and works fine for almost all applications)
// //options.ProfilerProvider = new MyProfilerProvider();
// //// (Optional) You can disable "Connection Open()", "Connection Close()" (and async variant) tracking.
// //// (defaults to true, and connection opening/closing is tracked)
// //options.TrackConnectionOpenClose = true;
// //// (Optional) Use something other than the "light" color scheme.
// //// (defaults to "light")
// //options.ColorScheme = StackExchange.Profiling.ColorScheme.Auto;
// //// The below are newer options, available in .NET Core 3.0 and above:
// //// (Optional) You can disable MVC filter profiling
// //// (defaults to true, and filters are profiled)
// //options.EnableMvcFilterProfiling = true;
// //// ...or only save filters that take over a certain millisecond duration (including their children)
// //// (defaults to null, and all filters are profiled)
// //// options.MvcFilterMinimumSaveMs = 1.0m;
// //// (Optional) You can disable MVC view profiling
// //// (defaults to true, and views are profiled)
// //options.EnableMvcViewProfiling = true;
// //// ...or only save views that take over a certain millisecond duration (including their children)
// //// (defaults to null, and all views are profiled)
// //// options.MvcViewMinimumSaveMs = 1.0m;
// //// (Optional) listen to any errors that occur within MiniProfiler itself
// //// options.OnInternalError = e => MyExceptionLogger(e);
// //// (Optional - not recommended) You can enable a heavy debug mode with stacks and tooltips when using memory storage
// //// It has a lot of overhead vs. normal profiling and should only be used with that in mind
// //// (defaults to false, debug/heavy mode is off)
// ////options.EnableDebugMode = true;
// });
// //.AddEntityFramework();
// }
// }
//}
@@ -0,0 +1,46 @@
using IRaCIS.Core.Domain.Share;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
namespace IRaCIS.Core.API
{
public class JSONCustomDateConverter : DateTimeConverterBase
{
private TimeZoneInfo _timeZoneInfo;
private string _dateFormat;
private IUserInfo _userInfo;
public JSONCustomDateConverter(string dateFormat, TimeZoneInfo timeZoneInfo, IUserInfo userInfo)
{
_dateFormat = dateFormat;
_timeZoneInfo = timeZoneInfo;
_userInfo = userInfo;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var timeZoneId = _userInfo.TimeZoneId;
var needConvertUtcDateTime = Convert.ToDateTime(value);
var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
var dateTimeOffset = new DateTimeOffset(needConvertUtcDateTime);
var time = TimeZoneInfo.ConvertTimeFromUtc(needConvertUtcDateTime, tz).ToString(_dateFormat);
writer.WriteValue(time);
writer.Flush();
}
}
}
@@ -1,103 +0,0 @@
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using StackExchange.Redis;
using System;
using System.Globalization;
namespace IRaCIS.Core.API
{
/// <summary>
/// 序列化,反序列化的时候,处理时间 时区转换
/// </summary>
public class JSONTimeZoneConverter : DateTimeConverterBase
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly TimeZoneInfo _clientTimeZone;
public JSONTimeZoneConverter(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
//默认是UTC
//var timeZoneId = "Etc/UTC";
var timeZoneId = "Asia/Shanghai";
var timeZoneIdHeader = _httpContextAccessor?.HttpContext?.Request?.Headers["TimeZoneId"];
if (timeZoneIdHeader is not null && !string.IsNullOrEmpty(timeZoneIdHeader.Value))
{
timeZoneId = timeZoneIdHeader.Value;
}
_clientTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
}
public override bool CanConvert(Type objectType)
{
// 仅支持 DateTime 类型的转换
return objectType == typeof(DateTime)|| objectType == typeof(DateTime?);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null)
{
return null;
}
DateTime dateTime;
if (reader.ValueType == typeof(DateTime) || reader.ValueType == typeof(DateTime?))
{
DateTime? nullableDateTime = reader.Value as DateTime?;
if (nullableDateTime != null && nullableDateTime.HasValue)
{
dateTime = nullableDateTime.Value;
}
else
{
return null;
}
}
else
{
if (DateTime.TryParse((string)reader.Value, out dateTime) == false)
{
return null;
}
}
// 将客户端时间转换为服务器时区的时间
var serverZoneTime = TimeZoneInfo.ConvertTime(dateTime, _clientTimeZone, TimeZoneInfo.Local);
return serverZoneTime;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
DateTime? nullableDateTime = value as DateTime?;
if (nullableDateTime != null && nullableDateTime.HasValue)
{
//第一个参数默认使用系统本地时区 也就是应用服务器的时区
DateTime clientZoneTime = TimeZoneInfo.ConvertTime(nullableDateTime.Value, _clientTimeZone);
writer.WriteValue(clientZoneTime);
}
else
{
writer.WriteNull();
}
}
}
}
@@ -1,6 +1,4 @@
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
using IRaCIS.Core.Application.Helper;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
@@ -10,12 +8,8 @@ namespace IRaCIS.Core.API
{
public static class NewtonsoftJsonSetup
{
public static void AddNewtonsoftJsonSetup(this IMvcBuilder builder, IServiceCollection services)
public static void AddNewtonsoftJsonSetup(this IMvcBuilder builder)
{
services.AddHttpContextAccessor();
services.AddScoped<JSONTimeZoneConverter>();
services.AddScoped<CustomStringConverter>();
services.AddScoped<IOSSService,OSSService>();
builder.AddNewtonsoftJson(options =>
{
@@ -29,15 +23,8 @@ namespace IRaCIS.Core.API
// 设置时间格式
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
//options.SerializerSettings.Converters.Add(new JSONCustomDateConverter()) ;
options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService<JSONTimeZoneConverter>());
//options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService<CustomStringConverter>());
//IsoDateTimeConverter
//options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
@@ -28,7 +28,7 @@ namespace IRaCIS.Core.API
if(_MemberInfo.PropertyType == typeof(string))
{
//去掉前后空格
_MemberInfo.SetValue(target, value==null?string.Empty: value.ToString()==string.Empty? value:value/*.ToString().Trim()*/);
_MemberInfo.SetValue(target, value==null?string.Empty: value.ToString()==string.Empty? value:value.ToString().Trim());
}
else
@@ -1,65 +0,0 @@
using IRaCIS.Core.Application.Helper;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System;
using System.Linq;
using System.Text.RegularExpressions;
namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson
{
public class CustomStringConverter : JsonConverter<string>
{
//private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IOSSService _oSSService;
// 构造函数
public CustomStringConverter(/*IHttpContextAccessor httpContextAccessor*/ IOSSService oSSService)
{
//_httpContextAccessor = httpContextAccessor;
_oSSService = oSSService;
}
public override string ReadJson(JsonReader reader, Type objectType, string existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.String)
{
return (string)reader.Value;
}
return null;
}
public override void WriteJson(JsonWriter writer, string value, JsonSerializer serializer)
{
if (value != null)
{
// 在这里对字符串进行处理,例如转换大小写、去除空格等
// 这里只是一个示例,您可以根据实际需求进行更改
// 获取当前正在序列化的属性名
string propertyName = writer.Path.Split('.').Last();
Regex guidRegex = new Regex(@"[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}");
if (propertyName.IndexOf("Path") > -1 && value.IndexOf('.')>-1 && guidRegex.IsMatch(value))
{
var tt= _oSSService.GetSignedUrl(value);
writer.WriteValue(tt);
}
else
{
// 将处理后的字符串写入到 JsonWriter 中
writer.WriteValue(value);
}
}
else
{
writer.WriteNull();
}
}
}
}
@@ -0,0 +1,49 @@
using IRaCIS.Application.Services.BackGroundJob;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Quartz;
namespace IRaCIS.Core.API
{
public static class QuartZSetup
{
public static void AddQuartZSetup(this IServiceCollection services, IConfiguration configuration)
{
services.AddTransient<CancelTaskQuartZJob>();
services.AddQuartz(q =>
{
// base quartz scheduler, job and trigger configuration
// as of 3.3.2 this also injects scoped services (like EF DbContext) without problems
q.UseMicrosoftDependencyInjectionJobFactory();
// 基本Quartz调度器、作业和触发器配置
//var jobKey = new JobKey("RegularTrialWork", "regularWorkGroup");
//q.AddJob<CacheTrialStatusQuartZJob>(jobKey, j => j
// .WithDescription("Trial regular work")
//);
//q.AddTrigger(t => t
// .WithIdentity("TrialStatusTrigger")
// .ForJob(jobKey)
// .WithCronSchedule("0 0 * * * ?")
// .WithDescription("My regular trial work trigger")
//);
});
// ASP.NET Core hosting
services.AddQuartzHostedService(options =>
{
// when shutting down we want jobs to complete gracefully
options.WaitForJobsToComplete = true;
});
}
}
}
@@ -19,11 +19,11 @@ namespace IRaCIS.Core.API
// Filter out ASP.NET Core infrastructre logs that are Information and below 日志太多了 一个请求 记录好几条
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
.MinimumLevel.Override("Hangfire", LogEventLevel.Warning)
.MinimumLevel.Override("System.Net.Http.HttpClient.HttpReports", LogEventLevel.Warning)
.MinimumLevel.Override("System.Net.Http.HttpClient.HttpReports", LogEventLevel.Warning)
.Enrich.WithClientIp()
.Enrich.FromLogContext()
.Filter.ByExcluding(logEvent =>logEvent.Properties.ContainsKey("RequestPath") && logEvent.Properties["RequestPath"].ToString().Contains("/health"))
.Enrich.FromLogContext()
//控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning,
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}")
@@ -35,7 +35,7 @@ namespace IRaCIS.Core.API
services.AddHangfireServer(option =>
{
option.Queues = new[] { "immediately_once", "default", "sys_init", "not_immediately_once" };
option.Queues = new[] { "immediately_once","default","sys_init" , "not_immediately_once" };
});
}
-61
View File
@@ -1,61 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
// "RemoteNew": "Server=47.117.165.18,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
// "Hangfire": "Server=47.117.165.18,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"AliyunOSS": {
"regionId": "cn-shanghai",
"endpoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
"bucketName": "zy-irc-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
},
"MinIO": {
"endpoint": "http://192.168.3.68",
"port": "8001",
"useSSL": false,
"accessKey": "IDFkwEpWej0b4DtiuThL",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
"bucketName": "test"
}
},
"BasicSystemConfig": {
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "IRC@extimaging.com",
"FromName": "IRC",
"AuthorizationCode": "ExtImg@2022",
"SiteUrl": "http://irc.extimaging.com/login",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗"
}
}
@@ -6,22 +6,16 @@
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=47.117.164.182,1434;Database=Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=47.117.164.182,1434;Database=Uat_IRC.Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"AliyunOSS": {
"regionId": "cn-shanghai",
"endpoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
"bucketName": "zy-irc-uat-store",
"bucketName": "zy-sir-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
"viewEndpoint": "https://zy-sir-cache.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
},
@@ -35,31 +29,33 @@
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.193.237,1434;Database=Prod_Study;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=101.132.193.237,1434;Database=Prod_Study_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
},
"BasicSystemConfig": {
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60
"LoginFailLockMinutes": 30
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "uat@extimaging.com",
"FromName": "UAT_IRC",
"AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.uat.extimaging.com/login",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗"
"FromEmail": "study@extimaging.com",
"FromName": "研究单位阅片系统",
"AuthorizationCode": "zhanying123",
"SiteUrl": "https://study.extimaging.com/login"
}
}
@@ -6,24 +6,16 @@
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"AliyunOSS": {
"regionId": "cn-shanghai",
"endPoint": "https://oss-cn-shanghai.aliyuncs.com",
"endpoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
"bucketName": "zy-irc-test-store",
"bucketName": "zy-sir-test-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"viewEndpoint": "https://zy-sir-test-store.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
},
@@ -39,7 +31,7 @@
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": true,
"useSSL": false,
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
"secretKey": "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",
"bucketName": "ei-irc-test-store",
@@ -47,6 +39,10 @@
}
},
"ConnectionStrings": {
"RemoteNew": "Server=123.56.94.154,1435;Database=Test_Study;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=123.56.94.154,1435;Database=Test_Study_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"BasicSystemConfig": {
"OpenUserComplexPassword": false,
@@ -56,29 +52,20 @@
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 1,
"LoginFailLockMinutes": 30
"AutoLoginOutMinutes": 1,
"OpenLoginMFA": false
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "test@extimaging.com",
"FromName": "Test_IRC",
"AuthorizationCode": "SHzyyl2021",
"FromEmail": "test-study@extimaging.com",
"FromName": "Test_Study",
"AuthorizationCode": "zhanying123",
"SiteUrl": "http://irc.test.extimaging.com/login",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗"
"SiteUrl": "http://study.test.extimaging.com/login"
}
}
-79
View File
@@ -1,79 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=us-mssql-service,1433;Database=Prod_US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=us-mssql-service,1433;Database=Prod_US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
//"RemoteNew": "Server=44.218.11.19,1435;Database=Prod_US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
//"Hangfire": "Server=44.218.11.19,1435;Database=Prod_US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"ObjectStoreService": {
"ObjectStoreUse": "AWS",
"AliyunOSS": {
"regionId": "cn-shanghai",
"endPoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
"bucketName": "zy-irc-test-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
},
"MinIO": {
"endPoint": "192.168.3.68",
"port": "8001",
"useSSL": false,
"accessKey": "IDFkwEpWej0b4DtiuThL",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
"bucketName": "test",
"viewEndpoint": "http://192.168.3.68:8001/test/"
},
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": true,
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
"secretKey": "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",
"bucketName": "ei-irc-test-store",
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
}
},
"BasicSystemConfig": {
"OpenUserComplexPassword": false,
"OpenSignDocumentBeforeWork": false,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "test@extimaging.com",
"FromName": "Test_IRC",
"AuthorizationCode": "SHzyyl2021",
"CompanyName": "Elevate Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Elevate Imaging",
"CompanyShortNameCN": "展影医疗"
}
}
@@ -6,10 +6,6 @@
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=47.117.164.182,1434;Database=Event_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=47.117.164.182,1434;Database=Event_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"AliyunOSS": {
@@ -17,11 +13,12 @@
"endpoint": "https://oss-cn-shanghai.aliyuncs.com",
"accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ",
"accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio",
"bucketName": "zy-irc-store",
"bucketName": "zy-sir-uat-store",
"roleArn": "acs:ram::1899121822495495:role/oss-upload",
"viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
"viewEndpoint": "https://zy-sir-uat-store.oss-cn-shanghai.aliyuncs.com",
"region": "oss-cn-shanghai"
},
"MinIO": {
"endpoint": "http://192.168.3.68",
"port": "8001",
@@ -31,28 +28,32 @@
"bucketName": "test"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=47.117.164.182,1434;Database=Uat.Study;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=47.117.164.182,1434;Database=Uat.Study.hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"BasicSystemConfig": {
"OpenUserComplexPassword": true,
"OpenUserComplexPassword": false,
"OpenSignDocumentBeforeWork": true,
"OpenSignDocumentBeforeWork": false,
"OpenLoginLimit": true,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60
"LoginFailLockMinutes": 30
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "uat@extimaging.com",
"FromName": "UAT_IRC",
"AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.event.extimaging.com/login"
"FromEmail": "uat-study@extimaging.com",
"FromName": "Uat_Study",
"AuthorizationCode": "zhanying123",
"SiteUrl": "http://study.uat.extimaging.com/login"
}
}
+5 -3
View File
@@ -1,10 +1,11 @@
{
"JwtSetting": {
"SecurityKey": "ShangHaiZhanYing_SecurityKey_SHzyyl@2021",
"Issuer": "Extimaging",
"Audience": "EICS",
"SecurityKey": "3e6dbfa227234a03977a2f421bdb7f4f",
"Issuer": "IRaCIS",
"Audience": "ZhiZhun",
"TokenExpireDays": "7"
},
//ip
"IpRateLimiting": {
"EnableEndpointRateLimiting": true,
"StackBlockedRequests": false,
@@ -19,6 +20,7 @@
"EndpointWhitelist": [
"post:/study/archivestudy/*"
],
"IpWhitelist": [],
"GeneralRules": [
{
Binary file not shown.
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好:
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{company abbreviation}为您添加了账户,账户信息如下:
展影医疗为您添加了账户,账户信息如下:
</div>
<span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
@@ -23,7 +23,7 @@
</div>
<div>
首次登陆前,请通过该链接修改您的账户信息:
<a href='{3}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
<a href='{3}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
初始化账号信息
</a>
</div>
@@ -32,7 +32,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
</div>
@@ -4,17 +4,17 @@
<meta charset='UTF-8'>
<title>Title</title>
</head>
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6'>
<body style='font-family: Times New Roman;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6;font-size: 16px'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
<div style='line-height: 40px;font-size: 16px'>
Dear {0} ,
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{company abbreviation} has created an account for you. The account information is as follows:
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
Extensive Imaging has generated a user account for you. <br>The account information is as follows:
</div>
<span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
<div>
User ID: {1}
</div>
@@ -22,17 +22,17 @@
Role: {2}
</div>
<div>
Before logging in for the first time, please modify the account information through this link
<a href='{3}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
Initialize account information
Before logging in for the first time, please initialize your account information through this link:
<a href='{3}' style='margin-left:30px;font-size:12px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;font-size: 16px'>
Initialize Account Information
</a>
</div>
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best regards,</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 16px;">Extensive Imaging</div>
</div>
</div>
</div>
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好:
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{company abbreviation}将您的账户密码已重置,账户信息如下:
展影医疗将您的账户密码已重置,账户信息如下:
</div>
<span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
@@ -29,7 +29,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
</div>
@@ -4,17 +4,17 @@
<meta charset='UTF-8'>
<title>Title</title>
</head>
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6'>
<body style='font-family: Times New Roman;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6;font-size: 16px'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
<div style='line-height: 40px;font-size: 16px'>
Dear {0} ,
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{company abbreviation} has reset your account password, and the account information is as follows:
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
Extensive Imaging has reset your password.<br>The account information is as follows:
</div>
<span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 12px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
<div>
User ID: {1}
</div>
@@ -27,9 +27,9 @@
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best regards,</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 16px;">Extensive Imaging</div>
</div>
</div>
</div>
@@ -19,7 +19,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
</div>
@@ -4,22 +4,22 @@
<meta charset='UTF-8'>
<title>Title</title>
</head>
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6'>
<body style='font-family: Times New Roman;padding: 0;margin: 0;font-size: 16px'>
<div style='padding-left: 40px;background: #f6f6f6;font-size: 16px'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
Dear
<div style='line-height: 40px;font-size: 16px'>
Dear Sir or Madam:
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Thank you for using {company abbreviation} Cloud System.
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
Thank you for using our IRC imaging system.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{0}
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
{0}.
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best regards,</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 16px;">Extensive Imaging</div>
</div>
</div>
</div>
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好:
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目阅片相关工作。
展影医疗作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目阅片相关工作。
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
该项目采用电子化工作流,系统及您的账号信息如下:
@@ -35,7 +35,7 @@
</div>
<div>
系统登录地址:
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
点击跳转
</a>
</div>
@@ -43,7 +43,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
</div>
@@ -4,20 +4,20 @@
<meta charset='UTF-8'>
<title>Title</title>
</head>
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
<body style='font-family: Times New Roman;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
<div style='line-height: 40px;font-size: 16px'>
Dear {0},
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
{company abbreviation} invites you to participate in the IRC work of a trial ({1} , {2}).
As the service provider of {1} trialProtocol ID is {2}, Extensive Imaging invites you to participate in the independent assessment work of this trial.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Your account information is as follows
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
Digital workflow is implemented for this trial, and your account information is as follows:
</div>
<span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
<div>
Trial ID: {3}
</div>
@@ -28,23 +28,22 @@
Study Name: {1}
</div>
<div>
User ID: {4}
User Name: {4}
</div>
<div>
Role: {5}
</div>
<div>
Login URL:
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
Click to login
Login URL:
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
click redirect
</a>
</div>
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best regards,</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 16px;">Extensive Imaging</div>
</div>
</div>
</div>
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好:
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC阅片相关工作,欢迎您提供指导和建议,非常感谢!
展影医疗作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目阅片相关工作,欢迎您提供指导和建议,非常感谢!
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
该项目采用电子化工作流,系统及您的账号信息如下:
@@ -35,7 +35,7 @@
</div>
<div>
首次登陆前,请通过该链接修改您的账户信息:
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
初始化账号信息
</a>
</div>
@@ -44,7 +44,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
</div>
@@ -4,20 +4,21 @@
<meta charset='UTF-8'>
<title>Title</title>
</head>
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
<body style='font-family: Times New Roman;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
<div style='line-height: 40px;font-size: 16px'>
Dear {0},
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{company abbreviation} invites you to participate in the IRC work of a trial ({1}, {2}).
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
As the service provider of {1}trial (Protocol ID is {2}), Extensive Imaging invites you to participate in the independent assessment work of this trial.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Your account information is as follows
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
Digital workflow is implemented for this trial, and your account information is as follows:
</div>
<span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
<div>
Trial ID: {3}
</div>
@@ -34,17 +35,17 @@
Role: {5}
</div>
<div>
Before logging in for the first time, please modify the account information through this link
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
Initialize account information
Before logging in for the first time, please modify your account information through this link:
<a href='{6}' style='margin-left:30px;font-size:16px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
Initialize Account Information
</a>
</div>
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;font-size: 16px'>
<div>Best regards,</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 16px;">Extensive Imaging</div>
</div>
</div>
</div>
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好:
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
您填写的中心调研表被驳回,详细信息如下:
好, 您填写的中心调研表被驳回,详细信息如下:
</div>
<span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
@@ -41,7 +41,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
</div>
@@ -4,17 +4,17 @@
<meta charset='UTF-8'>
<title>Title</title>
</head>
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
Dear {0} ,
<body style='font-family: Times New Roman;padding: 0;margin: 0;font-size: 16px'>
<div style='padding-left: 40px;background: #f6f6f6;font-size: 16px'>
<div style='padding-top: 20px;font-size: 16px'>
<div style='line-height: 40px;font-size: 16px'>
Dear {0} ,
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
The site survey form you filled in has been rejected. The details are as follows
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
The site survey questionnaire you filled in has been rejected. Details are as follows:
</div>
<span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
<div>
Trial ID: {1}
</div>
@@ -28,20 +28,20 @@
Site ID: {4}
</div>
<div>
Site name: {5}
Site Name: {5}
</div>
<div>
Reason for rejection: {6}
</div>
</div>
<a href='{7}' style='margin-left:60px;font-size:14px;padding: 10px;text-decoration: none;display:{8} ;height: 40px;width: 140px;background: #00D1B2;color:#fff;border-radius: 5px;line-height: 40px;text-align: center;margin-bottom: 100px;'>
Login and view
<a href='{7}' style='margin-left:60px;font-size:16px;padding: 10px;text-decoration: none;display:{8} ;height: 40px;width: 140px;background: #00D1B2;color:#fff;border-radius: 5px;line-height: 40px;text-align: center;margin-bottom: 100px;font-size: 16px'>
Login & View
</a>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best regards,</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 16px;">Extensive Imaging</div>
</div>
</div>
</div>
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好:
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目相关工作,欢迎您提供指导和建议,非常感谢!
展影医疗作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目相关工作,欢迎您提供指导和建议,非常感谢!
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
该项目采用电子化工作流,系统及您的账号信息如下:
@@ -35,7 +35,7 @@
</div>
<div>
系统登录地址:
<a href='{6}' style='margin-left:5px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
点击跳转
</a>
</div>
@@ -44,7 +44,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
</div>
@@ -4,20 +4,20 @@
<meta charset='UTF-8'>
<title>Title</title>
</head>
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
<body style='font-family: Times New Roman;padding: 0;margin: 0;font-size: 16px'>
<div style='padding-left: 40px;background: #f6f6f6;font-size: 16px'>
<div style='padding-top: 20px;font-size: 16px'>
<div style='line-height: 40px;font-size: 16px'>
Dear {0},
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
{company abbreviation} invites you to participate in the IRC work of a trial ({1}, {2}).
As the service provider of {1} trial (Protocol ID is {2}), Extensive Imaging invites you to participate in related work of this trial.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Your account information is as follows
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
Digital workflow is implemented for this trial, and your account information is as follows:
</div>
<span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
<div>
Trial ID: {3}
</div>
@@ -28,23 +28,23 @@
Study Name: {1}
</div>
<div>
User ID: {4}
User Name: {4}
</div>
<div>
Role: {5}
</div>
<div>
Login URL:
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
Click to login
Login URL:
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
click redirect
</a>
</div>
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best regards,</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 16px;">Extensive Imaging</div>
</div>
</div>
</div>
@@ -11,7 +11,7 @@
尊敬的 {0} ,您好:
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{company abbreviation}作为 [{1} (试验方案号:{2 })] 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢!
展影医疗作为 [{1} (试验方案号:{2 })] 项目的供应商,诚邀您参加该项目相关工作
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
该项目采用电子化工作流,系统及您的账号信息如下:
@@ -35,7 +35,7 @@
</div>
<div>
首次登陆前,请通过该链接修改您的账户信息:
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
<a href='{6}' style='margin-left:30px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
初始化账号信息
</a>
</div>
@@ -44,7 +44,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
</div>
@@ -4,20 +4,20 @@
<meta charset='UTF-8'>
<title>Title</title>
</head>
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
<body style='font-family: Times New Roman;padding: 0;margin: 0;font-size: 16px'>
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
<div style='line-height: 40px;font-size: 16px'>
Dear {0},
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{company abbreviation} invites you to participate in the IRC work of a trial ({1}, {2}).
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
As the service provider of {1} trial (Protocol ID is {2}), Extensive Imaging invites you to participate in related work of this trial.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
Your account information is as follows
Digital workflow is implemented for this trial, and your account information is as follows:
</div>
<span style="color: #00D1B2"></span>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 50%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;font-size: 16px'>
<div>
Trial ID: {3}
</div>
@@ -28,23 +28,23 @@
Study Name: {1}
</div>
<div>
User ID: {4}
User Name: {4}
</div>
<div>
Role: {5}
</div>
<div>
Before logging in for the first time, please modify the account information through this link
<a href='{6}' style='margin-left:1px;font-size:14px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
Initialize the account information
Before logging in for the first time, please modify your account information through this link:
<a href='{6}' style='margin-left:30px;font-size:16px;text-decoration: none;display: inline-block;color:#00D1B2;border-radius: 5px;line-height: 40px;text-align: center;'>
Initialize Account Information
</a>
</div>
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>Best regards,</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 16px;">Extensive Imaging</div>
</div>
</div>
</div>
@@ -8,20 +8,18 @@
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
{0}您好,
亲爱的用户 ,
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
感谢您使用展影云平台。
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{1},验证码是: <span style="font-weight:bold">{2}</span>
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
请在3分钟内输入该验证码,进行后续操作
{0},验证码是: {1},请在3分钟内输入该验证码,进行后续操作。如非本人操作,请忽略该邮件
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
</div>
@@ -4,25 +4,25 @@
<meta charset='UTF-8'>
<title>Title</title>
</head>
<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
<body style='font-family: Times New Roman;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
Dear {0},
<div style='line-height: 40px;font-size: 16px'>
Dear Sir or Madam:
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{1}
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
Thank you for using our imaging system.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
The verification code is <span style="font-weight:bold">{2}</span>.
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
{0}, the verification code is {1}. Please enter this code within 3 minutes for follow-up operations.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
This code will expire in 3 minutes.
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
If you are not the intended person, please ignore this email.
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;font-size: 16px'>
<div>Best regards,</div>
<div style="font-size: 14px;">{company}</div>
<div style="font-size: 16px;">Extensive Imaging</div>
</div>
</div>
</div>
@@ -276,10 +276,8 @@ var abp = abp || {};
}
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');
if (!password) {
alert('PassWord Can Not Be Null');
return false;
}
@@ -323,9 +321,6 @@ var abp = abp || {};
UserName: usernameOrEmailAddress,
Password: hex_md5(password),
}
if (pwdMd5 != '') {
parm.Password = pwdMd5;
}
xhr.send(JSON.stringify(parm));
//xhr.send("{" + "userName:'" + usernameOrEmailAddress + "'," + "passWord:'" + password + "'}");
@@ -420,8 +415,7 @@ var abp = abp || {};
//Inputs
createInput(modalUxContent, 'tenancyName', 'Tenancy Name (Leave empty for Host)');
createInput(modalUxContent, 'userName', 'Username or email address','text','cyldev');
createInput(modalUxContent, 'password', 'Password', 'password', '123456');
createInput(modalUxContent, 'pwdMd5', 'PwdMd5', 'text', '');
createInput(modalUxContent, 'password', 'Password','password','123456');
//Buttons
var authBtnWrapper = document.createElement('div');
@@ -0,0 +1,73 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using EasyCaching.Core;
using IRaCIS.Core.Domain;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Models;
using Microsoft.Extensions.Logging;
using Quartz;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Application.Contracts;
namespace IRaCIS.Application.Services.BackGroundJob
{
public class CancelTaskQuartZJob : IJob
{
private readonly IRepository<Subject> _subjectRepository;
private readonly ILogger<CancelTaskQuartZJob> _logger;
private readonly IRepository<VisitTask> _visitTaskRepository;
public CancelTaskQuartZJob(IRepository<Subject> subjectRepository, IEasyCachingProvider provider, ILogger<CancelTaskQuartZJob> logger, IRepository<VisitTask> visitTaskRepository)
{
_subjectRepository = subjectRepository;
_logger = logger;
_visitTaskRepository = visitTaskRepository;
}
public async Task Execute(IJobExecutionContext context)
{
_logger.LogInformation($"开始执行QuartZ定时取消任务作业");
try
{
JobDataMap dataMap = context.JobDetail.JobDataMap;
bool isInOrder = (bool)dataMap.Get("IsInOrder");
if (isInOrder)
{
Guid subjectId = (Guid)dataMap.Get("SubjectId");
Guid trialReadingCriterionId = (Guid)dataMap.Get("TrialReadingCriterionId");
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId==trialReadingCriterionId, u => new VisitTask() { SubjectCriterionClaimUserId = null });
}
else
{
Guid id = (Guid)dataMap.Get("VisitTaskId");
await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == id && t.ReadingTaskState!=ReadingTaskState.HaveSigned, u => new VisitTask() { DoctorUserId = null }, true);
}
}
catch (Exception e)
{
_logger.LogError($"QuartZ定时取消任务异常" + e.Message);
}
_logger.LogInformation("QuartZ定时取消任务作业结束");
}
}
}
@@ -5,10 +5,10 @@ using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using Microsoft.EntityFrameworkCore.SqlServer.Query.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SharpCompress.Common;
namespace IRaCIS.Application.Services.BackGroundJob
{
@@ -25,25 +25,22 @@ namespace IRaCIS.Application.Services.BackGroundJob
{
public static string JsonFileFolder = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources);
public static FileSystemWatcher FileSystemWatcher_US { get; set; }
public static FileSystemWatcher FileSystemWatcher_CN { get; set; }
private readonly IRepository<Trial> _trialRepository;
private readonly IEasyCachingProvider _provider;
private readonly ILogger<IRaCISCHangfireJob> _logger;
private readonly IRepository<SystemAnonymization> _systemAnonymizationRepository;
private readonly IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository;
private readonly IRepository<Internationalization> _internationalizationRepository;
public IRaCISCHangfireJob(IRepository<Trial> trialRepository, ILogger<IRaCISCHangfireJob> logger, IEasyCachingProvider provider, IRepository<TrialEmailNoticeConfig> trialEmailNoticeConfigRepository, IRepository<Internationalization> internationalizationRepository, IRepository<SystemAnonymization> systemAnonymizationRepository)
public IRaCISCHangfireJob(IRepository<Trial> trialRepository, ILogger<IRaCISCHangfireJob> logger, IEasyCachingProvider provider, IRepository<TrialEmailNoticeConfig> trialEmailNoticeConfigRepository, IRepository<Internationalization> internationalizationRepository)
{
_trialRepository = trialRepository;
_provider = provider;
_logger = logger;
_trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository;
_internationalizationRepository = internationalizationRepository;
_systemAnonymizationRepository = systemAnonymizationRepository;
}
public async Task InitHangfireJobTaskAsync()
@@ -54,8 +51,6 @@ namespace IRaCIS.Application.Services.BackGroundJob
//项目状态 立即加载到缓存中
await MemoryCacheTrialStatusAsync();
await MemoryCacheAnonymizeData();
//创建项目缓存 定时任务
HangfireJobHelper.AddOrUpdateInitCronJob<IIRaCISHangfireJob>("RecurringJob_Cache_TrialState", t => t.MemoryCacheTrialStatusAsync(), Cron.Daily());
@@ -85,16 +80,6 @@ namespace IRaCIS.Application.Services.BackGroundJob
}
public async Task MemoryCacheAnonymizeData()
{
var systemAnonymizationList = await _systemAnonymizationRepository.Where(t => t.IsEnable).ToListAsync();
_provider.Set(StaticData.Anonymize.Anonymize_AddFixedFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed).ToList(), TimeSpan.FromDays(7));
_provider.Set(StaticData.Anonymize.Anonymize_AddIRCInfoFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
_provider.Set(StaticData.Anonymize.Anonymize_FixedField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed).ToList(), TimeSpan.FromDays(7));
_provider.Set(StaticData.Anonymize.Anonymize_IRCInfoField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
}
#region
@@ -127,43 +112,29 @@ namespace IRaCIS.Application.Services.BackGroundJob
//监测Json文件变更 实时刷新数据
WatchJsonFile(usJsonPath);
WatchJsonFile(cnJsonPath);
if (!File.Exists(usJsonPath)|| !File.Exists(cnJsonPath))
}
public void WatchJsonFile(string filePath)
{
if (!File.Exists(filePath))
{
throw new BusinessValidationFailedException(StaticData.International("IRaCISCHangfireJob_FileNotFound"));
}
FileSystemWatcher_US = new FileSystemWatcher
{
Path = Path.GetDirectoryName(usJsonPath)!,
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size,
Filter = Path.GetFileName(usJsonPath),
EnableRaisingEvents = true,
};
// 添加文件更改事件的处理程序
FileSystemWatcher_US.Changed += (sender, e) => LoadJsonFile(usJsonPath);
FileSystemWatcher_CN = new FileSystemWatcher
{
Path = Path.GetDirectoryName(cnJsonPath)!,
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size,
Filter = Path.GetFileName(cnJsonPath),
EnableRaisingEvents = true,
};
FileSystemWatcher_CN.Changed += (sender, e) => LoadJsonFile(cnJsonPath);
FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(filePath), Path.GetFileName(filePath));
watcher.Changed += (sender, e) => LoadJsonFile(filePath);
watcher.EnableRaisingEvents = true;
}
private void LoadJsonFile(string filePath)
{
Console.WriteLine("刷新json内存数据");
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath,false,true);
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath);
IConfigurationRoot enConfiguration = builder.Build();
@@ -35,8 +35,6 @@ public class LimitUserRequestAuthorization : IAsyncAuthorizationFilter
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
var minutes = _verifyConfig.CurrentValue.AutoLoginOutMinutes;
if (_verifyConfig.CurrentValue.OpenLoginLimit)
{
if (context.ActionDescriptor.EndpointMetadata.Any(item => item is IAllowAnonymous))
@@ -60,45 +58,22 @@ public class LimitUserRequestAuthorization : IAsyncAuthorizationFilter
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["LimitUser_AuthTokenMissing"]));
}
//2、在这里取缓存 进行比较 看是否有其他人进行了登陆,如果其他人登陆了,就把之前用户挤掉
var cacheUserToken = (await _provider.GetAsync<string>(_userInfo.Id.ToString())).Value;
//缓存中没有取到Token
if (string.IsNullOrWhiteSpace(cacheUserToken))
{
cacheUserToken = _userInfo.UserToken;
//设置当前用户最新Token
await _provider.SetAsync(_userInfo.Id.ToString(), _userInfo.UserToken, TimeSpan.FromDays(7));
//重启应用程序,所有人续期,不一下子踢出所有人
await _provider.SetAsync($"{_userInfo.Id.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes));
cacheUserToken = _userInfo.UserToken;
}
//是同一个人
else if (cacheUserToken == _userInfo.UserToken)
{
var cacheTime = (await _provider.GetAsync<string>($"{_userInfo.Id.ToString()}_Online")).Value;
//过期了 需要自动退出
if (string.IsNullOrEmpty(cacheTime))
{
context.HttpContext.Response.ContentType = "application/json";
context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["LimitUser_AccountAuto_LoginOut"], ApiResponseCodeEnum.AutoLoginOut));
}
else
{
await _provider.SetAsync($"{_userInfo.Id.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(minutes));
}
}
else
@@ -32,9 +32,7 @@ namespace IRaCIS.Core.Application.Filter
if (context.Exception.GetType() == typeof(BusinessValidationFailedException))
{
var error = context.Exception as BusinessValidationFailedException;
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, error!.Code));
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message,ApiResponseCodeEnum.BusinessValidationFailed));
}
else if(context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException))
{
@@ -56,12 +56,16 @@ namespace IRaCIS.Core.Application.Filter
#region
// 后期列举出具体的类型,其他任何用户类型,都不允许操作
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA && _userInfo.RequestUrl.ToLower()!= "TrialDocument/userConfirm".ToLower())
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA)
{
//---对不起,您的账户没有操作权限。
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_NoAccessPermission"]));
if (!_userInfo.RequestUrl.Contains("TrialDocument/userConfirm"))
{
//---对不起,您的账户没有操作权限。
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_NoAccessPermission"]));
return;
return;
}
}
#endregion
@@ -50,7 +50,7 @@ namespace IRaCIS.Application.Services.BusinessFilter
//OK
var tuple = (dynamic)objectResult.Value;
var apiResponse = ResponseOutput.Ok(tuple!.Item1, tuple!.Item2);
var apiResponse = ResponseOutput.Ok(tuple.Item1, tuple.Item2);
objectResult.Value = apiResponse;
@@ -5,14 +5,17 @@ using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share;
using Magicodes.ExporterAndImporter.Excel;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using MiniExcelLibs.OpenXml;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using SkiaSharp;
using System.Collections;
using System.IO;
@@ -148,6 +151,10 @@ public static class ExcelExportHelper
workbook.RemoveSheetAt(1);
}
FileStream fileOut = new FileStream("resultTemplate", FileMode.Create, FileAccess.ReadWrite);
workbook.Write(fileOut);
var memoryStream2 = new MemoryStream();
workbook.Write(memoryStream2,true);
@@ -340,7 +347,7 @@ public static class ExcelExportHelper
IgnoreTemplateParameterMissing = true,
};
await MiniExcel.SaveAsByTemplateAsync(memoryStream, templateStream.ToArray(), translateData, config);
await MiniExcel.SaveAsByTemplateAsync(memoryStream, tplPath, translateData, config);
memoryStream.Seek(0, SeekOrigin.Begin);
@@ -0,0 +1,16 @@
using DocumentFormat.OpenXml.Bibliography;
using NPOI.XWPF.UserModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Helper
{
public class FileFormatConvertHelper
{
}
}
+165 -54
View File
@@ -1,12 +1,14 @@
using Aliyun.OSS;
using Aliyun.OSS.Util;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json.Linq;
using System.Configuration;
using System.Text;
using System.Text.RegularExpressions;
namespace IRaCIS.Core.Application.Helper;
@@ -14,6 +16,90 @@ namespace IRaCIS.Core.Application.Helper;
public static class FileStoreHelper
{
/// <summary>
/// 上传文件到OOS
/// </summary>
/// <param name="filePath">本地文件路径</param>
/// <param name="oosPath">OOS路径例如(test/test)</param>
/// <param name="isDeleteOriginalFile">是否删除本地文件</param>
/// <returns>返回文件路径</returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public static string UploadOOS(string filePath,string oosPath, bool isDeleteOriginalFile)
{
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
var enviromentName = config["ASPNETCORE_ENVIRONMENT"];
var configuration = new ConfigurationBuilder()
.AddJsonFile($"appsettings.{enviromentName}.json")
.Build();
var endpoint = configuration.GetSection("AliyunOSS:endpoint").Value;
// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
var accessKeyId = configuration.GetSection("AliyunOSS:accessKeyId").Value;
var accessKeySecret = configuration.GetSection("AliyunOSS:accessKeySecret").Value;
// 填写Bucket名称,例如examplebucket。
var bucketName = configuration.GetSection("AliyunOSS:bucketName").Value;
// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
var fileNameList = filePath.Split('\\').ToList();
var fileName = fileNameList[fileNameList.Count() - 1];
if (oosPath != string.Empty)
{
fileName = oosPath + "/" + fileName;
}
var objectName = fileName;
// 填写本地文件完整路径,例如D:\\localpath\\examplefile.txt。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
var localFilename = filePath;
// 创建OSSClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
// 上传文件。
var result = client.PutObject(bucketName, objectName, localFilename);
var expiration = DateTime.Now.AddYears(1);
var url = client.GeneratePresignedUri(bucketName, objectName, expiration).ToString();
if (File.Exists(filePath)&& isDeleteOriginalFile)
{
// 删除文件
File.Delete(filePath);
}
return url;
}
catch (Exception ex)
{
throw new BusinessValidationFailedException("上传异常!");
}
}
private static ObjectMetadata BuildCallbackMetadata(string callbackUrl, string callbackBody)
{
string callbackHeaderBuilder = new CallbackHeaderBuilder(callbackUrl, callbackBody).Build();
string CallbackVariableHeaderBuilder = new CallbackVariableHeaderBuilder().
AddCallbackVariable("x:var1", "x:value1").AddCallbackVariable("x:var2", "x:value2").Build();
var metadata = new ObjectMetadata();
metadata.AddHeader(HttpHeaders.Callback, callbackHeaderBuilder);
metadata.AddHeader(HttpHeaders.CallbackVar, CallbackVariableHeaderBuilder);
return metadata;
}
private static string GetCallbackResponse(PutObjectResult putObjectResult)
{
string callbackResponse = null;
using (var stream = putObjectResult.ResponseStream)
{
var buffer = new byte[4 * 1024];
var bytesRead = stream.Read(buffer, 0, buffer.Length);
callbackResponse = Encoding.Default.GetString(buffer, 0, bytesRead);
}
return callbackResponse;
}
//处理文件名 压缩包,或者目录类的 会带上相对路径
public static (string TrustedFileNameForFileStorage, string RealName) GetStoreFileName(string fileName,bool isChangeToPdfFormat=false)
{
@@ -42,12 +128,12 @@ public static class FileStoreHelper
if (isChangeToPdfFormat==false)
{
trustedFileNameForFileStorage= Guid.NewGuid().ToString() + fileName;
trustedFileNameForFileStorage= Path.GetFileNameWithoutExtension(fileName) + Guid.NewGuid().ToString()+Path.GetExtension(fileName) ;
}
else
{
trustedFileNameForFileStorage=Guid.NewGuid().ToString() + Path.GetFileNameWithoutExtension(fileName) + ".pdf";
trustedFileNameForFileStorage= Path.GetFileNameWithoutExtension(fileName) + Guid.NewGuid().ToString() + ".pdf";
}
return (trustedFileNameForFileStorage, fileName);
@@ -83,51 +169,6 @@ public static class FileStoreHelper
return physicalFilePath;
}
#region
public static (string PhysicalPath, string RelativePath) GetSystemFileUploadPath(IWebHostEnvironment _hostEnvironment, string templateFolderName, string fileName)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
//文件类型路径处理
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.SystemDataFolder, templateFolderName);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.SystemDataFolder}/{templateFolderName}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath);
}
public static (string PhysicalPath, string RelativePath) GetOtherFileUploadPath(IWebHostEnvironment _hostEnvironment, string templateFolderName, string fileName)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
//文件类型路径处理
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.OtherDataFolder, templateFolderName);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.OtherDataFolder}/{templateFolderName}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath);
}
#endregion
/// <summary>
///
/// </summary>
@@ -274,6 +315,54 @@ public static class FileStoreHelper
return (serverFilePath, relativePath);
}
#region
public static (string PhysicalPath, string RelativePath) GetSystemFileUploadPath(IWebHostEnvironment _hostEnvironment, string templateFolderName, string fileName)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
//文件类型路径处理
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.SystemDataFolder, templateFolderName);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.SystemDataFolder}/{templateFolderName}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath);
}
public static (string PhysicalPath, string RelativePath) GetOtherFileUploadPath(IWebHostEnvironment _hostEnvironment, string templateFolderName, string fileName)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
//文件类型路径处理
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.OtherDataFolder, templateFolderName);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.OtherDataFolder}/{templateFolderName}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath);
}
#endregion
// 获取通用文档存放路径(excel模板 )
public static (string PhysicalPath, string RelativePath) GetCommonDocPath(IWebHostEnvironment _hostEnvironment, string fileName)
@@ -339,6 +428,28 @@ public static class FileStoreHelper
return (serverFilePath, relativePath);
}
//获取 中心调研用户路径
public static (string PhysicalPath, string RelativePath) GetTrialSiteSurveyFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
//上传根路径
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), StaticData.Folder.UploadSiteSurveyData);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, realFileName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{StaticData.Folder.UploadSiteSurveyData}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath);
}
public static (string PhysicalPath, string RelativePath, string FileRealName) GetClinicalTemplatePath(IWebHostEnvironment _hostEnvironment, string fileName,Guid trialId)
{
@@ -515,18 +626,18 @@ public static class FileStoreHelper
// 获取 入组确认 PD 进展发送邮件Word|PDF 存放路径
public static (string PhysicalPath, string RelativePath, string FileRealName) GetSubjectEnrollConfirmOrPDEmailPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid trialSiteId, Guid subjectId,bool isChangeToPdfFormat=false)
public static (string PhysicalPath, string RelativePath, string FileRealName) GetSubjectEnrollConfirmOrPDEmailPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteId, Guid subjectId,bool isChangeToPdfFormat=false)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), trialSiteId.ToString(), subjectId.ToString());
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString());
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName, isChangeToPdfFormat);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{trialSiteId}/{subjectId}/{trustedFileNameForFileStorage}";
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
@@ -541,7 +652,7 @@ public static class FileStoreHelper
return Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder);
}
public static (string PhysicalPath, string RelativePath) GetDicomInstanceFilePath(IWebHostEnvironment _hostEnvironment, Guid trialId, Guid subjectId, Guid subjectVisitId, Guid studyId, Guid instanceId)
public static (string PhysicalPath, string RelativePath) GetDicomInstanceFilePath(IWebHostEnvironment _hostEnvironment, Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId, Guid studyId, Guid instanceId)
{
#region
//var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
@@ -552,7 +663,7 @@ public static class FileStoreHelper
//加入访视层级 和Data
var path = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(),
subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder, studyId.ToString());
siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder, studyId.ToString());
if (!Directory.Exists(path))
{
@@ -561,7 +672,7 @@ public static class FileStoreHelper
var physicalPath = Path.Combine(path, instanceId.ToString() );
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.DicomFolder}/{studyId}/{instanceId}";
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.DicomFolder}/{studyId}/{instanceId}";
//var physicalPath = Path.Combine(path, instanceId.ToString() + ".dcm");
@@ -9,7 +9,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static BeetleX.Redis.Commands.HSCAN;
using static IRaCIS.Core.Application.Service.Common.SystemMonitor;
namespace IRaCIS.Core.Application.Helper
@@ -23,7 +22,7 @@ namespace IRaCIS.Core.Application.Helper
if (!Directory.Exists(JsonFileFolder) ||
!Directory.GetFiles(JsonFileFolder).Any(filePath => Path.GetExtension(filePath).Equals(".json", StringComparison.OrdinalIgnoreCase)))
{
throw new BusinessValidationFailedException("国际化Json文件目录有误");
throw new BusinessValidationFailedException(StaticData.International("InternationalizationHelper_PathError"));
}
}
@@ -107,73 +106,8 @@ namespace IRaCIS.Core.Application.Helper
}
public static async Task InitInternationlizationDataAndWatchJsonFileAsync(IRepository _repository)
{
//查询数据库的数据
var toJsonList = await _repository.Where<Internationalization>(t => t.InternationalizationType == 1).Select(t => new
{
t.Code,
t.Value,
t.ValueCN
}).ToListAsync();
//组织成json 文件
var usJsonPath = Path.Combine(JsonFileFolder, StaticData.En_US_Json);
var cnJsonPath = Path.Combine(JsonFileFolder, StaticData.Zh_CN_Json);
//本地静态文件国际化需要
foreach (var tojsonItem in toJsonList)
{
StaticData.En_US_Dic[tojsonItem.Code] = tojsonItem.Value;
StaticData.Zh_CN_Dic[tojsonItem.Code] = tojsonItem.ValueCN;
}
File.WriteAllText(usJsonPath, JsonConvert.SerializeObject(StaticData.En_US_Dic));
File.WriteAllText(cnJsonPath, JsonConvert.SerializeObject(StaticData.Zh_CN_Dic));
//监测Json文件变更 实时刷新数据
WatchJsonFile(usJsonPath);
WatchJsonFile(cnJsonPath);
}
public static void WatchJsonFile(string filePath)
{
if (!File.Exists(filePath))
{
throw new BusinessValidationFailedException("国际化Json文件不存在");
}
FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(filePath), Path.GetFileName(filePath));
watcher.Changed += (sender, e) => LoadJsonFile(filePath);
watcher.EnableRaisingEvents = true;
}
private static void LoadJsonFile(string filePath)
{
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath);
IConfigurationRoot enConfiguration = builder.Build();
foreach (IConfigurationSection section in enConfiguration.GetChildren())
{
if (filePath.Contains(StaticData.En_US_Json))
{
StaticData.En_US_Dic[section.Key] = section.Value;
}
else
{
StaticData.Zh_CN_Dic[section.Key] = section.Value;
}
}
}
}
}
+9 -84
View File
@@ -15,6 +15,7 @@ using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
using SkiaSharp;
namespace IRaCIS.Core.Application.Helper
{
@@ -95,15 +96,13 @@ namespace IRaCIS.Core.Application.Helper
public interface IOSSService
{
public Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true);
public Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true);
public Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName);
public Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath);
public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath);
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
public Task<string> GetSignedUrl(string ossRelativePath);
}
@@ -123,12 +122,12 @@ namespace IRaCIS.Core.Application.Helper
/// <param name="fileStream"></param>
/// <param name="oosFolderPath"></param>
/// <param name="fileRealName"></param>
/// <param name="isFileNameAddGuid"></param>
/// <returns></returns>
public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true)
public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName)
{
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}";
//var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}";
var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}";
//var ossRelativePath = oosFolderPath + "/" + fileRealName;
using (var memoryStream = new MemoryStream())
@@ -206,12 +205,11 @@ namespace IRaCIS.Core.Application.Helper
/// <param name="oosFolderPath"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true)
public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath)
{
var localFileName = Path.GetFileName(localFilePath);
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}";
var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}";
//var ossRelativePath = oosFolderPath + "/" + localFileName;
@@ -266,7 +264,6 @@ namespace IRaCIS.Core.Application.Helper
}
public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath)
{
@@ -340,81 +337,9 @@ namespace IRaCIS.Core.Application.Helper
}
public async Task<string> GetSignedUrl(string ossRelativePath)
{
ossRelativePath = ossRelativePath.TrimStart('/');
try
{
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
// 生成签名URL。
var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get)
{
// 设置签名URL过期时间,默认值为3600秒。
Expiration = DateTime.Now.AddHours(1),
};
var uri = _ossClient.GeneratePresignedUri(req);
return uri.PathAndQuery;
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
//var reqParams = new Dictionary<string, string>(StringComparer.Ordinal)
// {
// { "response-content-type", "application/json" }
// };
var args = new PresignedGetObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithExpiry(3600)
/*.WithHeaders(reqParams)*/;
var presignedUrl = await minioClient.PresignedGetObjectAsync(args);
Uri uri = new Uri(presignedUrl);
string relativePath = uri.PathAndQuery;
return relativePath;
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
var minIOConfig = ObjectStoreServiceOptions.AWS;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
return string.Empty;
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
}
catch (Exception ex)
{
throw new BusinessValidationFailedException("oss授权url失败!" + ex.Message);
}
}
}
@@ -144,6 +144,9 @@ public static class SendEmailHelper
}
}
}
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>default</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
@@ -15,14 +15,14 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<NoWarn>1701;1702;1591;1587</NoWarn>
<NoWarn>1701;1702;1591;1587</NoWarn>
</PropertyGroup>
<ItemGroup>
<Using Include="IRaCIS.Core.Application;" />
<Using Include="IRaCIS.Core.Application;" />
<Using Include="AutoMapper.QueryableExtensions;" />
<Using Include="Microsoft.EntityFrameworkCore;" />
<Using Include="IRaCIS.Core.Domain.Models;" />
@@ -50,58 +50,61 @@
<ItemGroup>
<Content Include="Resources\zh-CN.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="Resources\en-US.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="Resources\zh-CN.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="Resources\en-US.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
<PackageReference Include="FreeSpire.Doc" Version="12.2.0" />
<PackageReference Include="Hangfire.Core" Version="1.8.12" />
<PackageReference Include="BeetleX.BNR" Version="1.0.1" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
<PackageReference Include="DistributedLock.Redis" Version="1.0.2" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.3" />
<PackageReference Include="EasyCaching.InMemory" Version="1.9.1" />
<PackageReference Include="EasyCaching.Redis" Version="1.9.1" />
<PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
<PackageReference Include="EasyCaching.Redis" Version="1.9.2" />
<PackageReference Include="EasyCaching.InMemory" Version="1.9.2" />
<PackageReference Include="EasyCaching.Interceptor.AspectCore" Version="1.9.1" />
<PackageReference Include="ExcelDataReader" Version="3.6.0" />
<PackageReference Include="ExcelDataReader.DataSet" Version="3.6.0" />
<PackageReference Include="DistributedLock.Redis" Version="1.0.3" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.4" />
<PackageReference Include="fo-dicom" Version="5.1.2" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.2" />
<PackageReference Include="fo-dicom.Codecs" Version="5.12.0" />
<PackageReference Include="IP2Region.Net" Version="2.0.2" />
<PackageReference Include="MailKit" Version="4.5.0" />
<PackageReference Include="MediatR" Version="12.2.0" />
<PackageReference Include="MimeKit" Version="4.5.0" />
<PackageReference Include="MiniExcel" Version="1.32.0" />
<PackageReference Include="Minio" Version="6.0.2" />
<PackageReference Include="MiniWord" Version="0.8.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
<TreatAsUsed>true</TreatAsUsed>
<PackageReference Include="fo-dicom" Version="5.1.1" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.0" />
<PackageReference Include="fo-dicom.Codecs" Version="5.10.8" />
<PackageReference Include="FreeSpire.Doc" Version="11.6.0" />
<PackageReference Include="Hangfire.Core" Version="1.8.5" />
<PackageReference Include="Magicodes.IE.Core" Version="2.7.4.5" />
<PackageReference Include="Magicodes.IE.Csv" Version="2.7.4.5">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="NPOI" Version="2.7.0" />
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
<PackageReference Include="WinSCP" Version="6.3.3" />
<PackageReference Include="Magicodes.IE.Excel" Version="2.7.4.5">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="Magicodes.IE.Excel.AspNetCore" Version="2.7.4.5" />
<PackageReference Include="MailKit" Version="4.2.0" />
<PackageReference Include="MediatR" Version="12.1.1" />
<PackageReference Include="MimeKit" Version="4.2.0" />
<PackageReference Include="MiniExcel" Version="1.31.2" />
<PackageReference Include="Minio" Version="6.0.1" />
<PackageReference Include="MiniWord" Version="0.7.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.0.0">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
<PackageReference Include="NPOI" Version="2.6.2" />
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.1" />
<PackageReference Include="Quartz" Version="3.7.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.11" />
<PackageReference Include="WinSCP" Version="6.1.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IRaCIS.Core.Infra.EFCore\IRaCIS.Core.Infra.EFCore.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="Resources\ip2region.xdb">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
File diff suppressed because it is too large Load Diff
+1 -592
View File
@@ -1,593 +1,2 @@
{
"test{0}{1}": "英文本地化{0}{1}",
"RequiredAttribute": "{0} is required",
// ------------------------------------------------------------_ServiceExtensions--------------------------------------------------------------------
//ApiResponseHandler
"ApiResponse_NoAccess": "You do not have access to this API",
"ApiResponse_Permission": "You do not have permission to do this",
// ------------------------------------------------------------Controllers--------------------------------------------------------------------
//FinancialChangeController
"Financial_ChargeSettled": "Expenses have been settled and workload can not be reset.",
"Financial_InvalidParameter": "Invalid parameter.",
//UploadDownLoadController
"UploadDownLoad_UnsupportedMedia": "Unsupported media type.",
"UploadDownLoad_ArchiveInProgress": "Another user is uploading or archiving this study.",
"UploadDownLoad_InvalidData": "Please ensure that the uploaded data conforms to the style of the template file and contains valid data.",
"UploadDownLoad_RequestError": "Request error, please try again!",
"UploadDownLoad_SupportedFormats": "Supports upload of .xlsx, .xls, and .csv formats.",
// ------------------------------------------------------------_MediatR--------------------------------------------------------------------
//ConsistencyVerificationRequest
"ConsistencyVerification_Tech": "Study Type",
"ConsistencyVerification_Time": "Incorrect time format",
//ConsistencyVerificationHandler
"ConsistencyVerification_Img": "Hello, according to the automatic recognition of this system, the imaging study submitted by the subject in the current visit in the IRC system is as follows:",
"ConsistencyVerification_Of": "Of",
"ConsistencyVerification_ImgC": "Imaging study",
"ConsistencyVerification_EDCA": "Check EDC data, completely consistent, approved",
"ConsistencyVerification_EDCB": "Check EDC data, completely consistent",
"ConsistencyVerification_Auto": "Automatically verified pass",
"ConsistencyVerification_Prob": "The following problems exist:",
"ConsistencyVerification_EdcL": "Image study (EDC missing)",
"ConsistencyVerification_IrcL": "Image study (IRC missing)",
"ConsistencyVerification_Desc": "Description: In order to efficiently solve all the above doubts, please verify the actual image study accurately. Please note that the image date may not be consistent with the actual study date, and multiple modalities of image studys (such as PET-CT) may exist at the same time. After accurate verification, please reply with the correct image study for this visit.",
"ConsistencyVerification_Conf": "According to the imported consistency check data, please confirm the following inconsistent inspection item information of this visit:",
"ConsistencyVerification_Edc": "EDC is lack of:",
"ConsistencyVerification_IrcLi": "IRC is lack of:",
//-------------------------------------------------------------------------------------Reading-----------------------------------------------------------------
//ClinicalDataSetService
"ClinicalDataSet_Apply": "",
"ClinicalDataSet_DupTypeFail": "The same type of clinical data exists. The operation failed.",
//ClinicalQuestionService
"ClinicalQuestion_Repeat": "",
//ReadingClinicalDataService
"ReadingClinicalData_DupTypeFail": "The same type of clinical data exists. The operation failed.",
"ReadingClinicalData_Unchecked": "The current clinical data status is not verified and signing is not allowed!",
//ReadingGlobalTaskService
"ReadingGlobal_NotGlobal": "System call error. The current read is not a global review read.",
//ReadingImageTaskService
"ReadingImage_NotVisit": "System call error. The current read is not a timepoint read.",
"ReadingImage_CantSplit": "The current read is a baseline read, and lesion split is not allowed.",
"ReadingImage_BeSigned": "The current read has already been signed. Please do not submit it again.",
"ReadingImage_Beinvalid": "The current read has already been invalidated, and reading is not allowed anymore.",
"ReadingImage_PresenceReview": "The current subject has a re-read request that has not been processed and is not allowed to operate",
"ReadingImage_NotaTask": "The coalesced lesions are not from the same timepoint.",
"ReadingImage_DeleteError": "Other lesions have split from or coalesced into the current lesion. Deletion failed.",
"ReadingImage_Idnotcorrespond": "Failed to add the lesion mark. The Instance ID and Series ID of the image do not match.",
"ReadingImage_IsLymphNotbigger": "The short diameter of this nodal non-target lesion on the current visit is smaller than the value on the previous visit, and the state cannot be set to 'Unequivocal progression'.",
"ReadingImage_NotLymphNotbigger": "The long diameter of this non-nodal non-target lesion on the current visit is smaller than the value on the previous visit, and the state cannot be set to 'Unequivocal progression'.",
"ReadingImage_Twice": "System call error. Questions & answers submitted are duplicated.",
"ReadingImage_MaxQuestion": "According to the imaging charter, the number of {0} cannot exceed {1}.",
"ReadingImage_Maxlesion": "According to the imaging charter, the number of target lesions in the same organ cannot exceed {0}. Please confirm.",
"ReadingImage_Maximum": "{0} can only be repeated {1} times, and it has been repeated {2} times so far.",
"ReadingImage_PCWGMaximum": "According to the imaging charter, the number of baseline lesions at the same location should enter only {0} time. Please confirm.",
"ReadingImage_NotNewFocus": "There should be no new lesions in the converted task",
"ReadingImage_RequiredQuestion": "Before submission, please fill in {0}.",
"ReadingImage_ClinicalRead": "The clinical data has not been read. Please confirm!",
"ReadingImage_IDMust": "System call failed. When there is no Read ID, the standard ID must be passed.",
"ReadingImage_TaskFinish": "Please note that all reads of the current subject have been completed.",
"ReadingImage_NeedRest": "You have been continuously reading for {0} hours. Please take a break of {1} minutes before resumption.",
//ReadingJudgeTaskService
"ReadingJudge_SouceIdNull": "System call failed. The Source ID of the global review which is being adjudicated currently is 'null'.",
//ReadingOncologyTaskService
"ReadingOncology_TaskError": "System call error. The current read is not an oncology read.",
"ReadingOncology_Abnormal": "System call exception. The result of adjudication is null",
//ReadingCalculate
"ReadingCalculate_Abnormal": "Configuration error of PCWG3 criteria. Data verification failed.",
"ReadingCalculate_questionable": "Problems with the lesions are as follows:",
"ReadingCalculate_NoMarker": "Lesion {0} lacks mark.",
"ReadingCalculate_StatusIsEmpty": "The state of Lesion {0} is empty.",
"ReadingCalculate_NoMarkerEmpty": "Lesion {0} is not marked, and its state is empty.",
"ReadingCalculate_NoDeveloped": "Please note that the current standard automatic calculation has not been developed.",
//ReadingMedicalReviewService
"MedicalReview_invalid": "This medical review read has already been invalidated, and the operation failed.",
"MedicalReview_SaveQuestion": "Unable to perform the current operation. Please save the medical review questions first.",
"MedicalReview_NeedSave": "Unable to perform the current operation. Please save the medical review questions and conclusions first.",
"MedicalReview_NotClosed": "Unable to perform the current operation. The current medical query conversation has not been closed.",
"MedicalReview_Finish": "The current medical review is the last one.",
//ReadingMedicineQuestionService
"ReadingMed_QNumDup": "Current question number is repeated",
"ReadingMed_HasSubQ": "This question has sub-question, please delete it first",
"ReadingMed_NoMedQ": "Medical review question has not been added yet. Please add it first before confirming",
"ReadingMed_MedQNumDup": "The display number of the medical imaging review question cannot be duplicated.",
"ReadingMed_ParentNumSmall": "The display number of the parent question should be smaller than that of the child question, please confirm.",
"ReadingMed_VisitQNotConfig": "This review criteria has no medical review questions for 'visit'",
"ReadingMed_GlobalQNotConfig": "The global review read is enabled in the current criterion, but has not configured with medical review questions",
"ReadingMed_ArbitrateQNotConfig": "Adjudication review reading is enabled in the current criterion, but has not configured with medical review questions",
"ReadingMed_TumorQNotConfig": "Oncology reading is enabled in the current criterion, but the oncology medical review question has not been configured",
//UserService
"User_CheckNameOrPw": "Please check the username or password.",
//Repository
"Repository_UpdateError": "Updated data does not exist in the database. ",
"Repository_DeleteError": "Deleted data does not exist in the database.",
//OrganInfoService
"OrganInfo_DuplicateData": "There are duplicate data, operation failed.",
//ReadingCriterionService
"ReadingCriterion_Referenced": "The current criterion has been referenced and cannot be deleted.",
"ReadingCriterion_InUse": "This criterion has been used in the project and cannot be deleted.",
"ReadingCriterion_ArbitratorWithoutJudgment": "There is no referee problem but there is an arbitration object, operation failed.",
//ReadingQuestionService
"ReadingQuestion_IdDup": "Duplicate problem ID.",
"ReadingQuestion_ChildrenExist": "This problem has sub-problems, please delete the sub-problems first.",
"ReadingQuestion_GroupReferenced": "This grouping has been referenced, please delete the referenced problems first.",
"ReadingQuestion_JudgmentSet": "The current question already has a referee criterion set, modification failed.",
"ReadingQuestion_ExcludeWithDependency": "The displayed dependent parent question and the required dependent question are the same, but the answers are mutually exclusive, operation failed.",
"ReadingQuestion_CircularDependency": "Calculation dependency has looped!",
//ReadingPeriodSetService
"ReadingPeriodSet_NameDup": "Review period name duplicate, operation failed",
"ReadingPeriodSet_Global": "Review period name cannot be Global",
"ReadingPeriodSet_AlreadyAdded": "{0} has already added the review period, cannot set it effective.",
"ReadingPeriodSet_TaskCompletedCannotRevoke": "The current criterion has generated reads and the reads have been completed, revoke failed.",
"ReadingPeriodSet_LastVisit": "Last visit.",
//ReadModuleService
"ReadModule_AlreadyAdded": "The current visit has already added a review period.",
"ReadModule_AddGlobalFirst": "Please add global review first.",
"ReadModule_VisitNotFound": "No qualified visit was found.",
"ReadModule_SignedDataCannotDelete": "Clinical data has been signed and cannot be deleted.",
"ReadModule_TumorExists": "The current visit has a tumor review, please delete it first.",
"ReadModule_TaskGenerated": "The current review has generated reads, operation failed.",
//UserWLTemplateService
"UserWLTS_MaxTemplate": "The same user can add a maximum of 10 templates.",
"UserWLTS_NameRepeated": "The template name is repeated",
"UserWLTS_ContentRepeated": "The template content is repeated",
// ------------------------------------------------------------Allocation--------------------------------------------------------------------
//TaskAllocationRuleService
"TaskAllocation_DoctorIdNotFound": "Error, the doctor's account Id was not found in the enrollment table.",
"TaskAllocation_DoctorConfigExists": "The doctor configuration is already available, and continued additions cannot be allowed.",
"TaskAllocation_TaskAssigned": "A read has been assigned to the doctor and it cannot be deleted.",
//TaskConsistentRuleService
"TaskConsistent_ConsistencyConfigExists": "Please configure the doctor for consistency analysis.",
"TaskConsistent_TaskGenerated": "The trial configuration is already available, and no continued additions are allowed.",
"TaskConsistent_MedicalAuditTaskExists": "The criterion already has reads generated by the Subject, and configuration modification is not allowed.",
"TaskConsistent_SignedTaskCannotBeInvalidated": "This criterion has generated a consistency analysis task and cannot be deleted.",
//TaskMedicalReviewRuleService
"TaskMedicalRule_TaskAlreadyAssigned": "The doctor configuration is already available, and continued additions cannot be allowed.",
"TaskMedicalRule_TaskStarted": "A medical review task has been generated.",
//TaskMedicalReviewService
"TaskMedical_DirtyData": "Signed files cannot be set to invalid.",
"TaskMedical_SubjectInOtherArm": "A task is currently assigned to someone else,and it cannot be assigned. Please refresh the list.",
//VisitTaskService
"VisitTask_VisitTask_TaskAlreadyApplied": "The trial has not confirmed any of the review criteria.",
"VisitTask_DoctorConfigNotFound": "The current doctor has begun to do the task of this standard of subject, so assignment cannot be canceled.",
"VisitTask_BackendDataError": "One of the reeads has been assigned to the doctor and is not allowed to be assigned.",
"VisitTask_DirtyData": "Dirty data appears, and the task source field has no value.",
"VisitTask_MissingTaskSource": "The subject had a visit and entered the return process, which has not been verified for consistency and is not allowed to be assigned.",
"VisitTask_InconsistentSubjectStatus": "There is a subject that already has the doctor in another Arm group. It is not allowed to add the doctor to a new group.",
"VisitTask_DuplicateDoctorInArm": "There is a subject that already has the doctor in another Arm group, so the futher assignment is not allowed. Please refresh the page to confirm whether the data on the page is expired.",
"VisitTask_DoctorAlreadyInArm": "The assignment of a Subject task cannot be canceled because it has been applied.",
"VisitTask_TaskAlreadyApplied": "The configured doctor cannot be found in the configuration table, and the binding cannot be applied. Please check the data.",
"VisitTask_DoctorConfiguration": "Background data error",
"VisitTask_BackendData": "Reads that have not been completed or have not been effective are not allowed to request re-reading.",
"VisitTask_UnreadTask": "Reads that re-read has been applied or approved are not allowed to apply for re-reading.",
"VisitTask_NoPMRecheck": "Additional review reads do not allow the PM to apply for re-reading",
"VisitTask_Reapply": "PM is not allowed to apply for re-reading of consistency analysis reads.",
"VisitTask_ConsistencyAnalysis": "PM is only allowed to apply for re-reading that the view type is visit.",
"VisitTask_VisitTypeRestriction": "This is chronological read, and the subject has visit that has applied for re-read by PM, but has not been processed, so it cannot been applied for continuing re-read at this time.",
"VisitTask_SequentialReading": "This is chronological read, and the subject has visit that has applied for re-read, but has not been processed, so it cannot been applied for re-read for now.",
"VisitTask_ImageProblem": "This is chronological read, and there is something wrong with the image. PM has applied for returning, so it cannot been applied for re-reading now.",
"VisitTask_LastReading": "This is chronological read, and only the request for re-readinng by the subject reader after completing the global task for the last time is allowed.",
"VisitTask_LastOncologistRecheck": "This is chronological read, and the subject will only be allowed to re-read after IR completing the last oncology read ",
"VisitTask_LastAdjudicatorRecheck": "This is chronological read, and the subject will only be allowed to re-read after IR completing the last adjudication read ",
"VisitTask_IRGlobalRecheck": "This is random read, IR is only allowed to apply for re-reading global and visit reads",
"VisitTask_IRReapply": "This is random read, IR is only allowed to apply for re-reading global and visit reads ",
"VisitTask_InvalidReapplyStatus": "The current re-read status is not requested and cannot be processed. Please refresh the page.",
"VisitTask_ReapplyStatusConflict": "The current re-read status has been affected by another re-read reads. The re-read review operation is not allowed for reads in this state",
"VisitTask_ReReadTaskNotApplied": "Only reads with visit type are allowed to approve of re-read.",
"VisitTask_ReReadTaskAlreadyAffected": "Do not conform to the PM request and SPM / CPM approve , or IR request and PM approve.",
"VisitTask_TaskTypeNotApproved": "The current re-read status is not requested and cannot be processed. Please refresh the page.",
"VisitTask_NoImageReturn": "Additional review reads do not allow PM to apply for re-reading",
"VisitTask_NonEffectiveTaskCannotBeReturned": "Only effective and unfinished visit read can be returned. Please refresh the page data.",
"VisitTask_NoFurtherReturn": "The current visit has been returned to image upload, so continuing to return is not allowed!",
"VisitTask_ConsistencyTaskCannotBeReturned": "The consistency analysis read is not allowed to be set return back.",
"VisitTask_PMOnlyAllowedForReturn": "Only PM can perform the return back.",
"VisitTask_UnsupportedTaskType": "Re-read types are not supported.",
"VisitTask_UndefinedList": "The current user view list is not defined.",
"VisitTask_NoConsistencyReturn": "The conformance analysis read cannot be returned back",
"VisitTask_VisitTypeTaskAllowedForPMOnly": "Only read with visit type can be returned by PM.",
// ------------------------------------------------------------Common--------------------------------------------------------------------
//CommonDocumentService
"Document_CodeDuplication": "The Code of the document cannot be repeated.",
"Document_SingleTemplate": "Only one template file is allowed per scenario and standard.",
"Document_ TemplateRead": "Failed to read the template content, please try saving the file as docx format!",
//DictionaryService
"Dictionary_DictionaryName": "There is already a dictionary with the name {0}.",
"Dictionary_DictionaryDeletion": "The current dictionary is referenced in the standard and cannot be deleted!",
"Dictionary_SubitemDeletion": "There is child data, direct deletion is not allowed!",
"Dictionary_ResumeReference": "The current entry has been referenced in the reader resume.",
"Dictionary_ProjectReference": "The current entry has been referenced in the trial information.",
"Dictionary_StandardReference": "The current entry has been referenced in the review criteria.",
//ExcelExportService
"ExcelExport_UnsupportedExport": "Currently the criterion export is not supported.",
//MailService
"Mail_EmailResetReminder": "[From Extensive Imaging IRC] A reminder about resetting the email.",
"Mail_Dear": "Dear {0},",
"Mail_ResettingEmail": "You are resetting an email address.",
"Mail_IRCResettingPassword ": "[From Extensive Imaging IRC] A reminder about resetting your password",
"Mail_ResettingPassword ": "You are resetting the email password",
"Mail_ImagingIRCReminder": "[From Extensive Imaging IRC] A reminder",
"Mail_IRCProject": "You are participating in the Extensive Imaging IRC trial",
"Mail_ProjectParticipationReminder": "[From Extensive Imaging IRC] [{0}] A reminder of the Site Survey",
"Mail_CenterResearchReminder": "You are participating in the Site Survey of the Extensive Imaging IRC trial.",
"Mail_AccountCreationReminder": "[From Extensive Imaging IRC] A reminder about creating an account",
"Mail_AccountPasswordResetReminder": "[From Extensive Imaging IRC] A reminder about resetting account passwords",
"Mail_InvitationEmail": "[From Extensive Imaging IRC][{0}]Invitation",
//SystemMonitor
"SysMon_JsonConfig": "Parsing the Json file configuration failed",
// ------------------------------------------------------------Doctor--------------------------------------------------------------------
//DoctorService
"Doctor_DupPhoneOrEmail": "The current tel or email number already existed",
"Doctor_DupPhone": "The current tel number already existed!",
"Doctor_DupEmail": "The current email already existed!",
"Doctor_StandardDuplicateFileTypeError": "This type of file has already been added to the current criterion.",
"Doctor_RequiredDocumentsError": "Resume & Consultant Agreement must be upload",
// ------------------------------------------------------------Document--------------------------------------------------------------------
//SystemDocumentService
"SystemD_DuplicateFile": "A file with the same type and same name already exists in the system.",
"SystemD_CannotDeleteSignedFile": "The file has already been read and signed by a user, and not allowed to be deleted.",
//TrialDocumentService
"TrialD_DuplicateFileInProject": "A file with the same type and same name already exists in this trial .",
"TrialD_DocumentHasAlready": "The file has already been read and signed by a user, and not allowed to be deleted.",
"TrialD_FileAlreadySigned": "The file has been signed.",
"TrialD_ObsoleteFile": "The file has been revoked. Signature failed!",
//TrialEmailNoticeConfigService
"TrialEmailN_TaskNotSigned": "Before sending the email, the task must have been signed and triggered to complete the corresponding task generation.",
"TrialEmailN_NoRecipient": "The message cannot be sent without the recipient.",
"TrialEmailN_InvalidEmailConfig": "The configuration of the sender mail of the trial is wrong, please check.",
"TrialEmailN_EmailTemplateNotFound": "The email template in the standard scenario of this trial cannot be found.",
"TrialEmailN_EnrollmentConfirmation": "[Enrollment Confirmation Report] About {0} item {1}Subject",
"TrialEmailN_Enrollment": "The attachment is the Enrollment Confirmation Report, please check.",
"TrialEmailN_PDReport": "[PD Confirmation Report] About {0} item {1}Subject",
"TrialEmailN_SubjectDiseaseProgression": "The attachment is the PD Confirmation Report, please check.",
"TrialEmailN_SingleBlindedSet": "The configuration of the single and chronological read is incorrect (there should be no adjudicator configuration), please check!",
"TrialEmailN_SingleBlindedSequenced": "The single and chronological read, should not enter the logic here, please contact the background developers to check!",
"TrialEmailN_PDProgressEmailTask": "Send PD progress email found problem with the task data!",
"TrialEmailN_DoubleBlindedError": "The double and chronological read does not defined the adjudication rule logic, please contact the developers to check!",
"TrialEmailN_InCons": "The trial is not configured with the Enrollment Confirmation!",
"TrialEmailN_NoBaseLine": "There is no baseline visit configured with Enrollment Confirmation and IR readedso email failed to send",
"TrialEmailN_IncompBase": "The baseline reads for enrollment confirmation has not been finished for IR!",
"TrialEmailN_EmailFail": "Email failed to generate manuallyplease contact developer to verify the failure cause",
"TrialEmailN_NoReader": "No IR has finished the baseline read at present!",
"TrialEmailN_NoPDConfig": "The trial is not configured with PD Confirmation!",
"TrialEmailN_NoPDTasks": "There is no baseline visit configured with “PD Confirmation” and IR readedso email failed to send",
"TrialEmailN_PDNotFinished": "The completion status of the latest PD interview and film reading task of the current subject does not meet the sending conditions",
"TrialEmailN_PDNoImaging": "The trial is configured with review period adjudication, but the current subject' s latest visit marked 'PD' have no review period",
"TrialEmailN_PDPhaseNotFinished": "The review period status of the current subject's latest PD visit does not meet the sending conditions",
"TrialEmailN_NoRuleDefined": "The sending logic for adjudication rule is not defined! ",
"TrialEmailN_NoDoubleOrder": "The current trial is not double and chronological read, so the sending condition is not met",
"TrialEmailN_NoSendLogicDefined": "The current trial is not defined sending logic",
"TrialEmailN_BlindedSequencedReading": "The configuration of the chronological read is wrong (should be single or double reading), please check!",
"TrialEmailN_UnblindedSequencedReading": "The configuration of random read is wrong (should be single read without adjudication, or double read with adjudication for visiting ), please check!",
"TrialEmailN_InvalidTaskTypeForEmailSending": "Do not send emails for other type except visit, adjudication and global read. Please check the logic.",
"TrialEmailN_PDLogicNotDefined": "Reads for this criterion has not yet defined the PD logic, please supplement it after consultation with the developer.",
"TrialEmailN_MailboxWrong": "The configuration of the sender mailbox of the trial is wrong, please check it.",
"TrialEmailN_InvalidRecipient": "The trial does not have a valid recipient, so the message cannot be sent.",
"TrialEmailN_EmailTestMessage": "Trial mail test",
"TrialEmailN_ConfigurationCorrect": "If this email is received, the email configuration is correct.",
"TrialEmailN_InvalidSenderEmailConfig": "The sender configuration is incorrect. Please check whether the server address or authorization code is correct or not.",
// ------------------------------------------------------------Financial--------------------------------------------------------------------
//CalculateService
"Cal_VolDataErr": "Volume reward data error.",
//ExchangeRateService
"ExR_SameMthExist": "The exchange rate of the same month already existed.",
"ExR_MthPymtRate": "The exchange rate has been used in monthly payment",
//PaymentAdjustmentService
"PayAdj_DocPymtLock": "Doctor payment has confirmed lock",
//RankPriceService
"RP_TitleUsedByRev": "This title has been used by reviewer payment information",
//TrialRevenuesPriceService
"TRP_AddMeaningful": "Please add meaningful data",
// ------------------------------------------------------------ImageAndDoc--------------------------------------------------------------------
//DicomArchiveService
"DAS_NoAnonCacheData": "The cache data for anonymous config is not obtained, and the upload stops. Please contact the developer to verify.",
//ImageShareService
"ISS_NoImgToShare": "There are no images to share for the current study.",
"ISS_ResNotExists": "The request resource wasnt found.",
"ISS_SharePwdError": "The shared password is incorrect.",
"ISS_ShareExpiration": "Resource sharing expires.",
//StudyService
"Study_VisitBeforePrevError": "The current visit check time {0} cannot be earlier than the previous visit check time {1}. Please check whether the check data is correct.",
"Study_VisitAfterSubseqError": "The current visit check time {0} cannot be later than the visit check time {1} .Please check whether the check data is correct.",
"Study_UploadArchiving": "Someone is currently uploading and archiving this visit!",
"Study_VisitEndedNotAllowed": "Subject visit is over, and uploading is not allowed!",
"Study_ImgAlreadyUploaded": "Uploading is not allowed above here.The current image check has been uploaded to {1} of subject {0}",
// ------------------------------------------------------------Inspection--------------------------------------------------------------------
//FrontAuditConfigService
"FrontAudit_IdDup": "The identifier is duplicated.",
"FrontAudit_NameDup": "The name is duplicated .",
"FrontAudit_CannotDelSub": "Subclasses exist, cannot delete.",
//InspectionService
"Inspection_UserDisabled": "The current user has been disabled.",
// ------------------------------------------------------------Institution--------------------------------------------------------------------
//CROService
"CRO_DupName": "CRO with the same name already exists. Please confirm.",
"CRO_InProject": "The CRO has participated in the trial and cannot be deleted.",
//HospitalService
"Hospital_DupName": "Hospital with the same name already exists. Please confirm.",
"Hospital_SiteAdded": "The current Site has been added to another Hospital.",
"Hospital_HasDoctors": "There are already doctors registered under the hospital's account and cannot be deleted.",
//SiteService
"Site_DupName": "Site with the same name already exists. Please confirm.",
"Site_InProject": "This site has been added to the project and cannot be deleted.",
//SponsorService
"Sponsor_DupName": "Sponsor with the same name already exists. Please confirm.",
"Sponsor_InProject": "The sponsor has been added to the trial and it is not allowed to delete.",
// ------------------------------------------------------------Management--------------------------------------------------------------------
//MenuService
"Menu_ParentDupChild": "A child node with the same name already exists under the parent node.",
"Menu_ChildExist": "Child nodes already exists under this node . Delete the child nodes before deleting the node.",
//UserService
"User_UsernameExist": "The user name already exists.",
"User_PhoneDup": "A user with the same phone number already exists in this user type.",
"User_EmailDup": "A user with the same email already exists in this user type.",
"User_NewOldPwdSame": "The new password is the same as the old one.",
"User_OldPwdInvalid": "Failed to verify the old password.",
"User_LegalEmail": "Please input a legal email.",
"User_VerificationCodeError": "The verification code is wrong.",
"User_VerificationCodeExpired": "The verification code has expired.",
"User_CreateFailed": "Check the email address or contact maintainers. The email fails to be sent and the account cannot be created.",
"User_InvalidEmail": "Please enter a correct E-mail address.",
"User_EmailError": "The email adress is wrong.",
"User_InProject": "The user has participated in the trial and cannot be deleted.",
"User_Disabled": "The user has been disabled.",
//UserTypeService
"UserType_InUse": "User already exists in that user type, and it cannot be deleted.",
// ------------------------------------------------------------QC--------------------------------------------------------------------
//QCCommon
"QCCommon_CannotOperate": "CRC has submitted the image. Operation is not allowed.",
"QCCommon_NoPermission": "You are not the current recipient of the image QC. No operation authority!",
"QCCommon_CheckTimeEarly": "The current visit study time {0} cannot be earlier than the previous visit study time {1}. Please check whether the study data is correct.",
"QCCommon_CheckTimeLate": "The current visit study time {0} cannot be later than the visit study time {1} .Please check whether the study data is correct.",
//QCOperationService
"QCOperation_CheckFirst": "Please check the image first and save review questions before query.",
"QCOperation_QuestionExist": "The unclosed query of the current visit has been set to approve CRC reupload. After CRC has reuploaded image, please close the original query first and then add a new query.",
"QCOperation_QuestionCannotClose": "CRC has applied for reuploading or QC has agreed to reupload. To close the query is not allowed. Please do not close the query until the QC rejects or the CRC reuploads the image.",
"QCOperation_CloseReason": "Reason for closing:",
"QCOperation_QuestionReplied": "The QC query has been answered.",
"QCOperation_NoPermissionReply": "You do not have permission to reply to the data reconciliation conversation.",
"QCOperation_CannotClose": "The current visit status is CRC request re-upload. The query is not allowed to be closed.",
"QCOperation_Reason": "Notes:",
"QCOperation_CannotPass": "The current visit is in the return status, and the data reconciliation cannot be set.",
"QCOperation_PassAfterClose": "Please close the data reconciliation query first, and then set the data reconciliation pass.",
"QCOperation_Cannotback": "The current visit has passed the consistency check and cannot be applied for re-upload.",
"QCOperation_CRCRollback": "CRC apples for re-upload.",
"QCOperation_OtherCRC": "Other CRCs have applied for processing. Please refresh the page.",
"QCOperation_PMReject": "PM/APM rejected the data reconciliation return.",
"QCOperation_NoPermission": "You do not have operation permission.",
"QCOperation_CannotRollback": "If the current visit has not do reconciliation or has passed, setbacks are not allowed.",
"QCOperation_PMAPMConsistency": "PM/APM agrees to the data reconciliation rollback.",
"QCOperation_NoModifyAfterSubmit": "Once submitted, no modifications are allowed.",
"QCOperation_UnresolvedQCQuery": "Image query of the current visit is not closed. This operation is not allowed.",
"QCOperation_CrcNoDelete": "The CRC has been committed and cannot be deleted.",
"QCOperation_NoRecipient": "You are not the current recipient of the quality control task, no operation authority!",
"QCOperation_QCImageTaskAlreadyReleased": "The image QC of the current visit has been released by the original recipient. You can get it by 'claime'.",
"QCOperation_QCTaskNoAccess": "The image quality control task of the current visit has been claimed by other QC, so it is not allowed to claim.",
"QCOperation_QCConfigFirst": "Please configure the image QC questions before claiming any image QC work.",
"QCOperation_NoQC": "The trial configuration of image QC was not check, and the QC Task was not be claimed.",
"QCOperation_InitialAuditPassed": "The first review has passed, continue to receive can not be allowed.",
"QCOperation_NoSingleAudit": "The trial is configured with single image QC , does not meet Submmit State: Submitted or Audit State: pending QC/ in QC, not allowed to collect.Please refresh the page.",
"QCOperation_NoSameReviewer": "The secondary QC cannot be the same person as the primary QC.",
"QCOperation_NoSecondaryAudit": "The trial is configured withr double image QC , does not meet Submmit State: Submitted or Audit State: pending review/ in QC, not allowed to collect.Please refresh the page.",
"QCOperation_NoTaskAccess": "You are not the current recipient of the quality control task, no operation authority!",
"QCOperation_NoQCFunction": "The project configuration of image QC process was not check, so there is no need to cancel the task function.",
"QCOperation_NoTaskOwner": "The current visiting image QC has not been claimed by anyone, and cannot been released.",
"QCOperation_DiseaseProgressConfirmation": "Current visit required PD Confirmation. Please process the unsubmitted prior visit before submitting the current visit: {0}.",
"QCOperation_UnsubmittedVisits": "After submitting the current visit, please submit any prior visits which have not been submitted as soon as possible. ({0})",
"QCOperation_NoBaselineData": "No clinical data at baseline. Confirm to submit?",
"QCOperation_NoImageData": "Dicom/ Non-dicom image data has not been uploaded. Submission is not allowed.",
"QCOperation_ImagesSubmitted": "The image data of the current visit has been submitted by another CRC.",
"QCOperation_BatchImagesSubmitted": "The visit image data is currently submitted in batches, part of which has been submitted by other CRCs.",
"QCOperation_MissingBaselineDate": "The trial is configured with the visit start date, but the visit start date for the subject is not filled. Submittion is not allowed.",
"QCOperation_RemoveItem": "You have been removed from the trial and have no operation rights.",
"QCOperation_QCNotClosed": "The QC query has not been closed for the current visit. This operation cannot be performed.",
"QCOperation_NoQCNeeded": "The trial configuration of image QC was no. No need to set image QC as pass.",
"QCOperation_QCNotSaved": "Image QC question is not saved. This operation is not allowed.",
"QCOperation_NotChangePass": "The trial configuration of image QC process was double check, so the current image QC task cannot change from the current state to pass.",
"QCOperation_CannotChangeToPass": "The trial configuration of image QC process was double check. The current audit state is {0}, which cannot be changed to approved.",
"QCOperation_NoQCNeededNotEnd": "The trial configuration of image QC process was not check, and setting image quality control termination is not allowed.",
"QCOperation_CannotChangeToStop": "The trial configuration of image QC process was single check, and the current review state is not In Primary QC and cannot be changed to the QC termination.",
"QCOperation_CannotChangeStop": "The trial configuration of image QC process was double check, and the current review state is {0} and cannot be changed to the QC termination.",
"QCOperation_InvalidResend": "The current reupload state is not QC agree, so reuploading is not allowed.",
"QCOperation_NoResendNeeded": "No check operation, there will be no need to reupload!",
"QCOperation_InvalidAgreeResend": "The current re-upload- status is not CRC requested and the approve of reuploading cannot be set.",
"QCOperation_CannotAgreeResend": "At the current visit, there is an unclosed query that QC set to agree to reupload, CRC has not uploaded, currently is not allowed to set again.",
"QCOperation_AgreeResend": "QC agrees to re-upload.",
"QCOperation_InvalidCompleteResend": "The current reupload status is not QC approved, setting reuploading completion is not allowed.",
"QCOperation_NoImageNotAllowed": "No image is currently available. Setting reuploaded is not allowed.",
"QCOperation_CRCTransferCompleted": "CRC reuploading has been completed. ",
"QCOperation_InvalidTransferStatus": "The current query re-upload status is not the initial| CRC re-uploaded. Application for re-uploading is not allowed",
"QCOperation_CRCTransfer": "CRC requests to reupload/upload images.",
"QCOperation_CannotModifyConfirmation": "The visit has been submitted, and the enrollment confirmation state cannot be modified.",
"QCOperation_CannotModifyPDStatus": "This visit status is return back. Modification of PD Confirmation status is not allowed.",
"QCOperation_ForwardingFailed": "Failed to forward the image:",
//QCQuestionService
"QCQuestion_DuplicateIndexFailed": "Operation failed because the serial number is repeated.",
"QCQuestion_HasChildQuestion": "The current task has a sub-question. Deletion failed.",
//TrialQCQuestionService
"TrialQCQuestion_TemplateConfirmed": "Image QC question template has been confirmed. No operation is allowed.",
"TrialQCQuestion_DuplicateIndexFailed": "Operation failed because the serial number is repeated.",
"TrialQCQuestion_DeleteChildFirst": "Before deleting the parent question, delete the child question that references the parent question.",
"TrialQCQuestion_ReferencedByQCProcess": "This review question has been cited by the image QC. Deletion is not allowed.",
// ------------------------------------------------------------QC--------------------------------------------------------------------
// ------------------------------------------------------------SiteSurvey--------------------------------------------------------------------
//TrialSiteEquipmentSurveyService
"TrialSiteEquipment_Locked": "Locked and operation is not allowed.",
//TrialSiteSurveyService
"TrialSiteSurvey_InvalidEmail": "Please enter the correct email address.",
"TrialSiteSurvey_WrongVerificationCode": "The verification code is incorrect.",
"TrialSiteSurvey_ExpiredVerificationCode": "The verification code has expired.",
"TrialSiteSurvey_NoRecordToUpdate": "The site does not have a site survey record for the transferor , so it is not allowed to choose to update.",
"TrialSiteSurvey_RecordUnderReview": "Your site survey record is in review and cannot be updated. If you need to update, please do so after rejection.",
"TrialSiteSurvey_LockedByCurrentUser": "In the current site, the submitted survey record has been locked. Updation of other people's email survey records is not allowed.",
"TrialSiteSurvey_LockedByOtherUsers": "The submitted survey record of the current site has been locked. Currently, the survey record submitted by other personnel is not locked. Updation of the survey submitted before is not allowed.",
"TrialSiteSurvey_UnlockedRecordsExist": "The current site has unlocked survey records. Locked survey records cannot be updated.",
"TrialSiteSurvey_NonLatestLockedRecord": "The site survey corresponding to the mailbox {0} is not the latest. Updation is not allowed",
"TrialSiteSurvey_AlreadyFilledByOtherUsers": "There are already survey filled out by other users under this site. You are not allowed to fill them out",
"TrialSiteSurvey_Locked": "The site survey has been locked, and no operation is allowed.",
"TrialSiteSurvey_IRCNotification": "[from Extensive Imaging IRC] A reminder about the site survey approval.",
"TrialSiteSurvey_CancelUnsubmittedRecord": "Only unsubmitted records are allowed to be repealed.",
"TrialSiteSurvey_NoAdminAcces": "The operation is not allowed by the administrator.",
"TrialSiteSurvey_FailedToGenerateAccountId": "If no value is obtained for the generated account Id. Please check.",
"TrialSiteSurvey_IRCInvitation": "[from Extensive Imaging IRC][{0}] Invitation letter",
"TrialSiteSurvey_IRCInvitationContent": "Hello, as the IRC supplier of experiment plan No. {0} trial, Extensive Imaging sincerely invites you to participate in the IRC related work of this project. Your guidance and suggestions are welcome.",
"TrialSiteSurvey_ViewAndConfirm": "Check and confirm",
//TrialSiteUserSurveyService
"TrialSiteUser_Locked": "Locked and not allowed to operate.",
"TrialSiteUser_InconsistentInfo": "The corresponding user of this email address is {0}, and the phone number is {1}. Please modify the inputted information and make it consistent with that already in the system, and then save.",
"TrialSiteUser_NoTestUserForFormal": "Formal and training triala are not allowed to add test users.",
"TrialSiteUser_NoFormalUserForTest": "It is the test project that regular users are not allowed in.",
// ------------------------------------------------------------Stat--------------------------------------------------------------------
// ------------------------------------------------------------TrialSiteUser--------------------------------------------------------------------
//TrialConfigService
"TrialConfig_JudgeTaskFail": "There are adjudication questions that the conditions for generating adjudication review read are not configured. Operation failed!",
"TrialConfig_StdConfigMissing": "Questions are not configured under the current criterion.",
"TrialConfig_AddEvalReq": "Selected additional assessment, must check additional assessment type",
"TrialConfig_SignTemplateMissing": "This operation requires electronic signature confirmation, but the signature template for this scenario is not found in the system.",
"TrialConfig_ProjectEnded": "The trial has ended or stopped. Configuration changes are not allowed.",
"TrialConfig_NoImageAuditQuestion": "No image QC question is currently added. Please add the image QC questions first, and then confirm.",
"TrialConfig_DuplicateAuditQuestionId": "Image QC question display number cannot be repeated.",
"TrialConfig_InvalidParentQuestionId": "Make sure that the display sequence number of the parent question is smaller than that of the child.",
"TrialConfig_AuditQuestionConfirmed": "The image QC questions have been confirmed by other personnel. Cofirmation again is not allowed. ",
"TrialConfig_ProjectNotInitialized": "The current trial status is not initialized. This operation is not allowed.",
"TrialConfig_UnconfirmedConfiguration": "This trials project configuration, & visit management have not been finished, and its status cannot be changed to “Ongoing”.",
"TrialConfig_UnconfirmedUNACKD": "This trials project configuration, & visit management have not been all confirmed, and its status cannot be changed",
"TrialConfig_ProjectNotStarted": "This trial status is not “Ongoing”, and cannot be set to Stoped or Completed.",
//TrialExternalUserService
"TrialExternalUser_Inconsistency": "The corresponding user of this email address is {0}, and the phone number is {1}. Please modify the inputted information and make it consistent with that already in the system, and then save.",
"TrialExternalUser_EmailTypeDuplicate": "Please confirm that the system already has an account with the same email address and user type as the one entered in the list.",
"TrialExternalUser_TestUserNotAllowed": "Formal and training trials are not allowed to add test users.",
"TrialExternalUser_FormalUserNotAllowed": "It is a training trial that regular users are not allowed in.",
"TrialExternalUser_NotEditable": "Staff information cannot be edited. Please delete it and add it again.",
"TrialExternalUser_CannotDelete": "The current user has participated in the trial and cannot be deleted.",
"TrialExternalUser_IRCInvitation": "Hello, as the IRC supplier of experiment plan No. {0} trial, Extensive Imaging sincerely invites you to participate in the IRC related work of this project. Your guidance and suggestions are welcome.",
"TrialExternalUser_ViewAndConfirm": "Check and confirm",
"TrialExternalUser_InvitationExpired": "The invitation time has expired. You can only confirm it after you are invited again.",
"TrialExternalUser_AccountInfo": "[from Extensive Imaging IRC][{0}] account information",
"TrialExternalUser_Welcome": "Hello, welcome to participate in the relevant work of trial scheme No. {0}IRC of the project. This trial adopts electronic workflow. The system and your account information are as follows:",
"TrialExternalUser_ProjectNumber": "Trial ID: {0}",
"TrialExternalUser_ExperimentPlanNumber": "Protocol ID: {0}",
"TrialExternalUser_ExperimentName": "Study Name: {0}",
"TrialExternalUser_Username": "User name: {0}",
"TrialExternalUser_Password": "Password: {0}Please modify it after login: ***You already have your account. If you forget your password, please find it by email",
"TrialExternalUser_Role": "User role: {0}",
"TrialExternalUser_LoginUrl": "System login address: {0} ",
"TrialExternalUser_ReinvitationRequired": "The invitation time has expired. You can only confirm it after you are invited again.",
"TrialExternalUser_UserIdStorageProblem": "There is a problem with the system user Id storage of the survey table. ",
"TrialExternalUser_IRCAccountInfo": "[from Extensive Imaging IRC][{0}] account information",
//TrialMaintenanceService
"TrialMaint_PersonnelJoined": "Participant has participated in site maintenance",
//TrialService
"Trial_PMApmPermission": "Only PM/APM has the operation permission!",
"Trial_TestUserCreateOnlyNonFormal": "Test users can only create informal projects",
"Trial_DuplicateProjectNumber": "The same project ID already exists.",
"Trial_InvalidProjectStatus": "Operations are allowed only when the project state is: initializing or ongoing.",
"Trial_CannotDeleteProject": "Deleting project data is not allowed in the current running environment.",
//TrialSiteService
"TrialSite_ParticipantJoined": "The subjects has been added to this site, and couldn't be disable.",
"TrialSite_CodeDuplicate": "Code is not allowed to be repeated",
"TrialSite_CannotDeleteAssociatedCRC": "The site has been associated with CRC, and couldn't be deleted.",
"TrialSite_CannotDeleteAssociatedSubject": "The subjects has been added, and couldn't be deleted.",
"TrialSite_CannotDeleteUploadedData": "The site has been uploaded survey, and couldn't be deleted.",
// ------------------------------------------------------------Visit--------------------------------------------------------------------
//SubjectService
"Subject_NoConfirmedPlan": "The visit plan of the trial is not confirmed. Please contact PM to confirm the visit plan before adding subjects.",
"Subject_DuplicateSubjectNum": "Subjects with the relevant subject ID already exists.",
"Subject_UploadedVisitNoDelete": "The subject has visit that has uploaded the image. Deletion is not allowed.",
//SubjectVisitService
"Visit_DuplicateVisitNo": "The subject's visit schedule already includes a visit with the same visit ID.",
"Visit_LastVisitNoChange": "The subject has already had a visit set as the last, and the current visit cannot be set as the last visit.",
"Visit_DuplicateVisitName": "The subject's visit schedule already includes a visit with the same visit name.",
"Visit_NoExtraVisitAfterLast": "Unplanned visits cannot be added after the last assessment is set.",
"Visit_FinishedTasksNoAdd": "The subject has reads completed in follow-up visit ( chronological read ) , which is not allowed to be added here. If necessary, please return.",
"Visit_NoPDStatusChangeAfterSubmission": "The PD Confirmation status cannot be modified after the current visit image is submitted.",
"Visit_UploadedNoLost": "The current visit has already uploaded images and cannot be set as visit lost to follow-up.",
"Visit_UploadedNoDelete": "The current visit has already uploaded images and deletion is not allowed.",
"Visit_PlanVisitNoDelete": "Planned visits are not allowed to be deleted.",
"Visit_PreviousVisitNoDelete": "The current visit has been set to the previous visit of another visit and cannot be deleted.",
//VisitPlanService
"VisitPlan_OnlyInitOrOngoing": "Can be operated only when the trial state is: Initialized or ongoing.",
"VisitPlan_LargerVisitNumLargerInterval": "In the visit plan, the interval between visits with a large number should also be larger than that of a visit with a smaller number.",
"VisitPlan_LargerPlanNumLargerInterval": "In the visit plan, the planned visit with a large number should also have a larger interval than the planned visit with a smaller event number.",
"VisitPlan_ExistNameOrNumTemplate": "A plan visit template with visit name or visit ID of trial already exists in the visit plan.",
"VisitPlan_ExistBaseline": "A baseline already exists in the visit plan.",
"VisitPlan_ExistBaselineImgNoModify": "The subjects baseline image data has been uploaded, so modification of baseline visits is not allowed.",
"VisitPlan_OnlyInitOrOngoingModifyConfirm": "Modification confirmation is allowed only when the trial is initialized or ongoing.",
"VisitPlan_NoBaselineNotConfirm": "No baseline, no confirmation allowed.",
"VisitPlan_ConfigNotConfirmNotConfirm": "If the trial configuration is not confirmed, the visit plan cannot be confirmed.",
"VisitPlan_BaselineNotMinDayNotConfirm": "Baseline's VisitDay is not minimal. Confirmation is not allowed.",
"VisitPlan_CheckExport": "Study export _{0}.xlsx",
"VisitPlan_Assigned": "The visit plan has been assigned to the subjects and executed.",
// ------------------------------------------------------------WorkLoad--------------------------------------------------------------------
//DoctorWorkloadService
"DoctorWorkload_AssignType": "A task has been assigned and does not allow you to reduce the reading type.",
"DoctorWorkload_Unique": "This type of data can only have one",
"DoctorWorkload_FeeSettled": "Expenses have been settled and workload cannot be modified.",
//EnrollService
"Enroll_NotFound": "Cannot find trial {0}",
"Enroll_EmailFormat": "The {0} mailbox format is faulty.",
"Enroll_CannotRollback": "Reviewers with workload cannot go back",
// ------------------------------------------------------------Triggers--------------------------------------------------------------------
//AddlTrialUserTrigger
"AddlTrialUser_NoTestUser": "Formal and training trials are not allowed to be added test users.",
"AddlTrialUser_NoFormalUser": "It is a training trial that regular users are not allowed in.",
//SubjectStateTrigger
"SubjectState_CannotSetCurrentAsLastVisit": "The subject has already had a visit set as the last, and the current visit cannot be set as the last.",
"SubjectState_CannotSetAsLastVisitWithImage": "The image of the subject's visit after the current visit has been uploaded, and the current visit is not allowed to be set as the last visit.",
//SubjectVisitFinalVisitTrigger
"SubjectVisit_CannotSetAsLastVisit": "The subject's follow-up visits has uploaded images or submitted , and the current visit is not allowed to be set as the last visit.",
// ------------------------------------------------------------BusinessFilter--------------------------------------------------------------------
//LimitUserRequestAuthorization
"LimitUser_AuthTokenMissing": "User token was not retrieved from Header/URL, please contact developer",
"LimitUser_AccountLoggedInElsewhere": "User token was not retrieved from Header/URL, please contact developer",
//ModelActionFilter
"ModelAction_InvalidAPIParameter": "Invalid parameters provided for the API.",
//ProjectExceptionFilter
"ProjectException_ConcurrentUpdateNotAllowed": "Concurrent update, operation not allowed at this time.",
"Project_ExceptionContactDeveloper": "Program exception, please contact developer.",
//TrialResourceFilter
"TrialResource_NoAccessPermission": "Sorry, your account does not have operation permissions.",
"TrialResource_ReferTrialIdFailed": "Regular expression failed to fetch trialId from request Refer, please contact developer to check",
"TrialResource_InterceptedProjectStatusRule": "This request was blocked by configured rules: only operations allowed when project status is in progress, please contact developer if this logic is incorrect and needs to be modified",
"TrialResource_MissingProjectNumber": "Project number not passed in the API parameters, please verify.",
//UnifiedApiResultFilter
"UnifiedAPI_ProgramError": "Program error, please contact developer.",
// ------------------------------------------------------------Helper--------------------------------------------------------------------
//FileStoreHelper
"FileStore_TemplateFileNotFound": "Database did not find the corresponding data template file for FileStoreHelper, please contact system maintenance personnel.",
"FileStore_TemplateFileStoragePathInvalid": "File doesnt exist. Please contact the system administrator!",
//SendEmailHelper
"SendEmail_SendFail": "Failed to send email in SendEmailHelper. Your operation was unsuccessful, please check your email or contact maintenance personnel.",
"SendEmail_NoRecipient": "No recipient in SendEmailHelper.",
// ------------------------------------------------------------IRaCIS.Core.Domain--------------------------------------------------------------------
//Trial
"Trial_number": "Subject ID is composed of 5 digits. The first 2 are the Site ID, and the following 3 are the order number. Please ensure it is identical to the ID from the EDC system. ",
// ------------------------------------------------------------IRaCIS.Core.Infrastructure--------------------------------------------------------------------
//ResponseOutput
"RO_BizObjNotExistsOrParamIncorrect": "The business object{0} does not exist in the database, or was deleted by someone else, or an incorrect parameter query caused",
"RO_ExpectChangeButNoEffect": "Expect a change, but the database data has not changed",
"RO_SaveFailed": "Saved failed"
}
}
Binary file not shown.
+1 -592
View File
@@ -1,593 +1,2 @@
{
"test{0}{1}": "中文本地化{0}{1}",
"RequiredAttribute": "{0} 字段是必须的",
// ------------------------------------------------------------_ServiceExtensions--------------------------------------------------------------------
//ApiResponseHandler
"ApiResponse_NoAccess": "您无权访问该接口",
"ApiResponse_Permission": "您的权限不允许进行该操作",
// ------------------------------------------------------------Controllers--------------------------------------------------------------------
//FinancialChangeController
"Financial_ChargeSettled": "费用已经结算,无法重置工作量",
"Financial_InvalidParameter": "无效的参数。",
//UploadDownLoadController
"UploadDownLoad_UnsupportedMedia": "不支持的MediaType",
"UploadDownLoad_ArchiveInProgress": "当前已有人正在上传和归档该检查!",
"UploadDownLoad_InvalidData": "请保证上传数据符合模板文件中的样式,且存在有效数据。",
"UploadDownLoad_RequestError": "请求异常,请重试!",
"UploadDownLoad_SupportedFormats": "支持.xlsx、.xls、.csv格式的文件上传。",
// ------------------------------------------------------------_MediatR--------------------------------------------------------------------
//ConsistencyVerificationRequest
"ConsistencyVerification_Tech": "检查技术",
"ConsistencyVerification_Time": "时间格式不对",
//ConsistencyVerificationHandler
"ConsistencyVerification_Img": "您好,根据本系统自动识别,该受试者当前访视在IRC系统中已提交的影像检查情况如下:",
"ConsistencyVerification_Of": "的",
"ConsistencyVerification_ImgC": "影像检查",
"ConsistencyVerification_EDCA": "核对EDC数据,完全一致, 审核通过",
"ConsistencyVerification_EDCB": "核对EDC数据,完全一致",
"ConsistencyVerification_Auto": "自动核查通过",
"ConsistencyVerification_Prob": "存在问题如下:",
"ConsistencyVerification_EdcL": "影像检查(EDC 缺少)",
"ConsistencyVerification_IrcL": "影像检查(IRC 缺少)",
"ConsistencyVerification_Desc": "说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。",
"ConsistencyVerification_Conf": "根据导入的一致性核查数据,请确认本访视以下不一致检查项信息:",
"ConsistencyVerification_Edc": "EDC 缺少:",
"ConsistencyVerification_IrcLi": "IRC 缺少:",
// ------------------------------------------------------------Reading--------------------------------------------------------------------
//ClinicalDataSetService
"ClinicalDataSet_Apply": "当前临床数据需要配置一个检查日期才能应用",
"ClinicalDataSet_DupTypeFail": "存在同类型的临床数据,操作失败",
//ClinicalQuestionService
"ClinicalQuestion_Repeat": "存在相同的问题名称!",
//ReadingClinicalDataService
"ReadingClinicalData_DupTypeFail": "存在同类型的临床数据,操作失败",
"ReadingClinicalData_Unchecked": "当前临床数据状态不是已核查状态,不允许签名!",
//ReadingGlobalTaskService
"ReadingGlobal_NotGlobal": "系统调用错误,当前任务不是全局阅片任务。",
//ReadingImageTaskService
"ReadingImage_NotVisit": "系统调用错误,当前任务不是访视任务。",
"ReadingImage_CantSplit": "当前任务是基线任务,不能执行分裂病灶的操作。",
"ReadingImage_BeSigned": "当前任务已经签名,请勿重复提交。",
"ReadingImage_Beinvalid": "当前任务已失效,不能执行阅片。",
"ReadingImage_PresenceReview": "当前受试者存在重阅申请还未处理,不允许操作",
"ReadingImage_NotaTask": "合并的病灶并非同一个访视任务",
"ReadingImage_DeleteError": "当前病灶分裂出其他病灶或者其他病灶合并到了当前病灶,删除失败。",
"ReadingImage_Idnotcorrespond": "病灶标记添加失败,影像的Instance ID和Series ID不对应。",
"ReadingImage_IsLymphNotbigger": "当前访视该淋巴结非靶病灶的短径小于上一访视的值,不能设置为显著增大。",
"ReadingImage_NotLymphNotbigger": "当前访视该非淋巴结非靶病灶的长径小于上一访视的值,不能设置为显著增大。",
"ReadingImage_Twice": "系统调用错误,提交的问题及答案重复。",
"ReadingImage_MaxQuestion": "按照《独立影像评估章程》的相关规则,当前{0}的病灶数量不能超过{1}个。",
"ReadingImage_Maxlesion": "按照《独立影像评估章程》的相关规则,同一器官的靶病灶数量不能超过{0}个,请确认",
"ReadingImage_Maximum": "{0}的重复次数限制为{1},目前已重复{2}次。",
"ReadingImage_PCWGMaximum": "按照《独立影像评估章程》的相关规则,同一部位的基线病灶只需录入{0}次,请确认。",
"ReadingImage_NotNewFocus": "转换后的任务不应该存在新病灶",
"ReadingImage_RequiredQuestion": "提交前,请完成{0}",
"ReadingImage_ClinicalRead": "临床数据未阅读,请确认!",
"ReadingImage_IDMust": "系统调用失败,当没有任务ID的时候,标准ID必传。",
"ReadingImage_TaskFinish": "当前受试者所有阅片任务已完成,请知悉。",
"ReadingImage_NeedRest": "您已连续阅片{0}个小时,请休息{1}分钟后,再继续阅片。",
//ReadingJudgeTaskService
"ReadingJudge_SouceIdNull": "系统调用失败,当前裁判的全局任务的SouceId为null。",
//ReadingOncologyTaskService
"ReadingOncology_TaskError": "系统调用错误,当前任务不是肿瘤学任务。",
"ReadingOncology_Abnormal": "系统调用异常,裁判结果为null。",
//ReadingCalculate
"ReadingCalculate_Abnormal": "PCWG3标准配置错误,数据验证失败。",
"ReadingCalculate_questionable": "病灶存在以下问题:",
"ReadingCalculate_NoMarker": "病灶{0}缺少标记",
"ReadingCalculate_StatusIsEmpty": "病灶{0}状态为空",
"ReadingCalculate_NoMarkerEmpty": "病灶{0}未做标记,且状态为空",
"ReadingCalculate_NoDeveloped": "当前标准自动计算未完成开发,请知悉。",
//ReadingMedicalReviewService
"MedicalReview_invalid": "该医学审核任务已失效,操作失败。",
"MedicalReview_SaveQuestion": "无法执行当前操作,请先保存医学审核问题。",
"MedicalReview_NeedSave": "无法执行当前操作,请先保存医学审核问题和结论。",
"MedicalReview_NotClosed": "无法执行当前操作,当前医学质询对话未关闭。",
"MedicalReview_Finish": "当前医学审核任务为最后一个任务。",
//ReadingMedicineQuestionService
"ReadingMed_QNumDup": "当前问题序号存在重复",
"ReadingMed_HasSubQ": "此问题存在子问题,请先删除子问题",
"ReadingMed_NoMedQ": "当前未添加医学审核问题。请先添加医学审核问题,再进行确认。",
"ReadingMed_MedQNumDup": "影像医学审核问题显示序号不能重复。",
"ReadingMed_ParentNumSmall": "父问题的显示序号要比子问题的显示序号小,请确认。",
"ReadingMed_VisitQNotConfig": "当前标准未配置访视医学审核问题。",
"ReadingMed_GlobalQNotConfig": "当前标准启用了全局阅片,但未配置全局医学审核问题",
"ReadingMed_ArbitrateQNotConfig": "当前标准启用了仲裁阅片,但未配置仲裁医学审核问题",
"ReadingMed_TumorQNotConfig": "当前标准启用了肿瘤学阅片,但未配置肿瘤学医学审核问题",
//UserService
"User_CheckNameOrPw": "请检查用户名或者密码。",
//Repository
"Repository_UpdateError": "修改的数据在数据库不存在。",
"Repository_DeleteError": "删除的数据在数据库不存在。",
//OrganInfoService
"OrganInfo_DuplicateData": "存在相同的数据,操作失败",
//ReadingCriterionService
"ReadingCriterion_Referenced": "当前标准被引用过了,不可以删除",
"ReadingCriterion_InUse": "此标准在项目里面已被使用,操作失败",
"ReadingCriterion_ArbitratorWithoutJudgment": "无裁判问题却有仲裁对象,操作失败",
//ReadingQuestionService
"ReadingQuestion_IdDup": "问题编号重复",
"ReadingQuestion_ChildrenExist": "此问题存在子问题,请先删除子问题",
"ReadingQuestion_GroupReferenced": "此分组已被引用,请先删除被引用的问题",
"ReadingQuestion_JudgmentSet": "当前问题已经设置了裁判标准了,修改失败",
"ReadingQuestion_ExcludeWithDependency": "显示依赖父问题和必填依赖的问题为同一个,但答案互斥,操作失败",
"ReadingQuestion_CircularDependency": "计算依赖循环了!",
//ReadingPeriodSetService
"ReadingPeriodSet_NameDup": "阅片期名称重复,操作失败",
"ReadingPeriodSet_Global": "阅片期名称不能为Global",
"ReadingPeriodSet_AlreadyAdded": "{0}已经添加过阅片期,无法设置生效",
"ReadingPeriodSet_TaskCompletedCannotRevoke": "当前标准阅片已生成任务并且阅片完成,撤销失败。",
"ReadingPeriodSet_LastVisit": "末次访视",
//ReadModuleService
"ReadModule_AlreadyAdded": "当前访视已经添加过阅片期",
"ReadModule_AddGlobalFirst": "请先添加全局阅片",
"ReadModule_VisitNotFound": "未找到符合要求的访视",
"ReadModule_SignedDataCannotDelete": "临床资料已签名,不允许删除",
"ReadModule_TumorExists": "当前访视存在肿瘤学阅片,请先删除肿瘤学阅片",
"ReadModule_TaskGenerated": "当前阅片已生成任务,操作失败。",
//UserWLTemplateService
"UserWLTS_MaxTemplate": "同一个用户最多只能添加10个模板",
"UserWLTS_NameRepeated": "模板名称存在重复",
"UserWLTS_ContentRepeated": "模板内容存在重复",
// ------------------------------------------------------------Allocation--------------------------------------------------------------------
//TaskAllocationRuleService
"TaskAllocation_DoctorIdNotFound": "错误,未在入组表中找到该医生的账号Id",
"TaskAllocation_DoctorConfigExists": "已有该医生配置,不允许继续增加",
"TaskAllocation_TaskAssigned": "已分配任务给该医生,不允许删除",
//TaskConsistentRuleService
"TaskConsistent_ConsistencyConfigExists": "请配置一致性分析的医生",
"TaskConsistent_TaskGenerated": "已有该项目配置,不允许继续增加",
"TaskConsistent_MedicalAuditTaskExists": "该标准已有Subject 生成了任务,不允许修改配置",
"TaskConsistent_SignedTaskCannotBeInvalidated": "该标准已产生一致性分析任务,不允许删除",
//TaskMedicalReviewRuleService
"TaskMedicalRule_TaskAlreadyAssigned": "已有该医生配置,不允许继续增加",
"TaskMedicalRule_TaskStarted": "已产生医学审核任务",
//TaskMedicalReviewService
"TaskMedical_DirtyData": "已签名的不允许设置为失效",
"TaskMedical_SubjectInOtherArm": "当前有任务已分配给其他人,不允许分配,请刷新列表",
//VisitTaskService
"VisitTask_VisitTask_TaskAlreadyApplied": "该项目还未确认任何一个阅片标准",
"VisitTask_DoctorConfigNotFound": "当前医生已开始做该Subject 该标准的任务,不允许取消分配",
"VisitTask_BackendDataError": "其中一个任务已分配给该医生,不允许分配",
"VisitTask_DirtyData": "出现脏数据 任务来源字段没有值",
"VisitTask_MissingTaskSource": "该受试者有访视进入了退回流程,还未经过一致性核查通过,不允许分配",
"VisitTask_InconsistentSubjectStatus": "有Subject 在其他Arm组已有该医生,不允许在新的组添加该医生",
"VisitTask_DuplicateDoctorInArm": "有Subject 已有该Arm组的医生,不允许继续分配,请刷新页面,确认页面数据是否过期",
"VisitTask_DoctorAlreadyInArm": "有Subject任务已应用,不允许取消分配",
"VisitTask_TaskAlreadyApplied": "在配置表中未找到配置的医生,无法应用绑定,请核对数据",
"VisitTask_DoctorConfiguration": "后台数据有错误",
"VisitTask_BackendData": "未阅片完成,或者未生效的任务不允许申请重阅",
"VisitTask_UnreadTask": "重阅已申请,或者重阅已同意状态下不允许申请重阅",
"VisitTask_NoPMRecheck": "附加评估标准任务不允许PM 申请影像重阅",
"VisitTask_Reapply": "PM 不允许对一致性分析任务进行申请重阅",
"VisitTask_ConsistencyAnalysis": "PM 仅仅允许对访视类型的任务申请重阅",
"VisitTask_VisitTypeRestriction": "当前为有序阅片,该受试者已有访视已申请重阅还未处理(项目组申请),暂不能继续申请重阅",
"VisitTask_SequentialReading": "当前为有序阅片,该受试者已有访视已申请重阅还未处理,暂不能继续申请重阅",
"VisitTask_ImageProblem": "当前为有序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅",
"VisitTask_LastReading": "有序阅片,只允许申请该受试者阅片人最后一次完成全局任务重阅",
"VisitTask_LastOncologistRecheck": "有序阅片,只允许申请该受试者阅片人最后一次完成肿瘤学任务重阅",
"VisitTask_LastAdjudicatorRecheck": "有序阅片,只允许申请该受试者阅片人最后一次完成裁判的任务重阅",
"VisitTask_IRGlobalRecheck": "无序阅片,仅仅允许IR 申请 全局和访视类型类别的任务进行重阅",
"VisitTask_IRReapply": "无序阅片,仅仅允许IR申请全局和访视类型类别的任务进行重阅",
"VisitTask_InvalidReapplyStatus": "当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面",
"VisitTask_ReapplyStatusConflict": "当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作",
"VisitTask_ReReadTaskNotApplied": "仅允许同意访视类型的任务重阅",
"VisitTask_ReReadTaskAlreadyAffected": "不符合 PM申请 SPM / CPM审批 | IR申请 PM 审批 ",
"VisitTask_TaskTypeNotApproved": "当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面",
"VisitTask_NoImageReturn": "附加评估标准任务不允许在此入口影像退回",
"VisitTask_NonEffectiveTaskCannotBeReturned": "仅仅允许针对生效、未完成的访视任务进行退回操作,请刷新页面数据",
"VisitTask_NoFurtherReturn": "当前访视已回退到影像上传,不允许继续回退!",
"VisitTask_ConsistencyTaskCannotBeReturned": "一致性分析的任务,不允许设置退回",
"VisitTask_PMOnlyAllowedForReturn": "仅PM 可以进行回退操作",
"VisitTask_UnsupportedTaskType": "不支持重阅的任务类型",
"VisitTask_UndefinedList": "当前用户查看列表未定义",
"VisitTask_NoConsistencyReturn": "不允许退回一致性分析任务",
"VisitTask_VisitTypeTaskAllowedForPMOnly": "仅仅访视类型的任务支持PM退回",
// ------------------------------------------------------------Common--------------------------------------------------------------------
//CommonDocumentService
"Document_CodeDuplication": "文档的Code不能够重复。",
"Document_SingleTemplate": "一个场景一个标准只允许有一个模板文档",
"Document_ TemplateRead": "读取模板内容失败, 请将文件另存为docx格式尝试!",
//DictionaryService
"Dictionary_DictionaryName": "已有{0}名称的字典",
"Dictionary_DictionaryDeletion": "当前字典在标准中被引用,不允许删除!",
"Dictionary_SubitemDeletion": "有子项数据,不允许直接删除!",
"Dictionary_ResumeReference": "当前条目已经在阅片人的简历中被引用。",
"Dictionary_ProjectReference": "当前条目已经在项目信息中被引用。",
"Dictionary_StandardReference": "当前条目已经在阅片标准中被引用。",
//ExcelExportService
"ExcelExport_UnsupportedExport": "当前标准导出还未支持",
//MailService
"Mail_EmailResetReminder": "[来自展影IRC] 关于重置邮箱的提醒",
"Mail_Dear": " 尊敬的 {0} , ",
"Mail_ResettingEmail": "您正在进行邮箱重置操作",
"Mail_IRCResettingPassword ": "[来自展影IRC] 关于重置密码的提醒",
"Mail_ResettingPassword ": "您正在进行邮箱重置密码操作",
"Mail_ImagingIRCReminder": "[来自展影IRC]的提醒",
"Mail_IRCProject": "您正在参与展影医疗IRC项目",
"Mail_ProjectParticipationReminder": "[来自展影IRC] [{0}] 关于中心调研的提醒",
"Mail_CenterResearchReminder": "您正在参与展影医疗IRC项目中心调研工作",
"Mail_AccountCreationReminder": "[来自展影IRC] 关于创建账户的提醒",
"Mail_AccountPasswordResetReminder": "[来自展影IRC] 关于重置账户密码的提醒",
"Mail_InvitationEmail": "[来自展影IRC] [{0}]邀请信",
//SystemMonitor
"SysMon_JsonConfig": "解析Json文件配置出现问题",
// ------------------------------------------------------------Doctor--------------------------------------------------------------------
//DoctorService
"Doctor_DupPhoneOrEmail": "当前的电话或电子邮件号码已经存在",
"Doctor_DupPhone": "当前的电话号码已经存在!",
"Doctor_DupEmail": "当前的邮箱已经存在!",
"Doctor_StandardDuplicateFileTypeError": "当前标准已添加过此类型文件",
"Doctor_RequiredDocumentsError": "简历及顾问协议必须上传",
// ------------------------------------------------------------Document--------------------------------------------------------------------
//SystemDocumentService
"SystemD_DuplicateFile": "系统中已存在同类型的同名文件。",
"SystemD_CannotDeleteSignedFile": "已有用户阅读该文档,并签名,不允许删除。",
//TrialDocumentService
"TrialD_DuplicateFileInProject": "该项目中已经存在同类型的同名文件。",
"TrialD_DocumentHasAlready": "已有用户阅读该文档,并签名,不允许删除。",
"TrialD_FileAlreadySigned": "该文件已经签名",
"TrialD_ObsoleteFile": "文件已废除,签署失败!",
//TrialEmailNoticeConfigService
"TrialEmailN_TaskNotSigned": "进行邮件发送前,该任务必须已签名完成并已经触发完成相应的任务生成",
"TrialEmailN_NoRecipient": "没有收件人,无法发送邮件",
"TrialEmailN_InvalidEmailConfig": "项目发件邮箱配置有误,请核实",
"TrialEmailN_EmailTemplateNotFound": "找不到该项目标准场景下邮件模板",
"TrialEmailN_EnrollmentConfirmation": "【入组确认报告】关于{0}项目{1}受试者",
"TrialEmailN_Enrollment": " 附件为入组确认报告,请查收",
"TrialEmailN_PDReport": "【疾病进展确认报告】关于{0}项目{1}受试者",
"TrialEmailN_SubjectDiseaseProgression": " 附件为疾病进展确认报告,请查收 ",
"TrialEmailN_SingleBlindedSet": "单重有序阅片配置有误(不应该有仲裁对象配置),请核查!",
"TrialEmailN_SingleBlindedSequenced": "单重有序阅片 该类型的任务不应进入此处逻辑,请联系后台开发核查!",
"TrialEmailN_PDProgressEmailTask": "发送PD 进展邮件中发现任务数据有问题!",
"TrialEmailN_DoubleBlindedError": "双重有序阅片 没有定义该仲裁规则处理逻辑,请联系业务和后台开发核查!",
"TrialEmailN_InCons": "项目未配置入组确认!",
"TrialEmailN_NoBaseLine": "不存在配置了入组确认的并且已阅的基线访视",
"TrialEmailN_IncompBase": "做入组确认的阅片人基线任务没有阅片完!",
"TrialEmailN_EmailFail": "邮件手动生成失败,请联系开发核实该场景失败原因",
"TrialEmailN_NoReader": "当前未有阅片人读完基线任务!",
"TrialEmailN_NoPDConfig": "项目未配置PD进展!",
"TrialEmailN_NoPDTasks": "不存在配置了PD进展的并且已阅的访视",
"TrialEmailN_PDNotFinished": "当前受试者最新PD访视阅片任务完成状态不符合发送条件",
"TrialEmailN_PDNoImaging": "项目配置了阅片期仲裁,但是当前受试者最新PD访视没有影像学阅片期",
"TrialEmailN_PDPhaseNotFinished": "当前受试者最新PD访视阅片期任务完成状态不符合发送条件",
"TrialEmailN_NoRuleDefined": "未定义该仲裁规则发送业务逻辑!",
"TrialEmailN_NoDoubleOrder": "当前项目配置,不满足双重有序阅片,不满足发送条件!",
"TrialEmailN_NoSendLogicDefined": "当前项目配置,未定义发送业务逻辑!",
"TrialEmailN_BlindedSequencedReading": "有序阅片配置有误(应为单重或者双重阅片),请核查!",
"TrialEmailN_UnblindedSequencedReading": "无序阅片配置有误(应为单重无仲裁对象,双重针对访视仲裁),请核查!",
"TrialEmailN_InvalidTaskTypeForEmailSending": "不应有除访视、裁判、全局其他类型的任务进行发送邮件,请核查业务逻辑",
"TrialEmailN_PDLogicNotDefined": "该标准任务还未定义PD获取逻辑,联系业务和后台开发协商后补充",
"TrialEmailN_MailboxWrong": "项目发件邮箱配置有误,请核实",
"TrialEmailN_InvalidRecipient": "项目没有有效的收件人,无法发送邮件",
"TrialEmailN_EmailTestMessage": "项目邮件测试",
"TrialEmailN_ConfigurationCorrect": " 收到此邮件,代表邮件配置正确",
"TrialEmailN_InvalidSenderEmailConfig": "发件人配置错误,请核对服务器地址或者授权码是否填写有误",
// ------------------------------------------------------------Financial--------------------------------------------------------------------
//CalculateService
"Cal_VolDataErr": "体积数据错误",
//ExchangeRateService
"ExR_SameMthExist": "同月的汇率已存在",
"ExR_MthPymtRate": "按月付款采用汇率",
//PaymentAdjustmentService
"PayAdj_DocPymtLock": "医生付款已确认锁定",
//RankPriceService
"RP_TitleUsedByRev": "此标题已被审稿人付款信息所使用",
//TrialRevenuesPriceService
"TRP_AddMeaningful": "请添加有意义的数据",
// ------------------------------------------------------------ImageAndDoc--------------------------------------------------------------------
//DicomArchiveService
"DAS_NoAnonCacheData": "未取到缓存匿名化配置数据,上传停止,请联系开发人员核实",
//ImageShareService
"ISS_NoImgToShare": "当前检查没有影像可以分享。 ",
"ISS_ResNotExists": "资源不存在。",
"ISS_SharePwdError": "分享密码错误。",
"ISS_ShareExpiration": "资源分享过期。",
//StudyService
"Study_VisitBeforePrevError": "当前访视检查时间{0}不能早于前序访视检查时间{1},请核对检查数据是否有误",
"Study_VisitAfterSubseqError": "当前访视检查时间{0}不能晚于该访视之后的检查时间{1},请核对检查数据是否有误",
"Study_UploadArchiving": "当前有人正在上传归档该检查!",
"Study_VisitEndedNotAllowed": "受试者访视结束,不允许上传!",
"Study_ImgAlreadyUploaded": "此处不可以上传。当前影像检查已经上传给受试者{0}的{1}",
// ------------------------------------------------------------Inspection--------------------------------------------------------------------
//FrontAuditConfigService
"FrontAudit_IdDup": "标识重复",
"FrontAudit_NameDup": "名称重复",
"FrontAudit_CannotDelSub": "存在子类 不能删除",
//InspectionService
"Inspection_UserDisabled": "当前用户已被禁用。",
// ------------------------------------------------------------Institution--------------------------------------------------------------------
//CROService
"CRO_DupName": "已经存在同名的CRO,请确认。",
"CRO_InProject": "该CRO已经参与项目,不能被删除。",
//HospitalService
"Hospital_DupName": "已经存在同名的医院,请确认。",
"Hospital_SiteAdded": "当前Site已经添加到其他Hospital了。",
"Hospital_HasDoctors": "该医院下已经注册有医生,不可以删除。",
//SiteService
"Site_DupName": "已经存在同名的中心,请确认。",
"Site_InProject": "该中心已经加入项目,不可以被删除。",
//SponsorService
"Sponsor_DupName": "已经存在同名的申办方,请确认。",
"Sponsor_InProject": "该申办方已经加入项目,不允许删除。",
// ------------------------------------------------------------Management--------------------------------------------------------------------
//MenuService
"Menu_ParentDupChild": "该父节点下已经存在同名的子节点。",
"Menu_ChildExist": "该节点存在子节点,请在删除子节点后,再删除该节点。",
//UserService
"User_UsernameExist": "用户名已经存在。",
"User_PhoneDup": "该用户类型中已存在具有相同的电话的用户。",
"User_EmailDup": "该用户类型中已存在具有相同邮箱的用户。",
"User_NewOldPwdSame": "新密码与旧密码相同。",
"User_OldPwdInvalid": "旧密码验证失败。",
"User_LegalEmail": "请输入合法的电子邮件。",
"User_VerificationCodeError": "验证码错误。",
"User_VerificationCodeExpired": "验证码已经过期。",
"User_CreateFailed": "请检查邮箱地址或者联系维护人员, 邮件发送失败, 未能创建账户成功。",
"User_InvalidEmail": "请输入一个正确的邮箱。",
"User_EmailError": "邮箱错误。",
"User_InProject": "该用户已经参加项目,不能够删除。",
"User_Disabled": "该用户已经被禁用。",
//UserTypeService
"UserType_InUse": "该用户类型中已存在用户,不能删除。",
// ------------------------------------------------------------QC--------------------------------------------------------------------
//QCCommon
"QCCommon_CannotOperate": "CRC已提交影像,不能进行操作。",
"QCCommon_NoPermission": "您不是该质控任务当前领取人,没有操作权限!",
"QCCommon_CheckTimeEarly": "当前访视检查时间{0}不能早于前序访视检查时间{1},请核对检查数据是否有误",
"QCCommon_CheckTimeLate": "当前访视检查时间{0}不能晚于该访视之后的检查时间{1},请核对检查数据是否有误",
//QCOperationService
"QCOperation_CheckFirst": "请先核查图像,并保存审核问题,然后再发质疑。",
"QCOperation_QuestionExist": "当前访视未关闭的质疑已设置了同意CRC重传影像。请在CRC完成影像重传后,先关闭原质疑,再添加新的质疑。",
"QCOperation_QuestionCannotClose": "CRC已申请重传或者QC同意重传,不允许关闭该质疑。请在QC拒绝重传申请或者CRC设置重传影像后,再关闭质疑。",
"QCOperation_CloseReason": "关闭原因: ",
"QCOperation_QuestionReplied": "当前QC质疑已经回复。",
"QCOperation_NoPermissionReply": "您没有权限回复一致性核查对话。",
"QCOperation_CannotClose": "当前访视处于申请重传状态, 不允许关闭质疑。",
"QCOperation_Reason": "原因:",
"QCOperation_CannotPass": "当前访视处于回退状态,不允许设置一致性核查通过",
"QCOperation_PassAfterClose": "请先关闭一致性核查质疑后,再设置一致性核查通过。",
"QCOperation_Cannotback": "当前访视已通过一致性核查,不允许申请重传",
"QCOperation_CRCRollback": "CRC申请重传",
"QCOperation_OtherCRC": "其他CRC已申请处理,请刷新页面",
"QCOperation_PMReject": "PM/APM拒绝一致性核查回退",
"QCOperation_NoPermission": "您不具备操作权限。",
"QCOperation_CannotRollback": "当前访视还未进行核查或者核查已通过,不允许设置回退。",
"QCOperation_PMAPMConsistency": "PM/APM同意一致性核查回退。",
"QCOperation_NoModifyAfterSubmit": "提交之后,不允许修改!",
"QCOperation_UnresolvedQCQuery": "当前访视有质疑未关闭,不允许该操作",
"QCOperation_CrcNoDelete": "CRC已经提交,不允许删除。",
"QCOperation_NoRecipient": "您不是该质控任务当前领取人,没有操作权限!",
"QCOperation_QCImageTaskAlreadyReleased": "当前访视的影像质控任务已被原领取人释放。您可以通过“领取”获得",
"QCOperation_QCTaskNoAccess": "当前访视的影像质控任务已被其他QC领取,不允许领取",
"QCOperation_QCConfigFirst": "请先配置影像质控审核问题,再领取影像质控任务",
"QCOperation_NoQC": "项目配置为不审,没有领取QC Task",
"QCOperation_InitialAuditPassed": "初审已通过,不能继续领取",
"QCOperation_NoSingleAudit": "项目配置为单审,不满足Submmit State:已提交 或者 Audit State:待审核/审核中, 不允许领取,请刷新界面",
"QCOperation_NoSameReviewer": "复审不能和初审是同一个人",
"QCOperation_NoSecondaryAudit": "项目配置为复审,不满足提交状态:已提交或者审核状态:待审核/QC中, 不允许领取,请刷新界面",
"QCOperation_NoTaskAccess": "您不是该质控任务当前领取人,没有操作权限!",
"QCOperation_NoQCFunction": "项目配置影像质控为不审,不需要取消任务功能",
"QCOperation_NoTaskOwner": "当前访视影像质控任务没有当前领取人,不能释放。",
"QCOperation_DiseaseProgressConfirmation": "当前访视要求进行疾病进展确认。请在提交当前访视前,先处理未提交的前序访视:{0}。",
"QCOperation_UnsubmittedVisits": "在提交当前访视后,请尽快处理尚未提交的前序访视:{0}。",
"QCOperation_NoBaselineData": "基线没有临床数据,确认提交?",
"QCOperation_NoImageData": "有访视未上传任何Dicom/非Dicom影像数据,不允许提交",
"QCOperation_ImagesSubmitted": "当前访视的影像数据,已经由其他CRC提交。",
"QCOperation_BatchImagesSubmitted": "当前批量提交访视的影像数据,其中部分已由其他CRC提交。",
"QCOperation_MissingBaselineDate": "项目配置了需要填写访视基准日期。但是受试者没有填写访视基准日期,不允许提交",
"QCOperation_RemoveItem": "您已经被移出项目,没有操作权限。",
"QCOperation_QCNotClosed": "当前访视有影像质控质疑未关闭,不能进行此操作。",
"QCOperation_NoQCNeeded": "项目配置影像质控为不审,不需要设置为影像质控通过。",
"QCOperation_QCNotSaved": "影像质控审核问题没有保存,不能进行此操作。",
"QCOperation_NotChangePass": "项目配置影像质控为单审,当前访视影像质控任务不能从当前审核状态变更到 审核通过。",
"QCOperation_CannotChangeToPass": "项目配置影像质控为双审。当前审核状态为 {0},不能变更到 审核通过。",
"QCOperation_NoQCNeededNotEnd": "项目配置影像质控为不审,不允许设置影像质控终止。",
"QCOperation_CannotChangeToStop": "项目配置影像质控为单审,当前审核状态不为 In Primary QC,不能变更到 审核终止",
"QCOperation_CannotChangeStop": "项目配置影像质控为双审,当前审核状态为 {0},不能变更到 审核终止",
"QCOperation_InvalidResend": "当前重传状态不为QC同意重传,不允许重传",
"QCOperation_NoResendNeeded": "不审操作,不会有需要重传的操作!",
"QCOperation_InvalidAgreeResend": "当前重传状态不为CRC申请重传,不允许设置同意重传",
"QCOperation_CannotAgreeResend": "当前访视,有一个未关闭的质疑 QC设置了同意重传,CRC还未完成上传,当前不允许再次设置",
"QCOperation_AgreeResend": "QC同意重传",
"QCOperation_InvalidCompleteResend": "当前重传状态不为QC同意重传,不允许设置重传完成",
"QCOperation_NoImageNotAllowed": "当前没有影像,不允许设置重传完成",
"QCOperation_CRCTransferCompleted": "CRC已重传完成",
"QCOperation_InvalidTransferStatus": "当前质疑重传状态不为初始状态|CRC重传完成状态,不允许申请重传",
"QCOperation_CRCTransfer": "CRC申请重传/上传影像",
"QCOperation_CannotModifyConfirmation": "该访视已提交,不能修改入组确认状态",
"QCOperation_CannotModifyPDStatus": "该访视为回退访视,不允许修改PD确认状态",
"QCOperation_ForwardingFailed": "转发影像失败。",
//QCQuestionService
"QCQuestion_DuplicateIndexFailed": "序号重复,操作失败",
"QCQuestion_HasChildQuestion": "当前任务存在子问题,删除失败",
//TrialQCQuestionService
"TrialQCQuestion_TemplateConfirmed": "影像质控审核问题模板已经确认,不允许操作。",
"TrialQCQuestion_DuplicateIndexFailed": "序号重复,操作失败",
"TrialQCQuestion_DeleteChildFirst": "请在删除父问题前,请先删除引用该父问题的子问题。",
"TrialQCQuestion_ReferencedByQCProcess": "该审核问题已被影像质控过程引用,不允许删除",
// ------------------------------------------------------------QC--------------------------------------------------------------------
// ------------------------------------------------------------SiteSurvey--------------------------------------------------------------------
//TrialSiteEquipmentSurveyService
"TrialSiteEquipment_Locked": "已锁定,不允许操作",
//TrialSiteSurveyService
"TrialSiteSurvey_InvalidEmail": "请输入正确的邮箱地址。",
"TrialSiteSurvey_WrongVerificationCode": "验证码错误。",
"TrialSiteSurvey_ExpiredVerificationCode": "验证码已经过期。",
"TrialSiteSurvey_NoRecordToUpdate": "该中心不存在该交接人的中心调研记录表,不允许选择更新。",
"TrialSiteSurvey_RecordUnderReview": "您的中心调研记录正在审核中,不允许进行更新操作。若需要更新,请在驳回后进行操作。",
"TrialSiteSurvey_LockedByCurrentUser": "当前中心中,您提交调研记录表已锁定,不允许更新其他人邮箱调研记录。",
"TrialSiteSurvey_LockedByOtherUsers": "当前中心,您提交的调研记录表已锁定。当前存在其他人员提交的调研记录表未锁定,不允许更新您之前提交的调研记录。",
"TrialSiteSurvey_UnlockedRecordsExist": "当前中心存在未锁定的调研记录,不允许更新已锁定的调研记录。",
"TrialSiteSurvey_NonLatestLockedRecord": "该邮箱{0}对应的调查表不是最新锁定的记录,不允许更新!",
"TrialSiteSurvey_AlreadyFilledByOtherUsers": "该中心下已经有其他用户已填写的调研表,您不被允许继续填写",
"TrialSiteSurvey_Locked": "中心调研已锁定,不允许操作。",
"TrialSiteSurvey_IRCNotification": "[来自展影IRC] [{0}] 关于中心调研审批的提醒",
"TrialSiteSurvey_CancelUnsubmittedRecord": "只允许废除未提交的记录。",
"TrialSiteSurvey_NoAdminAcces": "不允许管理员操作。",
"TrialSiteSurvey_FailedToGenerateAccountId": "生成账户Id 未取到值,请排查",
"TrialSiteSurvey_IRCInvitation": "[来自展影IRC] [{0}] 邀请信",
"TrialSiteSurvey_IRCInvitationContent": " 您好,展影医疗作为 实验方案号:{0} 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢!",
"TrialSiteSurvey_ViewAndConfirm": "查看并确认",
//TrialSiteUserSurveyService
"TrialSiteUser_Locked": "已锁定,不允许操作",
"TrialSiteUser_InconsistentInfo": "该邮件地址在系统中所对应的用户为 {0}, 电话号码是 {1}。请将所输入的信息修改为与系统一致后,再保存。",
"TrialSiteUser_NoTestUserForFormal": "正式类型 、培训类型的项目 不允许加入测试用户",
"TrialSiteUser_NoFormalUserForTest": "测试项目 不允许加入正式用户",
// ------------------------------------------------------------Stat--------------------------------------------------------------------
// ------------------------------------------------------------TrialSiteUser--------------------------------------------------------------------
//TrialConfigService
"TrialConfig_JudgeTaskFail": "有裁判问题未配置产生裁判阅片任务的条件,操作失败!",
"TrialConfig_StdConfigMissing": "当前标准下未配置问题",
"TrialConfig_AddEvalReq": "选择了附加评估,必须勾选附加评估类型",
"TrialConfig_SignTemplateMissing": "该操作需要电子签名确认,但未在系统中找到该场景的签名模板。",
"TrialConfig_ProjectEnded": "该项目已结束或停止,不允许修改配置。",
"TrialConfig_NoImageAuditQuestion": "当前未添加影像质控审核问题。请先添加影像质控审核问题,再进行确认。",
"TrialConfig_DuplicateAuditQuestionId": "影像质控审核问题显示序号不能重复。",
"TrialConfig_InvalidParentQuestionId": "父问题的显示序号要比子问题的显示序号小,请确认。",
"TrialConfig_AuditQuestionConfirmed": "影像质控审核问题已被其他人员确认,不允许再次确认。",
"TrialConfig_ProjectNotInitialized": "该项目当前状态不是初始化,不允许进行该操作。",
"TrialConfig_UnconfirmedConfiguration": "该项目的项目配置、访视管理尚未完成,无法将项目状态设为”启动”。",
"TrialConfig_UnconfirmedUNACKD": "该项目的项目配置、访视管理中,有未确认项,无法变更项目状态。",
"TrialConfig_ProjectNotStarted": "项目没有进入启动状态,不能设置为停止或完成状态",
//TrialExternalUserService
"TrialExternalUser_Inconsistency": "该邮件地址在系统中所对应的用户为 {0}, 电话号码是 {1}。请将所输入的信息修改为与系统一致后,再保存。",
"TrialExternalUser_EmailTypeDuplicate": "系统已经存在与列表中填写的邮箱和用户类型相同的账户,请确认。",
"TrialExternalUser_TestUserNotAllowed": "正式类型 、培训类型的项目 不允许加入测试用户 ",
"TrialExternalUser_FormalUserNotAllowed": "测试项目 不允许加入正式用户 ",
"TrialExternalUser_NotEditable": "人员信息不支持编辑,请删除后重新添加。",
"TrialExternalUser_CannotDelete": "当前用户已参与到项目,不允许删除",
"TrialExternalUser_IRCInvitation": " 您好,展影医疗作为 实验方案号:{0} 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢!",
"TrialExternalUser_ViewAndConfirm": "查看并确认",
"TrialExternalUser_InvitationExpired": "邀请加入时间已过期,重新被邀请后才可以进行确认操作",
"TrialExternalUser_AccountInfo": "[来自展影IRC] [{0}] 账户信息",
"TrialExternalUser_Welcome": "您好,欢迎您参加项目 实验方案号:{0}IRC相关工作。该项目采用电子化工作流,系统及您的账号信息如下:",
"TrialExternalUser_ProjectNumber": "项目编号: {0}",
"TrialExternalUser_ExperimentPlanNumber": "试验方案号: {0}",
"TrialExternalUser_ExperimentName": "试验名称: {0}",
"TrialExternalUser_Username": "用户名: {0}",
"TrialExternalUser_Password": "密码: ({0})(请在登录后进行修改) : ***(您已有账号, 若忘记密码, 请通过邮箱找回)",
"TrialExternalUser_Role": "角色: {0}",
"TrialExternalUser_LoginUrl": "系统登录地址: {0} ",
"TrialExternalUser_ReinvitationRequired": "邀请加入时间已过期,重新被邀请后才可以进行确认操作",
"TrialExternalUser_UserIdStorageProblem": "调研表系统用户Id 存储有问题",
"TrialExternalUser_IRCAccountInfo": "[来自展影IRC] [{0}] 账户信息",
//TrialMaintenanceService
"TrialMaint_PersonnelJoined": "人员已加入现场维护",
//TrialService
"Trial_PMApmPermission": "只有PM/APM拥有操作权限!",
"Trial_TestUserCreateOnlyNonFormal": "测试用户 只能创建非正式项目",
"Trial_DuplicateProjectNumber": "已经存在相同的项目编号。",
"Trial_InvalidProjectStatus": "项目状态只有处于:初始化或者进行中时,才允许操作。",
"Trial_CannotDeleteProject": "当前运行环境下,不允许删除项目数据。",
//TrialSiteService
"TrialSite_ParticipantJoined": "已有受试者加入中心,无法禁用",
"TrialSite_CodeDuplicate": "代码不能重复",
"TrialSite_CannotDeleteAssociatedCRC": "中心已经和CRC关联,不能删除",
"TrialSite_CannotDeleteAssociatedSubject": "受试者已经添加,不能删除",
"TrialSite_CannotDeleteUploadedData": "中心已经上传调研,无法删除",
// ------------------------------------------------------------Visit--------------------------------------------------------------------
//SubjectService
"Subject_NoConfirmedPlan": "项目访视计划没有确认。请联系项目经理确认项目访视计划后,再添加受试者。",
"Subject_DuplicateSubjectNum": "已存在具有相关受试者编号的受试者。",
"Subject_UploadedVisitNoDelete": "该受试者已经有访视已经上传影像,不允许删除。",
//SubjectVisitService
"Visit_DuplicateVisitNo": "该受试者的访视计划中已经包含一个具有相同访视号的访视。",
"Visit_LastVisitNoChange": "该受试者已经有访视设置为末次访视,不允许将当前访视设置为末次访视。",
"Visit_DuplicateVisitName": "该受试者的访视计划中已经包含一个具有相同访视名称的访视。",
"Visit_NoExtraVisitAfterLast": "设置末次评估后,不允许添加计划外访视。",
"Visit_FinishedTasksNoAdd": "该受试者后续访视已有任务完成阅片(有序阅片标准),不允许在此添加,如果确实需要,请回退",
"Visit_NoPDStatusChangeAfterSubmission": "当前访视影像提交后,不允许修改PD确认状态。",
"Visit_UploadedNoLost": "当前访视已经有影像上传,不允许设置为失访。",
"Visit_UploadedNoDelete": "当前访视已经有影像上传,不允许删除。",
"Visit_PlanVisitNoDelete": "计划内的访视不允许删除。",
"Visit_PreviousVisitNoDelete": "当前访视已经被设置为另一访视的上一访视,不允许删除。",
//VisitPlanService
"VisitPlan_OnlyInitOrOngoing": "只有当项目状态为:初始化或进行中时,可以操作。",
"VisitPlan_LargerVisitNumLargerInterval": "访视计划中,访视号大的访视,其访视间隔也应该比访视号小的访视大。",
"VisitPlan_LargerPlanNumLargerInterval": "访视计划中,访视号大的计划访视,其访视间隔也应该比访视号小的计划访视大。",
"VisitPlan_ExistNameOrNumTemplate": "访视计划中已经存在具有项目访视名称或者访视号的计划访视模板。",
"VisitPlan_ExistBaseline": "访视计划中已经存在基线。",
"VisitPlan_ExistBaselineImgNoModify": "有受试者的基线已经上传了影像数据,不允许修改基线访视。",
"VisitPlan_OnlyInitOrOngoingModifyConfirm": "仅仅在项目初始化或者进行中时,才允许修改确认",
"VisitPlan_NoBaselineNotConfirm": "没有基线,不允许确认",
"VisitPlan_ConfigNotConfirmNotConfirm": "项目配置未确认,不允许确认访视计划",
"VisitPlan_BaselineNotMinDayNotConfirm": "基线VisitDay 不是最小的, 不允许确认",
"VisitPlan_CheckExport": "检查导出_{0}.xlsx",
"VisitPlan_Assigned": "访问计划已分配给受试者并已执行",
// ------------------------------------------------------------WorkLoad--------------------------------------------------------------------
//DoctorWorkloadService
"DoctorWorkload_AssignType": "已分配任务,不允许减少阅片类型",
"DoctorWorkload_Unique": "此类数据唯一",
"DoctorWorkload_FeeSettled": "费用已结算,工作量无法修改",
//EnrollService
"Enroll_NotFound": "无法找到项目{0}",
"Enroll_EmailFormat": "{0}邮箱格式存在问题",
"Enroll_CannotRollback": "已有分配的审核人员不能回退",
// ------------------------------------------------------------Triggers--------------------------------------------------------------------
//AddlTrialUserTrigger
"AddlTrialUser_NoTestUser": "正式类型 、培训类型的项目 不允许加入测试用户",
"AddlTrialUser_NoFormalUser": "测试项目不允许加入正式用户",
//SubjectStateTrigger
"SubjectState_CannotSetCurrentAsLastVisit": "该受试者已经有访视被设置为末次访视,不允许将当前访视设置为末次访视。",
"SubjectState_CannotSetAsLastVisitWithImage": "该受试者当前访视后有访视的影像已上传,当前访视不允许设置为末次访视。",
//SubjectVisitFinalVisitTrigger
"SubjectVisit_CannotSetAsLastVisit": "该受试者已有后续访视已上传影像或已提交,当前访视不允许设置为末次访视。",
// ------------------------------------------------------------BusinessFilter--------------------------------------------------------------------
//LimitUserRequestAuthorization
"LimitUser_AuthTokenMissing": "当前请求未从Header/Url取到用户Token,请联系开发者",
"LimitUser_AccountLoggedInElsewhere": "您的账户在其他地方已登陆,您被迫下线。",
//ModelActionFilter
"ModelAction_InvalidAPIParameter": "提供给接口的参数无效。",
//ProjectExceptionFilter
"ProjectException_ConcurrentUpdateNotAllowed": "并发更新,当前不允许该操作",
"Project_ExceptionContactDeveloper": "程序异常,请联系开发人员。 ",
//TrialResourceFilter
"TrialResource_NoAccessPermission": "对不起,您的账户没有操作权限。",
"TrialResource_ReferTrialIdFailed": "正则取请求Refer 中trialId 失败,请联系开发人员核查",
"TrialResource_InterceptedProjectStatusRule": "本次请求被配置规则拦截:项目状态处于进行中时,才允许操作,若此处逻辑有误,请联系开发人员修改",
"TrialResource_MissingProjectNumber": "该接口参数中,没有传递项目编号,请核对。",
//UnifiedApiResultFilter
"UnifiedAPI_ProgramError": "程序错误,请联系开发人员。",
// ------------------------------------------------------------Helper--------------------------------------------------------------------
//FileStoreHelper
"FileStore_TemplateFileNotFound": "数据库没有找到对应的数据模板文件,请联系系统运维人员。",
"FileStore_TemplateFileStoragePathInvalid": "文件不存在,请联系系统管理员!",
//SendEmailHelper
"SendEmail_SendFail": "邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员",
"SendEmail_NoRecipient": "没有收件人",
// ------------------------------------------------------------IRaCIS.Core.Domain--------------------------------------------------------------------
//Trial
"Trial_number": "编号由5位数字组成,前2位为中心编号,后3位为顺序号,请与EDC录入的编号保持一致",
// ------------------------------------------------------------IRaCIS.Core.Infrastructure--------------------------------------------------------------------
//ResponseOutput
"RO_BizObjNotExistsOrParamIncorrect": "业务对象{0}在数据库中不存在,或被他人删除,或参数查询不正确导致",
"RO_ExpectChangeButNoEffect": "期望发生更改,但数据库数据没有更改",
"RO_SaveFailed": "保存失败"
}
}
@@ -0,0 +1,37 @@
using IRaCIS.Core.Domain.Share;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service.ViewModel
{
public class AllocationVisitViewModel
{
public Guid SubjectVisitId { get; set; }
public Guid SubjectId { get; set; }
public string BlindName { get; set; } = string.Empty;
public decimal VisitNum { get; set; }
public Guid SiteId { get; set; }
public String TrialSiteCode { get; set; } = String.Empty;
public string SubjectCode { get; set; } = String.Empty;
public string VisitName { get; set; } = string.Empty;
public DateTime? CheckPassedTime { get; set; }
public bool IsUrgent { get; set; }
public ReadingCategory ReadingCategoryEnum { get; set; }
}
}
@@ -24,9 +24,7 @@ namespace IRaCIS.Core.Application.ViewModel
public int? GeneratedSubjectCount { get; set; }
public int? MatchSubejctCount { get; set; }
public int? CanGeneratedSubejctCount => MatchSubejctCount - GeneratedSubjectCount;
}
@@ -36,13 +34,6 @@ namespace IRaCIS.Core.Application.ViewModel
}
public class SubjectGeneratedTask
{
public Guid SubjectId { get; set; }
public bool IsHaveGeneratedTask { get; set; }
}
public class ConsistentQuery : PageInput
{
[NotDefault]
@@ -55,15 +46,6 @@ namespace IRaCIS.Core.Application.ViewModel
}
public class GroupConsistentSimpleQuery
{
[NotDefault]
public Guid TrialId { get; set; }
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
}
public class GroupConsistentQuery : PageInput
{
[NotDefault]
@@ -74,21 +56,13 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid TrialReadingCriterionId { get; set; }
}
public class SelfConsistentSimpleQuery
public class ConsistentConfirmGenerateCommand
{
[NotDefault]
public Guid TaskConsistentRuleId { get; set; }
[NotDefault]
public Guid DoctorUserId { get; set; }
}
public class ConsistentConfirmGenerateCommand: SelfConsistentSimpleQuery
{
public List<Guid> SubejctIdList { get; set; }
public bool IsAutoAllocateGenerateTask { get; set; }
}
@@ -96,13 +70,7 @@ namespace IRaCIS.Core.Application.ViewModel
{
[NotDefault]
public Guid TrialId { get; set; }
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
public List<Guid> SubejctIdList { get; set; }
public bool IsAutoAllocateGenerateTask { get; set; }
}
public class DoctorSelfConsistentSubjectView: ConsistentCommonView
@@ -118,7 +86,7 @@ namespace IRaCIS.Core.Application.ViewModel
public class ConsistentCommonView
{
public Guid TrialId { get; set; }
public Guid TrialSiteId { get; set; }
public Guid SiteId { get; set; }
public String TrialSiteCode { get; set; }
public string SubjectCode { get; set; }
@@ -137,8 +105,6 @@ namespace IRaCIS.Core.Application.ViewModel
public List<VisitTaskGroupSimpleDTO> SubjectTaskVisitList => VisitTaskList.GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Select(g => g.First()).OrderBy(t=>t.VisitTaskNum).ToList();
public List<VisitTaskGroupSimpleDTO> VisitTaskList { get; set; } = new List<VisitTaskGroupSimpleDTO>();
public List<UserSimpleInfo> DoctorUserList { get; set; }=new List<UserSimpleInfo>();
}
public class VisitTaskGroupSimpleDTO
@@ -200,12 +166,31 @@ namespace IRaCIS.Core.Application.ViewModel
}
//public class DoctorConsistentRuleSubjectView
//{
// public Guid TrialId => VisitTaskList.Select(t => t.TrialId).First();
// public Guid SiteId => VisitTaskList.Select(t => t.SiteId).First();
// public String TrialSiteCode => VisitTaskList.Select(t => t.TrialSiteCode).First();
// public string SubjectCode => VisitTaskList.Select(t => t.SubjectCode).First();
// public Guid SubjectId { get; set; }
// public bool IsHaveGeneratedTask { get; set; }
// public int? ValidTaskCount { get; set; }
// public int? ValidVisitCount => VisitTaskList.Select(t => t.TaskName).Distinct().Count();
// public List<VisitTaskSimpleView> VisitTaskList { get; set; }
// //public List<UserSimpleInfo> HistoryDoctorUserList => VisitTaskList.SelectMany(t => t.RelationDoctorUserList).DistinctBy(t=>t.UserId).ToList();
//}
public class InfluenceTaskInfo
{
public Guid Id { get; set; }
public Guid TrialId { get; set; }
public Guid TrialSiteId { get; set; }
public Guid SiteId { get; set; }
public Guid SubjectId { get; set; }
@@ -248,7 +233,7 @@ namespace IRaCIS.Core.Application.ViewModel
{
public Guid Id { get; set; }
public Guid TrialId { get; set; }
public Guid TrialSiteId { get; set; }
public Guid SiteId { get; set; }
public Guid SubjectId { get; set; }
@@ -302,17 +287,6 @@ namespace IRaCIS.Core.Application.ViewModel
}
public class UpdateTrialSiteCodeCommand
{
public Guid TrialId { get; set; }
public string VirtualSiteCode { get; set; }
}
public class UpdateTrialSiteCodeCommandView: UpdateTrialSiteCodeCommand
{
public DateTime Creatime { get; set; }
}
///<summary> TaskConsistentRuleAddOrEdit 列表查询参数模型</summary>
public class TaskConsistentRuleAddOrEdit
@@ -15,6 +15,7 @@ namespace IRaCIS.Core.Application.ViewModel
{
public Guid VisitTaskId { get; set; }
public string MedicalNo { get; set; } = string.Empty;
public int AuditState { get; set; }
public DateTime? AuditSignTime { get; set; }
@@ -53,6 +54,7 @@ namespace IRaCIS.Core.Application.ViewModel
//开始读片时间
public DateTime? FirstReadingTime { get; set; }
public string MedicalNo { get; set; } = string.Empty;
//读片时间差
public TimeSpan? ReadingDurationTimeSpan { get; set; }
@@ -69,7 +71,7 @@ namespace IRaCIS.Core.Application.ViewModel
{
if (!ReadingDurationTimeSpan.HasValue)
return "";
else return string.Format("{0}h:{1}m:{2}s", (SignTime - FirstReadingTime)?.Hours, (SignTime - FirstReadingTime)?.Minutes, (SignTime - FirstReadingTime)?.Seconds)
else return string.Format("{0}d {1}h {2}min", (SignTime - FirstReadingTime)?.Days, (SignTime - FirstReadingTime)?.Hours, (SignTime - FirstReadingTime)?.Minutes)
/*string.Format("{0}分钟", (ReadingDurationTimeSpan)?.TotalMinutes)*/;
}
}
@@ -93,27 +95,19 @@ namespace IRaCIS.Core.Application.ViewModel
public class TaskMedicalReviewQuery : PageInput
{
public Guid TrialId { get; set; }
public Guid? TrialSiteId { get; set; }
public Guid? SiteId { get; set; }
/// <summary>
/// 传了Id
/// 传了Id 就不查询这条数据
/// </summary>
public Guid? Id { get; set; }
public Guid? SubjectId { get; set; }
public Guid? MedicalManagerUserId { get; set; }
public DateTime? BeginSignTime { get; set; }
public AuditAdvice? AuditAdviceEnum { get; set; }
public bool IsGetBeRead { get; set; } = false;
public DateTime? EndSignTime { get; set; }
public bool IsGetBeRead { get; set; } = false;
public bool IsGetNextMedicalReviewTask { get; set; } = false;
public string SubjectCode { get; set; } = String.Empty;
public string SubjectCode { get; set; } = String.Empty;
public string TrialSiteCode { get; set; } = String.Empty;
public string TaskName { get; set; } = String.Empty;
@@ -121,7 +115,7 @@ namespace IRaCIS.Core.Application.ViewModel
public bool? IsUrgent { get; set; }
public Guid? DoctorUserId { get; set; }
public bool? IsInvalid { get; set; }
public TaskState? TaskState { get; set; }
public MedicalReviewAuditState? AuditState { get; set; }
@@ -132,20 +126,6 @@ namespace IRaCIS.Core.Application.ViewModel
public ReadingTaskState? ReadingTaskState { get; set; }
public Guid? TrialReadingCriterionId { get; set; }
public MedicalReviewDoctorUserIdea? DoctorUserIdeaEnum { get; set; }
public Arm? ArmEnum { get; set; }
public DateTime? BeginAuditSignTime { get; set; }
public DateTime? EndAuditSignTime { get; set; }
public bool? IsEffect { get; set; }
public bool? IsHaveQuestion { get; set; }
public DateTime? BeginAllocateDate { get; set; }
public DateTime? EndAllocateDate { get; set; }
}
@@ -8,6 +8,7 @@ using IRaCIS.Core.Domain.Share;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Application.ViewModel
{
@@ -54,18 +55,14 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid UpdateUserId { get; set; }
public Guid TrialSiteId { get; set; }
public string BlindTrialSiteCode { get; set; }
public Guid SiteId { get; set; }
public String TrialSiteCode { get; set; } = String.Empty;
public string SubjectCode { get; set; } = String.Empty;
public string MedicalNo { get; set; } = string.Empty;
public string BlindSubjectCode { get; set; } = string.Empty;
public bool IsPMSetBack { get; set; }
#region
public Guid TrialReadingCriterionId { get; set; }
@@ -79,9 +76,11 @@ namespace IRaCIS.Core.Application.ViewModel
public bool IsClinicalDataSign { get; set; }
public CompleteClinicalDataEnum CompleteClinicalDataEnum =>
public CompleteClinicalDataEnum CompleteClinicalDataEnum =>
(IsNeedClinicalDataSign && IsClinicalDataSign) ? CompleteClinicalDataEnum.Complete : (IsNeedClinicalDataSign && IsClinicalDataSign == false) ? CompleteClinicalDataEnum.NotComplete : CompleteClinicalDataEnum.NA;
/// <summary>
@@ -92,7 +91,7 @@ namespace IRaCIS.Core.Application.ViewModel
/// <summary>
/// 任务展示访视 读片任务显示是否顺序
/// </summary>
public ReadingOrder IsReadingTaskViewInOrder { get; set; }
public bool IsReadingTaskViewInOrder { get; set; } = true;
/// <summary>
@@ -112,35 +111,18 @@ namespace IRaCIS.Core.Application.ViewModel
public CriterionType CriterionType { get; set; }
///// <summary>
///// 仲裁对象
///// </summary>
//public ArbitrationRule ArbitrationRule { get; set; } = ArbitrationRule.Reading;
///// <summary>
///// 阅片模式
///// </summary>
//public ReadingMethod ReadingType { get; set; } = ReadingMethod.Double;
///// <summary>
///// 全局阅片
///// </summary>
//public bool IsGlobalReading { get; set; } = true;
///// <summary>
///// 仲裁阅片
///// </summary>
//public bool IsArbitrationReading { get; set; } = true;
///// <summary>
///// 肿瘤学阅片 原字段 IsClinicalReading
///// </summary>
//public bool IsOncologyReading { get; set; }
#endregion
public PIAuditState PIAuditState { get; set; }
public string NotAgreeReason { get; set; }
public string PIAuditNote { get; set; } = string.Empty;
public bool? IsEnrollment { get; set; }
public bool? IsPDConfirm { get; set; }
public List<string> PIAuditImagePathList { get; set; }
}
@@ -156,18 +138,17 @@ namespace IRaCIS.Core.Application.ViewModel
public bool IsCanEditUrgentState { get; set; }
public DateTime? FirstReadingTime { get;set; }
public string ReadingDuration
{
get
{
if (!SignTime.HasValue)
return "";
else return string.Format("{0}h:{1}m:{2}s", (SignTime - FirstReadingTime)?.Hours, (SignTime - FirstReadingTime)?.Minutes, (SignTime - FirstReadingTime)?.Seconds)
/*string.Format("{0}分钟", (ReadingDurationTimeSpan)?.TotalMinutes)*/;
}
}
public bool? IsBaseline { get; set; }
public bool? IsEnrollmentConfirm { get; set; }
public PDStateEnum? PDState { get; set; }
}
public class UserSimpleInfo
@@ -177,6 +158,8 @@ namespace IRaCIS.Core.Application.ViewModel
public string UserName { get; set; }
public string FullName { get; set; }
public UserTypeEnum UserTypeEnum { get; set; }
//public string UserTypeShortName { get; set; }
}
@@ -189,6 +172,23 @@ namespace IRaCIS.Core.Application.ViewModel
}
public class PIReaingTaskView : ReadingTaskView
{
public Guid? FirstAuditUserId { get; set; }
public string FirstAuditUserName { get; set; }
public DateTime? FirstAuditTime { get; set; }
public Guid? LatestReplyUserId { get; set; }
public string LatestReplyUserName { get; set; }
public DateTime? LatestReplyTime { get; set; }
}
public class ReadingTaskView : VisitTaskView
{
@@ -201,7 +201,15 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid? SourceSubjectVisitId { get; set; }
public Guid? SouceReadModuleId { get; set; }
//public bool IsAfterConvertedTask { get; set; }
public List<PIReadingResult> PIReadingResultList { get; set; }
}
public class PIReadingResult
{
public Guid QuestionId { get; set; }
public string Answer { get; set; }
}
@@ -265,6 +273,12 @@ namespace IRaCIS.Core.Application.ViewModel
public ReReadingApplyState ReReadingApplyState { get; set; }
public DateTime? SuggesteFinishedTime { get; set; }
public string UserName { get; set; }
public string FullName { get; set; }
}
public class IRUnReadSubjectView
@@ -274,7 +288,10 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid SubjectId { get; set; }
public string SubjectCode { get; set; } = String.Empty;
public bool IsUrgent => UnReadCanReadTaskList.Any(t => t.IsUrgent);
public Guid? ClaimUserId { get; set; }
public string? ClaimUserName { get; set; }
public bool IsUrgent => UnReadTaskList.Any(t => t.IsUrgent);
public int UnReadTaskCount { get; set; }
@@ -288,42 +305,9 @@ namespace IRaCIS.Core.Application.ViewModel
public DateTime? SuggesteFinishedTime { get; set; }
public int? UrgentColor
{
get
{
if (this.SuggesteFinishedTime != null)
{
var date = DateTime.Now;
var timeSpan = SuggesteFinishedTime.Value- date;
if (timeSpan.TotalDays <= 2)
{
return 1;
}
else if (timeSpan.TotalDays <= 5)
{
return 2;
}
else
{
return 3;
}
}
else
{
return null;
}
}
}
public List<IRUnreadTaskView> UnReadCanReadTaskList => UnReadTaskList.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)).ToList();
public int UrgentCount { get; set; }
// public int UrgentCount => UnReadCanReadTaskList.Count(t => t.IsUrgent);
public List<IRUnreadTaskView> UnReadCanReadTaskList { get; set; } = new List<IRUnreadTaskView>();
// public List<IRUnreadTaskView> UnReadCanReadTaskList => UnReadTaskList.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)).ToList();
public List<IRUnreadTaskView> UnReadTaskList { get; set; } = new List<IRUnreadTaskView>();
public List<IRUnreadTaskView> UnReadTaskList { get; set; } = new List<IRUnreadTaskView>();
}
public class IRUnreadTaskView
@@ -372,11 +356,9 @@ namespace IRaCIS.Core.Application.ViewModel
public class GetOrderReadingIQueryableInDto
{
public Guid TrialId { get; set; }
public Guid TrialId { get; set; }
public Guid? SubjectId { get; set; }
public Guid TrialReadingCriterionId { get; set; }
public Guid TrialReadingCriterionId { get; set; }
public string? SubjectCode { get; set; } = null;
@@ -389,8 +371,7 @@ namespace IRaCIS.Core.Application.ViewModel
[NotDefault]
public Guid TrialId { get; set; }
public Guid? TrialSiteId { get; set; }
public Guid? SiteId { get; set; }
public Guid? SubjectId { get; set; }
@@ -412,15 +393,6 @@ namespace IRaCIS.Core.Application.ViewModel
public DateTime? EndAllocateDate { get; set; }
public DateTime? BeginSignTime { get; set; }
public DateTime? EndSignTime { get; set; }
public DateTime? BeginRequestReReadingTime { get; set; }
public DateTime? EndRequestReReadingTime { get; set; }
public Guid? RootReReadingTaskId { get; set; }
public string? TaskCode { get; set; }
@@ -442,17 +414,102 @@ namespace IRaCIS.Core.Application.ViewModel
public RequestReReadingResult? RequestReReadingResultEnum { get; set; }
public PIAuditState? PIAuditState { get; set; }
public bool? IsEffect { get; set; }
public string? RequestReReadingReason { get; set; }
public string? FirstAuditUserName { get; set; }
public bool? IsWaitPIAudit { get; set; }
public string? LatestReplyUserName { get; set; }
public DateTime? FirstAuditTimeBegin { get; set; }
public DateTime? FirstAuditTimeEnd { get; set; }
public DateTime? LatestReplyTimeBegin { get; set; }
public DateTime? LatestReplyTimeEnd { get; set; }
}
public class PIAuditTaskEnrollOrPdCommand
{
[NotDefault]
public Guid VisitTaskId { get; set; }
public bool? IsEnrollment { get; set; }
public bool? IsPDConfirm { get; set; }
}
public class PIAuditTaskCommand
{
[NotDefault]
public Guid VisitTaskId { get; set; }
public string NotAgreeReason { get; set; }
public string PIAuditNote { get; set; } = string.Empty;
public List<string> PIAuditImagePathList { get; set; }
public PIAuditState PIAuditState { get; set; }
}
public class PIAuditTaskReplyCommand
{
[NotDefault]
public Guid VisitTaskId { get; set; }
public string ReplyContent { get; set; } = string.Empty;
}
public class PIAuditDialogQuery
{
[NotDefault]
public Guid VisitTaskId { get; set; }
}
public class ClinicalDataDialog
{
public Guid Id { get; set; }
public DateTime CreateTime { get; set; }
public string Content { get; set; }
}
public class PIAuditDialogListView
{
public Guid VisitTaskId { get; set; }
public string NotAgreeReason { get; set; }
public string PIAuditNote { get; set; } = string.Empty;
public List<string> PIAuditImagePathList { get; set; }
public PIAuditState? PIAuditState { get; set; }
public string ReplyContent { get; set; } = string.Empty;
public bool? IsEnrollment { get; set; }
public bool? IsPDConfirm { get; set; }
public bool IsCurrentUser { get; set; }
public Guid CreateUserId { get; set; }
public string CreateUserName { get; set; }
public DateTime CreateTime { get; set; }
public UserTypeEnum UserTypeEnum { get; set; }
}
@@ -479,15 +536,15 @@ namespace IRaCIS.Core.Application.ViewModel
/// </summary>
public int FinishTaskCount { get; set; }
/// <summary>
/// 未完成裁判任务数量
/// </summary>
public int UnReadJudgeTaskCount { get; set; }
///// <summary>
///// 未完成裁判任务数量
///// </summary>
//public int UnReadJudgeTaskCount { get; set; }
/// <summary>
/// 完成裁判任务数量
/// </summary>
public int FinishJudgeTaskCount { get; set; }
///// <summary>
///// 完成裁判任务数量
///// </summary>
//public int FinishJudgeTaskCount { get; set; }
/// <summary>
/// 建议完成时间
@@ -501,7 +558,7 @@ namespace IRaCIS.Core.Application.ViewModel
[NotDefault]
public Guid TrialId { get; set; }
public Guid? TrialSiteId { get; set; }
public Guid? SiteId { get; set; }
public Guid? SubjectId { get; set; }
@@ -523,7 +580,7 @@ namespace IRaCIS.Core.Application.ViewModel
[NotDefault]
public Guid TrialId { get; set; }
public Guid? TrialSiteId { get; set; }
public Guid? SiteId { get; set; }
public Guid? SubjectId { get; set; }
@@ -532,9 +589,6 @@ namespace IRaCIS.Core.Application.ViewModel
public string SubjectCode { get; set; } = String.Empty;
public int? SubjectAllocateState { get; set; }
public List<Arm> ArmList { get; set; }=new List<Arm>() { };
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
@@ -566,7 +620,7 @@ namespace IRaCIS.Core.Application.ViewModel
public class SubjectAssignStat
{
public Guid TrialId { get; set; }
public Guid TrialSiteId { get; set; }
public Guid SiteId { get; set; }
public Guid SubjectId { get; set; }
@@ -646,7 +700,7 @@ namespace IRaCIS.Core.Application.ViewModel
public class SubjectAssignView
{
public Guid TrialId { get; set; }
public Guid TrialSiteId { get; set; }
public Guid SiteId { get; set; }
public Guid SubjectId { get; set; }
@@ -863,6 +917,19 @@ namespace IRaCIS.Core.Application.ViewModel
CancelAssign = 4,
}
public class ClaimSubjectDto
{
public bool IsInOrder { get; set; }
public Guid? VisitTaskId { get; set; }
public Guid TrialReadingCriterionId { get; set; }
public Guid SubejctId { get; set; }
public bool IsClaim { get; set; }
}
}
@@ -17,5 +17,7 @@ namespace IRaCIS.Core.Application.Service
Task<IResponseOutput> ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService);
Task<(int, List<IRUnReadSubjectView>)> GetOrderReadingIQueryable(GetOrderReadingIQueryableInDto inDto);
Task<IQueryable<VisitTask>> GetNotOrderReadingQueryableAsync(Guid trialId, Guid trialReadingCriterionId);
}
}
@@ -1,225 +0,0 @@
//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2022-06-07 13:14:38
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter;
namespace IRaCIS.Core.Application.Service
{
/// <summary>
/// 分配规则
/// </summary>
[ApiExplorerSettings(GroupName = "Trial")]
public class TaskAllocationRuleService : BaseService, ITaskAllocationRuleService
{
private readonly IRepository<TaskAllocationRule> _taskAllocationRuleRepository;
private readonly IRepository<User> _userRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<SubjectCanceDoctor> _subjectCanceDoctorRepository;
public TaskAllocationRuleService(IRepository<TaskAllocationRule> taskAllocationRuleRepository, IRepository<User> userRepository, IRepository<Trial> trialRepository, IRepository<SubjectCanceDoctor> subjectCanceDoctorRepository)
{
_taskAllocationRuleRepository = taskAllocationRuleRepository;
_userRepository = userRepository;
_trialRepository = trialRepository;
_subjectCanceDoctorRepository = subjectCanceDoctorRepository;
}
/// <summary>
/// 获取计划列表 医生带阅片类型
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
public async Task<(List<TaskAllocationRuleDTO>,object)> GetDoctorPlanAllocationRuleList(Guid trialId)
{
var list = await _taskAllocationRuleRepository.Where(t => t.TrialId == trialId).ProjectTo<TaskAllocationRuleDTO>(_mapper.ConfigurationProvider).ToListAsync();
//所有标准都是一样 后台只返回任意一个标准的就好了
var trialTaskConfig = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId && t.IsConfirm).ProjectTo<TrialTaskConfigView>(_mapper.ConfigurationProvider).FirstNotNullAsync();
return (list, trialTaskConfig);
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> AddOrUpdateTaskAllocationRule(TaskAllocationRuleAddOrEdit addOrEditTaskAllocationRule)
{
//冗余 存
var enrollId = _repository.Where<Enroll>(t => t.TrialId == addOrEditTaskAllocationRule.TrialId && t.DoctorUserId == addOrEditTaskAllocationRule.DoctorUserId).Select(t => t.Id).FirstOrDefault();
if (enrollId == Guid.Empty)
{
//"错误,未在入组表中找到该医生得账号Id"
return ResponseOutput.NotOk(_localizer["TaskAllocation_DoctorIdNotFound"]);
}
addOrEditTaskAllocationRule.EnrollId = enrollId;
var verifyExp1 = new EntityVerifyExp<TaskAllocationRule>()
{
VerifyExp = t => t.DoctorUserId == addOrEditTaskAllocationRule.DoctorUserId && t.TrialId == addOrEditTaskAllocationRule.TrialId,
// "已有该医生配置,不允许继续增加"
VerifyMsg = _localizer["TaskAllocation_DoctorConfigExists"]
};
var entity = await _taskAllocationRuleRepository.InsertOrUpdateAsync(addOrEditTaskAllocationRule, true, verifyExp1);
return ResponseOutput.Ok(entity.Id.ToString());
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[HttpDelete("{taskAllocationRuleId:guid}")]
public async Task<IResponseOutput> DeleteTaskAllocationRule(Guid taskAllocationRuleId)
{
if (await _taskAllocationRuleRepository.Where(t => t.Id == taskAllocationRuleId).AnyAsync(t => t.DoctorUser.VisitTaskList.Where(u => u.TrialId == t.TrialId).Any()))
{
//"已分配任务给该医生,不允许删除"
return ResponseOutput.NotOk(_localizer["TaskAllocation_TaskAssigned"]);
}
var success = await _taskAllocationRuleRepository.DeleteFromQueryAsync(t => t.Id == taskAllocationRuleId, true);
return ResponseOutput.Ok();
}
//public async Task<IResponseOutput> AddSubjectCancelDoctorNote(CancelDoctorCommand command)
//{
// await _subjectCanceDoctorRepository.InsertOrUpdateAsync(command, true);
// return ResponseOutput.Ok();
//}
public async Task<List<SubjectCancelDoctorView>> GetSubjectCancelDoctorHistoryList(Guid subjectId,Guid trialReadingCriterionId)
{
var list = await _subjectCanceDoctorRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId==trialReadingCriterionId).ProjectTo<SubjectCancelDoctorView>(_mapper.ConfigurationProvider).ToListAsync();
return list;
}
/// <summary>
/// 获取项目下 医生账户信息下拉
/// </summary>
/// <param name="trialId"></param>
/// <param name="_enrollRepository"></param>
/// <returns></returns>
[HttpGet("{trialId:guid}")]
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)
join user in _userRepository.AsQueryable() on enroll.DoctorId equals user.DoctorId
select new TrialDoctorUserSelectView()
{
TrialId = enroll.TrialId,
//ReadingType = enroll.Trial.ReadingType,
DoctorUserId = user.Id,
FullName = user.FullName,
UserCode = user.UserCode,
UserName = user.UserName,
UserTypeEnum = user.UserTypeRole.UserTypeEnum,
ReadingCategoryList = enroll.EnrollReadingCategoryList.Select(t => t.ReadingCategory).ToList()
};
return await query.ToListAsync();
}
[HttpPost]
public async Task<List<TrialDoctorUserSelectView>> GetDoctorSelectList(DoctorSelectQuery selectQuery, [FromServices] IRepository<Enroll> _enrollRepository)
{
var query = from allocationRule in _taskAllocationRuleRepository.Where(t => t.TrialId == selectQuery.TrialId && t.IsEnable)
.WhereIf(selectQuery.ReadingCategory != null && selectQuery.TrialReadingCriterionId == null, t => t.Enroll.EnrollReadingCategoryList.Any(t => t.ReadingCategory == selectQuery.ReadingCategory))
.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 && t.ReadingCategory==selectQuery.ReadingCategory))
join user in _userRepository.AsQueryable() on allocationRule.DoctorUserId equals user.Id
select new TrialDoctorUserSelectView()
{
TrialId = allocationRule.TrialId,
DoctorUserId = user.Id,
FullName = user.FullName,
UserCode = user.UserCode,
UserName = user.UserName,
UserTypeEnum = user.UserTypeRole.UserTypeEnum,
ReadingCategoryList = selectQuery.TrialReadingCriterionId == null ?
allocationRule.Enroll.EnrollReadingCategoryList.Where(t=> (selectQuery.ReadingCategory == null ?true: t.ReadingCategory == selectQuery.ReadingCategory) ).Select(t => t.ReadingCategory).OrderBy(t => t).ToList() :
allocationRule.Enroll.EnrollReadingCategoryList
.Where(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && (selectQuery.ReadingCategory == null?true : t.ReadingCategory == selectQuery.ReadingCategory) )
.Select(t => t.ReadingCategory).OrderBy(t => t).ToList()
};
return await query.ToListAsync();
}
#region
/// <summary>
/// 获取访视任务 应用Subject后 医生比率情况
/// </summary>
/// <returns></returns>
[HttpPost]
[Obsolete]
public async Task<List<DoctorVisitTaskStatView>> GetSubjectApplyDoctorTaskStatList(ApplySubjectCommand assignConfirmCommand)
{
var taskAllocationRuleQueryable = _taskAllocationRuleRepository.Where(t => t.TrialId == assignConfirmCommand.TrialId && t.IsJudgeDoctor == assignConfirmCommand.IsJudgeDoctor)
.ProjectTo<DoctorVisitTaskStatView>(_mapper.ConfigurationProvider, new { subjectIdList = assignConfirmCommand.SubjectIdList, isJudgeDoctor = assignConfirmCommand.IsJudgeDoctor });
return await taskAllocationRuleQueryable.ToListAsync();
}
[HttpPost]
[Obsolete]
public async Task<List<DoctorVisitTaskStatView>> GetTaskAllocationRuleList(TaskAllocationRuleQuery queryTaskAllocationRule)
{
var taskAllocationRuleQueryable = _taskAllocationRuleRepository.Where(t => t.TrialId == queryTaskAllocationRule.TrialId /*&& t.IsJudgeDoctor == queryTaskAllocationRule.IsJudgeDoctor*/)
.ProjectTo<DoctorVisitTaskStatView>(_mapper.ConfigurationProvider);
//var trialTaskConfig = _trialRepository.Where(t => t.Id == queryTaskAllocationRule.TrialId).ProjectTo<TrialProcessConfigDTO>(_mapper.ConfigurationProvider, new { isJudgeDoctor = queryTaskAllocationRule.IsJudgeDoctor }).FirstOrDefault();
return await taskAllocationRuleQueryable.ToListAsync();
}
#endregion
}
}
@@ -1,994 +0,0 @@
//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2022-07-01 15:33:04
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Domain.Share;
using System.Linq.Expressions;
using IRaCIS.Core.Infra.EFCore.Common;
using System.Linq;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using Medallion.Threading;
using IRaCIS.Core.Infrastructure.Extention;
using System;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace IRaCIS.Core.Application.Service
{
/// <summary>
/// 一致性分析配置表
/// </summary>
[ApiExplorerSettings(GroupName = "Trial")]
public class TaskConsistentRuleService : BaseService, ITaskConsistentRuleService
{
private readonly IRepository<TaskConsistentRule> _taskConsistentRuleRepository;
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IRepository<SubjectUser> _subjectUserRepository;
private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<Enroll> _enrollRepository;
private readonly IDistributedLockProvider _distributedLockProvider;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<TrialSite> _trialSiteRepository;
private readonly IRepository<TrialVirtualSiteCodeUpdate> _trialVirtualSiteCodeUpdateRepository;
private readonly IVisitTaskHelpeService _visitTaskCommonService;
public TaskConsistentRuleService(IRepository<VisitTask> visitTaskRepository, IRepository<Enroll> enrollRepository, IRepository<TaskConsistentRule> taskConsistentRuleRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<Subject> subjectRepository, IDistributedLockProvider distributedLockProvider,
IRepository<Trial> trialRepository, IRepository<TrialSite> trialSiteRepository, IRepository<TrialVirtualSiteCodeUpdate> trialVirtualSiteCodeUpdateRepository, IVisitTaskHelpeService visitTaskCommonService)
{
_taskConsistentRuleRepository = taskConsistentRuleRepository;
_visitTaskRepository = visitTaskRepository;
_subjectUserRepository = subjectUserRepository;
_subjectRepository = subjectRepository;
_enrollRepository = enrollRepository;
_distributedLockProvider = distributedLockProvider;
_trialRepository = trialRepository;
_trialSiteRepository = trialSiteRepository;
_trialVirtualSiteCodeUpdateRepository = trialVirtualSiteCodeUpdateRepository;
_visitTaskCommonService = visitTaskCommonService;
}
/// <summary>
/// 设置一致性分析任务失效
/// </summary>
/// <param name="taskIdList"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SetAnalysisTaskInvalid(List<Guid> taskIdList)
{
await _visitTaskRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.Id), u => new VisitTask() { TaskState = TaskState.Adbandon }, true);
await _visitTaskRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 一致性分析列表 (自身 组内 最后勾选 产生的任务)
/// </summary>
/// <param name="queryVisitTask"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput<PageOutput<AnalysisTaskView>>> GetAnalysisTaskList(VisitTaskQuery queryVisitTask )
{
var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
.Where(t => t.IsAnalysisCreate)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
.WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
.WhereIf(queryVisitTask.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState)
.WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState)
.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum)
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => /*(t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) ||*/ (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) /*&& t.IsAnalysisCreate == false*/))
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName))
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => ((t.Subject.Code.Contains(queryVisitTask.SubjectCode)||t.Subject.MedicalNo.Contains(queryVisitTask.SubjectCode)) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate))
.WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime >= queryVisitTask.BeginAllocateDate)
.WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime <= queryVisitTask.EndAllocateDate)
.WhereIf(queryVisitTask.BeginSignTime != null, t => t.SignTime >= queryVisitTask.BeginSignTime)
.WhereIf(queryVisitTask.EndSignTime != null, t => t.SignTime <= queryVisitTask.EndSignTime)
.ProjectTo<AnalysisTaskView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) };
var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);
var trialTaskConfig = _repository.Where<Trial>(t => t.Id == queryVisitTask.TrialId).Select(t => new { IsHaveDoubleReadCriterion=t.ReadingQuestionCriterionTrialList.Any(t=>t.IsSigned && t.IsConfirm && t.ReadingType==ReadingMethod.Double), t.VitrualSiteCode }).FirstOrDefault();
return ResponseOutput.Ok(pageList, trialTaskConfig);
}
/// <summary>
/// 为自身一致性分析医生,选择Subejct 列表
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<DoctorSelfConsistentSubjectView>> GetDoctorSelfConsistentRuleSubjectList(ConsistentQuery inQuery)
{
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == inQuery.TaskConsistentRuleId);
var pagedList = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, inQuery.DoctorUserId).ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(DoctorSelfConsistentSubjectView.SubjectCode) : inQuery.SortField, inQuery.Asc);
return pagedList;
}
/// <summary>
/// 确认生成自身一致性分析任务
/// </summary>
/// <param name="inCommand"></param>
/// <returns></returns>
[HttpPost]
[UnitOfWork]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> ConfirmGenerateSelfConsistentTask(ConsistentConfirmGenerateCommand inCommand)
{
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == inCommand.TaskConsistentRuleId);
var doctorUserId = inCommand.DoctorUserId;
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
//随机分配
if (inCommand.IsAutoAllocateGenerateTask)
{
var subjectList = (await GetSelfConsistentRuleMatchSubjectIdListAsync(new SelfConsistentSimpleQuery() { TaskConsistentRuleId = inCommand.TaskConsistentRuleId, DoctorUserId = inCommand.DoctorUserId })).ToList();
if (subjectList.Any(t => t.IsHaveGeneratedTask))
{
//已手动分配,不允许自动分配
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate"]);
}
if (subjectList.Count<2 * filterObj.PlanSubjectCount)
{
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate1"]);
}
inCommand.SubejctIdList = GetRandomSubjectIdList(subjectList.Select(t => t.SubjectId).ToList(), filterObj.PlanSubjectCount);
}
var list = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, doctorUserId, inCommand.SubejctIdList).ToListAsync();
//var (group, query) = GetIQueryableDoctorSelfConsistentRuleSubjectView(filterObj, inCommand.SubejctIdList);
//var list = query.OrderByDescending(t => t.IsHaveGeneratedTask).ToList();
var @lock = _distributedLockProvider.CreateLock($"VisitTaskCode");
using (await @lock.AcquireAsync())
{
int maxCodeInt = 0;
foreach (var subject in list)
{
//处理 Subject 编号
var blindSubjectCode = string.Empty;
var subjectTask = _visitTaskRepository.Where(t => t.SubjectId == subject.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == true).OrderByDescending(t => t.BlindSubjectCode).FirstOrDefault();
if (subjectTask != null && subjectTask.BlindSubjectCode != String.Empty)
{
blindSubjectCode = subjectTask.BlindSubjectCode;
}
else
{
var maxCodeStr = _visitTaskRepository.Where(t => t.TrialId == subject.TrialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == true).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault();
if (!string.IsNullOrEmpty(maxCodeStr))
{
int.TryParse(maxCodeStr.Substring(maxCodeStr.Length - filterObj.BlindSubjectNumberOfPlaces), out maxCodeInt);
}
blindSubjectCode = filterObj.BlindTrialSiteCode + (maxCodeInt + 1).ToString($"D{filterObj.BlindSubjectNumberOfPlaces}");
}
subject.VisitTaskList = subject.VisitTaskList.Take(filterObj.PlanVisitCount).ToList();
subject.VisitTaskList.ForEach(t =>
{
t.DoctorUserId = doctorUserId;
//t.TaskConsistentRuleId = filterObj.Id;
t.BlindTrialSiteCode = filterObj.BlindTrialSiteCode;
t.BlindSubjectCode = blindSubjectCode;
});
//最后一个访视添加全局
if (filterObj.IsGenerateGlobalTask)
{
var lastTask = (subject.VisitTaskList.Take(filterObj.PlanVisitCount).Last()).Clone();
var existGlobal = _visitTaskRepository.Where(t => t.SubjectId == lastTask.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum == lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).ProjectTo<VisitTaskSimpleDTO>(_mapper.ConfigurationProvider).FirstOrDefault();
if (existGlobal == null)
{
existGlobal = new VisitTaskSimpleDTO()
{
SubjectId = lastTask.SubjectId,
TrialId = lastTask.TrialId,
ArmEnum = lastTask.ArmEnum,
ReadingCategory = ReadingCategory.Global,
TaskName = lastTask.TaskName + "_Global",
TaskBlindName = lastTask.TaskBlindName + "_Global",
TrialReadingCriterionId = trialReadingCriterionId,
};
}
existGlobal.DoctorUserId = doctorUserId;
existGlobal.BlindSubjectCode = lastTask.BlindSubjectCode;
existGlobal.BlindTrialSiteCode = lastTask.BlindTrialSiteCode;
subject.VisitTaskList.Add(existGlobal);
}
await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand()
{
TrialId = filterObj.TrialId,
ReadingCategory = GenerateTaskCategory.SelfConsistent,
//产生的过滤掉已经生成的
GenerataConsistentTaskList = subject.VisitTaskList.Where(t => t.IsHaveGeneratedTask == false).ToList()
});
await _visitTaskRepository.SaveChangesAsync();
}
}
return ResponseOutput.Ok();
}
/// <summary>
/// 组间一致性分析 选择Subejct 列表
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput<PageOutput<DoctorGroupConsistentSubjectView>> > GetGroupConsistentRuleSubjectList(GroupConsistentQuery inQuery)
{
var trialId = inQuery.TrialId;
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == false);
if (filterObj == null)
{
object tt = null;
return ResponseOutput.Ok(new PageOutput<DoctorGroupConsistentSubjectView>(), new { Rule = tt, IsAllowAutoAllocate = false }) ;
}
var query = await GetGroupConsistentQueryAsync(filterObj);
var pagedList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(DoctorSelfConsistentSubjectView.SubjectCode) : inQuery.SortField, inQuery.Asc);
var rule = await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == false && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo<TaskConsistentRuleBasic>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
var list = await GetGroupConsistentRuleMatchSubjectIdListAsync(new GroupConsistentSimpleQuery() { TrialId = inQuery.TrialId, TrialReadingCriterionId = inQuery.TrialReadingCriterionId });
var isAllowAutoAllocate = !list.Any(t => t.IsHaveGeneratedTask) && list.Count() > 2*(rule?.PlanSubjectCount??0);
return ResponseOutput.Ok(pagedList, new {Rule=rule, IsAllowAutoAllocate = isAllowAutoAllocate });
}
/// <summary>
/// 确认生成组间一致性分析任务
/// </summary>
/// <param name="inCommand"></param>
/// <returns></returns>
[HttpPost]
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> ConfirmGenerateGroupConsistentTask(GroupConsistentConfirmGenrateCommand inCommand)
{
var trialId = inCommand.TrialId;
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.TrialReadingCriterionId == inCommand.TrialReadingCriterionId && t.IsSelfAnalysis == false);
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
//随机分配
if (inCommand.IsAutoAllocateGenerateTask)
{
var subjectSelectList = (await GetGroupConsistentRuleMatchSubjectIdListAsync(new GroupConsistentSimpleQuery() { TrialId = inCommand.TrialId, TrialReadingCriterionId = inCommand.TrialReadingCriterionId })).ToList();
if (subjectSelectList.Any(t => t.IsHaveGeneratedTask))
{
//已手动分配过,不允许自动分配
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate"]);
}
if (subjectSelectList.Count< 2 * filterObj.PlanSubjectCount)
{
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate1"]);
}
inCommand.SubejctIdList = GetRandomSubjectIdList(subjectSelectList.Select(t => t.SubjectId).ToList(), filterObj.PlanSubjectCount);
}
var query = await GetGroupConsistentQueryAsync(filterObj, inCommand.SubejctIdList);
var subjectList = query.ToList();
var doctorUserIdQuery = from enroll in _repository.Where<Enroll>(t => t.TrialId == trialId).Where(t => t.EnrollReadingCategoryList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(c => c.ReadingCategory == ReadingCategory.Global || c.ReadingCategory == ReadingCategory.Visit))
.Where(t => t.EnrollReadingCriteriaList.Any(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsJoinAnalysis == true))
join user in _repository.Where<User>() on enroll.DoctorId equals user.DoctorId
select user.Id;
var configDoctorUserIdList = await doctorUserIdQuery.ToListAsync();
var @lock = _distributedLockProvider.CreateLock($"VisitTaskCode");
using (await @lock.AcquireAsync())
{
int maxCodeInt = 0;
foreach (var subject in subjectList.Where(t => t.IsHaveGeneratedTask == false))
{
//组间一致性分析 也用盲态SubjectCode
//处理 Subject 编号
var blindSubjectCode = string.Empty;
var subjectTask = _visitTaskRepository.Where(t => t.SubjectId == subject.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == false).OrderByDescending(t => t.BlindSubjectCode).FirstOrDefault();
if (subjectTask != null && subjectTask.BlindSubjectCode != String.Empty)
{
blindSubjectCode = subjectTask.BlindSubjectCode;
}
else
{
var maxCodeStr = _visitTaskRepository.Where(t => t.TrialId == subject.TrialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == false).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault();
if (!string.IsNullOrEmpty(maxCodeStr))
{
int.TryParse(maxCodeStr.Substring(maxCodeStr.Length - filterObj.BlindSubjectNumberOfPlaces), out maxCodeInt);
}
blindSubjectCode = filterObj.BlindTrialSiteCode + (maxCodeInt + 1).ToString($"D{filterObj.BlindSubjectNumberOfPlaces}");
}
var subjectAddTaskList = new List<VisitTaskGroupSimpleDTO>();
//需要处理的医生
var needAddDoctorUserIdList = configDoctorUserIdList.Except(subject.VisitTaskList.Select(t => t.DoctorUserId!.Value)).ToList();
if (needAddDoctorUserIdList.Count == 0)
{
//"请配置一致性分析的医生"
throw new BusinessValidationFailedException(_localizer["TaskConsistent_ConsistencyConfigExists"]);
}
foreach (var needAddDoctorUserId in needAddDoctorUserIdList)
{
//每个医生 都生成处理的任务
foreach (var task in subject.SubjectTaskVisitList.Take(filterObj.PlanVisitCount))
{
subjectAddTaskList.Add(new VisitTaskGroupSimpleDTO()
{
ReadingCategory = task.ReadingCategory,
ReadingTaskState = task.ReadingTaskState,
TaskBlindName = task.TaskBlindName,
TaskName = task.TaskName,
TaskState = task.TaskState,
SubjectId = task.SubjectId,
VisitTaskNum = task.VisitTaskNum,
TrialId = task.TrialId,
DoctorUserId = needAddDoctorUserId,
ArmEnum = Arm.GroupConsistentArm,
SouceReadModuleId = task.SouceReadModuleId,
SourceSubjectVisitId = task.SourceSubjectVisitId,
TrialReadingCriterionId = task.TrialReadingCriterionId,
BlindSubjectCode = blindSubjectCode,
BlindTrialSiteCode = filterObj.BlindTrialSiteCode
});
}
//最后一个访视添加全局
if (filterObj.IsGenerateGlobalTask)
{
var lastTask = (subjectAddTaskList.Take(filterObj.PlanVisitCount).Last()).Clone();
var existGlobal = _visitTaskRepository.Where(t => t.SubjectId == lastTask.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum == lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).ProjectTo<VisitTaskGroupSimpleDTO>(_mapper.ConfigurationProvider).FirstOrDefault();
if (existGlobal == null)
{
existGlobal = new VisitTaskSimpleDTO()
{
SubjectId = lastTask.SubjectId,
TrialId = lastTask.TrialId,
ReadingCategory = ReadingCategory.Global,
TaskName = lastTask.TaskName + "_Global",
TaskBlindName = lastTask.TaskBlindName + "_Global",
TrialReadingCriterionId = trialReadingCriterionId,
BlindSubjectCode = blindSubjectCode,
BlindTrialSiteCode = filterObj.BlindTrialSiteCode
};
}
existGlobal.BlindSubjectCode = blindSubjectCode;
existGlobal.BlindTrialSiteCode = filterObj.BlindTrialSiteCode;
existGlobal.ArmEnum = Arm.GroupConsistentArm;
existGlobal.DoctorUserId = needAddDoctorUserId;
subjectAddTaskList.Add(existGlobal);
}
}
await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand()
{
TrialId = filterObj.TrialId,
ReadingCategory = GenerateTaskCategory.GroupConsistent,
GenerataGroupConsistentTaskList = subjectAddTaskList
});
await _taskConsistentRuleRepository.SaveChangesAsync();
}
}
return ResponseOutput.Ok();
}
/// <summary>
/// 仅仅自身一致性时使用(
/// </summary>
/// <param name="filterObj"></param>
/// <param name="doctorUserId"></param>
/// <param name="subejctIdList"></param>
/// <returns></returns>
private IQueryable<DoctorSelfConsistentSubjectView> GetIQueryableDoctorSelfConsistentSubjectView(TaskConsistentRule filterObj, Guid doctorUserId, List<Guid>? subejctIdList = null)
{
var trialId = filterObj.TrialId;
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
#region Subejct
Expression<Func<VisitTask, bool>> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && u.TrialReadingCriterionId == trialReadingCriterionId &&
u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject) && u.DoctorUserId == doctorUserId;
if (subejctIdList != null && subejctIdList?.Count > 0)
{
comonTaskFilter = comonTaskFilter.And(t => subejctIdList.Contains(t.SubjectId));
}
Expression<Func<VisitTask, bool>> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit);
////所选访视数量 的访视 其中必有一个访视后有全局任务
//if (filterObj.IsHaveReadingPeriod == true)
//{
// //这里的过滤条件 不能用 where(comonTaskFilter) 会报错,奇怪的问题 只能重新写一遍
// visitTaskFilter = visitTaskFilter.And(c => c.Subject.SubjectVisitTaskList.Any(t => t.VisitTaskNum == c.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global] && t.ReadingCategory == ReadingCategory.Global && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned &&
// t.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && (t.ReReadingApplyState == ReReadingApplyState.Default || t.ReReadingApplyState == ReReadingApplyState.Reject)));
//}
var subjectQuery = _subjectRepository.Where(t => t.TrialId == trialId &&
t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).Count() >= filterObj.PlanVisitCount)
.WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(filterObj.PlanVisitCount + 1).Any(t => t.ReadingCategory == ReadingCategory.Global))
;
var query = subjectQuery.Select(t => new DoctorSelfConsistentSubjectView()
{
TrialId = t.TrialId,
TrialSiteId = t.TrialSiteId,
SubjectCode = t.Code,
TrialSiteCode = t.TrialSite.TrialSiteCode,
SubjectId = t.Id,
IsReReadingOrBackInfluenceAnalysis = t.IsReReadingOrBackInfluenceAnalysis,
BlindSubjectCode = t.SubjectVisitTaskList.Where(t => t.IsAnalysisCreate && t.TrialReadingCriterionId == trialReadingCriterionId).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault(),
IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.DoctorUserId == doctorUserId && c.IsSelfAnalysis == true && c.TrialReadingCriterionId == trialReadingCriterionId),
ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).Count(),
VisitTaskList = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).OrderBy(t => t.VisitTaskNum).Select(c => new VisitTaskSimpleDTO()
{
Id = c.Id,
ReadingCategory = c.ReadingCategory,
ReadingTaskState = c.ReadingTaskState,
TaskBlindName = c.TaskBlindName,
TaskCode = c.TaskCode,
TaskName = c.TaskName,
TaskState = c.TaskState,
ArmEnum = c.ArmEnum,
SubjectId = c.SubjectId,
VisitTaskNum = c.VisitTaskNum,
TrialId = c.TrialId,
SourceSubjectVisitId = c.SourceSubjectVisitId,
SouceReadModuleId = c.SouceReadModuleId,
TrialReadingCriterionId = c.TrialReadingCriterionId,
IsClinicalDataSign = c.IsClinicalDataSign,
IsNeedClinicalDataSign = c.IsNeedClinicalDataSign,
//自身一致性才有意义
//IsHaveGeneratedTask = c.Subject.SubjectVisitTaskList.Any(t => t.ConsistentAnalysisOriginalTaskId == c.Id),
GlobalVisitTaskList = c.Subject.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.VisitTaskNum == c.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).Select(c => new VisitTaskSimpleDTO()
{
Id = c.Id,
ReadingCategory = c.ReadingCategory,
ReadingTaskState = c.ReadingTaskState,
TaskBlindName = c.TaskBlindName,
TaskCode = c.TaskCode,
TaskName = c.TaskName,
TaskState = c.TaskState,
ArmEnum = c.ArmEnum,
SubjectId = c.SubjectId,
VisitTaskNum = c.VisitTaskNum,
TrialId = c.TrialId,
SourceSubjectVisitId = c.SourceSubjectVisitId,
SouceReadModuleId = c.SouceReadModuleId,
TrialReadingCriterionId = c.TrialReadingCriterionId,
IsClinicalDataSign = c.IsClinicalDataSign,
IsNeedClinicalDataSign = c.IsNeedClinicalDataSign,
}).ToList(),
}).ToList()
});
return query.OrderByDescending(t => t.IsHaveGeneratedTask);
#endregion
}
/// <summary>
/// 组间一致性分析 满足条件的subject 筛选
/// </summary>
/// <param name="filterObj"></param>
/// <param name="subejctIdList"></param>
/// <returns></returns>
private async Task<IQueryable<DoctorGroupConsistentSubjectView>> GetGroupConsistentQueryAsync(TaskConsistentRule filterObj, List<Guid>? subejctIdList = null)
{
var trialId = filterObj.TrialId;
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
//var trialConfig = (await _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.ReadingType, t.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException();
Expression<Func<VisitTask, bool>> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && u.TrialReadingCriterionId == trialReadingCriterionId
&& (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject);
if (subejctIdList != null && subejctIdList?.Count > 0)
{
comonTaskFilter = comonTaskFilter.And(t => subejctIdList.Contains(t.SubjectId));
}
Expression<Func<VisitTask, bool>> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit);
////所选访视数量 的访视 其中必有一个访视后有全局任务
//if (filterObj.IsHaveReadingPeriod == true)
//{
// //visitTaskFilter = visitTaskFilter.And(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Any(u => u.VisitTaskNum == t.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global] && u.ReadingCategory == ReadingCategory.Global));
// //这里的过滤条件 不能用 where(comonTaskFilter) 会报错,奇怪的问题 只能重新写一遍
// visitTaskFilter = visitTaskFilter.And(c => c.Subject.SubjectVisitTaskList.Any(t => t.VisitTaskNum == c.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global] && t.ReadingCategory == ReadingCategory.Global && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned &&
// t.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && (t.ReReadingApplyState == ReReadingApplyState.Default || t.ReReadingApplyState == ReReadingApplyState.Reject)));
//}
IQueryable<Subject> subjectQuery = default;
//单重阅片没有组件一致性
subjectQuery = _subjectRepository.Where(t => t.TrialId == trialId &&
t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Select(t => t.DoctorUserId).Distinct().Count() == 2 &&
t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count() >= filterObj.PlanVisitCount
)
.WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(filterObj.PlanVisitCount * 2 + 2).Any(t => t.ReadingCategory == ReadingCategory.Global))
;
var query = subjectQuery.Select(t => new DoctorGroupConsistentSubjectView()
{
TrialId = t.TrialId,
TrialSiteId = t.TrialSiteId,
SubjectCode = t.Code,
TrialSiteCode = t.TrialSite.TrialSiteCode,
SubjectId = t.Id,
IsReReadingOrBackInfluenceAnalysis = t.IsReReadingOrBackInfluenceAnalysis,
IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.IsSelfAnalysis == false && c.TrialReadingCriterionId == trialReadingCriterionId),
DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed).Select(t => new UserSimpleInfo()
{
UserId = t.Id,
FullName = t.DoctorUser.FullName,
UserCode = t.DoctorUser.UserCode,
UserName = t.DoctorUser.UserName
}).ToList(),
ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count(),
VisitTaskList = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter)
.Select(c => new VisitTaskGroupSimpleDTO()
{
ReadingCategory = c.ReadingCategory,
ReadingTaskState = c.ReadingTaskState,
TaskBlindName = c.TaskBlindName,
TaskName = c.TaskName,
TaskState = c.TaskState,
SubjectId = c.SubjectId,
VisitTaskNum = c.VisitTaskNum,
TrialId = c.TrialId,
DoctorUserId = c.DoctorUserId,
SourceSubjectVisitId = c.SourceSubjectVisitId,
SouceReadModuleId = c.SouceReadModuleId,
TrialReadingCriterionId = c.TrialReadingCriterionId,
IsClinicalDataSign = c.IsClinicalDataSign,
IsNeedClinicalDataSign = c.IsNeedClinicalDataSign,
}).ToList()
//
});
query = query.OrderByDescending(t => t.IsHaveGeneratedTask);
return query;
}
[HttpPost]
public async Task<TaskConsistentRuleBasic?> GetConsistentRule(TaskConsistentRuleQuery inQuery)
{
return await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == inQuery.IsSelfAnalysis && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo<TaskConsistentRuleBasic>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
}
/// <summary>
/// 自身一致性分配 配置+ 统计已经生成数量统计表
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput<List<TaskConsistentRuleView>>> GetSelfConsistentDoctorStatList(TaskConsistentRuleQuery inQuery)
{
var trialId = inQuery.TrialId;
Expression<Func<VisitTask, bool>> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject);
//&& u.TrialReadingCriterionId == trialReadingCriterionId &&u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && u.DoctorUserId == doctorUserId;
Expression<Func<VisitTask, bool>> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit);
var taskConsistentRuleQueryable = from enroll in _repository.Where<Enroll>(t => t.TrialId == trialId && t.EnrollStatus == EnrollStatus.ConfirmIntoGroup
&& t.EnrollReadingCriteriaList.Any(c => c.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && c.IsJoinAnalysis))
join user in _repository.Where<User>() on enroll.DoctorUserId equals user.Id
join taskConsistentRule in _repository.Where<TaskConsistentRule>(t => t.TrialId == trialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis) on enroll.TrialId equals taskConsistentRule.TrialId
select new TaskConsistentRuleView()
{
Id = taskConsistentRule.Id,
CreateTime = taskConsistentRule.CreateTime,
BlindTrialSiteCode = taskConsistentRule.BlindTrialSiteCode,
BlindSubjectNumberOfPlaces = taskConsistentRule.BlindSubjectNumberOfPlaces,
CreateUserId = taskConsistentRule.CreateUserId,
IntervalWeeks = taskConsistentRule.IntervalWeeks,
IsEnable = taskConsistentRule.IsEnable,
PlanSubjectCount = taskConsistentRule.PlanSubjectCount,
Note = taskConsistentRule.Note,
TrialId = taskConsistentRule.TrialId,
UpdateTime = taskConsistentRule.UpdateTime,
UpdateUserId = taskConsistentRule.UpdateUserId,
IsGenerateGlobalTask = taskConsistentRule.IsGenerateGlobalTask,
IsHaveReadingPeriod = taskConsistentRule.IsHaveReadingPeriod,
PlanVisitCount = taskConsistentRule.PlanVisitCount,
GeneratedSubjectCount = taskConsistentRule.TrialReadingCriterion.VisitTaskList.Where(t => t.IsAnalysisCreate && t.IsSelfAnalysis == true && t.DoctorUserId == user.Id).Select(t => t.SubjectId).Distinct().Count(),
MatchSubejctCount = taskConsistentRule.Trial.SubjectList.AsQueryable()
.Where(t => taskConsistentRule.IsHaveReadingPeriod == false ? t.SubjectVisitTaskList.AsQueryable()
.Where(visitTaskFilter).Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.Id)
.Count() >= taskConsistentRule.PlanVisitCount :
t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter)
.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.Id)
.Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(taskConsistentRule.PlanVisitCount + 1).Any(t => t.ReadingCategory == ReadingCategory.Global))
.Count(),
AnalysisDoctorUser = new UserSimpleInfo()
{
UserId = user.Id,
UserCode = user.UserCode,
FullName = user.FullName,
UserName = user.UserName
}
};
//if (await _taskConsistentRuleRepository.AnyAsync(t => t.TrialId == inQuery.TrialId))
//{
// var rule = await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId).ProjectTo<TaskConsistentRuleBatchAddOrEdit>(_mapper.ConfigurationProvider).FirstAsync();
// rule.IsBatchAdd = true;
// await BatchAddOrUpdateTaskConsistentRule(rule);
//}
//#endregion
//var taskConsistentRuleQueryable = _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId)
// .ProjectTo<TaskConsistentRuleView>(_mapper.ConfigurationProvider);
var list= await taskConsistentRuleQueryable.ToListAsync();
var rule= await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == true && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo<TaskConsistentRuleBasic>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
return ResponseOutput.Ok(list, rule);
}
[HttpPost]
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> UpdateTrialVirtualSiteCode(UpdateTrialSiteCodeCommand inCommand)
{
if (_trialSiteRepository.Where(t => t.TrialId == inCommand.TrialId, false, true).Any(t => t.TrialSiteCode == inCommand.VirtualSiteCode))
{
return ResponseOutput.NotOk(_localizer["TaskConsistent_SiteCodeExists"]);
}
var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == inCommand.TrialId);
var oldCode = trial.VitrualSiteCode;
trial.VitrualSiteCode = inCommand.VirtualSiteCode;
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trial.Id, u => new VisitTask() { BlindTrialSiteCode = inCommand.VirtualSiteCode });
await _taskConsistentRuleRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trial.Id, u => new TaskConsistentRule() { BlindTrialSiteCode = inCommand.VirtualSiteCode });
await _visitTaskRepository.ExecuteUpdateAsync(t => t.TrialId == trial.Id, s => s.SetProperty(e => e.BlindSubjectCode, u => u.BlindSubjectCode.Replace(oldCode, inCommand.VirtualSiteCode)));
await _trialVirtualSiteCodeUpdateRepository.AddAsync(new TrialVirtualSiteCodeUpdate() { VirturalSiteCode = inCommand.VirtualSiteCode, TrialId = inCommand.TrialId });
await _trialRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
public async Task<List<UpdateTrialSiteCodeCommandView>> GetUpdateVirtualSiteCodeList(Guid trialId)
{
var list = await _trialVirtualSiteCodeUpdateRepository.Where(t => t.TrialId == trialId).Select(t => new UpdateTrialSiteCodeCommandView() { TrialId = trialId, VirtualSiteCode = t.VirturalSiteCode, Creatime = t.CreateTime }).OrderByDescending(t=>t.Creatime).ToListAsync();
return list;
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> AddOrUpdateTaskConsistentRule(TaskConsistentRuleAddOrEdit addOrEditTaskConsistentRule)
{
var verifyExp1 = new EntityVerifyExp<TaskConsistentRule>()
{
VerifyExp = t => t.TrialId == addOrEditTaskConsistentRule.TrialId && t.IsSelfAnalysis == addOrEditTaskConsistentRule.IsSelfAnalysis && t.TrialReadingCriterionId == addOrEditTaskConsistentRule.TrialReadingCriterionId,
//"已有该项目配置,不允许继续增加"
VerifyMsg = _localizer["TaskConsistent_TaskGenerated"]
};
if (await _visitTaskRepository.AnyAsync(t => t.IsSelfAnalysis == addOrEditTaskConsistentRule.IsSelfAnalysis && t.TrialId == addOrEditTaskConsistentRule.TrialId && t.TrialReadingCriterionId == addOrEditTaskConsistentRule.TrialReadingCriterionId))
{
//"该标准已有Subject 生成了任务,不允许修改配置"
return ResponseOutput.NotOk(_localizer["TaskConsistent_MedicalAuditTaskExists"]);
}
if (_trialSiteRepository.Where(t => t.TrialId == addOrEditTaskConsistentRule.TrialId, false, true).Any(t => t.TrialSiteCode == addOrEditTaskConsistentRule.BlindTrialSiteCode))
{
return ResponseOutput.NotOk(_localizer["TaskConsistent_SiteCodeExists"]);
}
var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == addOrEditTaskConsistentRule.TrialId);
if (string.IsNullOrEmpty(trial.VitrualSiteCode))
{
await _trialVirtualSiteCodeUpdateRepository.AddAsync(new TrialVirtualSiteCodeUpdate() { VirturalSiteCode = addOrEditTaskConsistentRule.BlindTrialSiteCode, TrialId = addOrEditTaskConsistentRule.TrialId });
}
trial.VitrualSiteCode = addOrEditTaskConsistentRule.BlindTrialSiteCode;
var entity = await _taskConsistentRuleRepository.InsertOrUpdateAsync(addOrEditTaskConsistentRule, true, verifyExp1);
return ResponseOutput.Ok(entity.Id.ToString());
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[HttpDelete("{taskConsistentRuleId:guid}")]
public async Task<IResponseOutput> DeleteTaskConsistentRule(Guid taskConsistentRuleId)
{
var config = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == taskConsistentRuleId);
if (await _visitTaskRepository.AnyAsync(t => t.IsAnalysisCreate && t.TrialId == config.TrialId && t.IsSelfAnalysis == config.IsSelfAnalysis && t.TrialReadingCriterionId == config.TrialReadingCriterionId))
{
//"该标准已产生一致性分析任务,不允许删除"
throw new BusinessValidationFailedException(_localizer["TaskConsistent_SignedTaskCannotBeInvalidated"]);
}
var success = await _taskConsistentRuleRepository.DeleteFromQueryAsync(t => t.Id == taskConsistentRuleId, true);
return ResponseOutput.Ok();
}
/// <summary>
/// 获取自身一致性分析 符合条件的subject 数组
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
public async Task<List<SubjectGeneratedTask>> GetSelfConsistentRuleMatchSubjectIdListAsync(SelfConsistentSimpleQuery inQuery)
{
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == inQuery.TaskConsistentRuleId);
var subjectList = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, inQuery.DoctorUserId).Select(t => new SubjectGeneratedTask() { SubjectId = t.SubjectId, IsHaveGeneratedTask = t.IsHaveGeneratedTask }).ToListAsync();
return subjectList;
}
/// <summary>
/// 获取组件一致性分析符合条件的subject 数组
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
public async Task<List<SubjectGeneratedTask>> GetGroupConsistentRuleMatchSubjectIdListAsync(GroupConsistentSimpleQuery inQuery)
{
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == inQuery.TrialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == false);
var subjectList = await (await GetGroupConsistentQueryAsync(filterObj)).Select(t => new SubjectGeneratedTask() { SubjectId = t.SubjectId, IsHaveGeneratedTask = t.IsHaveGeneratedTask }).ToListAsync();
return subjectList;
}
/// <summary>
/// 随机算法,选择指定数量的 subject
/// </summary>
/// <param name="matchSubjectIdList"></param>
/// <param name="countToSelect"></param>
/// <returns></returns>
public List<Guid> GetRandomSubjectIdList(List<Guid> matchSubjectIdList, int countToSelect)
{
// 使用 Fisher-Yates 随机置换算法来选择指定数量的 GUID
Random random = new Random();
for (int i = 0; i < countToSelect; i++)
{
// 生成一个随机索引
int randomIndex = random.Next(i, matchSubjectIdList.Count);
// 将选中的元素与当前元素交换位置
Guid temp = matchSubjectIdList[randomIndex];
matchSubjectIdList[randomIndex] = matchSubjectIdList[i];
matchSubjectIdList[i] = temp;
}
return matchSubjectIdList.Take(countToSelect).ToList();
// 使用洗牌算法来随机选择指定数量的GUID
//Random random = new Random();
//return matchSubjectIdList.OrderBy(g => random.Next()).Take(countToSelect).ToList();
}
}
}
@@ -67,11 +67,11 @@ namespace IRaCIS.Core.Application.Service
public async Task<IResponseOutput> DeleteTaskMedicalReviewRule(Guid taskMedicalReviewRuleId)
{
//if(await _taskMedicalReviewRuleRepository.Where(t=>t.Id== taskMedicalReviewRuleId).AnyAsync(t => t.TaskMedicalReviewList.Any()))
//{
// //"已产生医学审核任务"
// return ResponseOutput.NotOk(_localizer["TaskMedicalRule_TaskStarted"]);
//}
if(await _taskMedicalReviewRuleRepository.Where(t=>t.Id== taskMedicalReviewRuleId).AnyAsync(t => t.TaskMedicalReviewList.Any()))
{
//"已产生医学审核任务"
return ResponseOutput.NotOk(_localizer["TaskMedicalRule_TaskStarted"]);
}
var success = await _taskMedicalReviewRuleRepository.DeleteFromQueryAsync(t => t.Id == taskMedicalReviewRuleId,true);
@@ -11,7 +11,6 @@ using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter;
using Microsoft.Extensions.Logging;
namespace IRaCIS.Core.Application.Service
{
@@ -55,39 +54,21 @@ namespace IRaCIS.Core.Application.Service
{
var taskMedicalReviewQueryable = _taskMedicalReviewRepository.Where(t => t.VisitTask.TrialId == inQuery.TrialId)
.WhereIf(inQuery.IsEffect == true, t => t.VisitTask.TaskState == TaskState.Effect || t.VisitTask.TaskState == TaskState.Freeze)
.WhereIf(inQuery.IsEffect == false, t => t.VisitTask.TaskState == TaskState.Adbandon || t.VisitTask.TaskState == TaskState.HaveReturned)
.WhereIf(inQuery.TrialSiteId != null, t => t.VisitTask.Subject.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.SiteId != null, t => t.VisitTask.Subject.SiteId == inQuery.SiteId)
.WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode) || t.VisitTask.Subject.MedicalNo.Contains(inQuery.SubjectCode))
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName))
.WhereIf(inQuery.IsUrgent != null, t => t.VisitTask.IsUrgent == inQuery.IsUrgent)
.WhereIf(inQuery.DoctorUserId != null, t => t.VisitTask.DoctorUserId == inQuery.DoctorUserId)
.WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.VisitTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode) && t.VisitTask.IsAnalysisCreate) || (t.VisitTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode) && t.VisitTask.IsAnalysisCreate == false))
.WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory)
.WhereIf(inQuery.TaskState != null, t => t.VisitTask.TaskState == inQuery.TaskState)
.WhereIf(inQuery.ArmEnum != null, t => t.VisitTask.ArmEnum == inQuery.ArmEnum)
.WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState)
.WhereIf(inQuery.MedicalManagerUserId != null, t => t.MedicalManagerUserId == inQuery.MedicalManagerUserId)
.WhereIf(inQuery.BeginSignTime != null, t => t.VisitTask.SignTime > inQuery.BeginSignTime)
.WhereIf(inQuery.EndSignTime != null, t => t.VisitTask.SignTime < inQuery.EndSignTime)
.WhereIf(inQuery.AuditAdviceEnum != null, t => t.AuditAdviceEnum == inQuery.AuditAdviceEnum)
.WhereIf(inQuery.DoctorUserIdeaEnum != null, t => t.DoctorUserIdeaEnum == inQuery.DoctorUserIdeaEnum)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid)
.WhereIf(inQuery.IsHaveQuestion != null, t => t.IsHaveQuestion == inQuery.IsHaveQuestion)
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime >= inQuery.BeginAllocateDate)
.WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime <= inQuery.EndAllocateDate)
.WhereIf(inQuery.BeginAuditSignTime != null, t => t.AuditSignTime >= inQuery.BeginAuditSignTime)
.WhereIf(inQuery.EndAuditSignTime != null, t => t.AuditSignTime <= inQuery.EndAuditSignTime)
.ProjectTo<TaskMedicalReviewView>(_mapper.ConfigurationProvider);
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.ProjectTo<TaskMedicalReviewView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.AuditState), nameof(TaskMedicalReviewView.SubjectId), nameof(TaskMedicalReviewView.ArmEnum) , nameof(TaskMedicalReviewView.VisitTaskNum) };
var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(TaskMedicalReviewView.Id) : inQuery.SortField, inQuery.Asc);
return pageList;
}
@@ -104,25 +85,22 @@ namespace IRaCIS.Core.Application.Service
var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId)
.Where(t => t.IsAnalysisCreate == false && (t.TaskState == TaskState.Effect||t.TaskState==TaskState.Freeze) && t.ReadingTaskState == ReadingTaskState.HaveSigned)
.WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.SiteId != null, t => t.Subject.SiteId == inQuery.SiteId)
.WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId)
.WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent)
.WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId)
.WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory)
.WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState)
.WhereIf(inQuery.IsGeneratedJudge != null, t => t.JudgeVisitTaskId != null)
.WhereIf(inQuery.IsGlobalHaveUpdate != null, t => t.IsGlobalHaveUpdate == inQuery.IsGlobalHaveUpdate)
.WhereIf(inQuery.ArmEnum != null, t => t.ArmEnum == inQuery.ArmEnum)
.WhereIf(inQuery.IsGlobalHaveUpdate != null, t => t.IsGlobalHaveUpdate == inQuery.IsGlobalHaveUpdate)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName))
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.Subject.Code.Contains(inQuery.SubjectCode))
.WhereIf(inQuery.BeginSignTime != null, t => t.SignTime > inQuery.BeginSignTime)
.WhereIf(inQuery.EndSignTime != null, t => t.SignTime < inQuery.EndSignTime)
.ProjectTo<GenerateMedicalReviewTaskView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(GenerateMedicalReviewTaskView.IsUrgent) + " desc", nameof(GenerateMedicalReviewTaskView.SubjectId) };
var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.IsUrgent) + " desc", nameof(TaskMedicalReviewView.SubjectId) };
var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
@@ -158,53 +136,45 @@ namespace IRaCIS.Core.Application.Service
[HttpPost]
public async Task<TaskMedicalReviewView> GetNextMedicalReviewTask(GetNextMedicalReviewTaskInDto inDto)
{
var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.MedicalReviewId).Include(x => x.VisitTask).FirstNotNullAsync();
var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.MedicalReviewId).Include(x=>x.VisitTask).FirstNotNullAsync();
var subjectReview = (await GetMIMMedicalReviewTaskList(new TaskMedicalReviewQuery()
{
TrialId = medicalReview.TrialId,
IsGetBeRead = true,
Id=inDto.MedicalReviewId,
SubjectId= medicalReview.VisitTask.SubjectId,
TrialReadingCriterionId = medicalReview.VisitTask.TrialReadingCriterionId,
PageIndex=1,
PageSize=1,
})).Data;
if (subjectReview.CurrentPageData.Count == 1)
{
return subjectReview.CurrentPageData[0];
}
var data = (await GetMIMMedicalReviewTaskList(new TaskMedicalReviewQuery()
{
TrialId = medicalReview.TrialId,
IsGetBeRead = true,
Id = inDto.MedicalReviewId,
TrialReadingCriterionId = medicalReview.VisitTask.TrialReadingCriterionId,
IsGetNextMedicalReviewTask = true,
PageIndex = 1,
PageSize = 99999,
PageSize = 1,
})).Data;
if (data.CurrentPageData.Count > 0)
if (data.CurrentPageData.Count == 1)
{
var index = data.CurrentPageData.ToList().FindIndex(x => x.Id == inDto.MedicalReviewId);
var result = new TaskMedicalReviewView() { };
if (index+1 == data.CurrentPageData.Count()) // 最后一个
{
throw new BusinessValidationFailedException(_localizer["MedicalReview_Finish"]);
}
else if (index == -1 || data.CurrentPageData.Count == 1) // 第一个或者只有一个
{
if (data.CurrentPageData[0].Id == inDto.MedicalReviewId)
{
throw new BusinessValidationFailedException(_localizer["MedicalReview_Finish"]);
}
result = data.CurrentPageData[0];
}
else
{
result = data.CurrentPageData.Skip(index + 1).Take(1).First();
}
return result;
return data.CurrentPageData[0];
}
else
{
throw new BusinessValidationFailedException(_localizer["MedicalReview_Finish"]);
}
throw new BusinessValidationFailedException(_localizer["MedicalReview_Finish"]);
}
}
@@ -220,47 +190,21 @@ namespace IRaCIS.Core.Application.Service
{
var taskMedicalReviewQueryable = _taskMedicalReviewRepository.Where(t => t.VisitTask.TrialId == inQuery.TrialId && t.MedicalManagerUserId == _userInfo.Id&&t.VisitTask.TrialReadingCriterionId==inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.IsGetNextMedicalReviewTask,
x=>(
!x.IsInvalid&& x.AuditState== MedicalReviewAuditState.Auditing &
( x.ReadingMedicalReviewDialogList.Count()!=0&&
x.ReadingMedicalReviewDialogList.Count()>0&&
x.ReadingMedicalReviewDialogList.OrderByDescending(x=>x.CreateTime).FirstOrDefault().UserTypeEnumInt==(int)UserTypeEnum.IndependentReviewer)
) // 审核中最新回复为IR的
|| (!x.IsInvalid&& x.AuditState==MedicalReviewAuditState.WaitAudit)
||x.Id == inQuery.Id // 这里必须找传入id 因为要找到这条的索引 获取下一条
)
.WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId)
.WhereIf(inQuery.TrialSiteId != null, t => t.VisitTask.Subject.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId)
.WhereIf(inQuery.SiteId != null, t => t.VisitTask.Subject.SiteId == inQuery.SiteId)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode))
.WhereIf(inQuery.Id != null, t => t.Id != inQuery.Id)
.WhereIf(inQuery.IsUrgent != null, t => t.VisitTask.IsUrgent == inQuery.IsUrgent)
.WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState)
.WhereIf(inQuery.DoctorUserIdeaEnum != null, t => t.DoctorUserIdeaEnum == inQuery.DoctorUserIdeaEnum)
.WhereIf(inQuery.TaskState != null, t => t.VisitTask.TaskState == inQuery.TaskState)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode) || t.VisitTask.Subject.MedicalNo.Contains(inQuery.SubjectCode))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName))
.WhereIf(inQuery.TaskState != null, t => t.VisitTask.TaskState == inQuery.TaskState)
.WhereIf(inQuery.DoctorUserId != null, t => t.VisitTask.DoctorUserId == inQuery.DoctorUserId)
.WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory)
.WhereIf(inQuery.ReadingTaskState != null, t => t.VisitTask.ReadingTaskState == inQuery.ReadingTaskState)
.WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid)
.WhereIf(inQuery.IsGetBeRead,x=>!x.IsInvalid&&x.AuditState!= MedicalReviewAuditState.HaveSigned)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.BeginAuditSignTime != null, t => t.AuditSignTime >= inQuery.BeginAuditSignTime)
.WhereIf(inQuery.EndAuditSignTime != null, t => t.AuditSignTime <= inQuery.EndAuditSignTime)
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime >= inQuery.BeginAllocateDate)
.WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime <= inQuery.EndAllocateDate)
.WhereIf(inQuery.ArmEnum != null, t => t.VisitTask.ArmEnum == inQuery.ArmEnum)
.WhereIf(inQuery.MedicalManagerUserId != null, t => t.MedicalManagerUserId == inQuery.MedicalManagerUserId)
.WhereIf(inQuery.BeginSignTime != null, t => t.VisitTask.SignTime > inQuery.BeginSignTime)
.WhereIf(inQuery.EndSignTime != null, t => t.VisitTask.SignTime < inQuery.EndSignTime)
.WhereIf(inQuery.AuditAdviceEnum != null, t => t.AuditAdviceEnum == inQuery.AuditAdviceEnum)
.WhereIf(inQuery.IsHaveQuestion != null, t => t.IsHaveQuestion == inQuery.IsHaveQuestion)
.ProjectTo<TaskMedicalReviewView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.AuditState), nameof(TaskMedicalReviewView.SubjectId), nameof(TaskMedicalReviewView.ArmEnum), nameof(TaskMedicalReviewView.VisitTaskNum) };
var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray);
var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(TaskMedicalReviewView.Id) : inQuery.SortField, inQuery.Asc);
return ResponseOutput.Ok(pageList, new
{
@@ -351,7 +295,7 @@ namespace IRaCIS.Core.Application.Service
[HttpGet("{trialId:guid}")]
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 = _trialUserRepository.Where(t => t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MIM && t.TrialId == trialId).Select(t => t.User).ProjectTo<UserSimpleInfo>(_mapper.ConfigurationProvider);
return await query.ToListAsync();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -18,93 +18,31 @@ namespace IRaCIS.Core.Application.Service
CreateMap<ConvertedRowInfo, ReadingTableAnswerRowInfo>();
CreateMap<TaskAllocationRule, TaskAllocationRuleView>()
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName));
List<Guid> subjectIdList = new List<Guid>();
bool isJudgeDoctor = false;
CreateMap<TaskAllocationRule, DoctorVisitTaskStatView>()
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
.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.TotalTaskCount, t => t.MapFrom(u => u.Trial.VisitTaskList.Count()))
.ForMember(o => o.SelfUndoTaskCount, t => t.MapFrom(u => u.Trial.VisitTaskList.Count(t => t.DoctorUserId == u.DoctorUserId && t.ReadingTaskState != ReadingTaskState.HaveSigned)))
.ForMember(o => o.TotalSubjectCount, t => t.MapFrom(u => u.Trial.SubjectList.Count()))
.ForMember(o => o.SelfApplyedTaskCount, t => t.MapFrom(u => u.Trial.VisitTaskList.Count(t => t.DoctorUserId == u.DoctorUserId)))
.ForMember(o => o.ApplyedTotalTaskCount, t => t.MapFrom(u => u.Trial.VisitTaskList.Count(t => t.DoctorUserId != null)))
//.ForMember(o => o.SelfApplyedSubjectCount, t => t.MapFrom(u => u.Trial.SubjectDoctorUserList.Where(t => t.DoctorUserId == u.DoctorUserId && t.SubjectArmVisitTaskList.Any(c => c.DoctorUserId != null)).Count()))
.ForMember(o => o.SelfSubjectCount, t => t.MapFrom(u => u.Trial.SubjectDoctorUserList.Where(t => t.DoctorUserId == u.DoctorUserId).Count()))
.ForMember(o => o.ApplyedTotalSubjectCount, t => t.MapFrom(u => u.Trial.SubjectList.Count(c => c.SubjectVisitTaskList.Any(d => d.DoctorUserId != null))))
//该医生未应用Subject 数量
//.ForMember(o => o.WaitApplySelfSubjectCount, t => t.MapFrom(u =>
// subjectIdList.Count == 0 ? u.Trial.SubjectDoctorUserList.Where(t => t.DoctorUserId == u.DoctorUserId && t.SubjectArmVisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Any(c => c.DoctorUserId == null)).Count()
// : u.Trial.SubjectDoctorUserList.Where(t => t.DoctorUserId == u.DoctorUserId && subjectIdList.Contains(t.SubjectId) && t.SubjectArmVisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Any(c => c.DoctorUserId == null)).Count()
// ))
.ForMember(o => o.WaitApplyTotalSubjectCount, t => t.MapFrom(u =>
subjectIdList.Count == 0 ? u.Trial.SubjectList.Where(t => t.SubjectVisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Any(c => c.DoctorUserId == null)).Count()
: u.Trial.SubjectList.Where(t => subjectIdList.Contains(t.Id) && t.SubjectVisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Any(c => c.DoctorUserId == null)).Count()
))
//.ForMember(o => o.WaitApplySelfTaskCount, t => t.MapFrom(u =>
//subjectIdList.Count == 0 ? u.Trial.SubjectDoctorUserList.Where(d => d.DoctorUserId == u.DoctorUserId).SelectMany(t => t.SubjectArmVisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.DoctorUserId == null)).Count()
//: u.Trial.SubjectDoctorUserList.Where(d => d.DoctorUserId == u.DoctorUserId && subjectIdList.Contains(d.SubjectId)).SelectMany(t => t.SubjectArmVisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.DoctorUserId == null)).Count()
// ))
.ForMember(o => o.WaitApplyTotalTaskCount, t => t.MapFrom(u =>
subjectIdList.Count == 0 ? u.Trial.VisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.DoctorUserId == null).Count()
: u.Trial.VisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.DoctorUserId == null && subjectIdList.Contains(t.SubjectId)).Count()))
;
var trialReadingCriterionId = Guid.Empty;
CreateMap<TaskAllocationRule, TaskAllocationRuleDTO>()
.ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.Enroll.DoctorUser))
.ForMember(o => o.CriterionReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Select(t => new TrialCriterionReadingCategory() { EnrollId = t.EnrollId, ReadingCategory = t.ReadingCategory, TrialReadingCriterionId = t.TrialReadingCriterionId })))
.ForMember(o => o.TrialReadingCriterionList, t => t.MapFrom(u => u.Trial.ReadingQuestionCriterionTrialList.Where(t => t.IsConfirm)))
.ForMember(o => o.ReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Where(t=>t.TrialReadingCriterionId== trialReadingCriterionId).OrderBy(t => t.ReadingCategory).Select(t => t.ReadingCategory).ToList()))
;
CreateMap<ReadingQuestionCriterionTrial, TrialReadingCriterionDto>()
.ForMember(t => t.TrialReadingCriterionId, u => u.MapFrom(c => c.Id))
.ForMember(t => t.TrialReadingCriterionName, u => u.MapFrom(c => c.CriterionName));
CreateMap<TaskAllocationRule, AssignDoctorStatView>().IncludeBase<TaskAllocationRule, TaskAllocationRuleDTO>()
.ForMember(o => o.AssignedSubjectCount, t => t.MapFrom(u => u.DoctorUser.VisitTaskList.Where(t => t.TrialId == u.TrialId).Select(t => t.SubjectId).Distinct().Count()))
.ForMember(o => o.WaitDealTrialTaskCount, t => t.MapFrom(u => u.DoctorUser.VisitTaskList.Where(t => t.TrialId == u.TrialId).Where(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect).Count()))
.ForMember(o => o.WaitDealAllTaskCount, t => t.MapFrom(u => u.DoctorUser.VisitTaskList.Where(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect).Count()));
CreateMap<Subject, SubjectAssignStat>()
.ForMember(o => o.SubjectId, t => t.MapFrom(u => u.Id))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.Code))
.ForMember(o => o.VisitTaskTypeCount, t => t.MapFrom(u => u.SubjectVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Visit && t.TrialReadingCriterionId==trialReadingCriterionId && t.TaskState==TaskState.Effect).Select(t => t.VisitTaskNum).Distinct().Count()))
.ForMember(o => o.VisitTaskTypeCount, t => t.MapFrom(u => u.SubjectVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Visit && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect).Select(t => t.VisitTaskNum).Distinct().Count()))
.ForMember(o => o.GlobalTaskTypeCount, t => t.MapFrom(u => u.SubjectVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Global && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect).Select(t => t.VisitTaskNum).Distinct().Count()))
.ForMember(o => o.OncologyTaskTypeCount, t => t.MapFrom(u => u.SubjectVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Oncology && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect).Select(t => t.VisitTaskNum).Distinct().Count()))
.ForMember(o => o.JudgeTaskTypeCount, t => t.MapFrom(u => u.SubjectVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect).Select(t => t.VisitTaskNum).Distinct().Count()))
.ForMember(o => o.DoctorUserList, t => t.MapFrom(u => u.SubjectDoctorList.Where(t=>t.TrialReadingCriterionId== trialReadingCriterionId)));
CreateMap<SubjectUser, SubjectUserView>()
.ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.DoctorUser));
.ForMember(o => o.JudgeTaskTypeCount, t => t.MapFrom(u => u.SubjectVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect).Select(t => t.VisitTaskNum).Distinct().Count()));
CreateMap<SubjectUser, SubjectUserDTO>().IncludeBase<SubjectUser, SubjectUserView>()
.ForMember(o => o.IsHaveReading, t => t.MapFrom(u => u.Subject.SubjectVisitTaskList.Any(t => t.ReadingTaskState != ReadingTaskState.WaitReading && t.TrialReadingCriterionId==u.TrialReadingCriterionId && t.DoctorUserId==u.DoctorUserId)));
CreateMap<SubjectVisitClinicalDialog, ClinicalDataDialog>();
CreateMap<SubjectVisit, VisitGenerataTaskDTO>();
@@ -124,20 +62,19 @@ namespace IRaCIS.Core.Application.Service
CreateMap<VisitTask, VisitTaskView>().IncludeBase<VisitTask, VisitTaskViewBasic>()
.ForMember(o => o.TrialSiteId, t => t.MapFrom(u => u.Subject.TrialSiteId))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindTrialSiteCode :*/ u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.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.SiteId, t => t.MapFrom(u => u.Subject.SiteId))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code))
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
.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.IsBaseline, t => t.MapFrom(u => u.SourceSubjectVisit.IsBaseLine))
.ForMember(o => o.IsEnrollmentConfirm, t => t.MapFrom(u => u.SourceSubjectVisit.IsEnrollmentConfirm))
.ForMember(o => o.PDState, t => t.MapFrom(u => u.SourceSubjectVisit.PDState)) ;
var isEn_Us = true;
CreateMap<VisitTask, JudgeVisitTaskView>().IncludeBase<VisitTask, VisitTaskView>()
@@ -145,17 +82,19 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.HistoryReadingDoctorUserList, t => t.MapFrom(u => u.JudgeVisitList));
CreateMap<VisitTask, ReadingTaskView>().IncludeBase<VisitTask, VisitTaskView>()
.ForMember(t=>t.PIReadingResultList,u=>u.MapFrom(c=>c.ReadingTaskQuestionAnswerList
.Where(t=>t.ReadingQuestionTrial.IsJudgeQuestion==true ).Select(d=>new PIReadingResult() { QuestionId= d.ReadingQuestionTrialId,Answer=d.Answer})));
;
CreateMap<VisitTask, PIReaingTaskView>().IncludeBase<VisitTask, ReadingTaskView>()
.ForMember(o => o.FirstAuditUserName, t => t.MapFrom(u => u.FirstAuditUser.UserName))
.ForMember(o => o.LatestReplyUserName, t => t.MapFrom(u => u.LatestReplyUser.UserName));
CreateMap<VisitTask, AnalysisTaskView>().IncludeBase<VisitTask, VisitTaskView>()
.ForMember(o => o.IsReReadingOrBackInfluenceAnalysis, t => t.MapFrom(u => u.Subject.IsReReadingOrBackInfluenceAnalysis));
CreateMap<CancelDoctorCommand, SubjectCanceDoctor>();
CreateMap<SubjectCanceDoctor, SubjectCancelDoctorView>();
@@ -169,9 +108,11 @@ namespace IRaCIS.Core.Application.Service
CreateMap<VisitTask, IRHaveReadView>().IncludeBase<VisitTask, VisitTaskViewBasic>()
.ForMember(o => o.TrialSiteId, t => t.MapFrom(u => u.Subject.TrialSiteId))
.ForMember(o => o.SiteId, t => t.MapFrom(u => u.Subject.SiteId))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code));
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName));
@@ -188,22 +129,17 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.SubjectId, t => t.MapFrom(u => u.Id))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.Code))
.ForMember(o => o.IsJudge, t => t.MapFrom(u => isJudgeDoctor))
.ForMember(o => o.IsAssignedDoctorUser, t => t.MapFrom(u => u.SubjectDoctorList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Any()))
.ForMember(o => o.IsJudge, t => t.MapFrom(u => isJudgeDoctor));
.ForMember(o => o.TotalDoctorUserList, t => t.MapFrom(u => u.SubjectDoctorList.Where(t => isJudgeDoctor ? true : t.ArmEnum != Arm.JudgeArm).OrderBy(t => t.ArmEnum)));
CreateMap<SubjectUser, AssignDoctorView>()
//.ForMember(o => o.AssignTime, t => t.MapFrom(u => u.AssignTime))
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName));
CreateMap<TaskAllocationRuleAddOrEdit, TaskAllocationRule>();
CreateMap<User, TrialDoctorUserSelectView>()
@@ -225,19 +161,17 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.Id, t => t.MapFrom(u => u.Id))
.ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.VisitTask.Subject.MedicalNo))
.ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.VisitTask.DoctorUser))
.ForMember(o => o.MedicalManagerUser, t => t.MapFrom(u => u.MedicalManagerUser))
.ForMember(o => o.AllocateTime, t => t.MapFrom(u => u.AllocateTime))
;
.ForMember(o => o.MedicalManagerUser, t => t.MapFrom(u => u.MedicalManagerUser));
CreateMap<VisitTask, TaskMedicalReviewView>()
.ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u =>/* u.IsAnalysisCreate == true ? u.BlindTrialSiteCode :*/ u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindSubjectCode :*/ u.Subject.Code));
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code));
CreateMap<VisitTask, GenerateMedicalReviewTaskView>()
.ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindTrialSiteCode :*/ u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindSubjectCode :*/ u.Subject.Code))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code))
.ForMember(o => o.GeneratedMedicalReviewCount, t => t.MapFrom(u => u.TaskMedicalReviewList.Count()))
.ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.Subject.MedicalNo))
.ForMember(o => o.IsGeneratedJudge, t => t.MapFrom(u => u.JudgeVisitTaskId != null))
@@ -261,27 +195,27 @@ namespace IRaCIS.Core.Application.Service
//CreateMap<TaskMedicalReviewRule, TaskMedicalReviewRuleView>()
// .ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.DoctorUser))
// .ForMember(o => o.ActualVisitTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect
// && t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
CreateMap<TaskMedicalReviewRule, TaskMedicalReviewRuleView>()
.ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.DoctorUser))
.ForMember(o => o.ActualVisitTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect
&& t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
// .ForMember(o => o.ActualJudgeTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect &&
// t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.ActualJudgeTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect &&
t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
// .ForMember(o => o.ActualGlobalTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Global && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect &&
// t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.ActualGlobalTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Global && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect &&
t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
// .ForMember(o => o.ActualTumorTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Oncology && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect &&
// t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.ActualTumorTaskList, t => t.MapFrom(u => u.DoctorTrialVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Oncology && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect &&
t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.Id, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
// .ForMember(o => o.GeneratedGlobalTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Global && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.GeneratedGlobalTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Global && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
// .ForMember(o => o.GeneratedJudgeTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Judge && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.GeneratedJudgeTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Judge && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
// .ForMember(o => o.GeneratedTumorTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Oncology && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
.ForMember(o => o.GeneratedTumorTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Oncology && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })))
// .ForMember(o => o.GeneratedVisitTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Visit && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })));
.ForMember(o => o.GeneratedVisitTaskList, t => t.MapFrom(u => u.TaskMedicalReviewList.Where(t => t.VisitTask.ReadingCategory == ReadingCategory.Visit && t.VisitTask.IsAnalysisCreate == false && t.VisitTask.TaskState == TaskState.Effect && t.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned).OrderBy(t => t.VisitTask.SignTime).Select(t => new TaskBasicIdView() { TaskId = t.VisitTaskId, TrialId = t.TrialId, DoctorUserId = t.DoctorUserId })));
CreateMap<TaskMedicalReviewRuleAddOrEdit, TaskMedicalReviewRule>();
@@ -293,11 +227,6 @@ namespace IRaCIS.Core.Application.Service
//CreateMap<TaskConsistentRule, TaskConsistentRuleView>()
// .ForMember(o => o.GeneratedSubjectCount, t => t.MapFrom(u => u.DoctorVisitTaskList.Where(t => t.IsAnalysisCreate && t.TaskConsistentRuleId == u.Id).Select(t => t.SubjectId).Distinct().Count())) ;
CreateMap<TaskConsistentRule, TaskConsistentRuleBasic>();
CreateMap<TaskConsistentRuleAddOrEdit, TaskConsistentRule>();
CreateMap<TaskConsistentRuleBatchAddOrEdit, TaskConsistentRule>().ForMember(t => t.Id, u => u.Ignore()).ReverseMap();
CreateMap<VisitTask, VisitTaskSimpleView>()
@@ -317,8 +246,15 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.Id, t => t.MapFrom(u => u.InfluenceTask.Id));
CreateMap<PIAuditTaskCommand, PIAudit>();
CreateMap<PIAudit, PIAuditDialogListView>()
.ForMember(o => o.CreateUserName, t => t.MapFrom(u => u.CreateUser.UserName))
.ForMember(o => o.UserTypeEnum, t => t.MapFrom(u => u.CreateUser.UserTypeEnum))
//.ForMember(o => o.PIAuditState, t => t.MapFrom(u => u.VisitTask.PIAuditState))
;
}
}
@@ -35,7 +35,7 @@ namespace IRaCIS.Core.Application.ViewModel
{
public CriterionType? CriterionTypeEnum { get; set; }
public CommonDocumentFileType? FileTypeEnum { get; set; }
public EmailBusinessScenario? BusinessScenarioEnum { get; set; }
public CommonDocumentBusinessScenario? BusinessScenarioEnum { get; set; }
public string Name { get; set; } = String.Empty;
@@ -55,7 +55,7 @@ namespace IRaCIS.Core.Application.ViewModel
public CriterionType? CriterionTypeEnum { get; set; }
public CommonDocumentFileType FileTypeEnum { get; set; }
public EmailBusinessScenario BusinessScenarioEnum { get; set; }
public CommonDocumentBusinessScenario BusinessScenarioEnum { get; set; }
//public Guid FileTypeId { get; set; }
@@ -91,9 +91,7 @@ namespace IRaCIS.Application.Contracts
public class GetBasicDataAllSelectInDto
{
public Guid? TrialReadingCriterionId { get; set; }
public Guid? SystemReadingCriterionId { get; set; }
}
}
public class GetTrialCriterionDictionaryListInDto
@@ -8,7 +8,7 @@ using IRaCIS.Core.Domain.Share;
using Newtonsoft.Json;
namespace IRaCIS.Core.Application.Contracts
{
public class TrialSelectEmailNoticeConfigView : EmailNoticeConfigView
public class TrialSelectEmailNoticeConfigView: EmailNoticeConfigView
{
public bool IsHaveSelected { get; set; }
}
@@ -48,11 +48,11 @@ namespace IRaCIS.Core.Application.Contracts
}
///<summary>EmailNoticeConfigQuery 列表查询参数模型</summary>
public class EmailNoticeConfigQuery : PageInput
public class EmailNoticeConfigQuery:PageInput
{
//public Guid? ScenarioId { get; set; }
public EmailBusinessScenario? BusinessScenarioEnum { get; set; }
public CommonDocumentBusinessScenario? BusinessScenarioEnum { get; set; }
public bool? IsReturnRequired { get; set; }
public bool? IsEnable { get; set; }
@@ -71,7 +71,7 @@ namespace IRaCIS.Core.Application.Contracts
public Guid? Id { get; set; }
public string Code { get; set; } = String.Empty;
public EmailBusinessScenario BusinessScenarioEnum { get; set; }
public CommonDocumentBusinessScenario BusinessScenarioEnum { get; set; }
/// <summary>
/// 是否区分标准
@@ -16,25 +16,22 @@ namespace IRaCIS.Application.Services
public class DictionaryService : BaseService, IDictionaryService
{
private readonly IRepository<Dictionary> _dicRepository;
private readonly IRepository<DoctorDictionary> _doctorDictionaryRepository;
private readonly IRepository<TrialDictionary> _trialDictionaryRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<SystemCriterionDictionaryCode> _systemCriterionDictionaryCodeRepository;
private readonly IRepository<TrialCriterionDictionaryCode> _trialCriterionDictionaryCodeRepository;
private readonly IRepository<ReadingTrialCriterionDictionary> _readingTrialCriterionDictionaryRepository;
private readonly IRepository<ReadingSystemCriterionDictionary> _readingSystemCriterionDictionaryRepository;
private readonly IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository;
private readonly IRepository<ReadingQuestionCriterionSystem> _readingQuestionCriterionSystem;
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrial;
public DictionaryService(IRepository<Dictionary> sysDicRepository, IRepository<DoctorDictionary> doctorDictionaryRepository, IRepository<TrialDictionary> trialDictionaryRepository,
IRepository<Doctor> doctorRepository, IRepository<Trial> trialRepository,
public DictionaryService(IRepository<Dictionary> sysDicRepository, IRepository<TrialDictionary> trialDictionaryRepository,
IRepository<Trial> trialRepository,
IRepository<SystemCriterionDictionaryCode> systemCriterionDictionaryCodeRepository,
IRepository<TrialCriterionDictionaryCode> trialCriterionDictionaryCodeRepository,
IRepository<ReadingTrialCriterionDictionary> readingTrialCriterionDictionaryRepository,
IRepository<ReadingSystemCriterionDictionary> readingSystemCriterionDictionaryRepository,
IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository,
IRepository<ReadingQuestionCriterionSystem> readingQuestionCriterionSystem,
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrial
@@ -43,14 +40,13 @@ namespace IRaCIS.Application.Services
)
{
_dicRepository = sysDicRepository;
_doctorDictionaryRepository = doctorDictionaryRepository;
_trialDictionaryRepository = trialDictionaryRepository;
_doctorRepository = doctorRepository;
_trialRepository = trialRepository;
this._systemCriterionDictionaryCodeRepository = systemCriterionDictionaryCodeRepository;
this._trialCriterionDictionaryCodeRepository = trialCriterionDictionaryCodeRepository;
this._readingTrialCriterionDictionaryRepository = readingTrialCriterionDictionaryRepository;
this._readingSystemCriterionDictionaryRepository = readingSystemCriterionDictionaryRepository;
this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository;
this._readingQuestionCriterionSystem = readingQuestionCriterionSystem;
this._readingQuestionCriterionTrial = readingQuestionCriterionTrial;
@@ -87,18 +83,6 @@ namespace IRaCIS.Application.Services
return ResponseOutput.Ok(entity.Id.ToString());
}
/// <summary>
/// 获取所有字典的Key
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<List<string>> GetAllDictionaryKey()
{
var result =await _dicRepository.Where(t => t.ParentId == null).OrderBy(x=>x.Code).Select(x => x.Code).ToListAsync();
return result;
}
/// <summary>
/// 添加字典 的同时 一起添加子项 --New
@@ -240,14 +224,6 @@ namespace IRaCIS.Application.Services
return ResponseOutput.NotOk(_localizer["Dictionary_SubitemDeletion"]);
}
if ((await _doctorDictionaryRepository.AnyAsync(t => t.DictionaryId == id)) ||
(await _doctorRepository.AnyAsync(t => t.SpecialityId == id || t.PositionId == id || t.DepartmentId == id || t.RankId == id))
)
{
//---当前条目已经在阅片人的简历中被引用。
return ResponseOutput.NotOk(_localizer["Dictionary_ResumeReference"]);
}
if (await _trialDictionaryRepository.AnyAsync(t => t.DictionaryId == id) ||
await _trialRepository.AnyAsync(t => t.ReviewModeId == id))
@@ -476,11 +452,11 @@ namespace IRaCIS.Application.Services
var result = searchList.GroupBy(t => t.ParentCode).ToDictionary(g => g.Key, g => g.OrderBy(t => t.ShowOrder).ToList());
if (inDto.TrialReadingCriterionId == null && inDto.SystemReadingCriterionId == null)
if (inDto.TrialReadingCriterionId == null)
{
return result;
}
else if (inDto.TrialReadingCriterionId != null)
else
{
var trialCriterionType = await _readingQuestionCriterionTrial.Where(x => x.Id == inDto.TrialReadingCriterionId).Select(x => x.CriterionType).FirstOrDefaultAsync();
if (trialCriterionType == CriterionType.SelfDefine)
@@ -534,52 +510,8 @@ namespace IRaCIS.Application.Services
return result;
}
else
{
List<string> selectCode = await _systemCriterionDictionaryCodeRepository.Where(x => x.SystemCriterionId == inDto.SystemReadingCriterionId).Select(x => x.Code).ToListAsync();
var criterionCode = await _dicRepository.Where(x => x.ConfigDictionary.Code == "Reading_eCRF_Criterion").Select(x => x.Code).ToListAsync();
foreach (var item in criterionCode)
{
if (result.ContainsKey(item))
{
result[item] = new List<BasicDicSelect>();
}
}
var criterionDictionList = await _readingSystemCriterionDictionaryRepository.Where(x => x.CriterionId == inDto.SystemReadingCriterionId).Select(x => new BasicDicSelect()
{
ChildGroup = x.Dictionary.ChildGroup,
Code = x.Dictionary.Code,
Description = x.Dictionary.Description,
DataTypeEnum = x.Dictionary.DataTypeEnum,
ParentChildCodeEnum = x.Dictionary.Parent.ChildCodeEnum,
ShowOrder = x.Dictionary.ShowOrder,
ParentCode = x.ParentCode,
Id = x.DictionaryId,
CrterionDictionaryGroup = x.CrterionDictionaryGroup,
ParentId = x.Dictionary.ParentId,
Value = x.Dictionary.Value,
ValueCN = x.Dictionary.ValueCN
}).ToListAsync();
criterionDictionList = criterionDictionList.Where(x => selectCode.Contains(x.ParentCode)).ToList();
var criterionDic = criterionDictionList.GroupBy(x => x.ParentCode).ToDictionary(g => g.Key, g => g.OrderBy(t => t.ShowOrder).ToList());
foreach (var item in criterionDic)
{
result[item.Key] = item.Value;
}
return result;
}
}
#region
@@ -73,7 +73,7 @@ namespace IRaCIS.Core.Application.Contracts
foreach (var item in addOrEditEmailNoticeConfig.ToUserTypeList)
{
await _emailNoticeUserTypeRepository.AddAsync(new EmailNoticeUserType() { EmailUserType = EmailUserType.To, UserType = item, EmailNoticeConfigId = (Guid)emailNoticeConfigId });
await _emailNoticeUserTypeRepository.AddAsync(new EmailNoticeUserType() { EmailUserType = EmailUserType.To, UserType = item,EmailNoticeConfigId= (Guid)emailNoticeConfigId });
}
@@ -3,7 +3,6 @@ using DocumentFormat.OpenXml.Presentation;
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Service.Reading.Dto;
@@ -60,7 +59,7 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
var list = await _trialUseRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters()
exportInfo.List = await _trialUseRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters()
.WhereIf(param.UserTypeId != null, t => t.User.UserTypeId == param.UserTypeId)
.WhereIf(!string.IsNullOrWhiteSpace(param.UserName), t => t.User.UserName.Contains(param.UserName))
@@ -71,10 +70,8 @@ namespace IRaCIS.Core.Application.Service.Common
t => (t.User.FullName).Contains(param.UserRealName))
.ProjectTo<TrialMaintenanceDTO>(_mapper.ConfigurationProvider).ToListAsync();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialUserList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialMaintenanceDTO));
@@ -93,7 +90,7 @@ namespace IRaCIS.Core.Application.Service.Common
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> TrialSiteUserListExport(SiteCRCExportQueryDTO param,
[FromServices] IRepository<CommonDocument> _commonDocumentRepository,
[FromServices] IRepository<CommonDocument> _commonDocumentRepository,
[FromServices] IDictionaryService _dictionaryService,
[FromServices] IRepository<Trial> _trialRepository,
[FromServices] IRepository<TrialSiteUser> _trialSiteUserRepository
@@ -103,26 +100,21 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
var list = await _trialSiteUserRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters()
.WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted)
.WhereIf(!string.IsNullOrWhiteSpace(param.SiteName), t => t.TrialSite.TrialSiteName.Contains(param.SiteName) || t.TrialSite.TrialSiteAliasName.Contains(param.SiteName))
.WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteAliasName),
t => t.TrialSite.TrialSiteAliasName.Contains(param.TrialSiteAliasName))
.WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteCode),
t => t.TrialSite.TrialSiteCode.Contains(param.TrialSiteCode))
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator,
t => t.UserId == _userInfo.Id)
.WhereIf(!string.IsNullOrWhiteSpace(param.UserKeyInfo), t => (t.User.FullName).Contains(param.UserKeyInfo)
|| t.User.UserName.Contains(param.UserKeyInfo) || t.User.EMail.Contains(param.UserKeyInfo))
exportInfo.List = await _trialSiteUserRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters()
.WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted)
.WhereIf(!string.IsNullOrWhiteSpace(param.SiteName), t => t.Site.SiteName.Contains(param.SiteName))
.WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteAliasName),
t => t.TrialSite.TrialSiteAliasName.Contains(param.TrialSiteAliasName))
.WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteCode),
t => t.TrialSite.TrialSiteCode.Contains(param.TrialSiteCode))
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator,
t => t.UserId == _userInfo.Id)
.WhereIf(!string.IsNullOrWhiteSpace(param.UserKeyInfo), t => (t.User.FullName).Contains(param.UserKeyInfo)
|| t.User.UserName.Contains(param.UserKeyInfo) || t.User.EMail.Contains(param.UserKeyInfo))
.ProjectTo<SiteUserExportDTO>(_mapper.ConfigurationProvider).ToListAsync();
.ProjectTo<SiteUserExportDTO>(_mapper.ConfigurationProvider).ToListAsync();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteUserList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SiteUserExportDTO));
}
@@ -153,9 +145,9 @@ namespace IRaCIS.Core.Application.Service.Common
var groupSelectIdQuery =
_trialSiteSurveyRepository.Where(t => t.TrialId == queryParam.TrialId)
.WhereIf(queryParam.TrialSiteId != null, t => t.TrialSiteId == queryParam.TrialSiteId)
.WhereIf(queryParam.SiteId != null, t => t.SiteId == queryParam.SiteId)
.WhereIf(!string.IsNullOrEmpty(queryParam.FormWriterKeyInfo), t => (t.UserName).Contains(queryParam.FormWriterKeyInfo) || t.Email.Contains(queryParam.FormWriterKeyInfo) || t.Phone.Contains(queryParam.FormWriterKeyInfo))
.GroupBy(t => t.TrialSiteId)
.GroupBy(t => t.SiteId)
.Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First());
@@ -164,19 +156,17 @@ namespace IRaCIS.Core.Application.Service.Common
.WhereIf(queryParam.UserTypeId != null, t => t.UserTypeId == queryParam.UserTypeId)
.WhereIf(queryParam.IsGenerateAccount != null, t => t.IsGenerateAccount == queryParam.IsGenerateAccount)
.WhereIf(queryParam.State != null && queryParam.State != TrialSiteUserStateEnum.OverTime, t => t.InviteState == queryParam.State)
//.WhereIf(queryParam.State != null && queryParam.State == TrialSiteUserStateEnum.OverTime, t => t.InviteState == TrialSiteUserStateEnum.HasSend && t.ExpireTime < DateTime.Now)
.WhereIf(!string.IsNullOrEmpty(queryParam.UserName), t => (t.LastName + " / " + t.FirstName).Contains(queryParam.UserName))
.WhereIf(!string.IsNullOrEmpty(queryParam.OrganizationName), t => t.OrganizationName.Contains(queryParam.OrganizationName))
.ProjectTo<TrialSiteUserSummaryDto>(_mapper.ConfigurationProvider);
var list = await query.ToListAsync();
data.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
data.List = await query.ToListAsync();
var exportInfo = data;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteUserSummary_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialSiteUserSummaryDto));
}
@@ -222,7 +212,7 @@ namespace IRaCIS.Core.Application.Service.Common
var list = await _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId)
.Where(t => t.Subject.FinalSubjectVisitId != null ? t.VisitNum <= t.Subject.FinalSubjectVisit.VisitNum : true)
.WhereIf(visitSearchDTO.TrialSiteId != null, t => t.TrialSiteId == visitSearchDTO.TrialSiteId)
.WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId)
.WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId)
.WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => t.Subject.Code.Contains(visitSearchDTO.SubjectInfo))
@@ -239,9 +229,8 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == visitSearchDTO.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialCRCUploadImageList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CRCVisitExportDTO));
@@ -275,7 +264,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.WhereIf(challengeQuery.ChallengeState != null, t => t.SubjectVisit.ChallengeState == challengeQuery.ChallengeState)
.WhereIf(challengeQuery.ReuploadEnum != null, t => t.ReuploadEnum == challengeQuery.ReuploadEnum)
.WhereIf(challengeQuery.IsClosed != null, t => t.IsClosed == challengeQuery.IsClosed)
.WhereIf(challengeQuery.TrialSiteId != null, t => t.SubjectVisit.TrialSiteId == challengeQuery.TrialSiteId)
.WhereIf(challengeQuery.SiteId != null, t => t.SubjectVisit.SiteId == challengeQuery.SiteId)
.WhereIf(challengeQuery.SubjectId != null, t => t.SubjectVisit.SubjectId == challengeQuery.SubjectId)
.WhereIf(challengeQuery.CreateUserId != null, t => t.CreateUserId == challengeQuery.CreateUserId)
.WhereIf(!string.IsNullOrEmpty(challengeQuery.SubjectCode), t => t.SubjectVisit.Subject.Code.Contains(challengeQuery.SubjectCode))
@@ -290,9 +279,8 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == challengeQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialQCImageChanllengeList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCChanllengeExportDto));
}
@@ -318,7 +306,7 @@ namespace IRaCIS.Core.Application.Service.Common
.WhereIf(!string.IsNullOrWhiteSpace(param.Name), t => t.ShortName.Contains(param.Name))
.WhereIf(!string.IsNullOrWhiteSpace(param.Sex), t => t.Sex.Contains(param.Sex))
.WhereIf(param.Status != null, t => t.Status == param.Status)
.WhereIf(param.TrialSiteId != null, t => t.TrialSiteId == param.TrialSiteId)
.WhereIf(param.SiteId != null, t => t.SiteId == param.SiteId)
// CRC 只负责他管理site的受试者
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.ProjectTo<SubjectExportDTO>(_mapper.ConfigurationProvider).ToListAsync();
@@ -328,9 +316,8 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectExportDTO));
@@ -437,9 +424,8 @@ namespace IRaCIS.Core.Application.Service.Common
exportInfo.CriterionName = await _repository.Where<ReadingQuestionCriterionTrial>(u => u.TrialId == dto.TrialId && u.IsConfirm && u.Id == dto.TrialReadingCriterionId).Select(t => t.CriterionName).FirstOrDefaultAsync();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(StaticData.Export.TrialSubjectProgressList_Export, exportInfo, /*"", */_commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectProgressDto));
@@ -504,7 +490,7 @@ namespace IRaCIS.Core.Application.Service.Common
}
var memoryStream2 = new MemoryStream();
wb.Write(memoryStream2, true);
wb.Write(memoryStream2,true);
memoryStream2.Seek(0, SeekOrigin.Begin);
return new FileStreamResult(memoryStream2, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
@@ -532,16 +518,16 @@ namespace IRaCIS.Core.Application.Service.Common
var svExpression = QCCommon.GetStudyMonitorSubjectVisitFilter(studyQuery.VisitPlanArray);
var StudyMonitorQuery = _repository.Where<StudyMonitor>(t => t.TrialId == studyQuery.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.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression)
.WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo))
.WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId)
.WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId)
.WhereIf(studyQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == studyQuery.TrialSiteId)
.WhereIf(studyQuery.SiteId != null, t => t.SiteId == studyQuery.SiteId)
.Select(t => new UnionStudyMonitorExportDto()
{
TrialSiteCode = t.Subject.TrialSite.TrialSiteCode,
TrialSiteAliasName = t.Subject.TrialSite.TrialSiteAliasName,
TrialSiteCode = t.TrialSite.TrialSiteCode,
TrialSiteAliasName = t.TrialSite.TrialSiteAliasName,
SubjectCode = t.Subject.Code,
@@ -578,9 +564,8 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == studyQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialStudyUploadMonitor_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(UnionStudyMonitorExportDto));
@@ -615,9 +600,8 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectReadingPeriodList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReadPeriodExportDto));
@@ -642,7 +626,7 @@ namespace IRaCIS.Core.Application.Service.Common
var svExpression = QCCommon.GetDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray);
var dicomStudyQuery = _repository.Where<DicomStudy>(t => t.TrialId == studyQuery.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.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression)
.WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo))
.Where(x => x.SubjectVisit.AuditState == AuditStateEnum.QCPassed)
@@ -656,9 +640,9 @@ namespace IRaCIS.Core.Application.Service.Common
StudyCode = t.StudyCode,
StudyTime = t.StudyTime,
TrialSiteAliasName = t.Subject.TrialSite.TrialSiteAliasName,
TrialSiteAliasName = t.TrialSite.TrialSiteAliasName,
TrialSiteCode = t.Subject.TrialSite.TrialSiteCode,
TrialSiteCode = t.TrialSite.TrialSiteCode,
CheckState = t.SubjectVisit.CheckState,
//Uploader = t.Uploader.UserName,
@@ -670,7 +654,7 @@ namespace IRaCIS.Core.Application.Service.Common
var nodeDicomStudyQuery = _repository.Where<NoneDicomStudy>(t => t.TrialId == studyQuery.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.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression2)
.WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo))
.Where(x => x.SubjectVisit.AuditState == AuditStateEnum.QCPassed)
@@ -685,9 +669,9 @@ namespace IRaCIS.Core.Application.Service.Common
StudyCode = t.StudyCode,
StudyTime = t.ImageDate,
TrialSiteAliasName = t.Subject.TrialSite.TrialSiteAliasName,
TrialSiteAliasName = t.TrialSite.TrialSiteAliasName,
TrialSiteCode = t.Subject.TrialSite.TrialSiteCode,
TrialSiteCode = t.TrialSite.TrialSiteCode,
CheckState = t.SubjectVisit.CheckState,
@@ -705,9 +689,8 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == studyQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialStudyList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(UnionStudyExportDTO));
}
@@ -735,7 +718,7 @@ namespace IRaCIS.Core.Application.Service.Common
var list = await _subjectVisitRepository.Where(x => x.TrialId == checkQuery.TrialId)
.Where(x => x.AuditState == AuditStateEnum.QCPassed) //一致性核查中的,或者还没一致性核查的
.WhereIf(checkQuery.CheckState != null, t => t.CheckState == checkQuery.CheckState)
.WhereIf(checkQuery.TrialSiteId != null, t => t.TrialSiteId == checkQuery.TrialSiteId)
.WhereIf(checkQuery.SiteId != null, t => t.SiteId == checkQuery.SiteId)
.WhereIf(!string.IsNullOrEmpty(checkQuery.SubjectInfo), t => t.Subject.Code.Contains(checkQuery.SubjectInfo))
.WhereIf(checkQuery.VisitPlanArray != null && checkQuery.VisitPlanArray?.Length > 0, svExpression)
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))//CRC 过滤负责的site
@@ -745,9 +728,8 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == checkQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectVisitCheckList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(PMKCheckEXportDTO));
}
@@ -773,8 +755,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null)
.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum)
.WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -798,9 +779,8 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialReadingTaskList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReadingTaskExportDto));
}
@@ -827,7 +807,7 @@ namespace IRaCIS.Core.Application.Service.Common
var list = await _repository.Where<VisitTaskReReading>(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/)
.WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId)
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!))
.WhereIf(queryVisitTask.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId)
.WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState)
.WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId)
@@ -850,9 +830,8 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialReReadingTaskList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReReadingTaskExportDto));
}
@@ -875,7 +854,7 @@ namespace IRaCIS.Core.Application.Service.Common
{
var list = await _repository.Where<TaskMedicalReview>(t => t.VisitTask.TrialId == inQuery.TrialId)
.WhereIf(inQuery.TrialSiteId != null, t => t.VisitTask.Subject.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.SiteId != null, t => t.VisitTask.Subject.SiteId == inQuery.SiteId)
.WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName))
@@ -885,7 +864,7 @@ namespace IRaCIS.Core.Application.Service.Common
.WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory)
.WhereIf(inQuery.ReadingTaskState != null, t => t.VisitTask.ReadingTaskState == inQuery.ReadingTaskState)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.ProjectTo<TaskMedicalReviewExportDto>(_mapper.ConfigurationProvider).ToListAsync();
list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList();
@@ -893,9 +872,8 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialMedicalReviewList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TaskMedicalReviewExportDto));
}
@@ -917,7 +895,7 @@ namespace IRaCIS.Core.Application.Service.Common
[FromServices] IRepository<Trial> _trialRepository)
{
var criterion = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionName }).FirstNotNullAsync();
var criterion = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionName }).FirstOrDefaultAsync();
if (criterion.CriterionType != CriterionType.RECIST1Point1)
{
@@ -936,7 +914,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -962,7 +940,7 @@ namespace IRaCIS.Core.Application.Service.Common
foreach (var item in list)
{
//找到一致性分析的结果
var selfAnalysisTask = allList.Where(t => t.IsSelfAnalysis == true && t.SubjectCode == item.SubjectCode && t.VisitTaskNum == item.VisitTaskNum && t.TaskName == t.TaskName && t.UserName == item.UserName).FirstOrDefault();
var selfAnalysisTask = allList.Where(t => t.IsSelfAnalysis == true && t.SubjectCode == item.SubjectCode && t.VisitTaskNum == item.VisitTaskNum && t.TaskName == t.TaskName).FirstOrDefault();
//因为基线的评估结果是 是否存在疾病 而 其他访视的结果是 整体肿瘤评估结果 是用不同的枚举翻译的 所以这里手动翻译 不把翻译逻辑耦合到通用的翻译代码里面 在此特殊处理
@@ -978,9 +956,8 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.CriterionName = await _repository.Where<ReadingQuestionCriterionTrial>(u => u.TrialId == queryVisitTask.TrialId && u.IsConfirm && u.Id == queryVisitTask.TrialReadingCriterionId).Select(t => t.CriterionName).FirstOrDefaultAsync();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSelfAnalysisList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SelftAnalysisExport));
}
@@ -1000,7 +977,7 @@ namespace IRaCIS.Core.Application.Service.Common
[FromServices] IDictionaryService _dictionaryService,
[FromServices] IRepository<Trial> _trialRepository)
{
var criterion = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionName }).FirstNotNullAsync();
var criterion = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionName }).FirstOrDefaultAsync();
if (criterion.CriterionType != CriterionType.RECIST1Point1)
{
@@ -1020,7 +997,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -1036,7 +1013,7 @@ namespace IRaCIS.Core.Application.Service.Common
.ProjectTo<GroupAnalysisExport>(_mapper.ConfigurationProvider).ToListAsync();
//找到原任务(非组间一致性分析的)
var list = allList.Where(t => t.IsSelfAnalysis == null).OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList();
@@ -1082,9 +1059,8 @@ namespace IRaCIS.Core.Application.Service.Common
var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.CriterionName = await _repository.Where<ReadingQuestionCriterionTrial>(u => u.TrialId == queryVisitTask.TrialId && u.IsConfirm && u.Id == queryVisitTask.TrialReadingCriterionId).Select(t => t.CriterionName).FirstOrDefaultAsync();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(newList, _userInfo.TimeZoneId); ;
exportInfo.List = newList;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialGroupAnalysisList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(GroupAnalysisExport));
}
@@ -1123,7 +1099,7 @@ namespace IRaCIS.Core.Application.Service.Common
{
var list = new List<ExportDocumentDes>();
var criterion = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.Id == trialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionName }).FirstNotNullAsync();
var criterion = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.Id == trialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionName }).FirstOrDefaultAsync();
if (criterion.CriterionType == CriterionType.RECIST1Point1)
{
@@ -1151,41 +1127,30 @@ namespace IRaCIS.Core.Application.Service.Common
{
//处理裁判标记
var resultList = list.Where(t => t.ReadingCategory != ReadingCategory.Judge).ToList();
if (arbitrationRule == ArbitrationRule.Visit)
{
var resultList = list.Where(t => t.ReadingCategory != ReadingCategory.Judge).ToList();
foreach (var item in resultList)
if (arbitrationRule == ArbitrationRule.Visit)
{
item.IsGenerateJudge = list.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode
&& (t.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Judge]) == item.VisitTaskNum)?.JudgeArmEnum == item.ArmEnum ? true : false;
foreach (var item in resultList)
{
item.IsGenerateJudge = list.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode
&& (t.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Judge]) == item.VisitTaskNum)?.JudgeArmEnum == item.ArmEnum ? true : false;
}
}
if (arbitrationRule == ArbitrationRule.Reading)
{
foreach (var item in resultList)
{
item.IsGenerateJudge = list.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode && t.VisitTaskNum>item.VisitTaskNum
).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault()?.JudgeArmEnum == item.ArmEnum ? true : false;
}
}
return resultList;
}
if (arbitrationRule == ArbitrationRule.Reading)
{
foreach (var item in resultList)
{
item.IsGenerateJudge = list.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode && t.VisitTaskNum > item.VisitTaskNum
).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault()?.JudgeArmEnum == item.ArmEnum ? true : false;
}
}
//如果没有产生裁判,默认选择R1
//找到没有裁判的访视任务
var notJudgeList = resultList.GroupBy(t => new { t.SubjectCode, t.VisitTaskNum }).Where(g => g.All(t => t.IsGenerateJudge == false)).Select(g => new { g.Key.SubjectCode, g.Key.VisitTaskNum }).ToList();
foreach (var item in resultList)
{
if (notJudgeList.Any(t => t.SubjectCode == item.SubjectCode && t.VisitTaskNum == item.VisitTaskNum) && item.ArmEnum == Arm.DoubleReadingArm1)
{
item.IsGenerateJudge = true;
}
}
return resultList;
}
@@ -1224,7 +1189,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -1239,7 +1204,7 @@ namespace IRaCIS.Core.Application.Service.Common
.WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1))
.ProjectTo<OverallTumorEvaluationExport>(_mapper.ConfigurationProvider, new { criterionType = criterion.CriterionType }).ToListAsync();
list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.ArmEnum).ThenBy(t => t.VisitTaskNum).ToList();
list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList();
var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
exportInfo.CriterionName = criterion.CriterionName;
@@ -1247,9 +1212,8 @@ namespace IRaCIS.Core.Application.Service.Common
//处理裁判标记
list = DealJudgeMark(criterion.ArbitrationRule, list);
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.OverallTumorEvaluation_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(OverallTumorEvaluationExport), criterion.CriterionType);
@@ -1281,7 +1245,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -1302,14 +1266,13 @@ namespace IRaCIS.Core.Application.Service.Common
{
var list = await query.ProjectTo<RECIST1Point1EvaluationOfTumorEfficacyExport>(_mapper.ConfigurationProvider, new { criterionType = criterion.CriterionType }).ToListAsync();
list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.ArmEnum).ThenBy(t => t.VisitTaskNum).ToList();
list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList();
//处理裁判标记
list = DealJudgeMark(criterion.ArbitrationRule, list);
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.List = list;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.RECIST1Point1EvaluationOfTumorEfficacy_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(RECIST1Point1EvaluationOfTumorEfficacyExport), criterion.CriterionType);
@@ -1341,7 +1304,7 @@ namespace IRaCIS.Core.Application.Service.Common
{
//每次查询必须是单标准的
var criterion = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionName, t.ArbitrationRule }).FirstOrDefaultAsync();
var criterion = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionName,t.ArbitrationRule }).FirstOrDefaultAsync();
var query = _repository.Where<VisitTask>(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned)
@@ -1350,7 +1313,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
@@ -1371,7 +1334,7 @@ namespace IRaCIS.Core.Application.Service.Common
{
var list = await query.ProjectTo<RECIST1Point1DetailedOfEvaluatedLesionExport>(_mapper.ConfigurationProvider, new { criterionType = criterion.CriterionType, isEn_Us = _userInfo.IsEn_Us }).ToListAsync();
list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.ArmEnum).ThenBy(t => t.VisitTaskNum).ToList();
list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList();
var exportList = list.SelectMany(c =>
{
@@ -1381,7 +1344,6 @@ namespace IRaCIS.Core.Application.Service.Common
var clone = c.Clone();
clone.LessionCode = u.LessionCode;
clone.LessionType = u.LessionType;
clone.BeforeTranslateLessionTypeValue = u.LessionType;
clone.IsLymph = u.IsLymph;
@@ -1400,9 +1362,8 @@ namespace IRaCIS.Core.Application.Service.Common
//处理裁判标记
list = DealJudgeMark(criterion.ArbitrationRule, list);
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(exportList, _userInfo.TimeZoneId);
exportInfo.List = exportList;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.RECIST1Point1DetailedOfEvaluatedLesion_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(RECIST1Point1DetailedOfEvaluatedLesionExport), criterion.CriterionType);
@@ -1434,10 +1395,8 @@ namespace IRaCIS.Core.Application.Service.Common
//处理裁判标记
list = DealJudgeMark(criterion.ArbitrationRule, list);
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(exportList, _userInfo.TimeZoneId); ;
exportInfo.List = exportList;
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.PCWG3Point1DetailedOfEvaluatedLesion_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(PCWG3DetailedOfEvaluatedLesionExport), criterion.CriterionType);
@@ -11,183 +11,25 @@ namespace IRaCIS.Application.Services
public class FileService : IFileService
{
private readonly IDoctorService _doctorService;
private readonly IAttachmentService _attachmentService;
private readonly IWebHostEnvironment _hostEnvironment;
private string defaultUploadFilePath = string.Empty;
private readonly ILogger<FileService> _logger;
public FileService(IDoctorService doctorService, IAttachmentService attachmentService,
public FileService(
IWebHostEnvironment hostEnvironment, ILogger<FileService> logger)
{
_doctorService = doctorService;
_attachmentService = attachmentService;
_hostEnvironment = hostEnvironment;
defaultUploadFilePath = FileStoreHelper.GetIRaCISRootPath(_hostEnvironment);
_logger = logger;
}
/// <summary>
/// 打包医生官方简历
/// </summary>
/// <param name="language"></param>
/// <param name="doctorIds"></param>
/// <returns></returns>
public async Task<string> CreateOfficialResumeZip(int language, Guid[] doctorIds)
{
//准备下载文件的临时路径
var guidStr = Guid.NewGuid().ToString();
string uploadFolderPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "UploadFile");
var tempSavePath = Path.Combine(uploadFolderPath, "temp", guidStr); //待压缩的文件夹,将需要下载的文件拷贝到此文件夹
if (!Directory.Exists(tempSavePath))
{
Directory.CreateDirectory(tempSavePath);
}
//找到服务器简历路径 循环拷贝简历到临时路径
foreach (var doctorId in doctorIds)
{
var doctor = await _doctorService.GetBasicInfo(doctorId);
var doctorName = doctor.FirstName + "_" + doctor.LastName;
//找官方简历存在服务器的相对路径
var sourceCvPath = await _attachmentService.GetDoctorOfficialCV(language, doctorId);
if (!string.IsNullOrWhiteSpace(sourceCvPath))
{
//服务器简历文件实际路径
//var sourceCvFullPath = HostingEnvironment.MapPath(sourceCvPath);
var sourceCvPathTemp = sourceCvPath.Substring(1, sourceCvPath.Length - 1);//.Replace('/','\\');
string sourceCvFullPath = Path.Combine(defaultUploadFilePath, sourceCvPathTemp);
var arr = sourceCvPath.Split('.');
string extensionName = arr[arr.Length - 1]; //得到扩展名
//需要拷贝到的路径
var doctorPath = Path.Combine(tempSavePath, doctor.ReviewerCode.ToString() + "_" + doctorName + "." + extensionName);
if (File.Exists(sourceCvFullPath))
{
File.Copy(sourceCvFullPath, doctorPath, true);
}
}
}
//创建ZIP
DateTime now = DateTime.Now;
StringBuilder sb = new StringBuilder();
sb.Append(now.Year).Append(now.Month.ToString().PadLeft(2, '0')).Append(now.Day.ToString().PadLeft(2, '0'))
.Append(now.Hour.ToString().PadLeft(2, '0')).Append(now.Minute.ToString().PadLeft(2, '0'))
.Append(now.Second.ToString().PadLeft(2, '0')).Append(now.Millisecond.ToString().PadLeft(3, '0'));
string targetZipPath = Path.Combine(uploadFolderPath, "CV_" + sb.ToString() + ".zip");
ZipHelper.CreateZip(tempSavePath, targetZipPath);
//返回Zip路径
return Path.Combine("/IRaCISData/UploadFile/", "CV_" + sb.ToString() + ".zip");
}
/// <summary>
/// 打包医生的所有附件
/// </summary>
/// <param name="doctorIds"></param>
/// <returns></returns>
public async Task<string> CreateDoctorsAllAttachmentZip(Guid[] doctorIds)
{
#region
//准备下载文件的临时路径
var guidStr = Guid.NewGuid().ToString();
//string uploadFolderPath = HostingEnvironment.MapPath("/UploadFile/");
string uploadFolderPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "UploadFile");
var tempSavePath = Path.Combine(uploadFolderPath, "temp", guidStr); //待压缩的文件夹,将需要下载的文件拷贝到此文件夹
if (!Directory.Exists(tempSavePath))
{
Directory.CreateDirectory(tempSavePath);
}
foreach (var doctorId in doctorIds)
{
//获取医生基本信息
var doctor = await _doctorService.GetBasicInfo(doctorId);
var doctorName = doctor.FirstName + "_" + doctor.LastName;
var doctorCode = doctor.ReviewerCode;
var doctorDestPath = Path.Combine(tempSavePath, doctorCode + "_" + doctorName);
if (!Directory.Exists(doctorDestPath))
{
Directory.CreateDirectory(doctorDestPath);
}
//服务器上传后的源路径
string doctorFileSourcePath = Path.Combine(uploadFolderPath, doctorId.ToString());
if (Directory.Exists(doctorFileSourcePath))
{
CopyDirectory(doctorFileSourcePath, doctorDestPath);
}
}
string target = Guid.NewGuid().ToString();
string targetPath = Path.Combine(uploadFolderPath, target + ".zip");
ZipHelper.CreateZip(tempSavePath, targetPath);
return Path.Combine("/IRaCISData/UploadFile/", target + ".zip");
#endregion
}
public async Task<string> CreateZipPackageByAttachment(Guid doctorId, Guid[] attachmentIds)
{
var doctor = await _doctorService.GetBasicInfo(doctorId);
var doctorName = doctor.FirstName + "_" + doctor.LastName;
Guid temp = Guid.NewGuid();
//string root = HostingEnvironment.MapPath("/UploadFile/"); //文件根目录
string root = Path.Combine(defaultUploadFilePath, "UploadFile");
var tempPath = Path.Combine(root, "temp", temp.ToString(), doctor.ReviewerCode + doctorName); //待压缩的文件夹,将需要下载的文件拷贝到此文件夹
var packagePath = Path.Combine(root, "temp", temp.ToString()); //打包目录
if (!Directory.Exists(tempPath))
{
Directory.CreateDirectory(tempPath);
}
var attachemnts = (await _attachmentService.GetAttachments(doctorId)).Where(a => attachmentIds.Contains(a.Id));
foreach (var item in attachemnts)
{
var arr = item.Path.Trim().Split('/');
var myPath = string.Empty;
var myFile = string.Empty;
//需要改进
if (arr.Length > 0)
{
myFile = arr[arr.Length - 1];
foreach (var arrItem in arr)
{
if (arrItem != string.Empty && !"UploadFile".Equals(arrItem))
{
myPath += (arrItem + "/");
}
}
myPath = myPath.TrimEnd('/');
}
var sourcePath = Path.Combine(root, myPath);
if (!string.IsNullOrWhiteSpace(sourcePath) && File.Exists(sourcePath))
{
File.Copy(sourcePath, Path.Combine(tempPath, myFile), true);
}
}
string target = Guid.NewGuid().ToString();
string targetPath = Path.Combine(root, target + ".zip");
ZipHelper.CreateZip(packagePath, targetPath);
return Path.Combine("/IRaCISData/UploadFile/", target + ".zip");
}
private static void CopyDirectory(string srcPath, string destPath)
{
@@ -8,10 +8,10 @@ namespace IRaCIS.Application.Interfaces
//IResponseOutput<UploadFileInfo> DownloadOfficialResume(Guid[] doctorIds);
Task<string> CreateOfficialResumeZip(int language, Guid[] doctorIds);
Task<string> CreateDoctorsAllAttachmentZip(Guid[] doctorIds);
Task<string> CreateZipPackageByAttachment(Guid doctorId, Guid[] attachmentIds);
}
}

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