Compare commits

...

1082 Commits

Author SHA1 Message Date
hang 775704c509 继续测试
continuous-integration/drone/push Build is running
2026-06-05 15:41:48 +08:00
hang 96776b0b3d 触发发布
continuous-integration/drone/push Build was killed
2026-06-05 15:32:01 +08:00
hang 4e277bb9aa 去掉编码 2026-06-05 14:53:50 +08:00
hang d269131510 url编码测试
continuous-integration/drone/push Build was killed
2026-06-05 14:46:12 +08:00
hang bddfc633f4 编码路径测试 2026-06-05 14:24:09 +08:00
hang c72f50c1f7 信任证书
continuous-integration/drone/push Build is running
2026-06-05 14:16:07 +08:00
hang 5a27fbc127 改成内存流测试
continuous-integration/drone/push Build is running
2026-06-05 13:37:11 +08:00
hang c8d181e557 增加flush 测试
continuous-integration/drone/push Build is passing
2026-06-05 13:16:18 +08:00
hang 3fdfb3cc4b 修改正常压缩包
continuous-integration/drone/push Build is running
2026-06-05 11:44:42 +08:00
hang c91b645539 HIR 合并多帧修改 2026-06-03 11:19:12 +08:00
he 19bd2d145a 修改导出
continuous-integration/drone/push Build is passing
2026-05-28 16:43:12 +08:00
he 7d81cb72ee 下载压缩包 加入标准层级 2026-05-28 15:41:04 +08:00
he 49554ae764 修改导出逻辑
continuous-integration/drone/push Build is passing
2026-05-28 14:41:20 +08:00
he 9b0cde11c6 修改请求类型
continuous-integration/drone/push Build is running
2026-05-27 16:33:15 +08:00
he a7c462210c OSS修改
continuous-integration/drone/push Build is running
2026-05-27 12:15:22 +08:00
he 4f83944a30 功能修改
continuous-integration/drone/push Build is passing
2026-05-27 11:15:53 +08:00
he 8801308002 获取下载地址 2026-05-27 10:48:47 +08:00
hang 56e109ce0a 放开获取系统标准下拉框接口授权
continuous-integration/drone/push Build is passing
2026-03-24 09:54:16 +08:00
hang 8c6b73c236 超时时间设置为90s
continuous-integration/drone/push Build is passing
2026-03-23 16:38:32 +08:00
hang 04f971e24f 修改hir配置端口
continuous-integration/drone/push Build is passing
2026-03-19 18:08:01 +08:00
hang 88c1bf7e76 oss 异步获取流,检查时间修改格式
continuous-integration/drone/push Build is passing
2026-03-16 14:41:19 +08:00
hang 02aebab5ea 修改检查时间展示格式
continuous-integration/drone/push Build is passing
2026-03-16 12:01:05 +08:00
hang 80378a23f7 恢复为同步模式
continuous-integration/drone/push Build is passing
2026-03-16 11:53:00 +08:00
hang b3976783df minio 底层下载流 增加日志提示
continuous-integration/drone/push Build is passing
2026-03-16 11:14:05 +08:00
hang 4c11dd203c Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2026-03-16 09:17:22 +08:00
hang cdc0822677 返回项目列表增加课题组 2026-03-16 09:17:20 +08:00
hang fe209ee2c5 打印文件日志
continuous-integration/drone/push Build is passing
2026-03-14 23:00:03 +08:00
hang a595ca10fe 修改日志提示
continuous-integration/drone/push Build is passing
2026-03-13 09:48:12 +08:00
hang 0fdbb5dde0 没有生成dir 继续下载
continuous-integration/drone/push Build is passing
2026-03-12 11:22:30 +08:00
hang e488ba5edd 测试@人
continuous-integration/drone/push Build is failing
2026-02-05 16:01:59 +08:00
hang 3a7961ded5 增加具体服务名字
continuous-integration/drone/push Build is passing
2026-02-05 15:42:06 +08:00
hang 0db495a38a 步骤之间无法传递变量,去掉部署时间, 增加部署域名
continuous-integration/drone/push Build is failing
2026-02-05 15:28:19 +08:00
hang 1b1a18bac8 手动记录打包部署时间
continuous-integration/drone/push Build is passing
2026-02-05 15:16:01 +08:00
hang fee5cd7a75 修改drone 打包通知机器人key
continuous-integration/drone/push Build is passing
2026-02-05 14:38:50 +08:00
hang 3473a96014 修改脚本测试
continuous-integration/drone/push Build is passing
2026-02-05 14:28:07 +08:00
hang 88036f9355 增加提交人,和提交信息测试
continuous-integration/drone/push Build is failing
2026-02-05 14:17:49 +08:00
hang fdb9b825f8 测试10
continuous-integration/drone/push Build is failing
2026-02-05 14:06:38 +08:00
hang 3f85962584 测试9
continuous-integration/drone/push Build is passing
2026-02-05 14:03:11 +08:00
hang f52c5b5185 测试8 2026-02-05 14:01:31 +08:00
hang 7452eae07f 合并冲突 2026-02-05 13:57:50 +08:00
hang cb712c181a 测试7 2026-02-05 13:57:20 +08:00
hang 41c5686ac9 测试6 2026-02-05 13:27:00 +08:00
hang de500f28cd Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8 2026-02-05 13:16:46 +08:00
hang 1dce9f7255 测试打包通知4 2026-02-05 13:16:46 +08:00
hang 49346bc025 测试打包通知3 2026-02-05 13:14:17 +08:00
hang e2d19c5738 测试打包通知2 2026-02-05 13:12:42 +08:00
hang 5cab834978 测试打包通知1 2026-02-05 13:11:45 +08:00
hang da7727c4b2 测试打包通知 2026-02-05 13:09:45 +08:00
hang 5111168349 测试drone发布
continuous-integration/drone/push Build is passing
2026-01-29 17:11:11 +08:00
hang 07dc87d859 修改打包方式验证
continuous-integration/drone/push Build is passing
2026-01-29 16:47:32 +08:00
hang 7e6c41a3ff 打包脚本错误修改
continuous-integration/drone/push Build is passing
2026-01-28 23:46:52 +08:00
hang e3daf3af26 HIR 发布脚本位置变更
continuous-integration/drone/push Build is failing
2026-01-28 23:42:41 +08:00
hang 6af18aa977 修改drone流水线优化发布不同时发布,防止打包服务器崩溃 2026-01-26 15:58:42 +08:00
hang 179017fa2c HIR dir 修改
continuous-integration/drone/push Build is passing
2026-01-20 09:30:09 +08:00
hang af691d155d 修改配置文件
continuous-integration/drone/push Build is passing
2026-01-12 16:49:43 +08:00
hang 4c5a40bd11 dir 修改
continuous-integration/drone/push Build is passing
2026-01-12 15:20:15 +08:00
hang ccb7d5edc0 修改HIR 匿名化逻辑2
continuous-integration/drone/push Build is passing
2026-01-12 13:08:46 +08:00
hang 972b18e4df 修改HIR 匿名化逻辑
continuous-integration/drone/push Build is running
2026-01-12 11:45:44 +08:00
hang c290515e22 修改HIR 匿名化
continuous-integration/drone/push Build is passing
2026-01-08 15:17:47 +08:00
hang 8ad11f018b 修改接收服务多帧判断
continuous-integration/drone/push Build is passing
2026-01-05 09:12:24 +08:00
hang 78597d6866 多帧处理
continuous-integration/drone/push Build is passing
2026-01-05 08:58:57 +08:00
hang 274a8d2c21 排除库的原因,缩略图失败
continuous-integration/drone/push Build is passing
2026-01-04 18:35:05 +08:00
hang 4b9a277335 增加swagger 第一步
continuous-integration/drone/push Build is passing
2026-01-04 18:26:45 +08:00
hang 4d8b43f8df 修改接收文件bug
continuous-integration/drone/push Build is passing
2026-01-04 16:23:58 +08:00
hang 6a9f791b1b 查询NumberOfFrames
continuous-integration/drone/push Build is passing
2026-01-04 15:10:03 +08:00
hang f75c2d7283 单独方法测试
continuous-integration/drone/push Build is passing
2026-01-04 14:39:46 +08:00
hang 88ded12f37 将dicom文件内处理拆成单方法,减缓内存占用测试
continuous-integration/drone/push Build is passing
2026-01-04 14:33:26 +08:00
hang 72d7136f1c 修改HIR 接收影像
continuous-integration/drone/push Build is passing
2026-01-04 13:20:40 +08:00
hang b95cc97f55 数据库生命周期条调整
continuous-integration/drone/push Build is passing
2026-01-04 12:28:19 +08:00
hang 7fa043793e 修改下载影像处理sr ot 多帧处理失败
continuous-integration/drone/push Build is passing
2026-01-04 11:36:50 +08:00
hang 0cb2015aae 修改判断多帧图像
continuous-integration/drone/push Build is passing
2025-12-25 16:27:56 +08:00
hang 7b5b7e4ffa 优化下载
continuous-integration/drone/push Build is passing
2025-12-25 16:02:35 +08:00
hang 7fed7072c1 重新提交
continuous-integration/drone/push Build is passing
2025-12-25 15:27:45 +08:00
hang 6e5e49d322 有些影响特殊,需要完整的测试
continuous-integration/drone/push Build is passing
2025-12-25 15:16:41 +08:00
hang 8609c34fd7 修改维护数据
continuous-integration/drone/push Build was killed
2025-12-25 13:52:19 +08:00
hang 596c46d885 增加异常处理
continuous-integration/drone/push Build is running
2025-12-25 13:51:19 +08:00
hang 790d751c1f 修改swagger 测试发布
continuous-integration/drone/push Build is passing
2025-12-25 13:38:29 +08:00
hang f3cc7be5d7 维护dir
continuous-integration/drone/push Build is failing
2025-12-25 11:31:00 +08:00
hang 0ee3010e04 维护dir,方便下载
continuous-integration/drone/push Build is passing
2025-12-25 11:00:51 +08:00
hang c7d4159302 修改偏移表-最终解决方案
continuous-integration/drone/push Build is passing
2025-12-24 11:37:49 +08:00
hang 3ee81beb80 屏蔽bot
continuous-integration/drone/push Build is passing
2025-12-24 09:30:37 +08:00
hang db586038cf 增加测试代码
continuous-integration/drone/push Build is running
2025-12-24 09:28:25 +08:00
hang 4240015056 奇怪的问题
continuous-integration/drone/push Build is passing
2025-12-23 22:24:09 +08:00
hang 37b942f0a6 写入原始文件不行,暂不清楚问题
continuous-integration/drone/push Build is passing
2025-12-23 21:33:30 +08:00
hang 87dcebd00b post 表单方式传递参数
continuous-integration/drone/push Build is passing
2025-12-23 20:27:31 +08:00
hang 40fd641210 修改请求方式
continuous-integration/drone/push Build is passing
2025-12-23 17:59:32 +08:00
hang 2f701246ff 修改zip包
continuous-integration/drone/push Build was killed
2025-12-23 16:17:30 +08:00
hang 88a8a014c9 1
continuous-integration/drone/push Build was killed
2025-12-23 15:49:49 +08:00
hang fe7c6e5dfa 增加get请求
continuous-integration/drone/push Build is passing
2025-12-23 15:42:38 +08:00
hang a6f055bb1a 修改流
continuous-integration/drone/push Build was killed
2025-12-23 15:26:49 +08:00
hang 18d58951a2 修改路径
continuous-integration/drone/push Build was killed
2025-12-23 15:20:15 +08:00
hang 54f1f917eb 修改名字
continuous-integration/drone/push Build is passing
2025-12-23 15:06:55 +08:00
hang a0fd472e2e 增加测试接口
continuous-integration/drone/push Build is passing
2025-12-23 14:56:44 +08:00
hang fb33acd827 接口撤回
continuous-integration/drone/push Build is passing
2025-12-23 13:10:35 +08:00
hang 9c3e72b1bb 批量下载使用get请求
continuous-integration/drone/push Build is passing
2025-12-23 10:16:15 +08:00
hang 57515b2ecf 屏蔽本地测试代码
continuous-integration/drone/push Build is passing
2025-12-22 17:52:24 +08:00
hang 9f060c900f 重新造bot,方便下载的时候识别具体帧
continuous-integration/drone/push Build is passing
2025-12-22 17:08:10 +08:00
hang c804bdb5a1 Revert "创建bot测试-1"
continuous-integration/drone/push Build is passing
This reverts commit 48aafdc713.
2025-12-22 14:13:32 +08:00
hang 48aafdc713 创建bot测试-1
continuous-integration/drone/push Build is passing
2025-12-22 13:21:15 +08:00
hang 67b2d95c32 DIR /\ 修改,影响软件打开
continuous-integration/drone/push Build is passing
2025-12-19 13:25:14 +08:00
hang ee3133adee 修改流式返回
continuous-integration/drone/push Build is passing
2025-12-18 13:26:16 +08:00
hang a1b5d960ff 返回失败数量
continuous-integration/drone/push Build is passing
2025-12-18 10:10:00 +08:00
hang df7eaf6986 修改影像大小
continuous-integration/drone/push Build is passing
2025-12-18 09:51:06 +08:00
hang efd24ab9ba 下载大小和影像数量返回
continuous-integration/drone/push Build is passing
2025-12-18 09:33:16 +08:00
hang bd9d1a6298 修改访视下载bug
continuous-integration/drone/push Build is passing
2025-12-17 17:42:05 +08:00
hang 345189995e 增加访视下载接口
continuous-integration/drone/push Build is passing
2025-12-17 16:57:33 +08:00
hang 6dcdfe4d23 实时返回速度测试
continuous-integration/drone/push Build is passing
2025-12-17 15:55:21 +08:00
hang 2addbe30dd 修改推送频率
continuous-integration/drone/push Build is running
2025-12-17 15:34:24 +08:00
hang d2e3e4de86 返回写入流的进度消息
continuous-integration/drone/push Build is passing
2025-12-17 15:11:05 +08:00
hang d78a42dead HIR 流式写入zip 返回前端
continuous-integration/drone/push Build is passing
2025-12-17 13:49:33 +08:00
hang 93362ea4c9 修改下载接口返回信息
continuous-integration/drone/push Build is passing
2025-12-11 15:54:34 +08:00
hang 1033ff665c 修改美国配置文件
continuous-integration/drone/push Build is passing
2025-11-28 16:56:51 +08:00
hang f8478887ce 修改uat 配置文件
continuous-integration/drone/push Build is passing
2025-11-26 13:33:08 +08:00
hang 763984ca62 增加检查数量字段
continuous-integration/drone/push Build is passing
2025-11-24 16:23:55 +08:00
hang efbaae2a97 修改影像下载检查过滤2
continuous-integration/drone/push Build is passing
2025-11-24 15:57:13 +08:00
hang 49e4980fd0 修改影像下载检查过滤
continuous-integration/drone/push Build is passing
2025-11-24 15:48:07 +08:00
hang b2bcc37dab 修改配置文件
continuous-integration/drone/push Build is passing
2025-11-24 10:48:40 +08:00
hang 32ee818be8 修改配置文件
continuous-integration/drone/push Build is passing
2025-11-24 10:35:52 +08:00
hang d042be7828 修改DIR 验证
continuous-integration/drone/push Build is passing
2025-11-21 17:16:29 +08:00
hang 2017d781bf 修改下载列表
continuous-integration/drone/push Build is passing
2025-11-21 16:00:01 +08:00
hang fccf6686eb 修改返回名称
continuous-integration/drone/push Build is passing
2025-11-21 15:08:42 +08:00
hang 88f40125e1 修改请求方式
continuous-integration/drone/push Build is passing
2025-11-21 14:50:00 +08:00
hang facb318180 修改维护脚本
continuous-integration/drone/push Build is passing
2025-11-21 13:44:33 +08:00
hang 62352738e8 修改下载
continuous-integration/drone/push Build is passing
2025-11-21 11:44:43 +08:00
hang a22b7802b7 修改邮件配置文件
continuous-integration/drone/push Build is passing
2025-11-21 09:36:58 +08:00
hang 6aaeeeaeb9 修改下限制
continuous-integration/drone/push Build is passing
2025-11-11 17:24:27 +08:00
hang 7b606aee05 修改scp 服务bug
continuous-integration/drone/push Build is passing
2025-11-11 17:19:28 +08:00
hang 841f1892d4 修改接收转发多线程配置
continuous-integration/drone/push Build is passing
2025-11-03 13:12:11 +08:00
hang 106916f7ad 转发时传递目标AE
continuous-integration/drone/push Build is passing
2025-10-30 11:27:29 +08:00
hang 46ab1fc7bc 配置从数据库取,同时返回控制开关
continuous-integration/drone/push Build is passing
2025-10-30 11:18:06 +08:00
hang 3328c18279 限制不能空条件查询
continuous-integration/drone/push Build is passing
2025-10-28 18:03:15 +08:00
hang aed778bbc6 HIR 对接第三方初步测试完毕
continuous-integration/drone/push Build is passing
2025-10-28 15:08:23 +08:00
hang 064e3836ca 修改配置文件
continuous-integration/drone/push Build is passing
2025-10-28 11:21:36 +08:00
hang 3407f2f00d HIR服务注册遗漏
continuous-integration/drone/push Build is passing
2025-10-28 09:46:27 +08:00
hang e496cf1117 对接联影,转发c-find c-move请求,并且发送c-store 请求
continuous-integration/drone/push Build is passing
2025-10-27 15:26:49 +08:00
he e5f6685719 PCWG LastTaskState 取值修改
continuous-integration/drone/push Build is passing
2025-10-09 15:30:38 +08:00
he 837a3f66d5 修改
continuous-integration/drone/push Build is passing
2025-09-28 13:48:00 +08:00
he 0201c2f50f 修改
continuous-integration/drone/push Build is running
2025-09-28 13:44:48 +08:00
he a7ed38f03b 数据库可插入null
continuous-integration/drone/push Build is passing
2025-09-28 12:46:35 +08:00
he a436571364 修改
continuous-integration/drone/push Build is passing
2025-09-28 12:18:47 +08:00
he 34e6e1583e 修改
continuous-integration/drone/push Build is passing
2025-09-28 12:13:18 +08:00
he 400504db74 代码修改
continuous-integration/drone/push Build is passing
2025-09-28 09:09:09 +08:00
he 88e7febec5 修改
continuous-integration/drone/push Build is passing
2025-09-26 17:46:54 +08:00
he 02a49b2239 修改
continuous-integration/drone/push Build is passing
2025-09-26 17:17:56 +08:00
he d72b28afc2 修改
continuous-integration/drone/push Build is passing
2025-09-26 15:53:02 +08:00
he 2ba9e6e2d4 修改
continuous-integration/drone/push Build is passing
2025-09-26 14:59:43 +08:00
he 1d38ee3f49 代码修改
continuous-integration/drone/push Build is passing
2025-09-26 10:49:49 +08:00
he 9879625781 修改
continuous-integration/drone/push Build is passing
2025-09-26 09:17:48 +08:00
he a0f5e7b7e5 计算修改
continuous-integration/drone/push Build is passing
2025-09-25 18:01:10 +08:00
he 337d0fa05f 修改模板
continuous-integration/drone/push Build is passing
2025-09-25 17:42:24 +08:00
he 5d3df0b1f5 修改
continuous-integration/drone/push Build is running
2025-09-25 17:40:16 +08:00
he dd4cd5d330 修改
continuous-integration/drone/push Build is passing
2025-09-25 17:32:51 +08:00
he 3c28be9bf0 修改模板
continuous-integration/drone/push Build is passing
2025-09-25 17:19:49 +08:00
he 6e75404175 提交
continuous-integration/drone/push Build is passing
2025-09-25 17:12:37 +08:00
he 5b08640a02 修改
continuous-integration/drone/push Build is passing
2025-09-25 16:55:37 +08:00
he 9b3e4194a9 修改
continuous-integration/drone/push Build is passing
2025-09-25 16:22:28 +08:00
he c4eabde7a9 修改最多5条靶病灶
continuous-integration/drone/push Build is running
2025-09-25 16:21:10 +08:00
he 66e5570d82 修改模板
continuous-integration/drone/push Build is passing
2025-09-25 13:59:28 +08:00
he d1be23a69e 模板修改
continuous-integration/drone/push Build is passing
2025-09-25 13:51:46 +08:00
he 0ef8604da0 修改模板
continuous-integration/drone/push Build is passing
2025-09-25 13:47:40 +08:00
he 05124428ad Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-25 13:33:21 +08:00
he 17ce41209f 导出模板修改 2025-09-25 13:33:19 +08:00
hang a1afbc2487 访视退回过滤
continuous-integration/drone/push Build is passing
2025-09-24 17:26:03 +08:00
hang 3f6e006a95 修改提交事务
continuous-integration/drone/push Build is passing
2025-09-24 16:11:44 +08:00
hang 380546ca3c 增加影像退回接口
continuous-integration/drone/push Build is passing
2025-09-23 16:13:17 +08:00
hang e4cf4cc8b8 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-23 10:08:14 +08:00
hang ed580eab74 界面增加检查数量 2025-09-23 10:08:13 +08:00
he 2530843931 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-22 11:06:48 +08:00
he c4b588376d 修改计算 2025-09-22 11:06:45 +08:00
hang e63d6ba652 增加额外日志
continuous-integration/drone/push Build is passing
2025-09-19 17:57:16 +08:00
hang 64ef4ea0f2 继续增加日志
continuous-integration/drone/push Build is passing
2025-09-19 17:49:17 +08:00
hang b293559225 修改客户端断网测试
continuous-integration/drone/push Build is passing
2025-09-19 17:34:12 +08:00
hang 7214626850 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-19 16:48:35 +08:00
hang a4ef209fb1 修改影像接收设置失败标志 2025-09-19 16:48:33 +08:00
he e4cc044219 修改
continuous-integration/drone/push Build is passing
2025-09-19 15:56:05 +08:00
he db6c0457ae Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-19 14:56:44 +08:00
he e745271671 修改PD计算 2025-09-19 14:56:42 +08:00
hang 34686b10cc Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-19 13:16:04 +08:00
hang 711c4c5888 增加查询条件,通过邮件获取用户修改 2025-09-19 13:16:02 +08:00
he 3d19ee7b04 修改计算
continuous-integration/drone/push Build is passing
2025-09-18 16:52:01 +08:00
he 72fd347c01 修改
continuous-integration/drone/push Build is passing
2025-09-18 14:17:16 +08:00
he 4c1da73c33 修改
continuous-integration/drone/push Build is passing
2025-09-18 13:25:11 +08:00
he 2b01c777a7 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-18 10:00:44 +08:00
he d1ae500735 修改PCWG计算 2025-09-18 10:00:41 +08:00
hang 214ea985d9 返回studyUid 自动激活1个月判断
continuous-integration/drone/push Build is passing
2025-09-17 17:45:11 +08:00
hang 95fe063706 修改归档属性
continuous-integration/drone/push Build is passing
2025-09-17 16:41:38 +08:00
hang b6ceca9744 修改患者检查列表和查询
continuous-integration/drone/push Build is passing
2025-09-17 15:03:59 +08:00
hang 42e9c58d7a Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-17 14:17:29 +08:00
hang 8356fff9ce 通过邮箱获取用户信息 2025-09-17 14:17:26 +08:00
he e6f91b9c4b 同步所有pcwg标准
continuous-integration/drone/push Build is passing
2025-09-17 13:46:28 +08:00
he ba9c88d836 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-17 11:20:33 +08:00
he 237260dbd0 修改 2025-09-17 11:20:32 +08:00
hang 5a2136f205 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build was killed
2025-09-17 10:49:18 +08:00
hang f9d69995d3 scp 服务记录日志修改 2025-09-17 10:49:16 +08:00
he 32d78f556c Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is running
2025-09-17 10:47:00 +08:00
he d11afb10de 修改 2025-09-17 10:46:59 +08:00
hang 67e7eaaa96 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-17 10:36:50 +08:00
hang af95166782 修改scp 服务监控 2025-09-17 10:36:48 +08:00
he 29093e5617 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-17 09:08:19 +08:00
he b68c00c1b4 修改PCWG 自治疗后第二个访视点以来持续的新骨病变数量 计算 2025-09-17 09:08:18 +08:00
hang 2d06b12368 修改最新推送时间
continuous-integration/drone/push Build is passing
2025-09-16 18:05:47 +08:00
hang 0f7b80ff63 删除废弃
continuous-integration/drone/push Build is passing
2025-09-16 17:56:05 +08:00
hang 96c8b5d7f8 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-16 17:14:11 +08:00
hang 4ec15c2333 修改推送检查数量 2025-09-16 17:14:08 +08:00
he 11d5722f46 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-16 16:33:12 +08:00
he a079451951 导出模板去除TNM分期 2025-09-16 16:33:10 +08:00
hang eb7db8478f Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-16 14:53:37 +08:00
hang 444d5c8005 修改搜索条件 2025-09-16 14:53:32 +08:00
he d97edf6688 修改稽查
continuous-integration/drone/push Build is passing
2025-09-15 16:41:58 +08:00
he 359a6bf602 添加PCWG临时答案
continuous-integration/drone/push Build is passing
2025-09-15 16:17:35 +08:00
he bab20666af 稽查修改
continuous-integration/drone/push Build is passing
2025-09-15 15:51:50 +08:00
he 05244cdaf7 res 同步病灶调整
continuous-integration/drone/push Build is passing
2025-09-15 14:35:18 +08:00
he ef1b76f98c 修改
continuous-integration/drone/push Build is passing
2025-09-15 14:25:17 +08:00
he f887699341 稽查修改
continuous-integration/drone/push Build is passing
2025-09-15 13:47:51 +08:00
he 6b97d1ce68 稽查修改
continuous-integration/drone/push Build is passing
2025-09-15 13:14:00 +08:00
he 334e51d9fd MRECISTHCC 同步病灶
continuous-integration/drone/push Build is passing
2025-09-15 11:43:47 +08:00
he 8b43474734 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-15 11:31:10 +08:00
he 149cca011a PWCG 计算 2025-09-15 11:31:08 +08:00
hang aa63ca2def Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-12 18:37:33 +08:00
hang 9dcb63bdf2 修改scp 测试 2025-09-12 18:37:30 +08:00
he 323534e52b Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-12 17:57:18 +08:00
he b432002266 计算修改 2025-09-12 17:57:17 +08:00
hang e03884227e 增加环境启动
continuous-integration/drone/push Build is passing
2025-09-12 17:21:08 +08:00
he 0580b11e39 修改
continuous-integration/drone/push Build is passing
2025-09-12 16:54:44 +08:00
he 90a3021938 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-12 16:45:12 +08:00
he bc3f5c9394 PCWG间隔天数基线改为NA 2025-09-12 16:45:11 +08:00
hang 9e3eafa925 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-12 13:57:42 +08:00
hang 98f0e9e1a1 修改美国配置文件 2025-09-12 13:57:41 +08:00
he b66b3fcc6c 修改
continuous-integration/drone/push Build is passing
2025-09-12 13:40:09 +08:00
he 608f6387ae 修改
continuous-integration/drone/push Build is passing
2025-09-12 13:31:05 +08:00
he 4f7e73c990 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-12 13:23:06 +08:00
he 8baa8b7421 MRECISTHCCC 同步病灶修改 2025-09-12 13:23:05 +08:00
hang bb38899cee Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-12 13:17:14 +08:00
hang 64f04a3953 维护代码修改-人员添加默认课题组 2025-09-12 13:17:12 +08:00
he 38a42dc44f 去除报告缓存
continuous-integration/drone/push Build is passing
2025-09-12 11:35:41 +08:00
he 4c396dc4ae 修改复制 recist1.1 淋巴结病灶状态
continuous-integration/drone/push Build is passing
2025-09-12 11:30:52 +08:00
he e17d973fad 去掉骨扫描筛选
continuous-integration/drone/push Build is passing
2025-09-12 11:06:21 +08:00
he 1efe15a776 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-12 11:01:00 +08:00
he d7f87f77ab 删除FristAddTaskNum 2025-09-12 11:00:57 +08:00
hang 7eff5fd1bb 项目参与人员 去掉GA
continuous-integration/drone/push Build is passing
2025-09-12 09:49:55 +08:00
hang 2fe3441c3f 修改编译错误
continuous-integration/drone/push Build is passing
2025-09-12 09:07:34 +08:00
hang 98741d9a3b 接收影像第一张的时候就开始打标签
continuous-integration/drone/push Build is passing
2025-09-12 09:00:59 +08:00
hang 9386b89110 修改登出bug
continuous-integration/drone/push Build is passing
2025-09-11 17:46:03 +08:00
hang 32ca60156e 患者直接加入项目过滤
continuous-integration/drone/push Build is passing
2025-09-11 15:49:49 +08:00
hang b2022a912f 修改课题组绑定,和GA用户列表查看
continuous-integration/drone/push Build is passing
2025-09-11 14:52:32 +08:00
hang ffedc3f378 修改检查绑定+ GA 看到的课题组过滤
continuous-integration/drone/push Build is passing
2025-09-11 14:29:45 +08:00
hang 6d042459e3 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-11 14:09:27 +08:00
hang 0a5164682f admin 可以看所有医院,不受默认医院影响 2025-09-11 14:09:21 +08:00
he 62037c0d43 修改模板
continuous-integration/drone/push Build is passing
2025-09-10 17:29:38 +08:00
he ec45d80b9b 修改
continuous-integration/drone/push Build is passing
2025-09-10 16:35:52 +08:00
he 4187673b7a 修改
continuous-integration/drone/push Build is passing
2025-09-10 15:59:41 +08:00
he ad62ad7ae0 代码提交
continuous-integration/drone/push Build is passing
2025-09-10 15:48:35 +08:00
he 87709f0122 Ires肿瘤导出
continuous-integration/drone/push Build is passing
2025-09-10 15:25:03 +08:00
he 5ade2135ee 修改
continuous-integration/drone/push Build is passing
2025-09-10 15:11:34 +08:00
he f0a38ebec9 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-10 14:43:21 +08:00
he 15b50e39f1 代码修改 2025-09-10 14:43:19 +08:00
hang 5f71d7f1b2 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-10 13:12:43 +08:00
hang f4f94f1f48 增加课题组标签 相关接口 2025-09-10 13:12:40 +08:00
he 21cafcab53 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-10 11:14:13 +08:00
he c37903b2f4 bug 修改 2025-09-10 11:14:10 +08:00
hang 1fc70b1340 增加课题组标签,以及患者和标签关联
continuous-integration/drone/push Build is passing
2025-09-10 10:54:56 +08:00
hang 36844c291a Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-10 10:36:33 +08:00
hang 9b96259e59 修改课题组展示 2025-09-10 10:36:32 +08:00
he 4c3a96a0f6 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is failing
2025-09-09 18:12:17 +08:00
he 154c12eb93 稽查单位 2025-09-09 18:12:16 +08:00
hang c09f27bf7d Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-09 18:00:04 +08:00
hang f80ac02562 账号课题组启用禁用,系统课题组启用禁用实时修改 2025-09-09 18:00:03 +08:00
he f49d2ce06b 添加单位
continuous-integration/drone/push Build is passing
2025-09-09 17:42:39 +08:00
he eff5920568 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-09 17:07:07 +08:00
he 05be768188 单位翻译 2025-09-09 17:07:05 +08:00
hang c9387463ba 默认单位修改
continuous-integration/drone/push Build is passing
2025-09-09 15:41:51 +08:00
hang b230139f67 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-09 15:24:17 +08:00
hang d833093c33 设置subject 访视软删除 2025-09-09 15:24:11 +08:00
he c62fb1df92 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-09 14:49:53 +08:00
he 8c1a25aae3 稽查修改 2025-09-09 14:49:52 +08:00
hang 758e0aedcb 修改项目绑定检查课题组
continuous-integration/drone/push Build is passing
2025-09-09 14:41:04 +08:00
hang 563be56d27 PM 创建项目课题组下拉框
continuous-integration/drone/push Build is passing
2025-09-09 13:19:09 +08:00
hang db2bd6b725 增加用户列表查询条件
continuous-integration/drone/push Build is passing
2025-09-09 11:42:20 +08:00
hang 81d9fcae2e 修改国际化
continuous-integration/drone/push Build is passing
2025-09-09 11:38:17 +08:00
hang ea87692f49 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-09 10:49:44 +08:00
hang cee9d92a72 修改课题组 和导表去掉中心查询 2025-09-09 10:49:41 +08:00
he bbe89ade16 修改
continuous-integration/drone/push Build is passing
2025-09-09 09:47:43 +08:00
he 16e348a996 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-09 09:09:18 +08:00
he b6e3032767 修改 2025-09-09 09:09:16 +08:00
hang 690c759fa1 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-08 18:00:52 +08:00
hang 56a15f3b61 修改上传 2025-09-08 18:00:50 +08:00
he 589e9868a8 修改
continuous-integration/drone/push Build is passing
2025-09-08 16:32:23 +08:00
he 82afae93dc Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-08 16:00:55 +08:00
he 6875cf3188 修改 2025-09-08 16:00:53 +08:00
hang 076d99c6ba 增加通用工具返回路径
continuous-integration/drone/push Build is passing
2025-09-08 15:38:30 +08:00
hang 79d39125ff 或者文档
continuous-integration/drone/push Build is running
2025-09-08 15:35:07 +08:00
hang aafc1cd064 当前登录用户得课题组
continuous-integration/drone/push Build is passing
2025-09-08 15:26:08 +08:00
hang 26e7305bcf 返回课题组编码 和AE 限制
continuous-integration/drone/push Build is passing
2025-09-08 14:44:30 +08:00
hang d1e08b0fc0 漏提交事务
continuous-integration/drone/push Build is passing
2025-09-08 10:30:15 +08:00
hang df87c56544 导表Excel处理
continuous-integration/drone/push Build is passing
2025-09-05 16:34:48 +08:00
he a3b69d45ae 添加字段
continuous-integration/drone/push Build is passing
2025-09-05 15:16:46 +08:00
he ef95cdd4ec 添加字段
continuous-integration/drone/push Build is passing
2025-09-05 15:12:02 +08:00
he 4d7d42753f 修改
continuous-integration/drone/push Build is passing
2025-09-05 14:44:35 +08:00
he 9e9db251c8 修改
continuous-integration/drone/push Build is passing
2025-09-05 14:37:17 +08:00
he 8b1626e292 阅片期查询修改
continuous-integration/drone/push Build is passing
2025-09-05 14:21:50 +08:00
he a5a2dcdac9 PCWG需要全局
continuous-integration/drone/push Build is passing
2025-09-05 13:16:47 +08:00
he 93ea0cf8d1 修改模板
continuous-integration/drone/push Build is passing
2025-09-05 11:38:04 +08:00
he b91ea2c176 导出修改
continuous-integration/drone/push Build is passing
2025-09-05 11:22:03 +08:00
he 75be9eba74 导出修改
continuous-integration/drone/push Build is passing
2025-09-05 11:06:14 +08:00
he 335535d6d3 英文模版导出修改
continuous-integration/drone/push Build is passing
2025-09-05 10:13:29 +08:00
he 8b61b288fc Reapply "先改IRes导出"
This reverts commit f08a5b0d46.
2025-09-05 09:55:01 +08:00
he f08a5b0d46 Revert "先改IRes导出"
This reverts commit 7bc3378e0c.
2025-09-05 09:51:09 +08:00
he 7bc3378e0c 先改IRes导出
continuous-integration/drone/push Build is passing
2025-09-05 09:50:46 +08:00
he b87e531920 修改
continuous-integration/drone/push Build is passing
2025-09-04 14:50:27 +08:00
he d5234db48a 重置阅片任务
continuous-integration/drone/push Build is passing
2025-09-04 13:30:47 +08:00
he 7f6933df35 典型肝内病灶添加
continuous-integration/drone/push Build is running
2025-09-04 13:29:47 +08:00
he 70bff24348 修改患者编号
continuous-integration/drone/push Build is failing
2025-09-04 11:40:35 +08:00
he a8a1198c52 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-04 11:24:09 +08:00
he bd83153743 加入TNM分期 2025-09-04 11:24:07 +08:00
hang deeffe034b Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-04 11:18:58 +08:00
hang 39f579c10b 国际化修改提交 2025-09-04 11:18:56 +08:00
he 77eac6c1d0 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-04 09:46:54 +08:00
he 5cc192b317 导出修改 2025-09-04 09:46:53 +08:00
hang ba12a2977b 修改存储服务存储非封装的影像
continuous-integration/drone/push Build is passing
2025-09-03 16:32:54 +08:00
hang 1a7576039b Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-03 16:25:49 +08:00
hang 780f6451c3 修改稽查 2025-09-03 16:25:47 +08:00
he b576478eea Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-03 15:45:26 +08:00
he 8cbc5c5c26 发布 2025-09-03 15:45:25 +08:00
hang 0245aaf7ad Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build was killed
2025-09-03 15:42:32 +08:00
hang d954d13f81 minio 6.0.4 2025-09-03 15:42:30 +08:00
he c9e12993a6 修改
continuous-integration/drone/push Build is running
2025-09-03 15:40:58 +08:00
he 088a0b6fd5 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-03 15:36:06 +08:00
he 6b18e5eced 修改 2025-09-03 15:36:04 +08:00
hang 5673fcad5f 修改获取请求url测试
continuous-integration/drone/push Build is passing
2025-09-03 15:30:48 +08:00
hang 697ac6f57b Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-03 15:21:05 +08:00
hang e9b3b012f9 修改minio 版本测试 2025-09-03 15:21:03 +08:00
he d5d3d6e1c9 修改
continuous-integration/drone/push Build is passing
2025-09-03 15:03:03 +08:00
he 712d87a4dd 修改
continuous-integration/drone/push Build is passing
2025-09-03 14:47:52 +08:00
he f082217e99 稽查修改
continuous-integration/drone/push Build is passing
2025-09-03 14:43:15 +08:00
hang 16e5a0567f 修改查询
continuous-integration/drone/push Build is passing
2025-09-03 13:49:29 +08:00
hang 5fa12786aa 修改版本
continuous-integration/drone/push Build is passing
2025-09-03 12:13:16 +08:00
he 4350aa6459 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-03 11:46:23 +08:00
he 897dd2118d 稽查修改 2025-09-03 11:46:22 +08:00
hang f84a9c481a linux断点调试
continuous-integration/drone/push Build is passing
2025-09-03 11:30:21 +08:00
hang 3cb0ed4cd5 输出路径
continuous-integration/drone/push Build is passing
2025-09-03 11:16:17 +08:00
hang e346bfc527 创建目录测试
continuous-integration/drone/push Build is passing
2025-09-03 10:43:37 +08:00
hang 831ae8a591 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is failing
2025-09-02 18:08:28 +08:00
hang b359508ab4 修改minio 下载测试 2025-09-02 18:08:25 +08:00
he 7750b1ba12 BM报告
continuous-integration/drone/push Build is passing
2025-09-02 17:56:13 +08:00
he f5f4639cc8 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-02 17:09:18 +08:00
he 32e659c26b 重新发布 2025-09-02 17:09:17 +08:00
hang 2f69df7a83 修改绑定
continuous-integration/drone/push Build is passing
2025-09-02 16:50:50 +08:00
hang ff0662867e 修改角色默认值,返回用户基本信息
continuous-integration/drone/push Build is passing
2025-09-02 16:04:58 +08:00
hang 3ee9703dca Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-02 14:07:12 +08:00
hang 217df5dc2f 删除中心参数 2025-09-02 14:07:09 +08:00
he 7fe61af141 报告
continuous-integration/drone/push Build is passing
2025-09-02 13:39:51 +08:00
he a37a77949a 代码提交
continuous-integration/drone/push Build is passing
2025-09-02 13:28:31 +08:00
he eb885cc568 修改
continuous-integration/drone/push Build is passing
2025-09-02 10:52:15 +08:00
he c78a96eed0 添加适用的标准
continuous-integration/drone/push Build is passing
2025-09-01 17:28:16 +08:00
he f8b23604c2 分裂修改
continuous-integration/drone/push Build is passing
2025-09-01 17:18:48 +08:00
he 26d60857bf 稽查
continuous-integration/drone/push Build is running
2025-09-01 17:16:43 +08:00
he 4c9b3e1a23 代码提交
continuous-integration/drone/push Build is passing
2025-09-01 16:58:44 +08:00
he 5526a2dd53 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-01 16:20:17 +08:00
he f69ad1b4e3 稽查修改 2025-09-01 16:20:15 +08:00
hang b869693d63 修改遗漏领取逻辑
continuous-integration/drone/push Build is passing
2025-09-01 16:06:42 +08:00
hang 6f8f6000ba 增加影像分享配置
continuous-integration/drone/push Build is passing
2025-09-01 15:12:23 +08:00
hang ed5f8e8d9c 自动绑定逻辑bug
continuous-integration/drone/push Build is passing
2025-09-01 14:55:35 +08:00
hang 550cdff28f Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-01 14:27:03 +08:00
hang 6e363601a6 GA 非管理员看到的人员列表 2025-09-01 14:27:00 +08:00
he 6a63ffd1f2 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-01 13:32:59 +08:00
he 03c8cdd1d2 稽查修改 2025-09-01 13:32:58 +08:00
hang 99e5b102b7 修改bug
continuous-integration/drone/push Build is running
2025-09-01 13:32:24 +08:00
hang b331799b3f Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-01 13:13:07 +08:00
hang 20014e66d0 影像分享功能增加 2025-09-01 13:13:06 +08:00
he 8be56c5a4d Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-09-01 11:10:08 +08:00
he fa3df97dab 修改 2025-09-01 11:10:07 +08:00
hang dfd4cd533b Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is running
2025-09-01 11:09:00 +08:00
hang 0d3d1a7f70 修改提交影像逻辑测试 2025-09-01 11:08:56 +08:00
he c418b7e474 修改
continuous-integration/drone/push Build is passing
2025-09-01 10:42:29 +08:00
he ab79eff346 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is running
2025-09-01 10:41:21 +08:00
he c6e8ec0149 代码修改 2025-09-01 10:41:20 +08:00
hang e143cb0e73 修改绑定bug
continuous-integration/drone/push Build is passing
2025-08-29 18:09:59 +08:00
hang 5d1499025b 修改课题组删除操作
continuous-integration/drone/push Build is passing
2025-08-29 17:47:11 +08:00
hang 87c22f1033 修改检查删除课题组
continuous-integration/drone/push Build is passing
2025-08-29 17:34:27 +08:00
hang be5fc58ef7 修改GA课题组管理员查询下拉框
continuous-integration/drone/push Build is passing
2025-08-29 16:37:01 +08:00
hang d769d43d23 修改项目过滤和添加到项目
continuous-integration/drone/push Build is passing
2025-08-29 15:59:45 +08:00
hang 9de6a3c813 修改日志记录
continuous-integration/drone/push Build is passing
2025-08-29 14:52:24 +08:00
hang e38219a0ee Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-29 14:30:40 +08:00
hang 874d94cefb 编译错误 2025-08-29 14:30:38 +08:00
he 8e3f7d4ba4 更新修改
continuous-integration/drone/push Build is running
2025-08-29 14:29:32 +08:00
he 1d918909f0 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-29 14:24:15 +08:00
he 13b4c90518 文档修改 2025-08-29 14:24:14 +08:00
hang 2d2f399601 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is running
2025-08-29 14:21:55 +08:00
hang f49d8d81b1 修改课题组管理员 和普通GA 看到列表的区别 2025-08-29 14:21:53 +08:00
he 450f6c00ce Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-29 14:06:03 +08:00
he 07d4df81f6 模板代码修改 2025-08-29 14:06:03 +08:00
hang 2b696855cc Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-29 13:43:57 +08:00
hang 64bf0fb622 GA 获取自己是管理员的课题组列表 2025-08-29 13:43:56 +08:00
he 68fa7ce02e Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-29 13:38:14 +08:00
he bd8cf9ee42 修改 2025-08-29 13:38:14 +08:00
hang 224382bf62 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-29 11:36:31 +08:00
hang a19ba3c215 处理scp服务 拆分影像 2025-08-29 11:36:27 +08:00
he 5975004858 修改
continuous-integration/drone/push Build is running
2025-08-29 11:36:07 +08:00
he baffb0bb35 修改
continuous-integration/drone/push Build is passing
2025-08-29 10:51:28 +08:00
he 6ed0ea76da 修改
continuous-integration/drone/push Build is running
2025-08-29 10:50:09 +08:00
he 55f864c16c Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is running
2025-08-29 10:49:19 +08:00
he 59ecaaa5a7 修改关键帧 2025-08-29 10:49:16 +08:00
hang 4945daa0d4 增加默认值
continuous-integration/drone/push Build is passing
2025-08-28 17:32:42 +08:00
hang 59339969da 修改课题组管理
continuous-integration/drone/push Build is running
2025-08-28 17:29:42 +08:00
hang fdbdda71eb 课题组GA 是否被禁用
continuous-integration/drone/push Build is passing
2025-08-28 17:04:45 +08:00
hang b7c85d6b56 用户的课题组必须启用才能看到项目
continuous-integration/drone/push Build is passing
2025-08-28 16:38:42 +08:00
hang e3e884393f Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-28 16:25:26 +08:00
hang 70c744498b 修改待阅列表返回信息 2025-08-28 16:25:23 +08:00
he a3f8730aa8 添加 签名之后 不让设置TNMValue
continuous-integration/drone/push Build is passing
2025-08-28 16:16:31 +08:00
he d0352590ed 添加 TNMValue
continuous-integration/drone/push Build is running
2025-08-28 16:14:09 +08:00
he fd04315f17 添加字段
continuous-integration/drone/push Build is running
2025-08-28 15:55:15 +08:00
hang 6482316195 修改出生日期
continuous-integration/drone/push Build is passing
2025-08-28 15:18:03 +08:00
hang 525cae7232 修改查询条件
continuous-integration/drone/push Build is passing
2025-08-28 15:01:18 +08:00
hang afaba95ff2 影像修改信息展示
continuous-integration/drone/push Build is passing
2025-08-28 14:34:24 +08:00
he 5258ae5d4b Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-28 14:16:27 +08:00
he 54e30f008c 添加EvaluateProgress 任务评估进度相关字段 2025-08-28 14:16:25 +08:00
hang 9569cdab5f 更新callingAE
continuous-integration/drone/push Build is passing
2025-08-28 13:48:07 +08:00
hang e189daf569 增加字段
continuous-integration/drone/push Build is passing
2025-08-28 13:17:24 +08:00
hang 9b60114476 返回信息
continuous-integration/drone/push Build is passing
2025-08-28 11:34:41 +08:00
hang 97c123677e 课题组修改
continuous-integration/drone/push Build is passing
2025-08-28 09:29:06 +08:00
hang a3b57e2a04 项目基本信息返回课题组名字
continuous-integration/drone/push Build is passing
2025-08-27 17:20:26 +08:00
hang f80c1ec86e 列表过滤
continuous-integration/drone/push Build is passing
2025-08-27 17:10:31 +08:00
hang 32d613b146 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-27 15:59:10 +08:00
hang 649b02d5d3 人员退出,参与项目bug 2025-08-27 15:59:08 +08:00
he e622f601a4 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-27 15:19:50 +08:00
he fce4fd52de 修改 2025-08-27 15:19:49 +08:00
hang ed2a777fd4 修改缓存,删除限制
continuous-integration/drone/push Build is passing
2025-08-27 14:21:39 +08:00
hang 4de4e36e73 修改配置文件
continuous-integration/drone/push Build is passing
2025-08-27 09:48:33 +08:00
hang 17937783e9 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-27 09:42:11 +08:00
hang d1f79cd06b 修改配置文件,更新库 2025-08-27 09:42:10 +08:00
he 3f075ec367 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-27 09:18:02 +08:00
he 77add17984 添加获取关键序列 2025-08-27 09:18:01 +08:00
hang 06eae02b7a Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-26 17:25:58 +08:00
hang d7b5066683 项目添加和更新 2025-08-26 17:25:55 +08:00
he 046ad55b57 代码迁移
continuous-integration/drone/push Build is passing
2025-08-26 15:28:39 +08:00
he 9782c5ee04 获取访视下拉
continuous-integration/drone/push Build is passing
2025-08-26 14:23:20 +08:00
he 5f7c4dda97 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-26 14:14:53 +08:00
he 4ad3d30b1d 修改首次异地登录 2025-08-26 14:14:42 +08:00
hang 0f272ad935 遗漏修改
continuous-integration/drone/push Build is running
2025-08-26 14:11:39 +08:00
hang 68ac4c80af 修改scp 服务传输语法获取值
continuous-integration/drone/push Build is passing
2025-08-26 14:07:13 +08:00
hang 66095bccb1 重新拉取的时候更新检查信息
continuous-integration/drone/push Build is passing
2025-08-26 13:32:35 +08:00
hang 1fd2c01612 修改更新用户bug
continuous-integration/drone/push Build is passing
2025-08-26 13:06:53 +08:00
hang 98547ef145 修改映射方式
continuous-integration/drone/push Build is passing
2025-08-26 11:51:06 +08:00
hang efa9e511c3 预先提交准备测试 删除添加角色的问题
continuous-integration/drone/push Build is passing
2025-08-26 11:25:37 +08:00
hang b4e2af4c63 影像汇总页面增加
continuous-integration/drone/push Build is passing
2025-08-26 10:43:55 +08:00
hang 25425eab93 模型给默认参数
continuous-integration/drone/push Build is passing
2025-08-26 10:11:28 +08:00
hang e7261b1c7e dicom dir 增加字段,修改下载接口
continuous-integration/drone/push Build is passing
2025-08-26 10:07:59 +08:00
hang 02f3bfbfdd 默认值问题修改
continuous-integration/drone/push Build is passing
2025-08-25 16:01:05 +08:00
hang 9995a1b519 实体模型给默认值
continuous-integration/drone/push Build is passing
2025-08-25 15:55:51 +08:00
hang 10b47de079 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is running
2025-08-25 15:47:21 +08:00
hang ebf0c6b086 增加收藏功能 2025-08-25 15:47:19 +08:00
he 621da36150 添加Lugano 标准相关信息
continuous-integration/drone/push Build is passing
2025-08-25 15:41:27 +08:00
he 34f52d8218 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-25 14:41:16 +08:00
he 0c1dcd4610 添加是否双屏字段 2025-08-25 14:41:14 +08:00
hang ebaa2af196 修改c-find 列表
continuous-integration/drone/push Build is passing
2025-08-25 13:46:23 +08:00
hang 552509ad9e 修改项目用户
continuous-integration/drone/push Build is passing
2025-08-22 13:39:53 +08:00
hang 806f829e08 课题组打标签
continuous-integration/drone/push Build is passing
2025-08-22 11:02:13 +08:00
hang 75f0f5e3a5 增加callningAE
continuous-integration/drone/push Build is passing
2025-08-21 17:36:57 +08:00
hang 652d90af98 修改GA 过滤
continuous-integration/drone/push Build is passing
2025-08-21 16:16:41 +08:00
hang c4d1c652a3 编译错误
continuous-integration/drone/push Build is passing
2025-08-21 14:31:30 +08:00
hang 01b61f8fb6 修改判断
continuous-integration/drone/push Build is running
2025-08-21 14:30:29 +08:00
hang 7542c20bcc 修改查询
continuous-integration/drone/push Build is passing
2025-08-21 13:58:56 +08:00
hang 3a65046c48 修改课题组列表
continuous-integration/drone/push Build is passing
2025-08-21 13:42:28 +08:00
hang 659aadbc7f 修改接口
continuous-integration/drone/push Build is passing
2025-08-21 11:45:13 +08:00
hang 8b72566b91 修改接口和映射
continuous-integration/drone/push Build is passing
2025-08-21 11:08:37 +08:00
hang ce25556a9f 获取用户详情返回数组
continuous-integration/drone/push Build is passing
2025-08-21 10:47:40 +08:00
hang 1847e6f76f 修改过滤条件
continuous-integration/drone/push Build is passing
2025-08-21 09:56:56 +08:00
hang e6bf9697a5 课题组增加字段
continuous-integration/drone/push Build is passing
2025-08-20 15:26:40 +08:00
hang d2eec7676d GA 添加用户,下拉框过滤课题组
continuous-integration/drone/push Build is running
2025-08-20 15:25:26 +08:00
hang 7525c14e7d 邮箱校验规则返回
continuous-integration/drone/push Build is passing
2025-08-20 14:53:36 +08:00
hang 5644a2acd7 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-20 14:13:10 +08:00
hang d48ffc5051 课题组增加状态 2025-08-20 14:13:07 +08:00
he 48bb5ce47a 修改bug
continuous-integration/drone/push Build is passing
2025-08-20 14:04:53 +08:00
he 8693e3169c Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-20 13:53:41 +08:00
he f73529bfc1 查询修改 2025-08-20 13:53:41 +08:00
hang df6b89b3be 切换医院,设置缓存bug 修改
continuous-integration/drone/push Build is running
2025-08-20 13:52:40 +08:00
hang 893effcefe Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-20 13:25:23 +08:00
hang 77444e35fa 项目绑定医院,防止演示切换医院 2025-08-20 13:25:21 +08:00
he 53007ccb6a 修改bug
continuous-integration/drone/push Build is passing
2025-08-20 11:30:24 +08:00
he b301d51b2d 修改项目下拉筛选
continuous-integration/drone/push Build is passing
2025-08-20 11:21:23 +08:00
he b5d259f907 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is running
2025-08-20 11:18:11 +08:00
he 721826e346 修改项目下拉查询 2025-08-20 11:18:10 +08:00
hang c479574905 项目列表过滤
continuous-integration/drone/push Build is running
2025-08-20 11:16:23 +08:00
hang 291801efe2 修改HIR配置文件
continuous-integration/drone/push Build is passing
2025-08-20 11:10:58 +08:00
hang 13e907f876 邮件修改
continuous-integration/drone/push Build is passing
2025-08-20 10:52:34 +08:00
hang bee3084bbf 修改系统邮件配置
continuous-integration/drone/push Build is passing
2025-08-19 17:40:06 +08:00
hang 9300f5756d 精简日志展示
continuous-integration/drone/push Build is passing
2025-08-19 16:20:49 +08:00
hang 7b3cac1f63 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-19 16:08:17 +08:00
hang 0acdcbae0e 校验码接口修改 2025-08-19 16:08:16 +08:00
he 2c3483fa4e 修改
continuous-integration/drone/push Build is passing
2025-08-19 15:37:14 +08:00
hang 1b6d1dd4cb Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-19 15:07:34 +08:00
hang a9b907b717 修改签名接口 2025-08-19 15:07:33 +08:00
he ce5ca145ed Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-19 14:46:38 +08:00
he 15c9a370ee 添加服务注册 2025-08-19 14:46:37 +08:00
hang 006afc56d5 修改列表过滤
continuous-integration/drone/push Build is passing
2025-08-19 14:29:54 +08:00
hang 29da1ab464 修改用户,项目添加接口增加参数
continuous-integration/drone/push Build is passing
2025-08-19 09:57:12 +08:00
hang a7db0c2887 增加项目课题组,缓存bug修改
continuous-integration/drone/push Build is passing
2025-08-18 18:04:28 +08:00
hang f409c6468e Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-18 15:34:30 +08:00
hang ade2bdf181 项目运维人员修改 2025-08-18 15:34:28 +08:00
he 9ecbfb37aa Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-18 15:02:32 +08:00
he c44c861086 中山医院模版 2025-08-18 15:02:31 +08:00
hang a2deb93b6c x
continuous-integration/drone/push Build is passing
2025-08-18 14:24:34 +08:00
hang 5527f51880 验证通过,返回账户信息Id
continuous-integration/drone/push Build is running
2025-08-18 14:23:25 +08:00
hang b8d9cf1630 课题组修改管理员
continuous-integration/drone/push Build is passing
2025-08-18 14:03:47 +08:00
hang 73f1f2938f HIR 课题组列表增加
continuous-integration/drone/push Build is passing
2025-08-18 13:42:04 +08:00
hang 5ea6d221e3 修改账户触发日志
continuous-integration/drone/push Build is passing
2025-08-18 11:44:52 +08:00
hang 30edf87bc0 修改登录认证授权
continuous-integration/drone/push Build is passing
2025-08-18 10:41:31 +08:00
he 93a6bee01b Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-18 09:26:52 +08:00
he 17a7634a37 修改swagger 不显示某些方法 2025-08-18 09:26:50 +08:00
hang 4048c28628 升级efcore 测试内存
continuous-integration/drone/push Build is passing
2025-08-15 21:08:47 +08:00
hang 816d81b555 临时提交,解决swagger 大内存问题
continuous-integration/drone/push Build is passing
2025-08-15 18:49:27 +08:00
hang dedb1c152f 修改映射
continuous-integration/drone/push Build is passing
2025-08-15 14:44:17 +08:00
hang 083090ca05 swagger bug 核对
continuous-integration/drone/push Build is passing
2025-08-15 14:35:03 +08:00
hang 31c86c5d4a 升级swagger 版本测试
continuous-integration/drone/push Build is passing
2025-08-15 13:22:04 +08:00
hang bf785156f4 IRC swagger 迁移
continuous-integration/drone/push Build is running
2025-08-15 11:26:24 +08:00
hang 15af716651 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-15 10:55:26 +08:00
hang a2bd2857b2 映射修改 2025-08-15 10:55:24 +08:00
he d0351ef405 同步表结构
continuous-integration/drone/push Build is passing
2025-08-15 09:58:56 +08:00
hang 552a77ecd4 HIR 用户 文档调整第二次变更
continuous-integration/drone/push Build is passing
2025-08-15 09:50:39 +08:00
hang 9f10af6654 HIR 用户调整,初步修改
continuous-integration/drone/push Build is passing
2025-08-14 16:11:00 +08:00
hang 55c87d673c 测试结束
continuous-integration/drone/push Build is passing
2025-08-12 17:48:07 +08:00
hang 2607a05104 再次测试
continuous-integration/drone/push Build is passing
2025-08-12 17:13:09 +08:00
hang 4f2dc949a5 还原初始拉取
continuous-integration/drone/push Build is passing
2025-08-12 17:02:26 +08:00
hang 3695c5d596 继续测试
continuous-integration/drone/push Build is passing
2025-08-12 16:33:41 +08:00
hang 91cf1ab48c ?pacs 问题
continuous-integration/drone/push Build is passing
2025-08-12 16:27:35 +08:00
hang 2b2c5e3d77 还原,使用tag传输不行
continuous-integration/drone/push Build is passing
2025-08-12 16:13:09 +08:00
hang 94c4a81974 使用公用tag 传递信息
continuous-integration/drone/push Build is passing
2025-08-12 16:06:01 +08:00
hang b5956ef6d2 cmove 增加私有tag 测试
continuous-integration/drone/push Build is passing
2025-08-12 15:47:44 +08:00
hang 3861e7642a cmove-测试
continuous-integration/drone/push Build is passing
2025-08-12 15:33:19 +08:00
he 1bfe23f9ec Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-12 15:17:47 +08:00
he 9f0647e156 修复bug 2025-08-12 15:17:46 +08:00
hang 7f6222a0bc Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-08-12 15:03:41 +08:00
hang 39c07ecc4f 测试课题组信息传输 2025-08-12 15:03:39 +08:00
he 28c9b72e35 bug 修复
continuous-integration/drone/push Build is passing
2025-08-12 09:25:37 +08:00
hang 2778ecb74a 修改dicom 取tag bug2
continuous-integration/drone/push Build is passing
2025-07-25 10:36:22 +08:00
hang 40cbd73226 修改dicom 取tag bug
continuous-integration/drone/push Build is running
2025-07-25 10:35:54 +08:00
hang 7b456c9008 pacs server 使用c-find 其他的c-echo
continuous-integration/drone/push Build is passing
2025-07-17 14:34:04 +08:00
hang 011a75714e Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-07-17 14:20:48 +08:00
hang 38f408d1de 修改dicomAE 测试使用c-find,同时在c-find前不进行测试 2025-07-17 14:20:47 +08:00
he 006d1bd167 Revert "稽查修改"
continuous-integration/drone/push Build is passing
This reverts commit 83e64fd4aa.
2025-07-17 10:20:33 +08:00
he 83e64fd4aa 稽查修改
continuous-integration/drone/push Build is passing
2025-07-17 09:56:35 +08:00
hang 7c7ce6632a 获取授权码接口调整
continuous-integration/drone/push Build is passing
2025-05-29 14:48:57 +08:00
hang 787bc250c1 X
continuous-integration/drone/push Build is passing
2025-05-27 17:07:26 +08:00
hang 3b5ac96a98 导出bug
continuous-integration/drone/push Build is passing
2025-05-14 15:59:04 +08:00
hang 3d4dc0c1f4 HIR 导出bug
continuous-integration/drone/push Build is passing
2025-05-14 15:50:42 +08:00
hang 2990420361 修改缓存bug
continuous-integration/drone/push Build is passing
2025-05-13 14:28:27 +08:00
hang 2521147579 增加医院通用配置
continuous-integration/drone/push Build is passing
2025-05-13 10:19:17 +08:00
hang 4f860cca07 恢复老接口
continuous-integration/drone/push Build is passing
2025-05-09 09:49:17 +08:00
hang bea324aa56 增加访视名称查询
continuous-integration/drone/push Build is passing
2025-04-30 14:01:08 +08:00
hang c78cbbb737 重阅修改测量数据
continuous-integration/drone/push Build is passing
2025-04-28 18:00:33 +08:00
he e197f6c2bb 修改
continuous-integration/drone/push Build is passing
2025-04-27 17:51:36 +08:00
he c7d8e38cd3 模板修改
continuous-integration/drone/push Build is passing
2025-04-27 15:36:30 +08:00
he 8a241754ca Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-04-25 14:47:49 +08:00
he b3e77ec422 模板修改 2025-04-25 14:47:48 +08:00
hang daf593f76a 邮箱修改
continuous-integration/drone/push Build is passing
2025-04-24 11:05:21 +08:00
hang 5c4388a2e7 修改初始化逻辑
continuous-integration/drone/push Build is passing
2025-04-24 10:40:58 +08:00
hang 0da73ce1db 单独修改单位
continuous-integration/drone/push Build is passing
2025-04-24 09:58:53 +08:00
hang 1d2ef4561f 修改账号信息
continuous-integration/drone/push Build is passing
2025-04-24 09:42:44 +08:00
hang dbf75535c5 统一修改用户信息
continuous-integration/drone/push Build is passing
2025-04-24 09:35:32 +08:00
he aa34c96a39 模板修改
continuous-integration/drone/push Build is passing
2025-04-23 11:29:28 +08:00
he e6b6a24b3b 添加英文模板
continuous-integration/drone/push Build is passing
2025-04-22 17:49:09 +08:00
hang 0b958f21a5 修改切换角色 统一密码,checkCode 首次登录标志
continuous-integration/drone/push Build is passing
2025-04-21 13:37:56 +08:00
hang e6310a4533 过滤OA
continuous-integration/drone/push Build is passing
2025-04-18 17:46:51 +08:00
hang 49c3a0d494 修改国际化
continuous-integration/drone/push Build is passing
2025-04-18 13:06:59 +08:00
hang 213cb69332 修改切换医院bug
continuous-integration/drone/push Build is passing
2025-04-18 10:03:35 +08:00
hang e43dce220c 修改激活逻辑
continuous-integration/drone/push Build is passing
2025-04-18 09:54:44 +08:00
hang 52dc6e05d4 修改名字
continuous-integration/drone/push Build is passing
2025-04-17 10:10:39 +08:00
hang 31e76a2e97 HIR 修改配置文件
continuous-integration/drone/push Build is running
2025-04-17 10:08:01 +08:00
hang 19d9ca44fb 修改映射配置,字段
continuous-integration/drone/push Build is passing
2025-04-14 15:33:55 +08:00
hang c8b0681dfa Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-04-03 16:21:01 +08:00
hang eed17feae0 上传自签署https minio 2025-04-03 16:20:59 +08:00
he c0478ef96e 修改
continuous-integration/drone/push Build is running
2025-04-03 16:19:32 +08:00
he 4713d2a09b Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-04-03 16:05:01 +08:00
he ea72e6cf65 修改 2025-04-03 16:05:01 +08:00
hang 9f5aee9258 修改hir minio 上传测试
continuous-integration/drone/push Build is passing
2025-04-03 15:57:06 +08:00
hang e56d1b9573 换一种方式忽略证书
continuous-integration/drone/push Build is passing
2025-04-03 11:14:06 +08:00
hang 6d5a7bd3a2 修改验证https 证书测试
continuous-integration/drone/push Build is passing
2025-04-03 11:03:45 +08:00
he a73ef7108b 没用的文件删除
continuous-integration/drone/push Build is passing
2025-04-03 10:35:45 +08:00
he 507500f051 先不删除文件
continuous-integration/drone/push Build is passing
2025-04-03 10:12:47 +08:00
he 913084cc8d 修改
continuous-integration/drone/push Build is passing
2025-04-03 09:57:37 +08:00
he 5874223866 修改
continuous-integration/drone/push Build is passing
2025-04-03 09:55:04 +08:00
he d5609560e2 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-04-03 09:20:23 +08:00
he a5b4ab6531 修改 2025-04-03 09:20:22 +08:00
hang a91705b35d tj cmove 检查
continuous-integration/drone/push Build is passing
2025-04-02 10:01:33 +08:00
hang 65369c73bf 测试发布
continuous-integration/drone/push Build is passing
2025-04-01 17:32:37 +08:00
hang eb9bb75825 修改创建的临时token
continuous-integration/drone/push Build is passing
2025-04-01 17:04:50 +08:00
hang 69216ae75d HIR 同济对接接口完成
continuous-integration/drone/push Build is passing
2025-04-01 16:06:53 +08:00
hang 309ea7b1d1 HIR 对接自动生成账号
continuous-integration/drone/push Build is passing
2025-04-01 15:01:39 +08:00
hang 5beacacc0f 医院修改,导致配置修改
continuous-integration/drone/push Build is passing
2025-03-28 14:38:23 +08:00
hang 008a909f5b 增加统计配置文件
continuous-integration/drone/push Build is passing
2025-03-28 14:17:45 +08:00
hang bdfc65c07b 设置请求方式httpget
continuous-integration/drone/push Build is passing
2025-03-28 10:08:52 +08:00
hang 5ee7a70c65 修改账号排序
continuous-integration/drone/push Build is passing
2025-03-28 10:03:54 +08:00
hang c9590829b2 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-03-28 09:54:59 +08:00
hang 80805bde06 增加默认字段 2025-03-28 09:54:57 +08:00
he 20718bca5d Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-03-28 09:52:31 +08:00
he 3d58e91644 修改模板 2025-03-28 09:52:31 +08:00
hang ade2a25fc4 获取tj 医院tokenInfo
continuous-integration/drone/push Build is passing
2025-03-28 09:38:12 +08:00
hang dcddf88a66 getUser 返回账户信息
continuous-integration/drone/push Build is passing
2025-03-27 17:31:01 +08:00
hang 89574e05bc Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-03-27 16:30:50 +08:00
hang 95fe14fece HIR 增加下拉框切换账户 2025-03-27 16:30:43 +08:00
he cfaf14ed65 模板修改
continuous-integration/drone/push Build is passing
2025-03-27 16:25:14 +08:00
he a50f82c42a Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-03-27 15:54:51 +08:00
he 1c0e1e01ce 报告修改医院名称 2025-03-27 15:54:50 +08:00
hang 5ec3fc3d13 修改创建账户默认密码
continuous-integration/drone/push Build is passing
2025-03-27 14:48:04 +08:00
he 9bd080b566 修改模板
continuous-integration/drone/push Build is passing
2025-03-26 15:52:06 +08:00
he f7cdb5b858 修改
continuous-integration/drone/push Build is passing
2025-03-26 14:15:46 +08:00
he 00c3ad8f9e 修改模板
continuous-integration/drone/push Build is passing
2025-03-25 16:32:54 +08:00
he d4b3038f6d Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-03-25 15:45:16 +08:00
he dde513a976 修改检查类型 2025-03-25 15:45:15 +08:00
hang 8378e8f2d6 多模态过滤
continuous-integration/drone/push Build is passing
2025-03-25 15:30:15 +08:00
hang 374f024f85 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is failing
2025-03-25 14:56:22 +08:00
hang 32aadceaac 增加多模态 2025-03-25 14:56:19 +08:00
he 285e742136 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-03-25 14:34:07 +08:00
he 704a876cf0 修改 2025-03-25 14:34:06 +08:00
hang 7184ea9565 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-03-25 14:09:07 +08:00
hang 6da50126e1 增加国际化 2025-03-25 14:09:06 +08:00
he 965c8a56c9 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-03-25 13:11:25 +08:00
he 0611c1d9fe 代码修改 2025-03-25 13:11:22 +08:00
hang 642acc9cba Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-03-25 11:29:39 +08:00
hang b87fb98c6c 修改pacs 查询 2025-03-25 11:29:37 +08:00
he d0d249655b Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-03-25 09:37:00 +08:00
he a847bb1785 模版修改 2025-03-25 09:36:58 +08:00
hang 445ee00840 修改时间查询
continuous-integration/drone/push Build is passing
2025-03-25 09:25:28 +08:00
he ecd33d969b 修改
continuous-integration/drone/push Build is passing
2025-03-24 17:10:59 +08:00
he 470420410e 代码修改
continuous-integration/drone/push Build is passing
2025-03-24 16:39:07 +08:00
he 2952b9e59f 添加字段
continuous-integration/drone/push Build is passing
2025-03-24 16:18:19 +08:00
he 7e8995a7b2 生成肿瘤报告
continuous-integration/drone/push Build is passing
2025-03-24 16:15:21 +08:00
he e7046173f8 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2025-03-24 09:45:15 +08:00
he f1a39e3b9d 修改 2025-03-24 09:45:12 +08:00
hang 2838f232f3 修改权限
continuous-integration/drone/push Build is passing
2025-03-21 14:54:34 +08:00
hang 9ac4b262f3 增加id
continuous-integration/drone/push Build is passing
2025-03-21 14:08:39 +08:00
hang 582b8b3c07 更新数据库
continuous-integration/drone/push Build is passing
2025-03-21 10:19:04 +08:00
hang 91b20e07f2 HIR 管理端医院修改
continuous-integration/drone/push Build is passing
2025-03-21 10:15:31 +08:00
hang 5a99f476f9 增加拉取查询
continuous-integration/drone/push Build is passing
2025-03-20 15:04:45 +08:00
hang e06b47c8b3 查询某个项目下患者最新的检查列表初步修改
continuous-integration/drone/push Build is passing
2025-03-18 13:52:57 +08:00
hang 613cf6441b 修改推送监控记录
continuous-integration/drone/push Build is passing
2025-03-17 17:51:43 +08:00
hang 57dd964db2 minio 区域配置,导致上传失败问题
continuous-integration/drone/push Build is passing
2025-02-17 14:07:28 +08:00
hang 42dd5d384f 测试
continuous-integration/drone/push Build is passing
2025-02-07 19:55:42 +08:00
hang f2138623f4 修改日志记录文本名
continuous-integration/drone/push Build is passing
2025-02-07 17:56:32 +08:00
hang c69b2569ce 增加日志记录发送Cmove
continuous-integration/drone/push Build is passing
2025-02-07 17:21:29 +08:00
hang 6f8b88422b 修改配置文件
continuous-integration/drone/push Build is passing
2025-02-07 16:58:26 +08:00
hang 4c4d19b0d6 修改测试
continuous-integration/drone/push Build is passing
2025-02-07 16:17:50 +08:00
hang 91e0f0b787 每个检查只取instance的最新的一条
continuous-integration/drone/push Build is passing
2025-02-07 13:26:24 +08:00
hang c7f64ea0fe 修改查询位置
continuous-integration/drone/push Build is passing
2025-02-07 12:27:53 +08:00
hang fdb0b74296 修改Cmove 推送命令
continuous-integration/drone/push Build is passing
2025-02-07 11:25:08 +08:00
hang 0d7a04f1e8 清理状态再次测试
continuous-integration/drone/push Build is passing
2025-01-07 14:01:34 +08:00
hang 0a72c15dfd xxx
continuous-integration/drone/push Build is passing
2025-01-07 13:46:39 +08:00
hang 282c0b40c2 HIR 申请重阅,如果后续任务已经拷贝了表单,申请当前任务后,后续拷贝的表单删除
continuous-integration/drone/push Build is passing
2025-01-07 13:40:24 +08:00
hang 5783f5836a 数据库配置
continuous-integration/drone/push Build is passing
2025-01-06 14:35:54 +08:00
hang aff1f5b599 维护数据根据发送端加锁
continuous-integration/drone/push Build is passing
2024-12-30 09:01:12 +08:00
hang b12079f8d9 修改数据库连接
continuous-integration/drone/push Build is passing
2024-12-27 17:38:11 +08:00
hang 99de20ef76 修改AOA 不能看admin
continuous-integration/drone/push Build is passing
2024-12-27 17:19:57 +08:00
hang c187b5fb94 修改参数位置
continuous-integration/drone/push Build is passing
2024-12-20 13:55:02 +08:00
hang d852de4a5b 修改稽查报错
continuous-integration/drone/push Build is passing
2024-12-20 12:50:41 +08:00
hang d10020d944 修改关联关系
continuous-integration/drone/push Build is passing
2024-12-20 11:13:29 +08:00
hang f7c17546da 多模态修改
continuous-integration/drone/push Build is passing
2024-12-20 11:05:33 +08:00
hang c267bb34b4 支持多模态查询
continuous-integration/drone/push Build is passing
2024-12-20 10:31:59 +08:00
hang 98b0b36e3b 修改AE 测试
continuous-integration/drone/push Build is passing
2024-12-19 16:00:50 +08:00
hang 468224cae9 修改c-find 测试pacs在线与否
continuous-integration/drone/push Build is passing
2024-12-19 15:00:32 +08:00
hang 6b385b619a 修改国际化
continuous-integration/drone/push Build is passing
2024-12-19 14:42:56 +08:00
hang 88669ccbff 修改验证 和测试
continuous-integration/drone/push Build is passing
2024-12-19 14:30:14 +08:00
hang 5f338de0cd 修改时间解析
continuous-integration/drone/push Build is passing
2024-12-19 12:29:50 +08:00
hang c266c68be8 修改时间查询
continuous-integration/drone/push Build is passing
2024-12-19 10:36:21 +08:00
hang 364b84fd1c 修改时间
continuous-integration/drone/push Build is passing
2024-12-19 10:03:56 +08:00
hang 982bd80898 修改modality 查询
continuous-integration/drone/push Build is passing
2024-12-19 09:48:45 +08:00
hang 0050ae8d0a 增加patientName
continuous-integration/drone/push Build is passing
2024-12-18 13:10:43 +08:00
hang 8d11115fab 修改提示
continuous-integration/drone/push Build is passing
2024-12-18 12:55:06 +08:00
hang 355ca22134 增加客户端pacs ae 配置
continuous-integration/drone/push Build is passing
2024-12-18 11:30:19 +08:00
hang d568964c64 修改 HIR 验证
continuous-integration/drone/push Build is passing
2024-12-17 16:37:38 +08:00
hang 81443e5e36 列表展示
continuous-integration/drone/push Build is passing
2024-12-17 14:03:28 +08:00
hang 1c4d513f5b 修改查询
continuous-integration/drone/push Build is passing
2024-12-17 13:40:00 +08:00
hang d0a3ce9a09 后台任务Cmove 影像
continuous-integration/drone/push Build is passing
2024-12-16 13:44:54 +08:00
hang 0a368c0607 修改增加接口
continuous-integration/drone/push Build is passing
2024-12-13 16:52:15 +08:00
hang 1104c1481e 修改解析
continuous-integration/drone/push Build is passing
2024-12-13 16:00:25 +08:00
hang 7318dd4812 修改搜索条件
continuous-integration/drone/push Build is passing
2024-12-13 13:24:18 +08:00
hang 1ee30d047d 修改Patient 请求
continuous-integration/drone/push Build is passing
2024-12-12 17:48:33 +08:00
hang 39e7218b52 拉取影像
continuous-integration/drone/push Build is passing
2024-12-12 16:28:43 +08:00
hang 959fa1c40c 修改HIR 提示
continuous-integration/drone/push Build is passing
2024-12-02 13:33:55 +08:00
hang fb074048df 修改用户过滤
continuous-integration/drone/push Build is passing
2024-11-29 17:44:45 +08:00
hang 0b20c42513 修改加密解密
continuous-integration/drone/push Build is passing
2024-11-29 15:19:43 +08:00
hang 7c0e53db73 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2024-11-28 16:19:10 +08:00
hang d77a6ebda0 加密解密的修改 2024-11-28 16:19:07 +08:00
he 42f7bf9c97 修改模板
continuous-integration/drone/push Build is passing
2024-11-28 14:55:42 +08:00
hang b9d9552ae8 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is passing
2024-11-28 13:20:04 +08:00
hang ba81a842b7 修改用户机构名字 2024-11-28 13:20:03 +08:00
hang 28b3f16ef0 修改用户机构名字
continuous-integration/drone/push Build is passing
2024-11-28 13:17:31 +08:00
hang 37bf4905bb 修改IR查询条件
continuous-integration/drone/push Build is passing
2024-11-28 10:57:48 +08:00
hang 0ab9cebe45 修改IR 阅片查询
continuous-integration/drone/push Build is passing
2024-11-28 10:49:45 +08:00
hang a8c9587572 修改环境配置
continuous-integration/drone/push Build is passing
2024-11-28 10:30:16 +08:00
hang 48380aa7ea 修改HIR 配置文件
continuous-integration/drone/push Build is passing
2024-11-27 14:18:23 +08:00
hang b1831bfba0 修改token获取
continuous-integration/drone/push Build is passing
2024-11-27 13:41:35 +08:00
hang b9f866807e 修改模板调整
continuous-integration/drone/push Build is passing
2024-11-25 17:12:32 +08:00
hang 8896450fcc 修改导表 判断
continuous-integration/drone/push Build is passing
2024-11-25 16:21:20 +08:00
hang 2dc0cc3525 修改导表bug 初步测试
continuous-integration/drone/push Build is passing
2024-11-25 15:08:12 +08:00
hang a3f635894b 修改导表,日志记录
continuous-integration/drone/push Build is passing
2024-11-25 11:47:52 +08:00
hang 542ead68a7 稽查修改
continuous-integration/drone/push Build is passing
2024-11-25 09:30:30 +08:00
hang 7c25809ad5 稽查修改数据
continuous-integration/drone/push Build is passing
2024-11-22 17:10:09 +08:00
hang 1f14adec2a 增加邮箱查询
continuous-integration/drone/push Build is passing
2024-11-22 16:58:28 +08:00
hang 8173e6a8f2 修改下载返回间隔
continuous-integration/drone/push Build is failing
2024-11-22 16:25:00 +08:00
he 0baf4700f1 发布
continuous-integration/drone/push Build is failing
2024-11-22 15:22:05 +08:00
he e3f1fe5569 doctorID 匹配修改
continuous-integration/drone/push Build is failing
2024-11-22 15:14:43 +08:00
he 9aa5c27f60 Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8
continuous-integration/drone/push Build is failing
2024-11-22 14:53:30 +08:00
he a1479420c8 去掉doctorid匹配 2024-11-22 14:53:29 +08:00
hang 0f368f0a5e 修改发布
continuous-integration/drone/push Build is passing
2024-11-21 11:22:54 +08:00
hang 5d0c6417a4 修改Patient 返回影响列表
continuous-integration/drone/push Build is passing
2024-11-21 09:35:01 +08:00
hang 12d8944ca7 前端用新的方式对接修改
continuous-integration/drone/push Build is passing
2024-11-21 09:24:22 +08:00
hang 521a4ad3f0 HIR_UAT 修改
continuous-integration/drone/push Build is passing
2024-11-20 16:25:10 +08:00
hang 040777ec87 修改查询参数
continuous-integration/drone/push Build is passing
2024-11-14 17:22:51 +08:00
hang b68d3a5d99 移除HIR后端下载字段
continuous-integration/drone/push Build is passing
2024-11-14 17:00:11 +08:00
hang 0af3c5ab8b 影响下载修改
continuous-integration/drone/push Build is passing
2024-11-14 16:41:30 +08:00
hang 6ca1e81b6a 修改发布脚本
continuous-integration/drone/push Build is passing
2024-11-14 16:00:43 +08:00
hang 068b3fa8d7 修改HIR 获取检查报错
continuous-integration/drone/push Build is failing
2024-11-14 15:57:44 +08:00
hang 976b89e970 HIR 修改下载代码 2024-11-14 14:48:08 +08:00
he 47e85ebbdf Merge branch 'Test_HIR_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_HIR_Net8 2024-11-14 10:53:25 +08:00
he 44f33fb7f0 阅片报告功能 2024-11-14 10:53:23 +08:00
hang 2c5ba280e9 调整申请重阅调整 2024-11-14 10:12:32 +08:00
hang 5250cd524a 阅片接口返回之前的参数对接 2024-11-13 18:30:39 +08:00
hang 787dd9aa5f 修改标准默认配置,修改待阅列表数据 2024-11-13 15:39:16 +08:00
hang e059dcb2b2 HIR 稽查 授权,配置测试提交 2024-11-13 11:14:02 +08:00
hang 75bf9b394b 迁移HIR 初步提交 2024-11-12 16:50:28 +08:00
hang c158d53a39 HIR 数据库初始化准备 2024-11-12 09:40:13 +08:00
hang 8e6125796b IRC 迁移HIR 功能初步修改 2024-11-11 23:50:23 +08:00
hang 3603656a1c 全局过滤修改
continuous-integration/drone/push Build is passing
2024-11-11 18:09:18 +08:00
hang c372498251 病灶导表修改
continuous-integration/drone/push Build is passing
2024-11-11 16:53:24 +08:00
hang 05b5d0d264 OCT 斑块导出
continuous-integration/drone/push Build is passing
2024-11-11 14:51:29 +08:00
hang 45ab896bb9 修改导表日期
continuous-integration/drone/push Build is passing
2024-11-11 12:25:35 +08:00
hang 2326d26c0b Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2024-11-11 12:23:59 +08:00
hang 28587c8e91 修改导表日期处理 2024-11-11 12:23:58 +08:00
he 78c707a018 修改
continuous-integration/drone/push Build is passing
2024-11-11 11:34:42 +08:00
he 5e889b1529 修改
continuous-integration/drone/push Build is passing
2024-11-11 11:01:26 +08:00
he ec945b4b39 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-11 10:37:51 +08:00
he 4f72d97039 修改 2024-11-11 10:37:49 +08:00
hang 4d4af84716 hangfire 测试提交
continuous-integration/drone/push Build is passing
2024-11-11 09:26:15 +08:00
hang 47be1e52c9 项目术语配置,导表统一处理
continuous-integration/drone/push Build is passing
2024-11-09 17:05:34 +08:00
hang 4145421087 修改json 列
continuous-integration/drone/push Build is passing
2024-11-08 17:26:46 +08:00
hang f83bd75853 x
continuous-integration/drone/push Build is passing
2024-11-08 17:16:30 +08:00
hang 7e53c24919 修改冲突
continuous-integration/drone/push Build is running
2024-11-08 17:16:20 +08:00
hang 341e4321b2 json 列修改提交 2024-11-08 17:14:41 +08:00
hang c90258c49e 修改创建项目临时解决
continuous-integration/drone/push Build is passing
2024-11-08 16:56:41 +08:00
hang 5fdbdfec82 json 列更新需要手动设置
continuous-integration/drone/push Build is passing
2024-11-08 14:28:53 +08:00
hang 41a889f201 项目配置使用Json 列 测试
continuous-integration/drone/push Build is passing
2024-11-08 13:49:49 +08:00
hang 1f33a9fa4e efcore 8 json 列测试完毕
continuous-integration/drone/push Build is passing
2024-11-08 13:41:07 +08:00
hang 760321f8fa 修改模板
continuous-integration/drone/push Build is passing
2024-11-07 18:09:38 +08:00
hang aae8afd0c5 添加默认值
continuous-integration/drone/push Build is passing
2024-11-07 15:32:58 +08:00
hang 33bf0d908d 一致性分析过滤掉全局任务
continuous-integration/drone/push Build is passing
2024-11-07 14:35:19 +08:00
hang 4f67de2898 仅仅保留一致性分析有的任务的原始任务
continuous-integration/drone/push Build is passing
2024-11-07 14:18:44 +08:00
hang 79949b9bad 修改一致性分析导表arm 错误
continuous-integration/drone/push Build is passing
2024-11-07 14:08:55 +08:00
hang 1648cbef7b Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-07 11:03:56 +08:00
hang 4abd7c8fe2 修改一致性分析导表 2024-11-07 11:03:54 +08:00
he bdf14d8641 修改
continuous-integration/drone/push Build is passing
2024-11-07 10:48:59 +08:00
he d2530de925 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-07 10:45:32 +08:00
he f1a6ca24be 修改 2024-11-07 10:45:32 +08:00
hang 8d1a6c8cec Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-07 10:37:07 +08:00
hang 656b1cf252 项目顶级术语修改 2024-11-07 10:37:06 +08:00
he b89cfeb90c 修改
continuous-integration/drone/push Build is passing
2024-11-07 10:19:25 +08:00
he 5b3beea8fa Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-07 10:01:50 +08:00
he b7d3a365b4 修改 2024-11-07 10:01:49 +08:00
hang bf0ab3411d 用户添加触发器使用
continuous-integration/drone/push Build is passing
2024-11-07 08:52:12 +08:00
hang c5dacab771 修改导表标题少括号
continuous-integration/drone/push Build is passing
2024-11-06 17:12:27 +08:00
hang db363a7daa 修改组间一致性分析导表
continuous-integration/drone/push Build is passing
2024-11-06 16:56:12 +08:00
hang 4c41a5a579 导表筛选标准
continuous-integration/drone/push Build is passing
2024-11-06 15:29:50 +08:00
hang c48803ca0c 账户稽查修改
continuous-integration/drone/push Build is passing
2024-11-06 15:15:32 +08:00
hang b5e26da1ff Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-06 14:28:58 +08:00
hang 501272a2a2 修改批量添加 2024-11-06 14:28:57 +08:00
he e66475ab61 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-06 14:13:08 +08:00
he 6a54a36719 修改 2024-11-06 14:13:07 +08:00
hang b2851352f2 修改一致性分析导表
continuous-integration/drone/push Build is passing
2024-11-06 14:10:49 +08:00
hang 756838e106 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-06 13:51:06 +08:00
hang b83ea13aed 修改邮件配置 2024-11-06 13:51:05 +08:00
Hewt 5202ee7bd6 修改
continuous-integration/drone/push Build is passing
2024-11-05 14:12:46 +08:00
Hewt 424a05c211 简历信息修改 2024-11-05 13:07:24 +08:00
Hewt 702e20c834 测试推送
continuous-integration/drone/push Build is passing
2024-11-04 18:45:04 +08:00
hang 506955ca7c Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-04 18:02:28 +08:00
hang 9cbd1faf93 测试 2024-11-04 18:02:27 +08:00
he 3354aa37f4 修改
continuous-integration/drone/push Build is passing
2024-11-04 17:51:53 +08:00
he f17001bace Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-04 17:41:34 +08:00
he 80d99d4862 修改 2024-11-04 17:41:33 +08:00
hang d19b5da008 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-04 17:22:16 +08:00
hang 31fdedb033 增加邮件查询条件 2024-11-04 17:22:15 +08:00
he c87e268165 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-04 16:40:16 +08:00
he 93726ae28c 修改 2024-11-04 16:40:15 +08:00
hang fed21316df Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-04 16:31:47 +08:00
hang 205619071d 重置密码,清理密码错误限制 2024-11-04 16:31:47 +08:00
he 16e985b37e Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-04 15:04:33 +08:00
he 590a7e7b05 修改 2024-11-04 15:04:32 +08:00
hang 239f87320b 修改导表枚举翻译
continuous-integration/drone/push Build is passing
2024-11-04 13:35:20 +08:00
hang d03c00d138 修改导表枚举
continuous-integration/drone/push Build is passing
2024-11-04 13:27:56 +08:00
hang 9778f5e943 修改统计报错
continuous-integration/drone/push Build is passing
2024-11-04 13:14:32 +08:00
hang 3752bc0311 修改邮件查询列表
continuous-integration/drone/push Build is passing
2024-11-04 11:36:07 +08:00
hang 76bdbcbfcb Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-04 10:48:13 +08:00
hang 70d321f778 系统邮件修改 2024-11-04 10:48:11 +08:00
he e666d93829 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-04 10:41:01 +08:00
he a6a8f34734 修改 2024-11-04 10:41:00 +08:00
hang 317184ba7a 修改后处理上传
continuous-integration/drone/push Build is passing
2024-11-04 10:14:14 +08:00
hang 68052766f8 logto 授权码模式测试
continuous-integration/drone/push Build is passing
2024-11-03 12:59:49 +08:00
hang dc1cea6b5a 修改加急发送邮件
continuous-integration/drone/push Build is passing
2024-11-01 14:18:16 +08:00
hang ebe597a575 修改加急阅片10分钟
continuous-integration/drone/push Build is passing
2024-11-01 11:09:23 +08:00
hang 4b4688538d 修改重复邮件问题
continuous-integration/drone/push Build is passing
2024-11-01 10:59:32 +08:00
hang 0111136c95 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-01 10:47:17 +08:00
hang 8a0f1d0759 修改一致性分析导表 2024-11-01 10:47:15 +08:00
he 44c1ad740c Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-11-01 10:42:58 +08:00
he 664942a235 修改 2024-11-01 10:42:56 +08:00
hang 99e7079c14 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-31 18:05:11 +08:00
hang ec8e553304 增加 IdentityModel.OidcClient 测试ok 2024-10-31 18:05:10 +08:00
he 93ed4013fe 修改
continuous-integration/drone/push Build is passing
2024-10-31 17:59:46 +08:00
he 531e2f4a08 修改
continuous-integration/drone/push Build is passing
2024-10-31 17:57:30 +08:00
he 06059f15ac 修改
continuous-integration/drone/push Build is passing
2024-10-31 16:22:52 +08:00
he 23e6811e89 修噶
continuous-integration/drone/push Build is running
2024-10-31 16:22:26 +08:00
hang 6a1a7ba452 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-31 15:54:56 +08:00
hang a9c9486162 增加QC 添加质疑触发逻辑 2024-10-31 15:54:54 +08:00
he 3d6cfccbdf 修改
continuous-integration/drone/push Build is passing
2024-10-31 15:16:18 +08:00
he 3f5d53c2cb Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-31 14:57:17 +08:00
he e9c19d7396 修改 2024-10-31 14:57:17 +08:00
hang df04878154 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-31 13:51:46 +08:00
hang ad3dae4fcd 返回LatestReplyUserFullName 2024-10-31 13:51:43 +08:00
he 4af09e64a3 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-31 10:56:14 +08:00
he 520595796b 修改 2024-10-31 10:56:12 +08:00
hang d22ef17e91 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-30 16:06:05 +08:00
hang c0de59b3aa 自身和组件一致性分析修改 2024-10-30 16:06:02 +08:00
he 4e29d4094e 修改
continuous-integration/drone/push Build is passing
2024-10-30 15:20:19 +08:00
he 84d4678406 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-30 10:00:39 +08:00
he 53a5800a38 修改 2024-10-30 10:00:38 +08:00
hang fcaa6339c6 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-30 09:44:27 +08:00
hang 95042fe6ba 修改项目邮件这块 2024-10-30 09:44:24 +08:00
he 7b779d4ef5 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-30 09:27:18 +08:00
he 3a978b561b 添加 IndicationTypeId 2024-10-30 09:27:17 +08:00
hang 71e6099bbd 修改备注
continuous-integration/drone/push Build is passing
2024-10-29 23:55:42 +08:00
hang c713d0bc95 logto 客户端模式对接测试完成
continuous-integration/drone/push Build is passing
2024-10-29 23:11:37 +08:00
hang c6c8daaadf 临时代码提交
continuous-integration/drone/push Build is passing
2024-10-29 18:04:10 +08:00
hang 67667f6438 修改导表
continuous-integration/drone/push Build is passing
2024-10-29 17:37:20 +08:00
hang 2a1047f319 修改导表测试
continuous-integration/drone/push Build is passing
2024-10-29 16:36:32 +08:00
he 68b960abec Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-29 16:20:49 +08:00
he 419fef2e64 修改 2024-10-29 16:20:46 +08:00
hang d1b3256e52 修改验证bug
continuous-integration/drone/push Build is passing
2024-10-29 16:18:49 +08:00
hang 871990287a Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-29 16:07:09 +08:00
hang 6a54b0a6c8 修改拦截 2024-10-29 16:07:08 +08:00
he bec9af414f Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2024-10-29 16:06:19 +08:00
he 94293830d6 修改 2024-10-29 16:06:18 +08:00
hang 4fb018eaa6 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-29 15:57:29 +08:00
hang c65d6c4aa2 x 2024-10-29 15:57:27 +08:00
he cc4d879def Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2024-10-29 15:56:06 +08:00
he ba588e3e14 修改 2024-10-29 15:56:05 +08:00
hang fc392e869c 修改裁判一致率
continuous-integration/drone/push Build is running
2024-10-29 15:55:59 +08:00
hang 052bff9247 国际化导表修改
continuous-integration/drone/push Build is passing
2024-10-29 15:45:22 +08:00
hang d00f81b09a Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-29 15:23:38 +08:00
hang 6cde1b4405 修改一致性核查导表 2024-10-29 15:23:36 +08:00
he 3ef765e767 修改
continuous-integration/drone/push Build is passing
2024-10-29 14:11:50 +08:00
he 8f7e229513 修改请求方式
continuous-integration/drone/push Build is passing
2024-10-29 14:09:16 +08:00
he 0fdfeca3ec 数据库执行
continuous-integration/drone/push Build is passing
2024-10-29 14:01:18 +08:00
he 77bcdf79e8 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-29 13:56:38 +08:00
he 20cc430132 项目医生简历 2024-10-29 13:56:35 +08:00
hang 969d22fdae 修改裁判总数
continuous-integration/drone/push Build is passing
2024-10-29 11:42:17 +08:00
hang 9f95dc90bb 修改最大裁判导表
continuous-integration/drone/push Build is passing
2024-10-29 09:42:06 +08:00
hang 0b1c4f2c09 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-28 17:36:59 +08:00
hang 14d9d8e7a5 修改触发裁判逻辑 2024-10-28 17:36:57 +08:00
he 0cc2e2c7ee 修改字段
continuous-integration/drone/push Build is passing
2024-10-28 16:59:40 +08:00
he 0dfd33ced6 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-28 16:52:19 +08:00
he a96c5eefc3 修改 2024-10-28 16:52:18 +08:00
hang 6d628727bb 修改裁判一致率统计
continuous-integration/drone/push Build is passing
2024-10-28 16:40:32 +08:00
hang ae83489c74 修改阅片期统计
continuous-integration/drone/push Build is passing
2024-10-28 16:32:55 +08:00
hang 253a401c95 修改导表标志
continuous-integration/drone/push Build is passing
2024-10-28 15:32:29 +08:00
hang 1209b07c03 修改文档和导表修改
continuous-integration/drone/push Build is passing
2024-10-28 14:33:43 +08:00
hang 44f3b58bad 裁判任务标记
continuous-integration/drone/push Build is passing
2024-10-28 11:49:06 +08:00
hang 31e2e03536 修改导表动态处理
continuous-integration/drone/push Build is passing
2024-10-28 10:40:52 +08:00
hang 2a172acb15 修改合并bug
continuous-integration/drone/push Build is passing
2024-10-25 18:01:28 +08:00
hang 792a4235d2 修改导表bug 动态title
continuous-integration/drone/push Build is passing
2024-10-25 17:43:48 +08:00
hang 6003bf291a 修改iresist 导表
continuous-integration/drone/push Build is passing
2024-10-25 17:34:49 +08:00
hang 42ab61d0a2 修改导表测试
continuous-integration/drone/push Build is passing
2024-10-25 17:03:14 +08:00
hang 08158a58d6 导表修改
continuous-integration/drone/push Build is passing
2024-10-25 16:50:49 +08:00
hang b4269c4ed0 访视裁判统计数字错误
continuous-integration/drone/push Build is passing
2024-10-25 16:01:48 +08:00
hang 7f0e998eba 系统文档修改
continuous-integration/drone/push Build is passing
2024-10-25 15:12:33 +08:00
hang a3c0bacff2 修改filter bug
continuous-integration/drone/push Build is passing
2024-10-25 14:59:15 +08:00
hang 5c898ec6c8 临时解决问题
continuous-integration/drone/push Build is passing
2024-10-25 14:48:44 +08:00
hang 68353b9e7b x
continuous-integration/drone/push Build is passing
2024-10-25 14:36:09 +08:00
hang f9089a9700 增加日志测试
continuous-integration/drone/push Build is running
2024-10-25 14:35:27 +08:00
hang 57aedd7dd4 调试状态
continuous-integration/drone/push Build is passing
2024-10-25 14:26:14 +08:00
hang 8329362c33 导表查询问题解决
continuous-integration/drone/push Build is passing
2024-10-25 13:34:11 +08:00
hang 787081a485 废弃 TrialResourceFilter 使用ActionFilter
continuous-integration/drone/push Build is passing
2024-10-25 13:13:45 +08:00
hang 94aa943410 账号最有一次登录时间增加查询条件
continuous-integration/drone/push Build is passing
2024-10-25 11:07:27 +08:00
hang 08a916d699 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-25 11:02:12 +08:00
hang 77a11cacc2 利用中间件+特性解决minimal api 项目拦截功能 2024-10-25 11:02:10 +08:00
he a28f2e3bb2 修改
continuous-integration/drone/push Build is passing
2024-10-25 10:57:51 +08:00
he f060380735 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-25 10:44:10 +08:00
he 57737b0d04 校验去掉分组 2024-10-25 10:44:09 +08:00
hang 5023f5ed31 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-24 18:05:43 +08:00
hang cf6a7d9166 修改枚举展示 2024-10-24 18:05:41 +08:00
he a4c12dcbeb 修改
continuous-integration/drone/push Build is passing
2024-10-24 17:35:27 +08:00
he 70240da5c5 修改
continuous-integration/drone/push Build is passing
2024-10-24 16:10:14 +08:00
he 0b2c707ec7 修改
continuous-integration/drone/push Build is passing
2024-10-24 15:48:58 +08:00
hang aa1ecaf1fe Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-24 15:10:23 +08:00
hang 39435b0068 修改访视裁判导表 2024-10-24 15:10:21 +08:00
he 9fc6ee267e Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-24 14:57:38 +08:00
he 1364031439 修改 2024-10-24 14:57:37 +08:00
hang 9c95d22b6a 修改导表bug
continuous-integration/drone/push Build is passing
2024-10-24 14:48:11 +08:00
hang f8108da641 修改裁判选择标记
continuous-integration/drone/push Build is passing
2024-10-24 14:24:01 +08:00
hang 39bb3bf56b Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-24 14:12:01 +08:00
hang 2c37765969 修改 外部人员系统文档签署问题解决 2024-10-24 14:11:56 +08:00
he 3bb02ccb24 修改
continuous-integration/drone/push Build is passing
2024-10-24 13:54:53 +08:00
he 23ac7a73a7 修改
continuous-integration/drone/push Build is passing
2024-10-24 13:43:44 +08:00
he dacbe132a6 修改
continuous-integration/drone/push Build is passing
2024-10-24 13:36:00 +08:00
he 5f6d8b921f Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-24 13:26:03 +08:00
he fcb603abc6 邮件修改 2024-10-24 13:26:02 +08:00
hang 5ceb5e790a 编译错误修改
continuous-integration/drone/push Build is passing
2024-10-24 10:37:32 +08:00
hang 2b1b5dce52 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-24 10:29:43 +08:00
hang 293a8bce31 处理邮件延迟发送配置 2024-10-24 10:29:41 +08:00
he a7cfc1714a 修改
continuous-integration/drone/push Build is passing
2024-10-24 10:22:51 +08:00
he ad01628e48 代码修改
continuous-integration/drone/push Build is passing
2024-10-24 09:40:14 +08:00
he 558258fd89 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-24 09:24:48 +08:00
he 2a853e49f6 修改 2024-10-24 09:24:45 +08:00
hang acf9709d3a 修改病灶明细表显示标准
continuous-integration/drone/push Build is passing
2024-10-23 18:09:31 +08:00
hang 6c4ead5ab4 修改枚举
continuous-integration/drone/push Build is passing
2024-10-23 17:58:03 +08:00
hang 2ac995bf39 修改导出类别
continuous-integration/drone/push Build is passing
2024-10-23 17:52:45 +08:00
hang 3ee175f091 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-23 17:44:12 +08:00
hang a701c082d9 修改动态导表 2024-10-23 17:44:09 +08:00
he 9385e22c58 修改
continuous-integration/drone/push Build is passing
2024-10-23 17:29:08 +08:00
he 61278375ba 修改
continuous-integration/drone/push Build is passing
2024-10-23 17:05:27 +08:00
he 9a74b81e93 修改
continuous-integration/drone/push Build is passing
2024-10-23 14:21:36 +08:00
he 981c029492 修改
continuous-integration/drone/push Build is passing
2024-10-23 14:17:45 +08:00
he 2fd6f70995 修改
continuous-integration/drone/push Build is passing
2024-10-23 11:52:02 +08:00
he b809a3b102 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-23 11:47:23 +08:00
he 2d90ecd90f 修改 2024-10-23 11:47:21 +08:00
hang 5ee5bac4ad Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-23 10:34:47 +08:00
hang 8e764e5707 清理历史文件 2024-10-23 10:34:45 +08:00
he c4501321ed 修改
continuous-integration/drone/push Build is passing
2024-10-22 18:01:55 +08:00
he b0ece8bcfe 修改
continuous-integration/drone/push Build is passing
2024-10-22 17:46:13 +08:00
he cce4872341 修改
continuous-integration/drone/push Build is running
2024-10-22 17:45:33 +08:00
he 3c49192360 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-22 16:47:49 +08:00
he c610c3bac0 修改 2024-10-22 16:47:48 +08:00
hang 09405dea8b Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-22 15:30:40 +08:00
hang 06cb92b7e0 整理文件夹 2024-10-22 15:30:38 +08:00
he f7a3e87ba8 数据库修改
continuous-integration/drone/push Build is passing
2024-10-22 15:27:44 +08:00
he 2bad8065a5 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-22 15:25:08 +08:00
he 22998ccb71 修改 2024-10-22 15:25:07 +08:00
hang 38b4268c67 合并
continuous-integration/drone/push Build is passing
2024-10-22 15:11:51 +08:00
hang fb3228e18a 修改导表bug 2024-10-22 15:11:16 +08:00
he 056feade12 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-22 14:55:40 +08:00
he 6d98b140e1 修改 2024-10-22 14:55:39 +08:00
hang 698ce08d30 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2024-10-22 14:38:18 +08:00
hang 6eddf7e2a1 修改导表备注 2024-10-22 14:38:18 +08:00
he e26c9b6c1a 修改
continuous-integration/drone/push Build is passing
2024-10-22 13:55:35 +08:00
he 62d3b69bd5 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is running
2024-10-22 13:55:10 +08:00
he ab4e1f8649 修改 2024-10-22 13:55:09 +08:00
hang 773c657b67 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-22 13:45:17 +08:00
hang a90bb18154 提交阅片导表逻辑 2024-10-22 13:45:16 +08:00
he 3dcf94f637 代码修改
continuous-integration/drone/push Build is passing
2024-10-22 13:09:54 +08:00
he 5e384db795 修改
continuous-integration/drone/push Build is passing
2024-10-22 11:20:23 +08:00
he abd1562179 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-22 11:15:29 +08:00
he 2f1a9af5bd 修改 2024-10-22 11:15:26 +08:00
hang 78c90734b2 Excel 导表初步测试提交
continuous-integration/drone/push Build is passing
2024-10-22 10:54:26 +08:00
hang 7c246dcecd 修改导表展示列表
continuous-integration/drone/push Build is passing
2024-10-22 10:15:24 +08:00
hang f6252f62c4 serilog 增加环境发生错误发送邮件
continuous-integration/drone/push Build is passing
2024-10-22 09:57:25 +08:00
hang 9b91472186 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-21 21:03:23 +08:00
hang 3ff092fbda 测试 2024-10-21 21:03:22 +08:00
hang d0b73977a6 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-21 18:02:37 +08:00
hang 823f082396 修改日志输出测试 2024-10-21 18:02:35 +08:00
he 15701ef073 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-21 17:58:30 +08:00
he 51c4bcc10b 修改 2024-10-21 17:58:30 +08:00
hang 48ff2a347e 修改日志记录测试
continuous-integration/drone/push Build is passing
2024-10-21 17:27:20 +08:00
hang 922e61a636 修改scp 服务缩略图
continuous-integration/drone/push Build is passing
2024-10-21 17:06:01 +08:00
hang de0b95a22b 修改json 日志展示
continuous-integration/drone/push Build is passing
2024-10-21 16:19:14 +08:00
hang 47fe825aa7 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-21 15:39:58 +08:00
hang f7e47293dd 测试修改serilog 日志 2024-10-21 15:39:57 +08:00
he 80f05c2b74 修改
continuous-integration/drone/push Build is passing
2024-10-21 15:28:46 +08:00
he 8ec37f4337 修改
continuous-integration/drone/push Build is passing
2024-10-21 14:49:30 +08:00
he 2881d9e787 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-21 14:35:26 +08:00
he b5f12cd3b4 代码修改 2024-10-21 14:35:25 +08:00
hang 8bd82ed409 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-21 14:20:10 +08:00
hang ff589abd2c 整理NetonsoftJson 代码 2024-10-21 14:20:09 +08:00
he 121671e381 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-21 13:34:35 +08:00
he a87e73d221 修改 2024-10-21 13:34:34 +08:00
hang 19ebd117bc Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-21 13:23:25 +08:00
hang b03ab1aa35 整理api 代码 2024-10-21 13:23:24 +08:00
he 7cb177cb7c Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-21 11:49:38 +08:00
he fb3aa3d793 x修改 2024-10-21 11:49:37 +08:00
hang 5e79baa232 修改发布方式
continuous-integration/drone/push Build is passing
2024-10-21 11:46:35 +08:00
hang 391bf568cb 修改中心调研
continuous-integration/drone/push Build is passing
2024-10-21 11:44:23 +08:00
hang ebc35741c9 修改CRC提交触发逻辑
continuous-integration/drone/push Build is passing
2024-10-21 11:20:41 +08:00
hang 7859ad9895 修改中心调研名字重复问题
continuous-integration/drone/push Build is passing
2024-10-21 11:06:30 +08:00
hang 0ac17ac27f 转pdf minimal api 完成
continuous-integration/drone/push Build is passing
2024-10-19 18:22:58 +08:00
hang 41444bb292 升级nuget包,移除autofac
continuous-integration/drone/push Build is passing
2024-10-19 16:39:29 +08:00
hang 4ab4fbd599 利用第三方服务转pdf
continuous-integration/drone/push Build is passing
2024-10-19 16:31:27 +08:00
he f97cfd58c0 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-18 15:39:56 +08:00
he f0672f5dec 邮件修改 2024-10-18 15:39:54 +08:00
hang 2a0d01c161 修改中心调研表逻辑
continuous-integration/drone/push Build is passing
2024-10-18 15:08:28 +08:00
hang a7277be2ba 调研表spm 提交模板用错
continuous-integration/drone/push Build is passing
2024-10-18 13:55:23 +08:00
hang 7c0c9b986d 修改排序
continuous-integration/drone/push Build is passing
2024-10-18 13:43:52 +08:00
hang 98acb5ea70 增加抄送人
continuous-integration/drone/push Build is passing
2024-10-18 11:19:30 +08:00
hang d65f944312 修改枚举
continuous-integration/drone/push Build is passing
2024-10-18 11:09:38 +08:00
hang ec6fe109f4 中心调研邮件发件人遗漏
continuous-integration/drone/push Build is passing
2024-10-18 11:05:10 +08:00
hang 03d735a287 修改事件发布
continuous-integration/drone/push Build is passing
2024-10-18 11:01:57 +08:00
hang d578feec18 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-18 09:03:22 +08:00
hang 13db4fc9e1 IR 周期任务临时提交 2024-10-18 09:03:22 +08:00
hang 8760ad3904 IRecurringMessageScheduler 测试使用,以及bug发现
continuous-integration/drone/push Build is passing
2024-10-17 21:43:39 +08:00
hang 81b9c57de7 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-17 16:30:23 +08:00
hang 652cad9726 历史邮件整理 2024-10-17 16:30:22 +08:00
he b031b4e971 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-17 15:45:48 +08:00
he eed4a584e3 邮件修改 2024-10-17 15:45:47 +08:00
hang 05693d090d 处理延时的任务
continuous-integration/drone/push Build is passing
2024-10-17 14:32:46 +08:00
hang b0d17b0466 修改合并
continuous-integration/drone/push Build is passing
2024-10-17 13:39:14 +08:00
hang f1acb787f5 配合hangfire 周期任务暂时有问题 --待解决 2024-10-17 13:37:57 +08:00
he 289811e0e6 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-17 10:38:29 +08:00
he a258d3c4ae 代码修改 2024-10-17 10:38:28 +08:00
hang a03c11ae9d Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-17 10:35:57 +08:00
hang 9e057ff815 修改国际化配置提前 2024-10-17 10:35:56 +08:00
he 5745161142 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-10-17 10:14:52 +08:00
he 553fa097b4 修改 2024-10-17 10:14:50 +08:00
hang 8a3eb61a34 修改国际化异常 2024-10-17 10:03:47 +08:00
hang 41e8164c2e 测试打包
continuous-integration/drone/push Build is passing
2024-10-17 09:23:28 +08:00
hang 26652160df 计划任务修改临时提交1
continuous-integration/drone/push Build is passing
2024-10-17 09:01:52 +08:00
hang ece98887da 精简国际化代码
continuous-integration/drone/push Build is passing
2024-10-16 15:27:57 +08:00
hang 7d07e18853 修改静态文件国际化方式
continuous-integration/drone/push Build is passing
2024-10-16 11:06:17 +08:00
hang 663a6c7f5c 设置静态国际化+测试ok
continuous-integration/drone/push Build is passing
2024-10-16 10:40:38 +08:00
hang 8be3cc9e78 minimal api 模型验证+ 方法级别的过滤器暂时未有解决方案
continuous-integration/drone/push Build is passing
2024-10-16 09:03:12 +08:00
hang 74a0c8923c minimal api 踢用户下线 实现
continuous-integration/drone/push Build is passing
2024-10-15 15:42:08 +08:00
hang 947d6dc6d1 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-15 15:08:10 +08:00
hang 288dacf613 增加管道异常处理 IExceptionHandler 2024-10-15 15:08:09 +08:00
he 546d65ab16 修改
continuous-integration/drone/push Build is passing
2024-10-15 14:54:54 +08:00
he 1b70807824 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-15 14:40:29 +08:00
he 48da4994b9 修改 2024-10-15 14:40:27 +08:00
hang 5d51ac562a minimal api 测试
continuous-integration/drone/push Build is passing
2024-10-15 14:19:39 +08:00
hang 8e1ae18de0 增加codefirst 说明
continuous-integration/drone/push Build is passing
2024-10-15 13:41:17 +08:00
hang d723c64d5b 修改冲突
continuous-integration/drone/push Build is passing
2024-10-15 13:16:42 +08:00
hang 67e09bbf66 minimal api 测试准备 2024-10-15 13:16:09 +08:00
he 5f898ed93a 修改
continuous-integration/drone/push Build is passing
2024-10-15 11:29:42 +08:00
he 4621ed9e67 修改
continuous-integration/drone/push Build is passing
2024-10-15 10:37:59 +08:00
he ce32d7eea8 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-15 10:29:31 +08:00
he cb4296396f 修改 2024-10-15 10:29:31 +08:00
hang a3ec9618ed Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-15 10:17:01 +08:00
hang 155d24fafb swagger 兼容minimal api 调整 2024-10-15 10:17:00 +08:00
he 2208e1dbe5 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-15 10:03:49 +08:00
he ffd29eb268 代码提交 2024-10-15 10:03:47 +08:00
hang 08f4a0877b 清理swagger配置
continuous-integration/drone/push Build is passing
2024-10-15 09:22:15 +08:00
hang 827615f272 swagger 整理
continuous-integration/drone/push Build is passing
2024-10-15 09:13:32 +08:00
hang a81f05dcc7 swagger 预备修改调整
continuous-integration/drone/push Build is passing
2024-10-15 00:14:34 +08:00
hang 8e2904c541 修改uat配置文件
continuous-integration/drone/push Build is passing
2024-10-14 18:03:11 +08:00
hang 1346d565c4 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-14 17:08:56 +08:00
hang ab61372e33 修改导表 2024-10-14 17:08:55 +08:00
he 6709f0c653 Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-14 15:31:14 +08:00
he a88ef53104 修改 2024-10-14 15:31:13 +08:00
hang fad9428656 引入minimal api 测试
continuous-integration/drone/push Build is passing
2024-10-14 14:48:18 +08:00
hang c9a6f8b99b 删除废弃的组件
continuous-integration/drone/push Build is passing
2024-10-14 11:11:16 +08:00
hang c1c03a3f05 修改masstransit 测试代码
continuous-integration/drone/push Build is passing
2024-10-13 21:40:05 +08:00
hang e65227c7bf 清理多余引用
continuous-integration/drone/push Build is passing
2024-10-13 16:31:09 +08:00
hang 0206947202 移除属性注入改为构造函数注入
continuous-integration/drone/push Build is passing
2024-10-13 13:31:25 +08:00
hang f1be4eaf5f 动态移动表格+动态删除指定列
continuous-integration/drone/push Build is passing
2024-10-13 02:38:43 +08:00
hang fd3fc0ea03 修改导出
continuous-integration/drone/push Build is passing
2024-10-12 18:08:07 +08:00
hang ad7463c2c9 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-12 17:03:10 +08:00
hang 1008ed9f95 中心调研修改 2024-10-12 17:03:10 +08:00
he d7379e897b 合并
continuous-integration/drone/push Build is passing
2024-10-12 16:57:01 +08:00
he 20e546e5d3 代码修改 2024-10-12 16:56:34 +08:00
hang d6ff81bf87 中心调研邮件 和枚举增加
continuous-integration/drone/push Build is passing
2024-10-12 16:23:32 +08:00
hang 8eecabb897 增加备注
continuous-integration/drone/push Build is passing
2024-10-12 13:48:48 +08:00
hang c940976f7f 修改申请重阅事件
continuous-integration/drone/push Build is passing
2024-10-12 11:02:12 +08:00
hang 2f1f266ea3 清理模型
continuous-integration/drone/push Build is passing
2024-10-12 10:48:43 +08:00
hang 650f4706a8 增加事件类型简单名称,方便配置枚举,知道是什么事件
continuous-integration/drone/push Build is passing
2024-10-12 10:29:03 +08:00
hang f41bf281fe 下载增加TrialSiteCode
continuous-integration/drone/push Build is passing
2024-10-12 09:13:48 +08:00
hang f7fd880388 修改触发事件
continuous-integration/drone/push Build is passing
2024-10-11 22:07:14 +08:00
hang f67ebce739 消费者cultureInfo 自动处理,消费成功自动设置事件状态
continuous-integration/drone/push Build is passing
2024-10-11 19:43:15 +08:00
hang 79fd83449a 测试 CultureInfoFilter
continuous-integration/drone/push Build is passing
2024-10-11 18:00:45 +08:00
hang ed61419a6a 事件增加文化属性
continuous-integration/drone/push Build is passing
2024-10-11 17:03:02 +08:00
hang 971c4dcf9e 修改发布的事件记录信息
continuous-integration/drone/push Build is passing
2024-10-11 16:25:52 +08:00
hang 2ee34b8e7c 领域事件修改
continuous-integration/drone/push Build is passing
2024-10-11 14:35:53 +08:00
hang 464f70f501 暂时屏蔽事件存储
continuous-integration/drone/push Build is passing
2024-10-11 13:53:29 +08:00
hang a6fd6a5e69 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-11 11:38:11 +08:00
hang d3958dab42 下载导出bug 2024-10-11 11:38:11 +08:00
hang 5f7f0e4456 下载导出bug
continuous-integration/drone/push Build is passing
2024-10-11 11:35:02 +08:00
hang 54ee6cf0c0 遗漏await
continuous-integration/drone/push Build is passing
2024-10-11 11:19:51 +08:00
hang 6a8b01425d 查询返回TrialSiteCode
continuous-integration/drone/push Build is passing
2024-10-11 11:15:35 +08:00
hang 751c976f95 下载记录表 增加SubjectId字段
continuous-integration/drone/push Build is passing
2024-10-11 11:04:19 +08:00
hang 854f1e5109 修改hangfire 配置,任务调度更精准
continuous-integration/drone/push Build is passing
2024-10-11 09:37:59 +08:00
hang 1e99374de0 masstransit 集成hangfire
continuous-integration/drone/push Build is passing
2024-10-10 23:58:12 +08:00
hang a700658132 事件触发修改
continuous-integration/drone/push Build is passing
2024-10-10 16:57:49 +08:00
hang 84b2fc32b2 修改触发逻辑
continuous-integration/drone/push Build is passing
2024-10-10 16:50:51 +08:00
hang b4c7ecbf9e 删除多余的定义
continuous-integration/drone/push Build is passing
2024-10-10 16:22:40 +08:00
hang 9ad11b16d1 入组或者PD 增加触发和消费者
continuous-integration/drone/push Build is passing
2024-10-10 16:07:58 +08:00
hang 2d1785f513 增加访视触发事件
continuous-integration/drone/push Build is passing
2024-10-10 14:41:29 +08:00
hang ea67a69351 Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8 2024-10-10 14:24:59 +08:00
hang 2c1300acb4 事件存储准备 2024-10-10 14:24:56 +08:00
he 0c2aa9ca5e Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
2024-10-10 13:38:24 +08:00
he 6a6e449e49 读取下一个阅片 2024-10-10 13:38:21 +08:00
hang 2527d709fa 返回后台文件测试
continuous-integration/drone/push Build is passing
2024-10-10 12:37:19 +08:00
hang 1bb62fd134 阅片导出初步提交 2024-10-10 09:55:09 +08:00
603 changed files with 844967 additions and 18663 deletions
@@ -77,7 +77,7 @@ namespace IRaCIS.Core.Application.Service.BusinessFilter
else if(statusCode != 200&&!(objectResult.Value is IResponseOutput))
{
//---程序错误,请联系开发人员。
var apiResponse = ResponseOutput.NotOk(StaticData.International("UnifiedAPI_ProgramError"));
var apiResponse = ResponseOutput.NotOk(I18n.T("UnifiedAPI_ProgramError"));
objectResult.Value = apiResponse;
objectResult.DeclaredType = apiResponse.GetType();
@@ -0,0 +1,42 @@
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Helper
{
public static class SafeBussinessHelper
{
public static async Task<bool> RunAsync(Func<Task> func, [CallerMemberName] string caller = "", string errorMsgTitle = "")
{
try
{
await func();
return true;
}
catch (Exception ex)
{
Log.Logger.Error($"【{errorMsgTitle}失败 - {caller}】: {ex.Message}");
return false;
}
}
public static async Task<(bool Success, T? Result)> RunAsync<T>(Func<Task<T>> func, [CallerMemberName] string caller = "", string errorMsgTitle = "")
{
try
{
var result = await func();
return (true, result);
}
catch (Exception ex)
{
Log.Logger.Error($"【{errorMsgTitle}失败 - {caller}】: {ex.Message}");
return (false, default);
}
}
}
}
+1 -2
View File
@@ -27,8 +27,7 @@ namespace IRaCIS.Core.SCP
//public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); });
var logFactory = LoggerFactory.Create(builder => { builder.AddDebug(); });
options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value,
contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value);
options.UseLoggerFactory(logFactory);
+134
View File
@@ -0,0 +1,134 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
namespace IRaCIS.Core.API;
public enum SwaggerVersion
{
//[Description("HIR修改")]
//HIR = -1,
//[Description("医生模块")]
//Reviewer = 1,
[Description("项目模块")]
Trial = 2,
//[Description("入组模块")]
//Enroll = 3,
//[Description("工作量模块")]
//Workload = 4,
//[Description("通用信息获取")]
//Common = 5,
//[Description("机构信息模块")]
//Institution = 6,
//[Description("统计模块")]
//DashboardStatistics = 7,
//[Description("财务模块")]
//Financial = 8,
//[Description("管理模块")]
//Management = 9,
//[Description("影像模块")]
//Image = 10,
//[Description("读片模块")]
//Reading = 11
};
public static class SwaggerSetup
{
public static void AddSwaggerSetup(this IServiceCollection services)
{
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options =>
{
typeof(SwaggerVersion).GetFields(BindingFlags.Public | BindingFlags.Static).ToList()
.ForEach(field =>
{
var description = field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? field.Name;
options.SwaggerDoc(field.Name, new Microsoft.OpenApi.Models.OpenApiInfo
{
Version = field.Name,
Description = $"{field.Name} API",
Title = description // 使用Description作为Title
});
});
// 接口排序
options.OrderActionsBy(o => o.GroupName);
//添加注释
var basePath = AppContext.BaseDirectory;
//var xmlPath1 = Path.Combine(basePath, "IRaCIS.Core.Application.xml");
var xmlPath2 = Path.Combine(basePath, "IRC.Core.SCP.xml");
//options.IncludeXmlComments(xmlPath1, true);
options.IncludeXmlComments(xmlPath2, true);
// 在header中添加token,传递到后台
options.OperationFilter<SecurityRequirementsOperationFilter>();
// 添加登录按钮
options.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme()
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name = "Authorization",
//In = "header",
//Type = "apiKey"
});
});
}
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSwagger();
app.UseSwaggerUI(options =>
{
typeof(SwaggerVersion).GetFields(BindingFlags.Public | BindingFlags.Static).ToList()
.ForEach(field =>
{
var description = field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? field.Name;
options.SwaggerEndpoint($"swagger/{field.Name}/swagger.json", $"{description}");
});
var data = Assembly.GetExecutingAssembly().Location;
options.IndexStream = () => Assembly.GetExecutingAssembly()
.GetManifestResourceStream("IRC.Core.SCP.wwwroot.swagger.ui.Index.html");
//路径配置,设置为空,表示直接在根域名(localhost:8001)访问该文件,
//注意localhost:8001/swagger是访问不到的,去launchSettings.json把launchUrl去掉,如果你想换一个路径,直接写名字即可,比如直接写c.Route = "doc";
options.RoutePrefix = string.Empty;
//DocExpansion设置为none可折叠所有方法
options.DocExpansion(DocExpansion.None);
//DefaultModelsExpandDepth设置为 - 1 可不显示models
options.DefaultModelsExpandDepth(-1);
// 关键一句:关闭外网校验
options.ConfigObject.ValidatorUrl = null;
});
}
}
+42 -14
View File
@@ -4,31 +4,51 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<BaseOutputPath></BaseOutputPath>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DocumentationFile>.\IRC.Core.SCP.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.4" />
<Content Remove="wwwroot\swagger\ui\abp.js" />
<Content Remove="wwwroot\swagger\ui\Index.html" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="wwwroot\swagger\ui\abp.js">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="wwwroot\swagger\ui\Index.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.6" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="AWSSDK.S3" Version="3.7.402.7" />
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.400.16" />
<PackageReference Include="DistributedLock.Core" Version="1.0.7" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.5" />
<PackageReference Include="fo-dicom" Version="5.1.3" />
<PackageReference Include="fo-dicom.Codecs" Version="5.14.5" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.8" />
<PackageReference Include="AWSSDK.S3" Version="4.0.6.9" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.2" />
<PackageReference Include="DistributedLock.Core" Version="1.0.8" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.6" />
<PackageReference Include="fo-dicom" Version="5.2.2" />
<PackageReference Include="fo-dicom.Codecs" Version="5.16.4" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Minio" Version="6.0.3" />
<PackageReference Include="Minio" Version="7.0.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.1.1" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.4.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.3" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="9.0.0" />
<PackageReference Include="ZiggyCreatures.FusionCache" Version="2.4.0" />
</ItemGroup>
<ItemGroup>
@@ -36,4 +56,12 @@
<ProjectReference Include="..\IRaCIS.Core.Infra.EFCore\IRaCIS.Core.Infra.EFCore.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="appsettings.Prod_HIR_SCP.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
</Project>
+92
View File
@@ -0,0 +1,92 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>IRC.Core.SCP</name>
</assembly>
<members>
<member name="M:IRaCIS.Core.SCP.Service.CacheKeys.UserLoginError(System.String)">
<summary>
用户登录错误 限制登录
</summary>
<param name="userName"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.SCP.Service.CacheKeys.SkipReadingCacheKey(System.Guid)">
<summary>
跳过阅片
</summary>
<param name="userId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.SCP.Service.CacheKeys.StartReadingTimeKey(System.Guid)">
<summary>
开始阅片时间
</summary>
<param name="userId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.SCP.Service.CacheKeys.StartRestTime(System.Guid)">
<summary>
开始休息时间
</summary>
<param name="userId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.SCP.Service.DicomArchiveService.ArchiveDicomFileAsync(FellowOakDicom.DicomFile,System.String,System.String,System.String,System.Int64)">
<summary>
单个文件接收 归档
</summary>
<param name="dataset"></param>
<returns></returns>
<exception cref="T:System.NotImplementedException"></exception>
</member>
<member name="M:IRaCIS.Core.SCP.Service.PatientStudyService.AutoBindingPatientStudyVisitAsync(System.Collections.Generic.List{System.Guid})">
<summary>
传输完成后,自动给检查绑定访视
</summary>
<param name="inCommand"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.SCP.OSSService.UploadToOSSAsync(System.IO.Stream,System.String,System.String,System.Boolean)">
<summary>
oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
</summary>
<param name="fileStream"></param>
<param name="oosFolderPath"></param>
<param name="fileRealName"></param>
<param name="isFileNameAddGuid"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.SCP.OSSService.UploadToOSSAsync(System.String,System.String,System.Boolean)">
<summary>
oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
</summary>
<param name="localFilePath"></param>
<param name="oosFolderPath"></param>
<param name="isFileNameAddGuid"></param>
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>
<member name="M:IRaCIS.Core.SCP.OSSService.DeleteFromPrefix(System.String)">
<summary>
删除某个目录的文件
</summary>
<param name="prefix"></param>
<returns></returns>
</member>
<member name="T:IRaCIS.Core.Application.Service.BusinessFilter.UnifiedApiResultFilter">
<summary>
统一返回前端数据包装,之前在控制器包装,现在修改为动态Api 在ResultFilter这里包装,减少重复冗余代码
by zhouhang 2021.09.12 周末
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Service.BusinessFilter.UnifiedApiResultFilter.OnResultExecutionAsync(Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext,Microsoft.AspNetCore.Mvc.Filters.ResultExecutionDelegate)">
<summary>
异步版本
</summary>
<param name="context"></param>
<param name="next"></param>
<returns></returns>
</member>
</members>
</doc>
+41 -14
View File
@@ -6,6 +6,7 @@ using FellowOakDicom;
using FellowOakDicom.Imaging;
using FellowOakDicom.Imaging.NativeCodec;
using FellowOakDicom.Network;
using IRaCIS.Core.API;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.SCP;
using IRaCIS.Core.SCP.Filter;
@@ -14,6 +15,7 @@ using MassTransit;
using MassTransit.NewIdProviders;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Client;
using Panda.DynamicWebApi;
using Serilog;
using Serilog.Events;
@@ -82,7 +84,6 @@ builder.Services.AddControllers(options =>
.AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化 处理
builder.Services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
builder.Services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
builder.Services.AddOptions().Configure<DicomSCPServiceOption>(_configuration.GetSection("DicomSCPServiceConfig"));
@@ -126,37 +127,54 @@ builder.Services.Configure<ForwardedHeadersOptions>(options =>
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
//Dicom影像渲染图片 跨平台
//builder.Services.AddDicomSetup();
new DicomSetupBuilder()
.RegisterServices(s =>
s.AddFellowOakDicom()
.AddTranscoderManager<NativeTranscoderManager>()
builder.Services.AddFellowOakDicom().AddTranscoderManager<NativeTranscoderManager>()
//.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>()
.AddImageManager<ImageSharpImageManager>())
.SkipValidation()
.Build();
.AddImageManager<ImageSharpImageManager>();
////Dicom影像渲染图片 跨平台
////builder.Services.AddDicomSetup();
//new DicomSetupBuilder()
// .RegisterServices(s =>
// s.AddFellowOakDicom()
// .AddTranscoderManager<NativeTranscoderManager>()
// //.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>()
// .AddImageManager<ImageSharpImageManager>())
// .SkipValidation()
// .Build();
#endregion
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
//builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen();
//Swagger Api 文档
builder.Services.AddSwaggerSetup();
// FusionCache
builder.Services.AddFusionCache();
var app = builder.Build();
// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
//{
app.UseSwagger();
app.UseSwaggerUI();
//app.UseSwagger();
//app.UseSwaggerUI();
//}
//不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();
SwaggerSetup.Configure(app, app.Environment);
app.UseAuthorization();
app.MapControllers();
@@ -185,6 +203,7 @@ app.MapControllers();
Log.Logger = new LoggerConfiguration()
//.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("ZiggyCreatures.Caching.Fusion", LogEventLevel.Warning)
.WriteTo.Console()
.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day)
.CreateLogger();
@@ -211,9 +230,17 @@ else
#endregion
DicomSetupBuilder.UseServiceProvider(app.Services);
// Program.cs
IRCAppConfig.Configuration = builder.Configuration;
var logger = app.Services.GetService<Microsoft.Extensions.Logging.ILogger<Program>>();
var server = DicomServerFactory.Create<CStoreSCPService>(_configuration.GetSection("DicomSCPServiceConfig").GetValue<int>("ServerPort"), userState: app.Services,logger: logger);
app.Run();
+14 -4
View File
@@ -1,24 +1,34 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"Test_IRC_SCP": {
"Test_HIR_SCP": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:6200",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Test_IRC_SCP"
"ASPNETCORE_ENVIRONMENT": "Test_HIR_SCP"
}
},
"Uat_IRC_SCP": {
"Uat_HIR_SCP": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:6200",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Uat_IRC_SCP"
"ASPNETCORE_ENVIRONMENT": "Uat_HIR_SCP"
}
},
"Prod_HIR_SCP": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:6200",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Prod_HIR_SCP"
}
}
}
File diff suppressed because it is too large Load Diff
+101
View File
@@ -0,0 +1,101 @@
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infra.EFCore;
using Microsoft.EntityFrameworkCore;
namespace IRaCIS.Core.SCP.Service;
public static class CacheKeys
{
//项目缓存
public static string Trial(string trialIdStr) => $"TrialId:{trialIdStr}";
//检查编号递增锁
public static string TrialStudyMaxCode(Guid trialId) => $"TrialStudyMaxCode:{trialId}";
public static string TrialStudyUidUploading(Guid trialId, string studyUid) => $"TrialStudyUid:{trialId}_{studyUid}";
//CRC上传影像提交锁key
public static string TrialStudyUidDBLock(Guid trialId, string studyUid) => $"TrialStudyUidDBLock:{trialId}_{studyUid}";
public static string TrialTaskStudyUidUploading(Guid trialId, Guid visiTaskId, string studyUid) => $"TrialStudyUid:{trialId}_{visiTaskId}_{studyUid}";
//影像后处理上传提交锁key
public static string TrialTaskStudyUidDBLock(Guid trialId, Guid visiTaskId, string studyUid) => $"TrialTaskStudyUidDBLock:{trialId}_{visiTaskId}_{studyUid}";
//系统匿名化
public static string SystemAnonymization => $"SystemAnonymization";
//前端国际化
public static string FrontInternational => $"FrontInternationalList";
//登录挤账号
public static string UserToken(Guid userId) => $"UserToken:{userId}";
//超时没请求接口自动退出
public static string UserAutoLoginOut(Guid userId) => $"UserAutoLoginOut:{userId}";
public static string UserDisable(Guid userId) => $"UserDisable:{userId}";
public static string UserRoleDisable(Guid userRoleId) => $"UserRoleDisable:{userRoleId}";
/// <summary>
/// 用户登录错误 限制登录
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public static string UserLoginError(string userName) => $"login-failures:{userName}";
/// <summary>
/// 跳过阅片
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public static string SkipReadingCacheKey(Guid userId) => $"{userId}SkipReadingCache";
/// <summary>
/// 开始阅片时间
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public static string StartReadingTimeKey(Guid userId) => $"{userId}StartReadingTime";
/// <summary>
/// 开始休息时间
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public static string StartRestTime(Guid userId) => $"{userId}StartRestTime";
//每个用户 每个浏览器独立时间
public static string UserMFAVerifyPass(Guid userId, string browserFingerprint) => $"UserMFAVerifyPass:{userId}:{browserFingerprint}";
public static string TrialSiteInfo(Guid trialSiteId) => $"{trialSiteId}TrialSiteInfo";
}
public static class CacheHelper
{
public static async Task<string?> GetTrialStatusAsync(Guid trialId, IRepository<Trial> _trialRepository)
{
var statusStr = await _trialRepository.Where(t => t.Id == trialId, ignoreQueryFilters: true).Select(t => t.TrialStatusStr).FirstOrDefaultAsync();
return statusStr;
}
public class TrialSiteInfoDTO
{
public string TrialSiteCode { get; set; }
public string TrialCode { get; set; }
}
public static async Task<TrialSiteInfoDTO> GetTrialSiteInfo(Guid trialSiteId, IRepository<TrialSite> _trialSiteRepository)
{
var obj = await _trialSiteRepository.Where(t => t.Id == trialSiteId, ignoreQueryFilters: true).Select(t => new TrialSiteInfoDTO { TrialCode= t.Trial.TrialCode, TrialSiteCode= t.TrialSiteCode }).FirstOrDefaultAsync();
return obj??new TrialSiteInfoDTO();
}
public static async Task<List<SystemAnonymization>> GetSystemAnonymizationListAsync(IRepository<SystemAnonymization> _systemAnonymizationRepository)
{
var list = await _systemAnonymizationRepository.Where(t => t.IsEnable).ToListAsync();
return list;
}
}
+102 -60
View File
@@ -11,37 +11,19 @@ using FellowOakDicom.Network;
using IRaCIS.Core.SCP.Service;
using IRaCIS.Core.Infra.EFCore;
using MassTransit;
using System.Runtime.Intrinsics.X86;
using Serilog.Sinks.File;
using IRaCIS.Core.Infrastructure.Extention;
using ZiggyCreatures.Caching.Fusion;
namespace IRaCIS.Core.SCP.Service
{
public class DicomArchiveService : BaseService, IDicomArchiveService
public class DicomArchiveService(IRepository<SCPPatient> _patientRepository,
IRepository<SCPStudy> _studyRepository,
IRepository<SCPSeries> _seriesRepository,
IRepository<SCPInstance> _instanceRepository
) : BaseService, IDicomArchiveService
{
private readonly IRepository<SCPPatient> _patientRepository;
private readonly IRepository<SCPStudy> _studyRepository;
private readonly IRepository<SCPSeries> _seriesRepository;
private readonly IRepository<SCPInstance> _instanceRepository;
private readonly IRepository<Dictionary> _dictionaryRepository;
private readonly IDistributedLockProvider _distributedLockProvider;
private List<Guid> _instanceIdList = new List<Guid>();
public DicomArchiveService(IRepository<SCPPatient> patientRepository, IRepository<SCPStudy> studyRepository,
IRepository<SCPSeries> seriesRepository,
IRepository<SCPInstance> instanceRepository,
IRepository<Dictionary> dictionaryRepository,
IDistributedLockProvider distributedLockProvider)
{
_distributedLockProvider = distributedLockProvider;
_studyRepository = studyRepository;
_patientRepository = patientRepository;
_seriesRepository = seriesRepository;
_instanceRepository = instanceRepository;
_dictionaryRepository = dictionaryRepository;
}
@@ -52,18 +34,20 @@ namespace IRaCIS.Core.SCP.Service
/// <param name="dataset"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<Guid> ArchiveDicomFileAsync(DicomDataset dataset, Guid trialId, Guid trialSiteId, string fileRelativePath, string callingAE, string calledAE,long fileSize)
public async Task<Guid> ArchiveDicomFileAsync(DicomFile dicomFile, string fileRelativePath, string callingAE, string calledAE, long fileSize)
{
var dataset = dicomFile.Dataset;
string studyInstanceUid = dataset.GetString(DicomTag.StudyInstanceUID);
string seriesInstanceUid = dataset.GetString(DicomTag.SeriesInstanceUID);
string sopInstanceUid = dataset.GetString(DicomTag.SOPInstanceUID);
string patientIdStr = dataset.GetSingleValueOrDefault(DicomTag.PatientID,string.Empty);
string patientIdStr = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty);
//Guid patientId= IdentifierHelper.CreateGuid(patientIdStr);
Guid studyId = IdentifierHelper.CreateGuid(studyInstanceUid,trialId.ToString());
Guid seriesId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, trialId.ToString());
Guid instanceId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, sopInstanceUid, trialId.ToString());
Guid studyId = IdentifierHelper.CreateGuid(studyInstanceUid);
Guid seriesId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid);
Guid instanceId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, sopInstanceUid);
var isStudyNeedAdd = false;
var isSeriesNeedAdd = false;
@@ -74,15 +58,16 @@ namespace IRaCIS.Core.SCP.Service
//using (@lock.Acquire())
{
var findPatient = await _patientRepository.FirstOrDefaultAsync(t => t.PatientIdStr == patientIdStr && t.TrialSiteId==trialSiteId );
var findStudy = await _studyRepository.FindAsync(studyId);
var findSerice = await _seriesRepository.FindAsync(seriesId);
var findInstance = await _instanceRepository.FindAsync(instanceId);
var findPatient = await _patientRepository.FirstOrDefaultAsync(t => t.PatientIdStr == patientIdStr);
var findStudy = await _studyRepository.FirstOrDefaultAsync(t => t.Id == studyId);
var findSerice = await _seriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
var findInstance = await _instanceRepository.FirstOrDefaultAsync(t => t.Id == instanceId);
DateTime? studyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.StudyDate).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.StudyTime).TimeOfDay);
//先传输了修改了患者编号的,又传输了没有修改患者编号的,导致后传输的没有修改患者编号的下面的检查为0
if (findPatient == null && findStudy==null)
//先传输了,修改了患者编号的,又传输了没有修改患者编号的,导致后传输的没有修改患者编号的下面的检查为0
if (findPatient == null /*&& findStudy == null*/)
{
isPatientNeedAdd = true;
@@ -90,8 +75,6 @@ namespace IRaCIS.Core.SCP.Service
findPatient = new SCPPatient()
{
Id = NewId.NextSequentialGuid(),
TrialId=trialId,
TrialSiteId=trialSiteId,
PatientIdStr = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty),
PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty),
PatientAge = dataset.GetSingleValueOrDefault(DicomTag.PatientAge, string.Empty),
@@ -117,20 +100,6 @@ namespace IRaCIS.Core.SCP.Service
{
findPatient.PatientBirthDate = birthDateStr;
DateTime birthDate;
if (findPatient.PatientAge == string.Empty && studyTime.HasValue && DateTime.TryParse(findPatient.PatientBirthDate,out birthDate))
{
var patientAge = studyTime.Value.Year - birthDate.Year;
// 如果生日还未到,年龄减去一岁
if (studyTime.Value < birthDate.AddYears(patientAge))
{
patientAge--;
}
findPatient.PatientAge = patientAge.ToString();
}
}
else
{
@@ -151,6 +120,32 @@ namespace IRaCIS.Core.SCP.Service
}
findPatient.LatestPushTime = DateTime.Now;
findPatient.PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty);
findPatient.PatientSex = dataset.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty);
findPatient.PatientAge = dataset.GetSingleValueOrDefault(DicomTag.PatientAge, string.Empty);
findPatient.PatientBirthDate = dataset.GetSingleValueOrDefault(DicomTag.PatientBirthDate, string.Empty);
if (findPatient.PatientBirthDate.Length == 8)
{
var birthDateStr = $"{findPatient.PatientBirthDate[0]}{findPatient.PatientBirthDate[1]}{findPatient.PatientBirthDate[2]}{findPatient.PatientBirthDate[3]}-{findPatient.PatientBirthDate[4]}{findPatient.PatientBirthDate[5]}-{findPatient.PatientBirthDate[6]}{findPatient.PatientBirthDate[7]}";
var yearStr = $"{findPatient.PatientBirthDate[0]}{findPatient.PatientBirthDate[1]}{findPatient.PatientBirthDate[2]}{findPatient.PatientBirthDate[3]}";
int year = 0;
var canParse = int.TryParse(yearStr, out year);
if (canParse && year > 1900)
{
findPatient.PatientBirthDate = birthDateStr;
}
else
{
findPatient.PatientBirthDate = string.Empty;
}
}
}
if (findStudy == null)
@@ -163,10 +158,12 @@ namespace IRaCIS.Core.SCP.Service
PatientId = findPatient.Id,
Id = studyId,
TrialId = trialId,
TrialSiteId = trialSiteId,
StudyInstanceUid = studyInstanceUid,
StudyTime = studyTime,
DicomStudyDate = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty),
DicomStudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty),
Modalities = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty),
//ModalityForEdit = modalityForEdit,
Description = dataset.GetSingleValueOrDefault(DicomTag.StudyDescription, string.Empty),
@@ -201,6 +198,20 @@ namespace IRaCIS.Core.SCP.Service
findStudy.PatientBirthDate = $"{findStudy.PatientBirthDate[0]}{findStudy.PatientBirthDate[1]}{findStudy.PatientBirthDate[2]}{findStudy.PatientBirthDate[3]}-{findStudy.PatientBirthDate[4]}{findStudy.PatientBirthDate[5]}-{findStudy.PatientBirthDate[6]}{findStudy.PatientBirthDate[7]}";
}
}
else
{
findStudy.DicomStudyDate = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty);
findStudy.DicomStudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty);
findStudy.CalledAE = calledAE;
findStudy.CallingAE = callingAE;
findStudy.PatientIdStr = patientIdStr;
findStudy.PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty);
findStudy.PatientSex = dataset.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty);
findStudy.PatientAge = dataset.GetSingleValueOrDefault(DicomTag.PatientAge, string.Empty);
findStudy.UpdateTime = DateTime.Now;
await _patientRepository.BatchUpdateNoTrackingAsync(t => t.Id == findStudy.PatientId, u => new SCPPatient() { LatestPushTime = DateTime.Now });
}
if (findSerice == null)
@@ -218,6 +229,9 @@ namespace IRaCIS.Core.SCP.Service
//SeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, DateTime.Now).Add(dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, DateTime.Now).TimeOfDay),
//SeriesTime = DateTime.TryParse(dataset.GetSingleValue<string>(DicomTag.SeriesDate) + dataset.GetSingleValue<string>(DicomTag.SeriesTime), out DateTime dt) ? dt : null,
SeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.SeriesDate).Add(dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.SeriesTime).TimeOfDay),
DicomSeriesDate = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, string.Empty),
DicomSeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, string.Empty),
Modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty),
Description = dataset.GetSingleValueOrDefault(DicomTag.SeriesDescription, string.Empty),
SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty),
@@ -239,7 +253,20 @@ namespace IRaCIS.Core.SCP.Service
++findStudy.SeriesCount;
}
else
{
findSerice.DicomSeriesDate = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, string.Empty);
findSerice.DicomSeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, string.Empty);
findSerice.UpdateTime = DateTime.Now;
}
var transferSyntaxUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.TransferSyntaxUID, string.Empty);
var isEncapsulated = false;
if (transferSyntaxUID.IsNotNullOrEmpty())
{
isEncapsulated = DicomTransferSyntax.Lookup(DicomUID.Parse(transferSyntaxUID)).IsEncapsulated;
}
if (findInstance == null)
{
@@ -253,6 +280,12 @@ namespace IRaCIS.Core.SCP.Service
SeriesInstanceUid = findSerice.SeriesInstanceUid,
SopInstanceUid = sopInstanceUid,
SOPClassUID = dataset.GetSingleValueOrDefault(DicomTag.SOPClassUID, string.Empty),
MediaStorageSOPClassUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPClassUID, string.Empty),
TransferSyntaxUID = transferSyntaxUID,
MediaStorageSOPInstanceUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPInstanceUID, string.Empty),
IsEncapsulated = isEncapsulated,
InstanceNumber = dataset.GetSingleValueOrDefault(DicomTag.InstanceNumber, 1),
InstanceTime = dataset.GetSingleValueOrDefault(DicomTag.ContentDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.ContentDate).Add(dataset.GetSingleValueOrDefault(DicomTag.ContentTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.ContentTime).TimeOfDay),
//InstanceTime = DateTime.TryParse(dataset.GetSingleValue<string>(DicomTag.ContentDate) + dataset.GetSingleValue<string>(DicomTag.ContentTime), out DateTime dt) ? dt : null,
@@ -264,7 +297,7 @@ namespace IRaCIS.Core.SCP.Service
SliceLocation = dataset.GetSingleValueOrDefault(DicomTag.SliceLocation, 0),
SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty),
NumberOfFrames = dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 0),
NumberOfFrames = dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 1),
PixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.PixelSpacing, string.Empty),
ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
FrameOfReferenceUID = dataset.GetSingleValueOrDefault(DicomTag.FrameOfReferenceUID, string.Empty),
@@ -273,13 +306,21 @@ namespace IRaCIS.Core.SCP.Service
Path = fileRelativePath,
FileSize= fileSize,
FileSize = fileSize,
};
++findStudy.InstanceCount;
++findSerice.InstanceCount;
}
else
{
findInstance.SOPClassUID = dataset.GetSingleValueOrDefault(DicomTag.SOPClassUID, string.Empty);
findInstance.MediaStorageSOPClassUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPClassUID, string.Empty);
findInstance.TransferSyntaxUID = transferSyntaxUID;
findInstance.MediaStorageSOPInstanceUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPInstanceUID, string.Empty);
findInstance.IsEncapsulated = isEncapsulated;
findInstance.UpdateTime = DateTime.Now;
}
if (isPatientNeedAdd)
{
@@ -298,16 +339,17 @@ namespace IRaCIS.Core.SCP.Service
{
await _seriesRepository.AddAsync(findSerice);
}
if (isInstanceNeedAdd)
{
await _instanceRepository.AddAsync(findInstance);
}
else
{
await _instanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == instanceId, u => new SCPInstance() { Path = fileRelativePath,FileSize=fileSize });
await _instanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == instanceId, u => new SCPInstance() { Path = fileRelativePath, FileSize = fileSize });
}
//await _studyRepository.SaveChangesAsync();
await _studyRepository.SaveChangesAsync();
return findStudy.Id;
}
@@ -5,7 +5,7 @@ namespace IRaCIS.Core.SCP.Service
{
public interface IDicomArchiveService
{
Task<Guid> ArchiveDicomFileAsync(DicomDataset dicomDataset,Guid trialId,Guid trialSiteId, string fileRelativePath,string callingAE,string calledAE,long fileSize);
Task<Guid> ArchiveDicomFileAsync(DicomFile dicomFile,string fileRelativePath,string callingAE,string calledAE,long fileSize);
}
}
+13 -2
View File
@@ -12,6 +12,7 @@ using MassTransit;
using Microsoft.Extensions.Options;
using Minio;
using Minio.DataModel.Args;
using System.Net;
using System.Reactive.Linq;
using System.Runtime.InteropServices;
@@ -118,7 +119,7 @@ public class AWSTempToken
public string SecretAccessKey { get; set; }
public string BucketName { get; set; }
public string ViewEndpoint { get; set; }
public DateTime Expiration { get; set; }
public DateTime? Expiration { get; set; }
}
public enum ObjectStoreUse
@@ -216,9 +217,19 @@ public class OSSService : IOSSService
.WithBucket(minIOConfig.BucketName)
.WithObject(ossRelativePath)
.WithStreamData(memoryStream)
.WithObjectSize(memoryStream.Length);
await minioClient.PutObjectAsync(putObjectArgs);
var putResponse = await minioClient.PutObjectAsync(putObjectArgs);
if (putResponse.ResponseStatusCode == HttpStatusCode.OK)
{
}
else
{
throw new BusinessValidationFailedException($"上传失败ResponseStatusCode{putResponse.ResponseStatusCode}{putResponse.ResponseContent}");
}
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
+317
View File
@@ -0,0 +1,317 @@
using FellowOakDicom;
using FellowOakDicom.Imaging;
using FellowOakDicom.Imaging.Codec;
using FellowOakDicom.Network;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using IRaCIS.Core.SCP.Service;
using MassTransit;
using Medallion.Threading;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using SixLabors.ImageSharp.Formats.Jpeg;
using System.Data;
using System.Text;
namespace IRaCIS.Core.SCP.Service
{
public interface IPatientStudyService
{
Task<IResponseOutput> AutoBindingPatientStudyVisitAsync(List<Guid> scpStudyIdList);
}
[ApiExplorerSettings(GroupName = "Trial")]
public class PatientStudyService : BaseService, IPatientStudyService
{
private readonly IRepository<SCPStudySubjectVisit> _studySubjectVisitRepository;
private readonly IRepository<SubjectPatient> _subjectPatientRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<SCPPatient> _patientRepository;
private readonly IRepository<SCPStudy> _studyRepository;
private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IDistributedLockProvider _distributedLockProvider;
public PatientStudyService(IRepository<SCPStudySubjectVisit> studySubjectVisitRepository, IRepository<SCPStudy> studyRepository, IRepository<SubjectPatient> subjectPatientRepository, IRepository<Trial> trialRepository, IRepository<SCPPatient> patientRepository, IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository, IDistributedLockProvider distributedLockProvider)
{
_studySubjectVisitRepository = studySubjectVisitRepository;
_studyRepository = studyRepository;
_subjectPatientRepository = subjectPatientRepository;
_trialRepository = trialRepository;
_patientRepository = patientRepository;
_subjectRepository = subjectRepository;
_subjectVisitRepository = subjectVisitRepository;
_distributedLockProvider = distributedLockProvider;
}
[AllowAnonymous]
public async Task<IResponseOutput> TestImage(string folderPath)
{
if (!Directory.Exists(folderPath))
return ResponseOutput.Ok("目录不存在");
// 获取所有 .dcm 文件
var dicomFiles = Directory.GetFiles(folderPath);
foreach (var fileFullPath in dicomFiles)
{
try
{
var file = await DicomFile.OpenAsync(fileFullPath);
// 生成缩略图
using (var memoryStream = new MemoryStream())
{
DicomImage image = new DicomImage(file.Dataset);
var sharpimage = image.RenderImage().AsSharpImage();
sharpimage.Save(memoryStream, new JpegEncoder());
// 关键点:一定要回到开头
memoryStream.Position = 0;
using (var fileStream = File.Create($"{fileFullPath}.jpg"))
{
await memoryStream.CopyToAsync(fileStream);
}
}
}
catch (Exception)
{
continue;
}
}
return ResponseOutput.Ok();
}
public class AuToBindingStudyInfo
{
public Guid SCPStudyId { get; set; }
public DateTime? StudyTime { get; set; }
}
private async Task DealAutoBindingStudyAsync(Guid trialId, Guid subjectId, List<AuToBindingStudyInfo> studyList, decimal? startBindVisitNum = null)
{
//自动创建访视 和检查绑定
//1. 查询已存在的访视
var subjectAllVisitList = await _subjectVisitRepository.Where(t => t.SubjectId == subjectId)
.Select(t => new
{
t.SubjectId,
SubjectVisitId = t.Id,
t.SubmitState,
VisitNum = t.VisitNum,
MaxStudyTime = t.SCPStudySubjectVisitList.Max(t => t.SCPStudy.StudyTime),
MinStudyTime = t.SCPStudySubjectVisitList.Min(t => t.SCPStudy.StudyTime)
})
.ToListAsync();
//2、获取项目配置
var trialconfig = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.BlindBaseLineName, t.BlindFollowUpPrefix }).FirstOrDefault();
//3、 未提交的最小的访视号 从这个访视开始绑定
decimal subjectMaxVisitNum = 0;
if (startBindVisitNum == null)
{
if (subjectAllVisitList.Any(t => t.SubmitState != SubmitStateEnum.Submitted))
{
subjectMaxVisitNum = subjectAllVisitList.Where(t => t.SubmitState != SubmitStateEnum.Submitted).MinOrDefault(t => t.VisitNum);
}
else
{
//没有未提交的,那么开始绑定的就是已提交的加1
subjectMaxVisitNum = subjectAllVisitList.Any() ? subjectAllVisitList.Last().VisitNum + 1 : 0;
}
}
else
{
subjectMaxVisitNum = startBindVisitNum.Value;
}
//var subjectMaxVisitNum = startBindVisitNum == null ? subjectAllVisitList.Where(t => t.SubmitState != SubmitStateEnum.Submitted).MinOrDefault(t => t.VisitNum) : startBindVisitNum.Value;
List<(int VisitCount, Guid SCPStudyId)> visits = new List<(int, Guid)>();
int visitCount = 0;
DateTime? lastVisitTime = null;
foreach (var study in studyList)
{
if (lastVisitTime == null || (study.StudyTime - lastVisitTime.Value).Value.TotalDays >= 15)
{
// 当前时间点与上一个访视时间点间隔大于等于 15 天,需要建立一个新的访视
visitCount++;
visits.Add((visitCount, study.SCPStudyId));
}
else
{
visits.Add((visitCount, study.SCPStudyId));
}
lastVisitTime = study.StudyTime;
}
//4、生成访视 并且绑定
for (int i = 0; i < visitCount; i++)
{
var bindSubjectVisitId = Guid.Empty;
var bindVisitNum = i + subjectMaxVisitNum;
var existSubjectVisit = subjectAllVisitList.FirstOrDefault(t => t.SubjectId == subjectId && t.VisitNum == bindVisitNum);
if (existSubjectVisit == null)
{
bindSubjectVisitId = NewId.NextGuid();
//基线
if (bindVisitNum == 0)
{
await _subjectVisitRepository.AddAsync(new SubjectVisit() { TrialId = trialId, SubjectId = subjectId, VisitName = trialconfig.BlindBaseLineName, VisitNum = bindVisitNum, Id = bindSubjectVisitId, SubmitState = SubmitStateEnum.ToSubmit, IsBaseLine = true });
}
else
{
await _subjectVisitRepository.AddAsync(new SubjectVisit() { TrialId = trialId, SubjectId = subjectId, VisitName = trialconfig.BlindFollowUpPrefix + $" {(int)bindVisitNum}", VisitNum = bindVisitNum, Id = bindSubjectVisitId, SubmitState = SubmitStateEnum.ToSubmit });
}
}
else
{
bindSubjectVisitId = existSubjectVisit.SubjectVisitId;
}
var currentVisitStudyList = visits.Where(t => t.VisitCount == (i + 1)).ToList();
foreach (var item in currentVisitStudyList)
{
//访视状态为未提交才绑定
if (!subjectAllVisitList.Any(t => t.SubjectId == subjectId && t.SubjectVisitId == bindSubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted))
{
var find = await _subjectVisitRepository.FindAsync(bindSubjectVisitId);
find.SubmitState = SubmitStateEnum.ToSubmit;
await _studySubjectVisitRepository.AddAsync(new SCPStudySubjectVisit() { TrialId = trialId, SubjectVisitId = bindSubjectVisitId, SCPStudyId = item.SCPStudyId, SubjectId = subjectId });
}
}
}
await _subjectPatientRepository.SaveChangesAsync();
}
/// <summary>
/// 传输完成后,自动给检查绑定访视
/// </summary>
/// <param name="inCommand"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> AutoBindingPatientStudyVisitAsync(List<Guid> scpStudyIdList)
{
//一个检查 可能绑定到不同的项目的不同subject 有的该检查已绑定访视,有的该检查绑定了访视
var query = from scpStudy in _studyRepository.Where(t => scpStudyIdList.Contains(t.Id))
join subjectPatient in _subjectPatientRepository.AsQueryable()
on scpStudy.PatientId equals subjectPatient.PatientId
select new
{
subjectPatient.Subject.Status,
subjectPatient.Subject.TrialId,
subjectPatient.SubjectId,
subjectPatient.PatientId,
SCPStudyId = scpStudy.Id,
scpStudy.StudyTime
};
var list = query.ToList();
if (list.Count > 0)
{
var subjectIdList = list.Select(t => t.SubjectId).ToList();
var allSubjectVisitList = await _subjectVisitRepository.Where(t => subjectIdList.Contains(t.SubjectId))
.Select(t => new { t.SubjectId, SubjectVisitId = t.Id, t.SubmitState, VisitNum = t.VisitNum, MaxStudyTime = t.SCPStudySubjectVisitList.Max(t => t.SCPStudy.StudyTime), MinStudyTime = t.SCPStudySubjectVisitList.Min(t => t.SCPStudy.StudyTime) })
.ToListAsync();
foreach (var g in list.GroupBy(t => new { t.SubjectId, t.TrialId, t.Status }))
{
var subjectId = g.Key.SubjectId;
var trialId = g.Key.TrialId;
//访视结束,那么就不处理
if (g.Key.Status == SubjectStatus.EndOfVisit)
{
continue;
}
// 预先处理1: 数据库可能有已存在的subject 患者绑定,在这里要一起考虑绑定
var dbPatientIdList = _subjectPatientRepository.Where(t => t.SubjectId == subjectId).Select(t => t.PatientId).ToList();
// 预先处理2: 删除未提交的所有绑定的检查记录,所有检查一起考虑绑定
await _studySubjectVisitRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId && t.SubjectVisit.SubmitState != SubmitStateEnum.Submitted);
//预处理3 找到该subjecct 已提交的访视的最大检查时间,绑定的检查时间要比这个时间要大
var maxStudyTime = allSubjectVisitList.Where(t => t.SubjectId == subjectId && t.SubmitState == SubmitStateEnum.Submitted).MaxOrDefault(t => t.MaxStudyTime);
// 预处理4 处理需要绑定的检查
//获取 该受试者绑定患者已存在的检查,考虑要生成多少个访视,去除已提交的检查
var studyList = await _studyRepository.Where(t => dbPatientIdList.Contains(t.PatientId)
&& !t.SCPStudySubjectVisitList.Any(t => t.SubjectId == subjectId && t.SubjectVisit.SubmitState == SubmitStateEnum.Submitted))
.WhereIf(maxStudyTime != null, t => t.StudyTime > maxStudyTime)
.Select(t => new AuToBindingStudyInfo { SCPStudyId = t.Id, StudyTime = t.StudyTime }).OrderBy(t => t.StudyTime).ToListAsync();
await DealAutoBindingStudyAsync(trialId, subjectId, studyList);
}
await _subjectVisitRepository.SaveChangesAsync();
}
//将检查设置为传输结束
await _studyRepository.BatchUpdateNoTrackingAsync(t => scpStudyIdList.Contains(t.Id), u => new SCPStudy() { IsUploadFinished = true });
return ResponseOutput.Ok();
}
}
}
@@ -0,0 +1,37 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "MinIO",
"MinIO": {
"EndPoint": "47.102.87.183",
"Port": "9000",
"UseSSL": false,
"AccessKeyId": "fbStsVYCIPKHQneeqMwD",
"SecretAccessKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"BucketName": "hir-images",
"ViewEndpoint": "http://47.102.87.18:9001/hir-images/"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=47.102.87.183,1434;Database=HIR_Prod;User ID=sa;Password=xc_123456;TrustServerCertificate=true",
"Hangfire": "Server=47.102.87.183,1434;Database=HIR_Prod_Hangfire;User ID=sa;Password=xc_123456;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"IsUploadImageAnonymization": true,
"IsSupportThirdService": true,
"IsForwardImageMultiThread": true,
"MultiThreadCount": 10,
"CalledAEList": [
"HIRAE",
"STORESCP"
],
"ServerPort": 11115
}
}
@@ -1,37 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
"BucketName": "zy-irc-store",
"ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
}
},
"ConnectionStrings": {
"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"
},
"DicomSCPServiceConfig": {
"CalledAEList": [
"STORESCP"
],
"ServerPort": 11112
}
}
@@ -0,0 +1,35 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "MinIO",
"MinIO": {
"EndPoint": "192.168.40.99",
"Port": "9000",
"UseSSL": false,
"AccessKeyId": "Jnywl9aIw83yewZIJKod",
"SecretAccessKey": "N83bTzoJGkg4OLW8x54IZRwwSvdxcdYi9UZ2BYII",
"BucketName": "tj-hir",
"ViewEndpoint": "http://192.168.40.99:9000/tj-hir"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=192.168.40.98,1433;Database=TJ_Prod_HIR;User ID=sa;Password=xc_123456;TrustServerCertificate=true",
"Hangfire": "Server=192.168.40.98,1433;Database=TJ_Prod_HIR_Hangfire;User ID=sa;Password=xc_123456;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"CalledAEList": [
"STORESCP",
"HIRAE",
"Value2",
"Value3"
],
"ServerPort": 11112
}
}
@@ -0,0 +1,37 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "MinIO",
"MinIO": {
"EndPoint": "106.14.89.110",
"Port": "9001",
"UseSSL": false,
"AccessKeyId": "fbStsVYCIPKHQneeqMwD",
"SecretAccessKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"BucketName": "hir-test",
"ViewEndpoint": "http://106.14.89.110:9001/hir-test/"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_HIR_New;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=106.14.89.110,1435;Database=Test_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"IsUploadImageAnonymization": false,
"IsSupportThirdService": true,
"IsForwardImageMultiThread": true,
"MultiThreadCount": 10,
"CalledAEList": [
"HIRAE",
"STORESCP"
],
"ServerPort": 11115
}
}
@@ -1,48 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
"BucketName": "zy-irc-test-store",
"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"MinIO": {
"endPoint": "106.14.89.110",
"port": "9001",
"useSSL": false,
"accessKey": "fbStsVYCIPKHQneeqMwD",
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"bucketName": "hir-test",
"viewEndpoint": "http://106.14.89.110:9001/hir-test/"
}
},
"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"
},
"DicomSCPServiceConfig": {
"CalledAEList": [
"STORESCP"
],
"ServerPort": 11112
}
}
+37
View File
@@ -0,0 +1,37 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "MinIO",
"MinIO": {
"EndPoint": "3.226.182.187",
"Port": "9001",
"UseSSL": false,
"AccessKeyId": "7rvVIHs7D6pbyscRcJhz",
"SecretAccessKey": "DQsCQldHFL3QRjlnaLWV7oM4E9PtsO21QPC2h9BD",
"BucketName": "hir-us",
"ViewEndpoint": "http://hir-minio.uat.elevateimaging.ai/hir-us"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=3.226.182.187,1435;Database=US_HIR;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=3.226.182.187,1435;Database=US_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"IsUploadImageAnonymization": true,
"IsSupportThirdService": true,
"IsForwardImageMultiThread": true,
"MultiThreadCount": 10,
"CalledAEList": [
"STORESCP",
"HIRAE"
],
"ServerPort": 11115
}
}
-34
View File
@@ -1,34 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "AWS",
"AWS": {
"Region": "us-east-1",
"EndPoint": "s3.us-east-1.amazonaws.com",
"UseSSL": true,
"RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access",
"AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM",
"SecretAccessKey": "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",
"BucketName": "ei-med-s3-lili-store",
"ViewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com",
"DurationSeconds": 7200
}
},
"ConnectionStrings": {
"RemoteNew": "Server=us-prod-mssql-service,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=us-prod-mssql-service,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"CalledAEList": [
"STORESCP"
],
"ServerPort": 11112
}
}
-34
View File
@@ -1,34 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "AWS",
"AWS": {
"Region": "us-east-1",
"EndPoint": "s3.us-east-1.amazonaws.com",
"UseSSL": true,
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
"SecretAccessKey": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
"DurationSeconds": 7200
}
},
"ConnectionStrings": {
"RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"CalledAEList": [
"STORESCP"
],
"ServerPort": 11112
}
}
+37
View File
@@ -0,0 +1,37 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "MinIO",
"MinIO": {
"EndPoint": "101.132.253.119",
"Port": "9001",
"UseSSL": false,
"AccessKeyId": "ylWQa99fDdVdTfnj47ll",
"SecretAccessKey": "kVpy2RIYN0GmyFsU2qAWhbKDf4Nskt23tEqd6sob",
"BucketName": "hir-uat",
"ViewEndpoint": "http://101.132.253.119:9001/hir-uat/"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_HIR_New;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=101.132.253.119,1435;Database=Uat_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"IsUploadImageAnonymization": true,
"IsSupportThirdService": true,
"IsForwardImageMultiThread": true,
"MultiThreadCount": 10,
"CalledAEList": [
"STORESCP",
"HIRAE"
],
"ServerPort": 11115
}
}
-35
View File
@@ -1,35 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
"BucketName": "zy-irc-uat-store",
"ViewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
}
},
"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"
},
"DicomSCPServiceConfig": {
"CalledAEList": [
"STORESCP"
],
"ServerPort": 11112
}
}
+128
View File
@@ -0,0 +1,128 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>%(DocumentTitle)</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="./swagger-ui.css">
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<style>
html {
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 0;
background: #fafafa;
}
</style>
%(HeadContent)
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
<defs>
<symbol viewBox="0 0 20 20" id="unlocked">
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
</symbol>
<symbol viewBox="0 0 20 20" id="locked">
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z" />
</symbol>
<symbol viewBox="0 0 20 20" id="close">
<path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z" />
</symbol>
<symbol viewBox="0 0 20 20" id="large-arrow">
<path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z" />
</symbol>
<symbol viewBox="0 0 20 20" id="large-arrow-down">
<path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z" />
</symbol>
<symbol viewBox="0 0 24 24" id="jump-to">
<path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z" />
</symbol>
<symbol viewBox="0 0 24 24" id="expand">
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" />
</symbol>
</defs>
</svg>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js"></script>
<script src="./swagger-ui-standalone-preset.js"></script>
<script src="/swagger/ui/abp.js"></script>
<script src="/swagger/ui/abp.swagger.js?v=1"></script>
<!--<script src="/lib/jquery/jquery.min.js"></script>-->
<script>
window.onload = function () {
var configObject = JSON.parse('%(ConfigObject)');
// Apply mandatory parameters
configObject.dom_id = "#swagger-ui";
configObject.presets = [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset];
configObject.layout = "StandaloneLayout";
configObject.requestInterceptor = function (request) {
request.headers.Authorization = "Bearer " + abp.auth.getToken();
return request;
};
if (!configObject.hasOwnProperty("oauth2RedirectUrl")) {
configObject.oauth2RedirectUrl = window.location + "oauth2-redirect.html"; // use the built-in default
}
function getAuthorizeButtonText() {
return abp.auth.getToken() ? 'Logout' : 'Authorize';
}
function getAuthorizeButtonCssClass() {
return abp.auth.getToken() ? 'cancel' : 'authorize';
}
configObject.plugins = [
function (system) {
return {
components: {
authorizeBtn: function () {
return system.React.createElement("button",
{
id: "authorize",
className: "btn " + getAuthorizeButtonCssClass(),
style: {
lineHeight: "normal"
},
onClick: function () {
var authorizeButton = document.getElementById('authorize');
if (abp.auth.getToken()) {
abp.swagger.logout();
authorizeButton.innerText = getAuthorizeButtonText();
authorizeButton.className = 'btn ' + getAuthorizeButtonCssClass();
} else {
abp.swagger.openAuthDialog(function () {
authorizeButton.innerText = getAuthorizeButtonText();
authorizeButton.className = 'btn ' + getAuthorizeButtonCssClass();
abp.swagger.closeAuthDialog();
});
}
}
}, getAuthorizeButtonText());
}, info: function () {
return null;
}
}
}
}
];
// Build a system
SwaggerUIBundle(configObject);
}</script>
</body>
</html>
+117
View File
@@ -0,0 +1,117 @@
var abp = abp || {};
(function () {
/* Application paths *****************************************/
// Current application root path (including virtual directory if exists).
abp.appPath = abp.appPath || '/';
/* AUTHORIZATION **********************************************/
// Implements Authorization API that simplifies usage of authorization scripts generated by Abp.
abp.auth = abp.auth || {};
abp.auth.tokenCookieName = 'Abp.AuthToken';
abp.auth.tokenHeaderName = 'Authorization';
abp.auth.setToken = function (authToken, expireDate) {
abp.utils.setCookieValue(abp.auth.tokenCookieName, authToken, expireDate, abp.appPath);
};
abp.auth.getToken = function () {
return abp.utils.getCookieValue(abp.auth.tokenCookieName);
}
abp.auth.clearToken = function () {
abp.auth.setToken();
}
/* UTILS ***************************************************/
abp.utils = abp.utils || {};
/**
* Sets a cookie value for given key.
* This is a simple implementation created to be used by ABP.
* Please use a complete cookie library if you need.
* @param {string} key
* @param {string} value
* @param {Date} expireDate (optional). If not specified the cookie will expire at the end of session.
* @param {string} path (optional)
*/
abp.utils.setCookieValue = function (key, value, expireDate, path) {
var cookieValue = encodeURIComponent(key) + '=';
if (value) {
cookieValue = cookieValue + encodeURIComponent(value);
}
if (expireDate) {
cookieValue = cookieValue + "; expires=" + expireDate.toUTCString();
}
if (path) {
cookieValue = cookieValue + "; path=" + path;
}
document.cookie = cookieValue;
};
/**
* Gets a cookie with given key.
* This is a simple implementation created to be used by ABP.
* Please use a complete cookie library if you need.
* @param {string} key
* @returns {string} Cookie value or null
*/
abp.utils.getCookieValue = function (key) {
var equalities = document.cookie.split('; ');
for (var i = 0; i < equalities.length; i++) {
if (!equalities[i]) {
continue;
}
var splitted = equalities[i].split('=');
if (splitted.length != 2) {
continue;
}
if (decodeURIComponent(splitted[0]) === key) {
return decodeURIComponent(splitted[1] || '');
}
}
return null;
};
/**
* Deletes cookie for given key.
* This is a simple implementation created to be used by ABP.
* Please use a complete cookie library if you need.
* @param {string} key
* @param {string} path (optional)
*/
abp.utils.deleteCookie = function (key, path) {
var cookieValue = encodeURIComponent(key) + '=';
cookieValue = cookieValue + "; expires=" + (new Date(new Date().getTime() - 86400000)).toUTCString();
if (path) {
cookieValue = cookieValue + "; path=" + path;
}
document.cookie = cookieValue;
}
/* SECURITY ***************************************/
abp.security = abp.security || {};
abp.security.antiForgery = abp.security.antiForgery || {};
abp.security.antiForgery.tokenCookieName = 'XSRF-TOKEN';
abp.security.antiForgery.tokenHeaderName = 'X-XSRF-TOKEN';
abp.security.antiForgery.getToken = function () {
return abp.utils.getCookieValue(abp.security.antiForgery.tokenCookieName);
};
})();
@@ -0,0 +1,597 @@
var abp = abp || {};
(function () {
/* md5*/
/*
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
/*
* Configurable variables. You may need to tweak these to be compatible with
* the server-side, but the defaults work in most cases.
*/
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
/*
* These are the functions you'll usually want to call
* They take string arguments and return either hex or base-64 encoded strings
*/
function hex_md5(s) { return binl2hex(core_md5(str2binl(s), s.length * chrsz)); }
function b64_md5(s) { return binl2b64(core_md5(str2binl(s), s.length * chrsz)); }
function str_md5(s) { return binl2str(core_md5(str2binl(s), s.length * chrsz)); }
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
/*
* Perform a simple self-test to see if the VM is working
*/
function md5_vm_test() {
return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}
/*
* Calculate the MD5 of an array of little-endian words, and a bit length
*/
function core_md5(x, len) {
/* append padding */
x[len >> 5] |= 0x80 << ((len) % 32);
x[(((len + 64) >>> 9) << 4) + 14] = len;
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
for (var i = 0; i < x.length; i += 16) {
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
}
return Array(a, b, c, d);
}
/*
* These functions implement the four basic operations the algorithm uses.
*/
function md5_cmn(q, a, b, x, s, t) {
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
}
function md5_ff(a, b, c, d, x, s, t) {
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t) {
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t) {
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t) {
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}
/*
* Calculate the HMAC-MD5, of a key and some data
*/
function core_hmac_md5(key, data) {
var bkey = str2binl(key);
if (bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
var ipad = Array(16), opad = Array(16);
for (var i = 0; i < 16; i++) {
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
return core_md5(opad.concat(hash), 512 + 128);
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function bit_rol(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
}
/*
* Convert a string to an array of little-endian words
* If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
*/
function str2binl(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz)
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32);
return bin;
}
/*
* Convert an array of little-endian words to a string
*/
function binl2str(bin) {
var str = "";
var mask = (1 << chrsz) - 1;
for (var i = 0; i < bin.length * 32; i += chrsz)
str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask);
return str;
}
/*
* Convert an array of little-endian words to a hex string.
*/
function binl2hex(binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +
hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);
}
return str;
}
/*
* Convert an array of little-endian words to a base-64 string
*/
function binl2b64(binarray) {
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var str = "";
for (var i = 0; i < binarray.length * 4; i += 3) {
var triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16)
| (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8)
| ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF);
for (var j = 0; j < 4; j++) {
if (i * 8 + j * 6 > binarray.length * 32) str += b64pad;
else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
}
}
return str;
}
/* Swagger */
abp.swagger = abp.swagger || {};
abp.swagger.addAuthToken = function () {
var authToken = abp.auth.getToken();
if (!authToken) {
return false;
}
var cookieAuth = new SwaggerClient.ApiKeyAuthorization(abp.auth.tokenHeaderName, 'Bearer ' + authToken, 'header');
swaggerUi.api.clientAuthorizations.add('bearerAuth', cookieAuth);
return true;
}
abp.swagger.addCsrfToken = function () {
var csrfToken = abp.security.antiForgery.getToken();
if (!csrfToken) {
return false;
}
var csrfCookieAuth = new SwaggerClient.ApiKeyAuthorization(abp.security.antiForgery.tokenHeaderName, csrfToken, 'header');
swaggerUi.api.clientAuthorizations.add(abp.security.antiForgery.tokenHeaderName, csrfCookieAuth);
return true;
}
function loginUserInternal(tenantId, callback) {
var usernameOrEmailAddress = document.getElementById('userName').value;
// if (!usernameOrEmailAddress) {
// alert('UserName Can Not Be Null');
// return false;
// }
var password = document.getElementById('password').value;
var pwdMd5 = document.getElementById('pwdMd5').value;
console.log(pwdMd5);
if (!password && !pwdMd5) {
alert('PassWord And Md5 Can Not Be Null');
return false;
}
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
// debugger;
if (xhr.status === 200) {
// debugger;
var resultdata = JSON.parse(xhr.responseText);
if (resultdata.ErrorMessage != '') {
alert(resultdata.ErrorMessage);
return false;
}
if (resultdata.code == 300) {
alert(resultdata.message);
}
else {
var responseJSON = JSON.parse(xhr.responseText);
var result = responseJSON;
var expireDate = new Date(Date.now() + (60 * 60 * 24 * 1000));
abp.auth.setToken(result.Result.JWTStr, expireDate);
let selectDom = document.getElementById("roleSelect")
selectDom.options.length = 0;
result.Result.BasicInfo.AccountList.forEach(item => {
selectDom.options.add(new Option(item.UserTypeShortName, item.Id));
})
// callback();
}
} else {
alert('Login failed !');
}
}
};
xhr.open('POST', '/User/getUserLoginRoleList', true);
xhr.setRequestHeader('Abp.TenantId', tenantId);
xhr.setRequestHeader('Content-type', 'application/json');
var parm = {
UserName: usernameOrEmailAddress,
Password: hex_md5(password),
}
if (pwdMd5 != '') {
parm.Password = pwdMd5;
}
xhr.send(JSON.stringify(parm));
//xhr.send("{" + "userName:'" + usernameOrEmailAddress + "'," + "passWord:'" + password + "'}");
};
function loginUserInternalRole(tenantId, callback) {
var usernameOrEmailAddress = document.getElementById('roleSelect').value;
//if (!usernameOrEmailAddress) {
// alert('UserName Can Not Be Null');
// return false;
//}
var password = document.getElementById('password').value;
var pwdMd5 = document.getElementById('pwdMd5').value;
console.log(pwdMd5);
if (!password && !pwdMd5) {
alert('PassWord And Md5 Can Not Be Null');
return false;
}
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
// debugger;
if (xhr.status === 200) {
// debugger;
var resultdata = JSON.parse(xhr.responseText);
if (resultdata.ErrorMessage != '') {
alert(resultdata.ErrorMessage);
return false;
}
if (resultdata.code == 300) {
alert(resultdata.message);
}
else {
var responseJSON = JSON.parse(xhr.responseText);
var result = responseJSON;
var expireDate = new Date(Date.now() + (60 * 60 * 24 * 1000));
abp.auth.setToken(result.Result, expireDate);
callback();
}
} else {
alert('Login failed !');
}
}
};
xhr.open('get', `/User/loginSelectUserRole?userRoleId=${usernameOrEmailAddress}`, true);
xhr.setRequestHeader('Abp.TenantId', tenantId);
xhr.setRequestHeader('Content-type', 'application/json');
var authToken = abp.auth.getToken();
xhr.setRequestHeader('Authorization', `Bearer ${authToken}`);
xhr.send();
//xhr.send("{" + "userName:'" + usernameOrEmailAddress + "'," + "passWord:'" + password + "'}");
};
abp.swagger.login = function (callback) {
//Get TenantId first
var tenancyName = document.getElementById('tenancyName').value;
if (tenancyName) {
var xhrTenancyName = new XMLHttpRequest();
xhrTenancyName.onreadystatechange = function () {
if (xhrTenancyName.readyState === XMLHttpRequest.DONE && xhrTenancyName.status === 200) {
var responseJSON = JSON.parse(xhrTenancyName.responseText);
var result = responseJSON.result;
if (result.state === 1) { // Tenant exists and active.
loginUserInternal(result.tenantId, callback); // Login for tenant
} else {
alert('There is no such tenant or tenant is not active !');
}
}
};
xhrTenancyName.open('POST', '/api/services/app/Account/IsTenantAvailable', true);
xhrTenancyName.setRequestHeader('Content-type', 'application/json');
xhrTenancyName.send("{" + "tenancyName:'" + tenancyName + "'}");
} else {
loginUserInternal(null, callback); // Login for host
}
};
abp.swagger.loginRole = function (callback) {
//Get TenantId first
var tenancyName = document.getElementById('tenancyName').value;
if (tenancyName) {
var xhrTenancyName = new XMLHttpRequest();
xhrTenancyName.onreadystatechange = function () {
if (xhrTenancyName.readyState === XMLHttpRequest.DONE && xhrTenancyName.status === 200) {
var responseJSON = JSON.parse(xhrTenancyName.responseText);
var result = responseJSON.result;
if (result.state === 1) { // Tenant exists and active.
loginUserInternalRole(result.tenantId, callback); // Login for tenant
} else {
alert('There is no such tenant or tenant is not active !');
}
}
};
xhrTenancyName.open('POST', '/api/services/app/Account/IsTenantAvailable', true);
xhrTenancyName.setRequestHeader('Content-type', 'application/json');
xhrTenancyName.send("{" + "tenancyName:'" + tenancyName + "'}");
} else {
loginUserInternalRole(null, callback); // Login for host
}
};
abp.swagger.logout = function () {
abp.auth.clearToken();
}
abp.swagger.closeAuthDialog = function () {
if (document.getElementById('abp-auth-dialog')) {
document.getElementsByClassName("swagger-ui")[1].removeChild(document.getElementById('abp-auth-dialog'));
}
}
abp.swagger.openAuthDialog = function (loginCallback) {
abp.swagger.closeAuthDialog();
var abpAuthDialog = document.createElement('div');
abpAuthDialog.className = 'dialog-ux';
abpAuthDialog.id = 'abp-auth-dialog';
document.getElementsByClassName("swagger-ui")[1].appendChild(abpAuthDialog);
// -- backdrop-ux
var backdropUx = document.createElement('div');
backdropUx.className = 'backdrop-ux';
abpAuthDialog.appendChild(backdropUx);
// -- modal-ux
var modalUx = document.createElement('div');
modalUx.className = 'modal-ux';
abpAuthDialog.appendChild(modalUx);
// -- -- modal-dialog-ux
var modalDialogUx = document.createElement('div');
modalDialogUx.className = 'modal-dialog-ux';
modalUx.appendChild(modalDialogUx);
// -- -- -- modal-ux-inner
var modalUxInner = document.createElement('div');
modalUxInner.className = 'modal-ux-inner';
modalDialogUx.appendChild(modalUxInner);
// -- -- -- -- modal-ux-header
var modalUxHeader = document.createElement('div');
modalUxHeader.className = 'modal-ux-header';
modalUxInner.appendChild(modalUxHeader);
var modalHeader = document.createElement('h3');
modalHeader.innerText = 'Authorize';
modalUxHeader.appendChild(modalHeader);
// -- -- -- -- modal-ux-content
var modalUxContent = document.createElement('div');
modalUxContent.className = 'modal-ux-content';
modalUxInner.appendChild(modalUxContent);
modalUxContent.onkeydown = function (e) {
if (e.keyCode === 13) {
//try to login when user presses enter on authorize modal
abp.swagger.login(loginCallback);
}
};
//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', '');
createSelect(modalUxContent, 'roleSelect', 'role', [])
//Buttons
var authBtnWrapper = document.createElement('div');
authBtnWrapper.className = 'auth-btn-wrapper';
modalUxContent.appendChild(authBtnWrapper);
//Close button
var closeButton = document.createElement('button');
closeButton.className = 'btn modal-btn auth btn-done button';
closeButton.innerText = 'Close';
closeButton.style.marginRight = '5px';
closeButton.onclick = abp.swagger.closeAuthDialog;
authBtnWrapper.appendChild(closeButton);
//Authorize button
var authorizeButton = document.createElement('button');
authorizeButton.className = 'btn modal-btn auth authorize button';
authorizeButton.innerText = 'Login';
authorizeButton.onclick = function () {
abp.swagger.login(loginCallback);
};
authBtnWrapper.appendChild(authorizeButton);
// login role
var authorizeButton = document.createElement('button');
authorizeButton.className = 'btn modal-btn auth authorize button';
authorizeButton.innerText = 'LoginRole';
authorizeButton.onclick = function () {
abp.swagger.loginRole(loginCallback);
};
authBtnWrapper.appendChild(authorizeButton);
}
function createInput(container, id, title, type, value = "") {
var wrapper = document.createElement('div');
wrapper.className = 'wrapper';
if (id == "tenancyName") {
wrapper.style.display = 'none';
}
container.appendChild(wrapper);
var label = document.createElement('label');
label.innerText = title;
wrapper.appendChild(label);
var section = document.createElement('section');
section.className = 'block-tablet col-10-tablet block-desktop col-10-desktop';
wrapper.appendChild(section);
var input = document.createElement('input');
input.id = id;
input.type = type ? type : 'text';
input.style.width = '100%';
input.value = value;
input.autocomplete = "off";
section.appendChild(input);
}
function createSelect(container, id, title, option = []) {
var wrapper = document.createElement('div');
wrapper.className = 'wrapper';
if (id == "tenancyName") {
wrapper.style.display = 'none';
}
container.appendChild(wrapper);
var label = document.createElement('label');
label.innerText = title;
wrapper.appendChild(label);
var section = document.createElement('section');
section.className = 'block-tablet col-10-tablet block-desktop col-10-desktop';
wrapper.appendChild(section);
var input = document.createElement('select');
input.id = id;
input.style.width = '100%';
option.forEach(item => {
input.options.add(new Option(item.UserTypeShortName, item.Id));
})
section.appendChild(input);
}
})();
@@ -25,12 +25,12 @@ namespace EasyCaching.Demo.Interceptors.Controllers
{
ControllerContext.HttpContext.Response.StatusCode = 401;
}
return ResponseOutput.NotOk($"Client error, actual request error status code({code})");
}
else
{
return ResponseOutput.NotOk($"Server error , actual request error status code({code})");
}
+164 -299
View File
@@ -1,43 +1,40 @@
using System;
using System.Net.Http;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Http;
using IRaCIS.Core.Application.Interfaces;
using System.Threading.Tasks;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure;
using System.Linq;
using Microsoft.Extensions.Logging;
using MassTransit;
using Microsoft.AspNetCore.Hosting;
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;
using NetTopologySuite.Algorithm;
using ZiggyCreatures.Caching.Fusion;
using AlibabaCloud.SDK.Sts20150401;
using AlibabaCloud.SDK.Sts20150401.Models;
using Org.BouncyCastle.Tls;
using Amazon.SecurityToken.Model;
using AlibabaCloud.SDK.Sts20150401;
using Amazon.Auth.AccessControlPolicy;
using Amazon.SecurityToken;
using Amazon;
using Azure.Core;
using IdentityModel.Client;
using IdentityModel.OidcClient;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit;
using MassTransit.Futures.Contracts;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using RestSharp;
using RestSharp.Authenticators;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using ZiggyCreatures.Caching.Fusion;
using AssumeRoleRequest = Amazon.SecurityToken.Model.AssumeRoleRequest;
using AutoMapper;
using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO;
namespace IRaCIS.Api.Controllers
{
@@ -45,7 +42,10 @@ namespace IRaCIS.Api.Controllers
/// 医生基本信息 、工作信息 专业信息、审核状态
/// </summary>
[ApiController, ApiExplorerSettings(GroupName = "Reviewer")]
public class ExtraController : ControllerBase
public class ExtraController([FromServices] IAttachmentService attachmentService, [FromServices] IDoctorService _doctorService,
[FromServices] IEducationService _educationService, [FromServices] ITrialExperienceService _trialExperienceService,
[FromServices] IResearchPublicationService _researchPublicationService, [FromServices] IVacationService _vacationService) : ControllerBase
{
@@ -60,34 +60,40 @@ namespace IRaCIS.Api.Controllers
/// <param name="_vacationService"></param>
/// <param name="doctorId"></param>
/// <returns></returns>
[HttpGet, Route("doctor/getDetail/{doctorId:guid}")]
[HttpPost, Route("doctor/getDetail")]
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)
public async Task<IResponseOutput<DoctorDetailDTO>> GetDoctorDetail(GetDoctorDetailInDto inDto)
{
var education = await _educationService.GetEducation(doctorId);
var education = await _educationService.GetEducation(inDto.doctorId);
var sowList = _doctorService.GetDoctorSowList(doctorId);
var ackSowList = _doctorService.GetDoctorAckSowList(doctorId);
var sowList = _doctorService.GetDoctorSowList(inDto.doctorId);
var ackSowList = _doctorService.GetDoctorAckSowList(inDto.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),
AuditView = await _doctorService.GetAuditState(inDto.doctorId),
BasicInfoView = await _doctorService.GetBasicInfo(inDto.doctorId),
EmploymentView = await _doctorService.GetEmploymentInfo(inDto.doctorId),
AttachmentList = await attachmentService.GetAttachments(inDto.doctorId),
SummarizeInfo = await _doctorService.GetSummarizeInfo(new GetSummarizeInfoInDto()
{
DoctorId = inDto.doctorId,
TrialId = inDto.TrialId
}),
PaymentModeInfo = await _doctorService.GetPaymentMode(inDto.doctorId),
EducationList = education.EducationList,
PostgraduateList = education.PostgraduateList,
TrialExperienceView = await _trialExperienceService.GetTrialExperience(doctorId),
ResearchPublicationView = await _researchPublicationService.GetResearchPublication(doctorId),
TrialExperienceView = await _trialExperienceService.GetTrialExperience(new TrialExperienceModelIndto()
{
DoctorId = inDto.doctorId,
TrialId = inDto.TrialId
}),
ResearchPublicationView = await _researchPublicationService.GetResearchPublication(inDto.doctorId),
SpecialtyView = await _doctorService.GetSpecialtyInfo(doctorId),
InHoliday = (await _vacationService.OnVacation(doctorId)).IsSuccess,
IntoGroupInfo = _doctorService.GetDoctorIntoGroupInfo(doctorId),
SpecialtyView = await _doctorService.GetSpecialtyInfo(inDto.doctorId),
InHoliday = (await _vacationService.OnVacation(inDto.doctorId)).IsSuccess,
IntoGroupInfo = _doctorService.GetDoctorIntoGroupInfo(inDto.doctorId),
SowList = sowList,
AckSowList = ackSowList
};
@@ -96,201 +102,6 @@ namespace IRaCIS.Api.Controllers
}
/// <summary> 系统用户登录接口[New] </summary>
[HttpPost, Route("user/login")]
[AllowAnonymous]
public async Task<IResponseOutput> Login(UserLoginDTO loginUser,
[FromServices] IFusionCache _fusionCache,
[FromServices] IUserService _userService,
[FromServices] ITokenService _tokenService,
[FromServices] IReadingImageTaskService readingImageTaskService,
[FromServices] IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig,
[FromServices] IOptionsMonitor<SystemEmailSendConfig> _emailConfig,
[FromServices] IMailVerificationService _mailVerificationService)
{
var emailConfig = _emailConfig.CurrentValue;
var companyInfo = new SystemEmailSendConfigView() { CompanyName = emailConfig.CompanyName, CompanyNameCN = emailConfig.CompanyNameCN, CompanyShortName = emailConfig.CompanyShortName, CompanyShortNameCN = emailConfig.CompanyShortNameCN };
//MFA 邮箱验证 前端传递用户Id 和MFACode
if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA)
{
Guid userId = (Guid)loginUser.UserId;
//验证MFA 编码是否有问题 ,前端要拆开,自己调用验证的逻辑
//await _userService.VerifyMFACodeAsync(userId, loginUser.MFACode);
//var loginUser = await _userRepository.Where(u => u.UserName.Equals(userName) && u.Password == password).ProjectTo<UserBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
var basicInfo = await _userService.GetUserBasicInfo(userId, loginUser.Password);
var loginReturn = new LoginReturnDTO() { BasicInfo = basicInfo };
loginReturn.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(loginReturn.BasicInfo));
// 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
var option = new CookieOptions
{
Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
HttpOnly = false, // 确保 cookie 只能通过 HTTP 访问
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None, // 设置 SameSite 属性
Secure = false // 确保 cookie 只能通过 HTTPS 访问
};
HttpContext.Response.Cookies.Append("access_token", loginReturn.JWTStr, option);
// 验证阅片休息时间
await readingImageTaskService.ResetReadingRestTime(userId);
await _fusionCache.SetAsync(CacheKeys.UserToken(userId), loginReturn.JWTStr, TimeSpan.FromDays(7));
await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(userId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
loginReturn.CompanyInfo = companyInfo;
return ResponseOutput.Ok(loginReturn);
}
else
{
var returnModel = await _userService.Login(loginUser.UserName, loginUser.Password);
if (returnModel.IsSuccess)
{
#region GRPC IIS问题 http/2 使
////重试策略
//var defaultMethodConfig = new MethodConfig
//{
// Names = { MethodName.Default },
// RetryPolicy = new RetryPolicy
// {
// MaxAttempts = 3,
// InitialBackoff = TimeSpan.FromSeconds(1),
// MaxBackoff = TimeSpan.FromSeconds(5),
// BackoffMultiplier = 1.5,
// RetryableStatusCodes = { Grpc.Core.StatusCode.Unavailable }
// }
//};
//#region unable to trust the certificate then the gRPC client can be configured to ignore the invalid certificate
//var httpHandler = new HttpClientHandler();
//// Return `true` to allow certificates that are untrusted/invalid
//httpHandler.ServerCertificateCustomValidationCallback =
// HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
//////这一句是让grpc支持本地 http 如果本地访问部署在服务器上,那么是访问不成功的
//AppContext.SetSwitch(
// "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
//#endregion
//var grpcAdress = configuration.GetValue<string>("GrpcAddress");
////var grpcAdress = "http://localhost:7200";
//var channel = GrpcChannel.ForAddress(grpcAdress, new GrpcChannelOptions
//{
// HttpHandler = httpHandler,
// ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }
//});
////var channel = GrpcChannel.ForAddress(grpcAdress);
//var grpcClient = new TokenGrpcService.TokenGrpcServiceClient(channel);
//var userInfo = returnModel.Data.BasicInfo;
//var tokenResponse = grpcClient.GetUserToken(new GetTokenReuqest()
//{
// Id = userInfo.Id.ToString(),
// ReviewerCode = userInfo.ReviewerCode,
// IsAdmin = userInfo.IsAdmin,
// RealName = userInfo.RealName,
// UserTypeEnumInt = (int)userInfo.UserTypeEnum,
// UserTypeShortName = userInfo.UserTypeShortName,
// UserName = userInfo.UserName
//});
//returnModel.Data.JWTStr = tokenResponse.Token;
#endregion
var userId = returnModel.Data.BasicInfo.Id;
if (_verifyConfig.CurrentValue.OpenLoginMFA)
{
//MFA 发送邮件
returnModel.Data.IsMFA = true;
var email = returnModel.Data.BasicInfo.EMail;
var hiddenEmail = IRCEmailPasswordHelper.MaskEmail(email);
returnModel.Data.BasicInfo.EMail = hiddenEmail;
//修改密码
if (returnModel.Data.BasicInfo.IsFirstAdd || returnModel.Data.BasicInfo.LoginState == 1)
{
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
}
else
{
//正常登录才发送邮件
await _userService.SendMFAEmail(userId);
}
}
else
{
returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));
// 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
var option = new CookieOptions
{
Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
HttpOnly = false, // 确保 cookie 只能通过 HTTP 访问
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None, // 设置 SameSite 属性
Secure = false // 确保 cookie 只能通过 HTTPS 访问
};
HttpContext.Response.Cookies.Append("access_token", returnModel.Data.JWTStr, option);
// 验证阅片休息时间
await readingImageTaskService.ResetReadingRestTime(returnModel.Data.BasicInfo.Id);
await _fusionCache.SetAsync(CacheKeys.UserToken(userId), returnModel.Data.JWTStr, TimeSpan.FromDays(7));
await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(userId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
}
}
returnModel.Data.CompanyInfo = companyInfo;
return returnModel;
}
}
[AllowAnonymous]
[HttpGet, Route("user/getPublicKey")]
public IResponseOutput GetPublicKey([FromServices] IOptionsMonitor<IRCEncreptOption> _IRCEncreptOption)
@@ -305,22 +116,18 @@ namespace IRaCIS.Api.Controllers
[AllowAnonymous]
public IResponseOutput ShareImage([FromServices] ITokenService _tokenService)
{
var token = _tokenService.GetToken(IRaCISClaims.Create(new UserBasicInfo()
var token = _tokenService.GetToken(new UserTokenInfo()
{
Id = Guid.Empty,
IsReviewer = false,
IsAdmin = false,
RealName = "Share001",
IdentityUserId = Guid.NewGuid(),
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/GetObjectStoreToken")]
[AllowAnonymous]
public async Task<IResponseOutput> GetObjectStoreTokenAsync([FromServices] IOptionsMonitor<ObjectStoreServiceOptions> options, [FromServices] IOSSService _oSSService)
{
@@ -370,55 +177,58 @@ namespace IRaCIS.Api.Controllers
return tempToken;
}
#region
#region aliyun-net-sdk-sts
//[HttpGet("user/GenerateSTS")]
//public IResponseOutput GenerateSTS([FromServices] IOptionsMonitor<AliyunOSSOptions> options)
//{
// var ossOptions = options.CurrentValue;
[HttpGet("user/GenerateSTS")]
public IResponseOutput GenerateSTS([FromServices] IOptionsMonitor<ObjectStoreServiceOptions> options)
{
var ossOptions = options.CurrentValue.AliyunOSS;
var client = new Client(new AlibabaCloud.OpenApiClient.Models.Config()
{
AccessKeyId = ossOptions.AccessKeyId,
AccessKeySecret = ossOptions.AccessKeySecret,
Endpoint = "sts.cn-hangzhou.aliyuncs.com"
});
var assumeRoleRequest = new AlibabaCloud.SDK.Sts20150401.Models.AssumeRoleRequest();
// 将<YOUR_ROLE_SESSION_NAME>设置为自定义的会话名称,例如oss-role-session。
assumeRoleRequest.RoleSessionName = $"session-name-{NewId.NextGuid()}";
// 将<YOUR_ROLE_ARN>替换为拥有上传文件到指定OSS Bucket权限的RAM角色的ARN。
assumeRoleRequest.RoleArn = ossOptions.RoleArn;
//assumeRoleRequest.RoleArn = "acs:ram::1899121822495495:role/webdirect";
assumeRoleRequest.DurationSeconds = ossOptions.DurationSeconds;
var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
var response = client.AssumeRoleWithOptions(assumeRoleRequest, runtime);
var credentials = response.Body.Credentials;
// IClientProfile profile = DefaultProfile.GetProfile(ossOptions.regionId, ossOptions.accessKeyId, ossOptions.accessKeySecret);
// DefaultAcsClient client = new DefaultAcsClient(profile);
// 返回STS令牌信息给前端
var stsToken = new
{
AccessKeyId = credentials.AccessKeyId,
AccessKeySecret = credentials.AccessKeySecret,
SecurityToken = credentials.SecurityToken,
Expiration = credentials.Expiration,
// // 创建一个STS请求
// AssumeRoleRequest request = new AssumeRoleRequest
// {
// RoleArn = ossOptions.roleArn, // 角色ARN,需要替换为你的角色ARN
// RoleSessionName = $"session-name-{NewId.NextGuid()}", // 角色会话名称,可自定义
// DurationSeconds = 900, // 令牌有效期(单位:秒),这里设置为1小时
// };
Region = ossOptions.Region,
BucketName = ossOptions.BucketName,
ViewEndpoint = ossOptions.ViewEndpoint,
};
// AssumeRoleResponse response = client.GetAcsResponse(request);
return ResponseOutput.Ok(stsToken);
// // 返回STS令牌信息给前端
// var stsToken = new
// {
// AccessKeyId = response.Credentials.AccessKeyId,
// AccessKeySecret = response.Credentials.AccessKeySecret,
// SecurityToken = response.Credentials.SecurityToken,
// Expiration = response.Credentials.Expiration,
}
// Region = ossOptions.region,
// BucketName = ossOptions.bucketName,
// ViewEndpoint = ossOptions.viewEndpoint,
// };
// return ResponseOutput.Ok(stsToken);
//}
#endregion
[HttpGet("User/UserRedirect")]
[AllowAnonymous]
public async Task<IActionResult> UserRedirect([FromServices] IRepository<User> _userRepository, string url, [FromServices] ILogger<ExtraController> _logger)
public async Task<IActionResult> UserRedirect([FromServices] IRepository<IdentityUser> _useRepository, string url, [FromServices] ILogger<ExtraController> _logger, [FromServices] ITokenService _tokenService)
{
var decodeUrl = System.Web.HttpUtility.UrlDecode(url);
@@ -433,10 +243,22 @@ namespace IRaCIS.Api.Controllers
var errorUrl = domainStrList[0] + "//" + domainStrList[2] + "/error";
if (!await _userRepository.AnyAsync(t => t.Id == Guid.Parse(userId) && t.EmailToken == token && t.IsFirstAdd))
if (lang == "zh")
{
decodeUrl = errorUrl + $"?lang={lang}&ErrorMessage={System.Web.HttpUtility.UrlEncode(lang == "zh" ? "" : "ErrorThe initialization link has expired. Return")} ";
CultureInfo.CurrentCulture = new CultureInfo(StaticData.CultureInfo.zh_CN);
CultureInfo.CurrentUICulture = new CultureInfo(StaticData.CultureInfo.zh_CN);
}
else
{
CultureInfo.CurrentCulture = new CultureInfo(StaticData.CultureInfo.en_US);
CultureInfo.CurrentUICulture = new CultureInfo(StaticData.CultureInfo.en_US);
}
var isExpire = _tokenService.IsTokenExpired(token);
if (!await _useRepository.AnyAsync(t => t.Id == Guid.Parse(userId) && t.EmailToken == token && t.IsFirstAdd) || isExpire)
{
decodeUrl = errorUrl + $"?lang={lang}&ErrorMessage={System.Web.HttpUtility.UrlEncode(I18n.T("UserRedirect_InitializationLinkExpire"))} ";
}
return Redirect(decodeUrl);
@@ -445,7 +267,47 @@ namespace IRaCIS.Api.Controllers
#region Oauth
/// <summary>
/// 回调到前端,前端调用后端的接口
/// 参考链接:https://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html
/// 后端通过这个code ,带上客户端信息,和授权类型 可以向单点登录提供商,获取厂商token
///
/// 但是单点登录提供商提供的token 和我们系统的token 是有区别的,我们的token里面有我们业务系统的UserId,涉及到很多业务操作,所以在此出现了两种方案
/// 1、前端使用厂商的Token。 后端通过code 获取厂商的Token 返回前端的同时返回我们系统的UserId,前段在http 请求头加上一个自定义参数,带上UserId 后端取用户Id的地方变动下,
/// 但是除了UserId外,后端还有其他信息也是从Token取的,所以在请求头也需要带上,此外后端认证Token的方式也需要变化,改造成本稍大(如果是微服务,做这种处理还是可以的)。
/// 2、前端还是使用我们后台自己的Token。后端通过code 获取厂商Token的同时,后端做一个隐藏登录,返回厂商的Token的同时,也返回我们系统的Token。
/// (像我们单体,这种方式最简单,我们用单点登录,无非就是不想记多个系统的密码,自动登录而已,其他不支持的项目改造成本也是最低的)
/// </summary>
/// <param name="type">回调的厂商类型 比如github, google, 我们用的logto ,不同的厂商回调到前端的地址可以不同的,但是请求后端的接口可以是同一个 </param>
/// <param name="code">在第三方平台登录成功后,回调前端的时候会返回一个code </param>
/// <returns></returns>
[HttpGet("User/OAuthCallBack")]
public async Task<IResponseOutput> OAuthCallBack(string type, string code)
{
#region AccessTo
//var headerDic = new Dictionary<string, string>();
//headerDic.Add("code", code);
//headerDic.Add("grant_type", "authorization_code");
//headerDic.Add("redirect_uri", "http://localhost:6100");
//headerDic.Add("scope", "all");
#endregion
return ResponseOutput.Ok();
}
#endregion
#region ip
[HttpGet, Route("ip")]
[AllowAnonymous]
public IResponseOutput Get([FromServices] IHttpContextAccessor _context)
@@ -486,6 +348,9 @@ namespace IRaCIS.Api.Controllers
}
return ResponseOutput.Ok(sb.ToString());
}
#endregion
}
}
@@ -1,18 +1,18 @@
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.BusinessFilter;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.Service.Inspection.DTO;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace IRaCIS.Core.API.Controllers.Special
{
@@ -24,7 +24,7 @@ namespace IRaCIS.Core.API.Controllers.Special
ICalculateService _calculateService,
IStringLocalizer _localizer) : ControllerBase
{
//[TrialAudit(AuditType.TrialAudit, AuditOptType.AddOrUpdateTrial)]
@@ -36,8 +36,8 @@ namespace IRaCIS.Core.API.Controllers.Special
public async Task<IResponseOutput> AddOrUpdateTrialInspection(DataInspectionDto<TrialCommand> opt)
{
var fun =await AddOrUpdateTrial(opt.Data);
var fun = await AddOrUpdateTrial(opt.Data);
return fun;
}
@@ -48,8 +48,8 @@ namespace IRaCIS.Core.API.Controllers.Special
[HttpPost, Route("trial/addOrUpdateTrial")]
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AddOrUpdateTrial", "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })]
public async Task<IResponseOutput<Trial>> AddOrUpdateTrial(TrialCommand param)
[TrialGlobalLimit( "AddOrUpdateTrial", "BeforeOngoingCantOpt", "AfterStopCannNotOpt" )]
public async Task<IResponseOutput<Trial>> AddOrUpdateTrial(TrialCommand param)
{
var userId = Guid.Parse(User.FindFirst("id").Value);
var result = await _trialService.AddOrUpdateTrial(param);
@@ -86,9 +86,9 @@ namespace IRaCIS.Core.API.Controllers.Special
/// <param name="_trialWorkloadService"></param>
/// <param name="workLoadAddOrUpdateModel"></param>
/// <returns></returns>
[HttpPost, Route("doctorWorkload/workLoadAddOrUpdate")]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
public async Task<IResponseOutput> WorkLoadAddOrUpdate([FromServices] IDoctorWorkloadService _trialWorkloadService, WorkloadCommand workLoadAddOrUpdateModel)
{
var userId = Guid.Parse(User.FindFirst("id").Value);
@@ -108,9 +108,9 @@ namespace IRaCIS.Core.API.Controllers.Special
}
[HttpDelete, Route("doctorWorkload/deleteWorkLoad/{id:guid}/{trialId:guid}")]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
public async Task<IResponseOutput> DeleteWorkLoad([FromServices] IDoctorWorkloadService _trialWorkloadService, Guid id)
{
//先判断该工作量的费用是否被锁定,如果被锁定,则不能删除
@@ -143,7 +143,7 @@ namespace IRaCIS.Core.API.Controllers.Special
/// <summary>
/// 添加或更新汇率(会触发没有对锁定的费用计算)
/// </summary>
[HttpPost, Route("exchangeRate/addOrUpdateExchangeRate")]
public async Task<IResponseOutput> AddOrUpdateExchangeRate([FromServices] IExchangeRateService _exchangeRateService, [FromServices] IPaymentAdjustmentService _costAdjustmentService, ExchangeRateCommand addOrUpdateModel)
{
@@ -153,7 +153,7 @@ namespace IRaCIS.Core.API.Controllers.Special
{
if (item != null)
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
@@ -163,7 +163,7 @@ namespace IRaCIS.Core.API.Controllers.Special
}, User.FindFirst("id").Value);
}
}
await _costAdjustmentService.CalculateCNY(addOrUpdateModel.YearMonth, addOrUpdateModel.Rate);
await _costAdjustmentService.CalculateCNY(addOrUpdateModel.YearMonth, addOrUpdateModel.Rate);
return result;
}
@@ -171,13 +171,13 @@ namespace IRaCIS.Core.API.Controllers.Special
/// <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 needCalReviewerIds = await _reviewerPayInfoService.GetReviewerIdByRankId(Guid.Parse(addOrUpdateModel.Id.ToString()));
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty);
foreach (var item in calcList)
@@ -204,12 +204,12 @@ namespace IRaCIS.Core.API.Controllers.Special
/// <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 result = await _doctorPayInfoService.AddOrUpdateReviewerPayInfo(addOrUpdateModel, userId);
var calcList = await _calculateService.GetNeedCalculateReviewerList(addOrUpdateModel.DoctorId, string.Empty);
foreach (var item in calcList)
{
@@ -233,12 +233,12 @@ namespace IRaCIS.Core.API.Controllers.Special
/// <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 result = await _trialPaymentPriceService.AddOrUpdateTrialPaymentPrice(addOrUpdateModel);
var needCalReviewerIds = await _trialService.GetTrialEnrollmentReviewerIds(addOrUpdateModel.TrialId);
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty);
@@ -246,7 +246,7 @@ namespace IRaCIS.Core.API.Controllers.Special
{
if (item != null && needCalReviewerIds.Contains(item.DoctorId))
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
@@ -262,12 +262,12 @@ namespace IRaCIS.Core.API.Controllers.Special
/// <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 result = await _volumeRewardService.AddOrUpdateVolumeRewardPriceList(addOrUpdateModel);
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty);
foreach (var item in calcList)
@@ -1,24 +1,19 @@
using System.Threading.Tasks;
using AutoMapper;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.BusinessFilter;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Image.QA;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.Service.Inspection.DTO;
using IRaCIS.Core.Application.Service.Inspection.Interface;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.Service.Reading.Interface;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
namespace IRaCIS.Core.API.Controllers
@@ -27,7 +22,6 @@ namespace IRaCIS.Core.API.Controllers
[ApiController, ApiExplorerSettings(GroupName = "Reviewer")]
[UnitOfWork]
public class InspectionController(
ITrialDocumentService _trialDocumentService,
IReadingImageTaskService _iReadingImageTaskService,
ITrialConfigService _trialConfigService,
IClinicalAnswerService _clinicalAnswerService,
@@ -38,7 +32,7 @@ namespace IRaCIS.Core.API.Controllers
IReadingMedicineQuestionService _readingMedicineQuestionService
) : ControllerBase
{
#region
/// <summary>
/// 获取稽查数据
@@ -57,7 +51,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingImageTask/SubmitOncologyReadingInfo")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> SetOncologyReadingInfo(DataInspectionDto<SubmitOncologyReadingInfoInDto> opt)
@@ -74,7 +68,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingImageTask/SubmitDicomVisitTask")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> SubmitDicomVisitTask(DataInspectionDto<SubmitDicomVisitTaskInDto> opt)
@@ -93,7 +87,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingImageTask/SubmitGlobalReadingInfo")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> SubmitGlobalReadingInfo(DataInspectionDto<SubmitGlobalReadingInfoInDto> opt)
@@ -112,12 +106,12 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/configTrialBasicInfo/TrialReadingInfoSign")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> TrialReadingInfoSign(DataInspectionDto<TrialReadingInfoSignInDto> opt)
{
var singid = await _inspectionService.RecordSing(opt.SignInfo);
var result = await _trialConfigService.TrialReadingInfoSign(opt.Data);
await _inspectionService.CompletedSign(singid, result);
@@ -131,7 +125,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingMedicalReview/FinishMedicalReview")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> FinishMedicalReview(DataInspectionDto<FinishMedicalReviewInDto> opt)
@@ -148,7 +142,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingMedicineQuestion/ConfirmReadingMedicineQuestion")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> ConfirmReadingMedicineQuestion(DataInspectionDto<ConfirmReadingMedicineQuestionInDto> opt)
@@ -166,7 +160,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingImageTask/SubmitVisitTaskQuestions")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> SubmitVisitTaskQuestions(DataInspectionDto<SubmitVisitTaskQuestionsInDto> opt)
@@ -184,7 +178,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ClinicalAnswer/CRCSignClinicalData")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> CRCSignClinicalData(DataInspectionDto<CRCSignClinicalDataInDto> opt)
@@ -202,7 +196,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ClinicalAnswer/CRCConfirmClinical")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> CRCConfirmClinical(DataInspectionDto<CRCConfirmClinicalInDto> opt)
@@ -219,7 +213,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ClinicalAnswer/CRCCancelConfirmClinical")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> CRCCancelConfirmClinical(DataInspectionDto<CRCCancelConfirmClinicalInDto> opt)
@@ -237,7 +231,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ClinicalAnswer/PMConfirmClinical")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> PMConfirmClinical(DataInspectionDto<CRCConfirmClinicalInDto> opt)
@@ -255,7 +249,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingClinicalData/SignConsistencyAnalysisReadingClinicalData")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> SignConsistencyAnalysisReadingClinicalData(DataInspectionDto<SignConsistencyAnalysisReadingClinicalDataInDto> opt)
@@ -272,7 +266,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ClinicalAnswer/SubmitClinicalFormAndSign")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> SubmitClinicalFormAndSign(DataInspectionDto<SubmitClinicalFormInDto> opt)
@@ -289,7 +283,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingImageTask/SubmitJudgeVisitTaskResult")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> SubmitJudgeVisitTaskResult(DataInspectionDto<SaveJudgeVisitTaskResult> opt)
@@ -308,12 +302,12 @@ namespace IRaCIS.Core.API.Controllers
/// <returns></returns>
[HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialBasicInfoConfirm")]
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt" })]
[TrialGlobalLimit( "BeforeOngoingCantOpt" )]
public async Task<IResponseOutput> ConfigTrialBasicInfoConfirm(DataInspectionDto<BasicTrialConfig> opt)
{
opt.Data.IsTrialBasicLogicConfirmed = true;
var singid= await _inspectionService.RecordSing(opt.SignInfo);
var singid = await _inspectionService.RecordSing(opt.SignInfo);
var result = await _trialConfigService.ConfigTrialBasicInfo(opt.Data);
await _inspectionService.CompletedSign(singid, result);
return result;
@@ -328,7 +322,7 @@ namespace IRaCIS.Core.API.Controllers
/// <returns></returns>
[HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialProcessInfoConfirm")]
[UnitOfWork]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt" })]
//[TrialGlobalLimit( "BeforeOngoingCantOpt" )]
public async Task<IResponseOutput> ConfigTrialProcessInfoConfirm(DataInspectionDto<TrialProcessConfig> opt)
{
opt.Data.IsTrialProcessConfirmed = true;
@@ -340,7 +334,7 @@ namespace IRaCIS.Core.API.Controllers
}
/// <summary>
@@ -350,12 +344,12 @@ namespace IRaCIS.Core.API.Controllers
/// <returns></returns>
[HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialUrgentInfoConfirm")]
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt" })]
[TrialGlobalLimit( "BeforeOngoingCantOpt" )]
public async Task<IResponseOutput> ConfigTrialUrgentInfoConfirm(DataInspectionDto<TrialUrgentConfig> opt)
{
opt.Data.IsTrialUrgentConfirmed = true;
var singid = await _inspectionService.RecordSing(opt.SignInfo);
var result= await _trialConfigService.ConfigTrialUrgentInfo(opt.Data);
var result = await _trialConfigService.ConfigTrialUrgentInfo(opt.Data);
await _inspectionService.CompletedSign(singid, result);
return result;
}
@@ -363,7 +357,7 @@ namespace IRaCIS.Core.API.Controllers
[HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialPACSInfoConfirm")]
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt" })]
[TrialGlobalLimit( "BeforeOngoingCantOpt" )]
public async Task<IResponseOutput> ConfigTrialPACSInfoConfirm(DataInspectionDto<TrialPACSConfig> opt)
{
opt.Data.IsTrialPACSConfirmed = true;
@@ -379,7 +373,7 @@ namespace IRaCIS.Core.API.Controllers
/// <returns></returns>
[HttpPost, Route("Inspection/configTrialBasicInfo/TrialConfigSignatureConfirm")]
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
public async Task<IResponseOutput> TrialConfigSignatureConfirm(DataInspectionDto<SignConfirmDTO> opt)
{
@@ -390,31 +384,31 @@ namespace IRaCIS.Core.API.Controllers
}
/// <summary>
/// 重置并同步项目阅片标准
/// </summary>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingCriterion/ResetAndAsyncCriterion")]
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
/// <summary>
/// 重置并同步项目阅片标准
/// </summary>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadingCriterion/ResetAndAsyncCriterion")]
[UnitOfWork]
[TrialGlobalLimit( "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;
}
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")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
/// <summary>
/// CRC RequestToQC 批量提交
/// </summary>
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/QCOperation/CRCRequestToQC")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> CRCRequestToQC(DataInspectionDto<CRCRequestToQCCommand> opt)
{
@@ -429,12 +423,12 @@ namespace IRaCIS.Core.API.Controllers
/// 设置QC 通过或者不通过 7:QC failed 8QC passed
/// </summary>
[HttpPost, Route("Inspection/QCOperation/QCPassedOrFailed")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> QCPassedOrFailed(DataInspectionDto<QCPassedOrFailedDto> opt)
{
var singid = await _inspectionService.RecordSing(opt.SignInfo);
var result= await _qCOperationService.QCPassedOrFailed(opt.Data.trialId, opt.Data.subjectVisitId, opt.Data.auditState);
var result = await _qCOperationService.QCPassedOrFailed(opt.Data.trialId, opt.Data.subjectVisitId, opt.Data.auditState);
await _inspectionService.CompletedSign(singid, result);
return result;
}
@@ -443,12 +437,12 @@ namespace IRaCIS.Core.API.Controllers
/// 一致性核查 回退 对话记录不清除 只允许PM回退
/// </summary>
[HttpPost, Route("Inspection/QCOperation/CheckBack")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> CheckBack(DataInspectionDto<IDDto> opt)
{
var singid = await _inspectionService.RecordSing(opt.SignInfo);
var result = await _qCOperationService.CheckBack(opt.Data.Id);
var result = await _qCOperationService.CheckBack(opt.Data.Id);
await _inspectionService.CompletedSign(singid, result);
return result;
}
@@ -460,7 +454,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/ReadClinicalData/ReadClinicalDataSign")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> ReadClinicalDataSign(DataInspectionDto<ReadingClinicalDataSignIndto> opt)
{
@@ -475,9 +469,9 @@ namespace IRaCIS.Core.API.Controllers
/// CRC 设置已经重传完成
/// </summary>
[HttpPost, Route("Inspection/QCOperation/SetReuploadFinished")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> SetReuploadFinished(DataInspectionDto<CRCReuploadFinishedCommand> opt)
public async Task<IResponseOutput> SetReuploadFinished(DataInspectionDto<CRCReuploadFinishedCommand> opt)
{
var singid = await _inspectionService.RecordSing(opt.SignInfo);
var result = await _qCOperationService.SetReuploadFinished(opt.Data);
@@ -491,8 +485,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param>
/// <returns></returns>
[HttpPost, Route("Inspection/TrialConfig/updateTrialState")]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt" })]
[TrialGlobalLimit( "BeforeOngoingCantOpt")]
[UnitOfWork]
public async Task<IResponseOutput> UpdateTrialState(DataInspectionDto<UpdateTrialStateDto> opt)
{
@@ -503,21 +496,7 @@ namespace IRaCIS.Core.API.Controllers
}
/// <summary>
/// 用户 签名某个文档
/// </summary>
/// <returns></returns>
[HttpPost, Route("Inspection/TrialDocument/userConfirm")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "SignSystemDocNoTrialId", "AfterStopCannNotOpt" })]
[UnitOfWork]
public async Task<IResponseOutput> UserConfirm(DataInspectionDto<UserConfirmCommand> opt)
{
var singid = await _inspectionService.RecordSing(opt.SignInfo);
opt.Data.SignText = opt.SignInfo.SignText;
var result = await _trialDocumentService.UserConfirm(opt.Data);
await _inspectionService.CompletedSign(singid, result);
return result;
}
/// <summary>
@@ -525,16 +504,16 @@ namespace IRaCIS.Core.API.Controllers
/// </summary>
/// <returns></returns>
[HttpPost, Route("Inspection/VisitTask/ConfirmReReading")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[UnitOfWork]
public async Task<IResponseOutput> ConfirmReReading(DataInspectionDto<ConfirmReReadingCommand> opt , [FromServices] IVisitTaskHelpeService _visitTaskCommonService,[FromServices] IVisitTaskService _visitTaskService)
public async Task<IResponseOutput> ConfirmReReading(DataInspectionDto<ConfirmReReadingCommand> opt, [FromServices] IVisitTaskHelpeService _visitTaskCommonService, [FromServices] IVisitTaskService _visitTaskService)
{
var singId = await _inspectionService.RecordSing(opt.SignInfo);
var result = await _visitTaskService.ConfirmReReading(opt.Data, _visitTaskCommonService);
await _inspectionService.CompletedSign(singId, result);
return result;
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,363 @@
using AutoMapper.Execution;
using DocumentFormat.OpenXml.Bibliography;
using FellowOakDicom;
using FellowOakDicom.Network;
using FellowOakDicom.Network.Client;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Org.BouncyCastle.Bcpg;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
namespace IRaCIS.Core.API.HostService
{
public class DicomSCPService : DicomService, IDicomServiceProvider, IDicomCFindProvider, IDicomCEchoProvider, IDicomCMoveProvider
{
private static readonly DicomTransferSyntax[] _acceptedTransferSyntaxes = new DicomTransferSyntax[]
{
DicomTransferSyntax.ExplicitVRLittleEndian,
DicomTransferSyntax.ExplicitVRBigEndian,
DicomTransferSyntax.ImplicitVRLittleEndian
};
private static readonly DicomTransferSyntax[] _acceptedImageTransferSyntaxes = new DicomTransferSyntax[]
{
// Lossless
DicomTransferSyntax.JPEGLSLossless,
DicomTransferSyntax.JPEG2000Lossless,
DicomTransferSyntax.JPEGProcess14SV1,
DicomTransferSyntax.JPEGProcess14,
DicomTransferSyntax.RLELossless,
// Lossy
DicomTransferSyntax.JPEGLSNearLossless,
DicomTransferSyntax.JPEG2000Lossy,
DicomTransferSyntax.JPEGProcess1,
DicomTransferSyntax.JPEGProcess2_4,
// Uncompressed
DicomTransferSyntax.ExplicitVRLittleEndian,
DicomTransferSyntax.ExplicitVRBigEndian,
DicomTransferSyntax.ImplicitVRLittleEndian
};
private IServiceProvider _serviceProvider { get; set; }
private DicomSCPServiceOption DicomSCPServiceConfig { get; set; }
public string CallingAE { get; protected set; }
public string CalledAE { get; protected set; }
public DicomSCPService(INetworkStream stream, Encoding fallbackEncoding, Microsoft.Extensions.Logging.ILogger log, DicomServiceDependencies dependencies, IServiceProvider injectServiceProvider)
: base(stream, fallbackEncoding, log, dependencies)
{
_serviceProvider = injectServiceProvider.CreateScope().ServiceProvider;
}
public void OnConnectionClosed(Exception exception)
{
if (exception != null)
{
Logger.LogError($"Closed, exception is {exception.Message}");
}
}
public void OnReceiveAbort(DicomAbortSource source, DicomAbortReason reason)
{
Logger.LogError($"Received abort from {source}, reason is {reason}");
}
public Task OnReceiveAssociationReleaseRequestAsync()
{
return SendAssociationReleaseResponseAsync();
}
public Task OnReceiveAssociationRequestAsync(DicomAssociation association)
{
CallingAE = association.CallingAE;
CalledAE = association.CalledAE;
Logger.LogInformation($"Received association request from AE: {CallingAE} with IP: {association.RemoteHost} ");
DicomSCPServiceConfig = _serviceProvider.GetService<IOptionsMonitor<DicomSCPServiceOption>>().CurrentValue;
var calledAEList = DicomSCPServiceConfig.CalledAEList;
//不支持三方服务 或者CallAE不对,那么拒绝连接
if (!calledAEList.Contains(CalledAE) || DicomSCPServiceConfig.IsSupportThirdService == false || CallingAE != DicomSCPServiceConfig.ThirdCallningAE)
{
Logger.LogError($"Association with {CallingAE} rejected since called aet {CalledAE} is unknown");
return SendAssociationRejectAsync(DicomRejectResult.Permanent, DicomRejectSource.ServiceUser, DicomRejectReason.CalledAENotRecognized);
}
foreach (var pc in association.PresentationContexts)
{
if (pc.AbstractSyntax == DicomUID.Verification
|| pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelFind
|| pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelMove
|| pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelFind
|| pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelMove)
{
pc.AcceptTransferSyntaxes(_acceptedTransferSyntaxes);
}
else if (pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelGet
|| pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelGet)
{
pc.AcceptTransferSyntaxes(_acceptedImageTransferSyntaxes);
}
else if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None)
{
pc.AcceptTransferSyntaxes(_acceptedImageTransferSyntaxes);
}
else
{
Logger.LogWarning($"Requested abstract syntax {pc.AbstractSyntax} from {CallingAE} not supported");
pc.SetResult(DicomPresentationContextResult.RejectAbstractSyntaxNotSupported);
}
}
Logger.LogInformation($"Accepted association request from {CallingAE}");
return SendAssociationAcceptAsync(association);
}
public Task<DicomCEchoResponse> OnCEchoRequestAsync(DicomCEchoRequest request)
{
Logger.LogInformation("Received verification request from AE {0} with IP: {1}", CallingAE, Association.RemoteHost);
return Task.FromResult(new DicomCEchoResponse(request, DicomStatus.Success));
}
public async IAsyncEnumerable<DicomCFindResponse> OnCFindRequestAsync(DicomCFindRequest request)
{
Console.WriteLine("Received C-FIND request, forwarding to real PACS...");
var cts = new CancellationTokenSource();
var _dicomAERepository = _serviceProvider.GetService<IRepository<DicomAE>>();
var find = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.PacsServer && t.CalledAE == DicomSCPServiceConfig.ThirdSearchPacsAE);
var hirClient = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.HIRClient);
if (find == null || hirClient == null)
{
Logger.LogInformation("客户端和Pacs配置未查询到");
yield return new DicomCFindResponse(request, DicomStatus.ProcessingFailure);
yield break;
}
string patientID = request.Dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty);
string patientName = request.Dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty);
string studyDate = request.Dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty);
string studyInstanceUID = request.Dataset.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, string.Empty);
string accessionNumber = request.Dataset.GetSingleValueOrDefault(DicomTag.AccessionNumber, string.Empty);
if (patientID.IsNullOrEmpty() && patientName.IsNullOrEmpty() && studyInstanceUID.IsNullOrEmpty() && studyDate.IsNullOrEmpty() && accessionNumber.IsNullOrEmpty())
{
yield return new DicomCFindResponse(request, DicomStatus.MissingAttribute);
yield break;
}
// 创建 channel 用于异步传递响应
var channel = Channel.CreateUnbounded<DicomCFindResponse>();
// 克隆 dataset 避免线程/状态冲突
var clonedDataset = request.Dataset?.Clone() ?? new DicomDataset();
var forward = new DicomCFindRequest(request.SOPClassUID, request.Level)
{
Dataset = clonedDataset
};
var receivedCount = 0;
// 标记是否已收到 final 状态(Success/Failure/Cancel
var finalReceived = false;
// 当远端 PACS 返回响应时,异步写入 channel
forward.OnResponseReceived += (rq, rp) =>
{
#region
////100条的时候直接取消
//if (receivedCount >= 10)
//{
// rp.Status = DicomStatus.Cancel;
// cts.Cancel(); // 触发取消
// Logger.LogWarning("超过100条,剩余的取消!");
//}
//receivedCount++;
#endregion
var dsCopy = rp.Dataset?.Clone();
var proxyResp = new DicomCFindResponse(request, rp.Status)
{
Dataset = dsCopy
};
channel.Writer.TryWrite(proxyResp);
if (!rp.Status.Equals(DicomStatus.Pending))
{
finalReceived = true;
}
};
// 异步发送到真实 PACS
_ = Task.Run(async () =>
{
try
{
var client = DicomClientFactory.Create(find.IP, find.Port, false, hirClient.CalledAE, find.CalledAE);
await client.AddRequestAsync(forward);
await client.SendAsync(cancellationToken: cts.Token);
}
catch (Exception ex)
{
Console.WriteLine("Error forwarding C-FIND: " + ex.Message);
}
finally
{
channel.Writer.Complete();
}
});
// 异步 yield 返回给上游
await foreach (var resp in channel.Reader.ReadAllAsync())
{
yield return resp;
}
// 兜底:如果没有 final 响应,返回 Success
if (!finalReceived)
{
yield return new DicomCFindResponse(request, DicomStatus.Success);
}
}
public async IAsyncEnumerable<DicomCMoveResponse> OnCMoveRequestAsync(DicomCMoveRequest request)
{
Console.WriteLine("Received C-Move request, forwarding to real PACS...");
var _dicomAERepository = _serviceProvider.GetService<IRepository<DicomAE>>();
var _cmoveStudyRepository = _serviceProvider.GetService<IRepository<CmoveStudy>>();
var find = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.PacsServer && t.CalledAE == DicomSCPServiceConfig.ThirdSearchPacsAE);
var hirServer = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.HIRServer);
var hirClient = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.HIRClient);
if (find == null || hirClient == null || hirServer == null)
{
Logger.LogInformation("客户端和Pacs配置未查询到");
}
var studyInstanceUid = request.Dataset?.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, string.Empty);
if (studyInstanceUid.IsNotNullOrEmpty())
{
await _cmoveStudyRepository.AddAsync(new CmoveStudy() { CallingAE = CallingAE, CalledAE = CalledAE, DestinationAE = request.DestinationAE, StudyInstanceUIDList = new List<string>() { studyInstanceUid }, HopitalGroupIdList = new List<Guid>() }, true);
}
var channel = Channel.CreateUnbounded<DicomCMoveResponse>();
var clonedDataset = request.Dataset?.Clone() ?? new DicomDataset();
var forward = new DicomCMoveRequest(hirServer.CalledAE, studyInstanceUid)
{
Dataset = clonedDataset
};
bool finalReceived = false;
// PACS 返回响应时写入 channel
forward.OnResponseReceived += (rq, rp) =>
{
var dsCopy = rp.Dataset?.Clone();
var proxyResp = new DicomCMoveResponse(request, rp.Status)
{
Dataset = dsCopy,
Remaining = rp.Remaining,
Completed = rp.Completed,
Failures = rp.Failures,
Warnings = rp.Warnings,
};
Logger.LogInformation($"Completed:{rp.Completed}");
channel.Writer.TryWrite(proxyResp);
if (!rp.Status.Equals(DicomStatus.Pending))
{
finalReceived = true;
}
};
// 异步发送到真实 PACS
_ = Task.Run(async () =>
{
try
{
var client = DicomClientFactory.Create(find.IP, find.Port, false, hirClient.CalledAE, find.CalledAE);
await client.AddRequestAsync(forward);
await client.SendAsync();
}
catch (Exception ex)
{
Console.WriteLine("Error forwarding C-MOVE: " + ex.Message);
}
finally
{
channel.Writer.Complete();
}
});
// 异步 yield 回上游
await foreach (var resp in channel.Reader.ReadAllAsync())
{
yield return resp;
}
// 兜底
if (!finalReceived)
{
yield return new DicomCMoveResponse(request, DicomStatus.Success);
}
}
}
}
@@ -0,0 +1,68 @@
using Microsoft.Extensions.Hosting;
using System.Threading;
using System;
using System.Threading.Tasks;
using MassTransit;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infra.EFCore;
using Microsoft.Extensions.Logging;
using Hangfire;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Consumer;
using IRaCIS.Core.Domain.Share;
using MassTransit.Scheduling;
using Hangfire.Storage;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using MassTransit.Mediator;
namespace IRaCIS.Core.API.HostService;
public class HangfireHostService(IRecurringMessageScheduler _recurringMessageScheduler,
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository,
IMediator _mediator,
ILogger<HangfireHostService> _logger) : IHostedService
{
public async Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("项目启动 hangfire 任务初始化 执行开始~");
//创建邮件定时任务
//项目定时任务都在default 队列
var dbJobIdList = JobStorage.Current.GetConnection().GetRecurringJobs().Where(t => t.Queue == "default").Select(t => t.Id).ToList();
foreach (var jobId in dbJobIdList)
{
HangfireJobHelper.RemoveCronJob(jobId);
}
var taskInfoList = await _trialEmailNoticeConfigRepository.Where(t => t.Trial.TrialStatusStr == StaticData.TrialState.TrialOngoing && t.EmailCron != string.Empty && t.IsAutoSend)
.Select(t => new { t.Id, t.Code, TrialCode = t.Trial.TrialCode, t.EmailCron, t.BusinessScenarioEnum, t.TrialId })
.ToListAsync();
foreach (var task in taskInfoList)
{
//利用主键作为任务Id
var jobId = $"{task.TrialId}({task.TrialCode})_({task.BusinessScenarioEnum})";
var trialId = task.TrialId;
HangfireJobHelper.AddOrUpdateTrialCronJob(jobId, trialId, task.BusinessScenarioEnum, task.EmailCron);
}
//await _recurringMessageScheduler.ScheduleRecurringPublish(new QCImageQuestionSchedule() { CronExpression = "0/3 * * * * ? " }, new MasstransiTestCommand { value = "message at " + DateTime.Now.ToString() });
_logger.LogInformation("项目启动 hangfire 任务初始化 执行结束");
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
@@ -0,0 +1,30 @@
using IRaCIS.Core.Application.MassTransit.Consumer;
using MassTransit;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Threading.Tasks;
namespace IRaCIS.Core.API.HostService
{
public class RecurringJobConfigurationService :
BackgroundService
{
readonly IServiceScopeFactory _scopeFactory;
public RecurringJobConfigurationService(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await using var scope = _scopeFactory.CreateAsyncScope();
var endpoint = scope.ServiceProvider.GetRequiredService<IPublishEndpoint>();
await endpoint.AddOrUpdateRecurringJob(nameof(MasstransitTestConsumer), new MasstransiTestCommand(), x => x.Every(minutes: 1),
stoppingToken);
}
}
}
+76 -12
View File
@@ -38,11 +38,18 @@
<None Remove="GrpcToken.proto" />
<None Remove="IRaCIS.Core.API.xml" />
<None Remove="Protos\GrpcToken.proto" />
<None Remove="Resources\ip2region.xdb" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="GrpcToken.proto" />
</ItemGroup>
<ItemGroup>
<Content Include="Resources\ip2region.xdb">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="wwwroot\swagger\ui\abp.js">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
@@ -62,25 +69,22 @@
<ItemGroup>
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="ConfigMapFileProvider" Version="2.0.1" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.14" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.20" />
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
<PackageReference Include="Hangfire.InMemory" Version="0.10.3" />
<PackageReference Include="Hangfire.SqlServer" Version="1.8.14" />
<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.8" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.1.1" />
<PackageReference Include="Hangfire.InMemory" Version="1.0.0" />
<PackageReference Include="Hangfire.SqlServer" Version="1.8.20" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.Email" Version="4.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.7.3" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.3" />
</ItemGroup>
<ItemGroup>
@@ -100,6 +104,66 @@
<Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Resources\en-US.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Resources\zh-CN.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\downLoad\file.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\ReportTemplate_IRECIST_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\ReportTemplate_PCWG3_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\ReportTemplate_RECIST1.1_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\TumorEvaluation_IRECIST1.1_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\TumorEvaluation_IRECIST1.1_EN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\TumorEvaluation_RECIST1.1_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\医院模板\协和\ReportTemplate_IRECIST_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\医院模板\协和\ReportTemplate_PCWG3_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\医院模板\协和\ReportTemplate_RECIST1.1_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\医院模板\同济\ReportTemplate_IRECIST_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\医院模板\同济\ReportTemplate_PCWG3_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\医院模板\同济\ReportTemplate_RECIST1.1_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\医院模板\复旦大学肿瘤附属医院\ReportTemplate_IRECIST_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\医院模板\复旦大学肿瘤附属医院\ReportTemplate_PCWG3_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\ReadReoprtTemplate\医院模板\复旦大学肿瘤附属医院\ReportTemplate_RECIST1.1_CN_V1.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Update="Resources\GeoLite2-City.mmdb">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ProjectExtensions>
+34 -42
View File
@@ -16,7 +16,12 @@
医生基本信息 、工作信息 专业信息、审核状态
</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)">
<member name="M:IRaCIS.Api.Controllers.ExtraController.#ctor(IRaCIS.Application.Interfaces.IAttachmentService,IRaCIS.Application.Interfaces.IDoctorService,IRaCIS.Application.Interfaces.IEducationService,IRaCIS.Application.Interfaces.ITrialExperienceService,IRaCIS.Application.Interfaces.IResearchPublicationService,IRaCIS.Application.Interfaces.IVacationService)">
<summary>
医生基本信息 、工作信息 专业信息、审核状态
</summary>
</member>
<member name="M:IRaCIS.Api.Controllers.ExtraController.GetDoctorDetail(IRaCIS.Application.Contracts.GetDoctorDetailInDto)">
<summary>
获取医生详情
</summary>
@@ -29,8 +34,21 @@
<param name="doctorId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,ZiggyCreatures.Caching.Fusion.IFusionCache,IRaCIS.Core.Application.Service.IUserService,IRaCIS.Core.Application.Auth.ITokenService,IRaCIS.Core.Application.Contracts.IReadingImageTaskService,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig},IRaCIS.Core.Application.Service.IMailVerificationService)">
<summary> 系统用户登录接口[New] </summary>
<member name="M:IRaCIS.Api.Controllers.ExtraController.OAuthCallBack(System.String,System.String)">
<summary>
回调到前端,前端调用后端的接口
参考链接:https://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html
后端通过这个code ,带上客户端信息,和授权类型 可以向单点登录提供商,获取厂商token
但是单点登录提供商提供的token 和我们系统的token 是有区别的,我们的token里面有我们业务系统的UserId,涉及到很多业务操作,所以在此出现了两种方案
1、前端使用厂商的Token。 后端通过code 获取厂商的Token 返回前端的同时返回我们系统的UserId,前段在http 请求头加上一个自定义参数,带上UserId 后端取用户Id的地方变动下,
但是除了UserId外,后端还有其他信息也是从Token取的,所以在请求头也需要带上,此外后端认证Token的方式也需要变化,改造成本稍大(如果是微服务,做这种处理还是可以的)。
2、前端还是使用我们后台自己的Token。后端通过code 获取厂商Token的同时,后端做一个隐藏登录,返回厂商的Token的同时,也返回我们系统的Token。
(像我们单体,这种方式最简单,我们用单点登录,无非就是不想记多个系统的密码,自动登录而已,其他不支持的项目改造成本也是最低的)
</summary>
<param name="type">回调的厂商类型 比如github, google, 我们用的logto ,不同的厂商回调到前端的地址可以不同的,但是请求后端的接口可以是同一个 </param>
<param name="code">在第三方平台登录成功后,回调前端的时候会返回一个code </param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateTrialInspection(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Application.Contracts.TrialCommand})">
<summary> 添加实验项目-返回新增Id[AUTH]</summary>
@@ -257,12 +275,6 @@
<param name="opt"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.UserConfirm(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.Contracts.UserConfirmCommand})">
<summary>
用户 签名某个文档
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.ConfirmReReading(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Core.Application.ViewModel.ConfirmReReadingCommand},IRaCIS.Core.Application.Service.IVisitTaskHelpeService,IRaCIS.Core.Application.Service.IVisitTaskService)">
<summary>
重阅同意
@@ -290,7 +302,7 @@
<param name="_studyMonitorRepository"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadNoneDicomFile(IRaCIS.Core.API.Controllers.StudyController.UploadNoneDicomFileCommand,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.StudyMonitor},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile})">
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadNoneDicomFile(IRaCIS.Core.API.Controllers.UploadNoneDicomFileCommand,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.StudyMonitor},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile})">
<summary>
上传非Dicom 文件 支持压缩包 多文件上传
</summary>
@@ -310,33 +322,6 @@
<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.UploadDownLoadController.DownloadCommonFile(System.String,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument})">
<summary> 通用文件下载 </summary>
</member>
@@ -352,6 +337,16 @@
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.DownloadReadingReportAndImage(IRaCIS.Core.Application.Contracts.IReadingImageTaskService,IRaCIS.Core.Application.Helper.IOSSService,Microsoft.AspNetCore.SignalR.IHubContext{IRaCIS.Core.API.DownloadHub,IRaCIS.Core.API.IDownloadClient},IRaCIS.Core.Application.Service.Reading.Dto.GetReadingReportAndImageInDto)">
<summary>
下载阅片报告和图片
</summary>
<param name="_readingImageTaskService"></param>
<param name="_oSSService"></param>
<param name="_downLoadHub"></param>
<param name="inCommand"></param>
<returns></returns>
</member>
<member name="T:IRaCIS.Core.API.IpPolicyRateLimitSetup">
<summary>
IPLimit限流 启动服务
@@ -367,13 +362,10 @@
序列化,反序列化的时候,处理时间 时区转换
</summary>
</member>
<member name="M:IRaCIS.Core.API.NullToEmptyStringResolver.CreateProperties(System.Type,Newtonsoft.Json.MemberSerialization)">
<member name="T:IRaCIS.Core.API.NullToEmptyStringResolver">
<summary>
创建属性
LowerCamelCaseJsonAttribute 可以设置类小写返回给前端
</summary>
<param name="type">类型</param>
<param name="memberSerialization">序列化成员</param>
<returns></returns>
</member>
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
<summary>
+111 -210
View File
@@ -1,43 +1,38 @@
using System;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;
using System.Threading.Tasks;
using FellowOakDicom.Network;
using FellowOakDicom;
using IRaCIS.Core.API;
using IRaCIS.Core.API.HostService;
using IRaCIS.Core.Application.BusinessFilter;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.MassTransit.Consumer;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.Service.BusinessFilter;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit;
using MassTransit.NewIdProviders;
using System.IO;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Application.Helper;
using System.Runtime.InteropServices;
using Microsoft.AspNetCore.Builder;
using IRaCIS.Core.API;
using Autofac;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.HttpOverrides;
using IRaCIS.Core.Application.Service.BackGroundJob;
using LogDashboard;
using FellowOakDicom.Network;
using IRaCIS.Core.Application.Service.ImageAndDoc;
using IP2Region.Net.Abstractions;
using IP2Region.Net.XDB;
using IRaCIS.Core.Application.BusinessFilter;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Localization;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Diagnostics;
using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Application.MassTransit.Consumer;
using DocumentFormat.OpenXml.InkML;
using IRaCIS.Core.Domain;
using Serilog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using FellowOakDicom.Imaging.NativeCodec;
using FellowOakDicom.Imaging;
using IRaCIS.Core.Application.Contracts;
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
#region
//以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数)
var config = new ConfigurationBuilder()
@@ -56,29 +51,15 @@ if (string.IsNullOrWhiteSpace(enviromentName))
}
#endregion
// Serilog
SerilogExtension.AddSerilogSetup(enviromentName);
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
EnvironmentName = enviromentName
});
#region windows
//foreach (var arg in args)
//{
// Console.WriteLine(arg);
//}
int urlsIndex = Array.FindIndex(args, arg => arg != null && arg.StartsWith("--urls"));
if (urlsIndex > -1)
{
var url = args[urlsIndex].Substring("--urls=".Length);
Console.WriteLine(url);
builder.WebHost.UseUrls(url);
}
#endregion
#region
@@ -87,50 +68,49 @@ NewId.SetProcessIdProvider(new CurrentProcessIdProvider());
builder.Configuration.AddJsonFile(ConfigMapFileProvider.FromRelativePath(""), "appsettings.json", false, true)
.AddJsonFile(ConfigMapFileProvider.FromRelativePath(""), $"appsettings.{enviromentName}.json", false, true);
builder.Host
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
containerBuilder.RegisterModule<AutofacModuleSetup>();
})
.UseWindowsService().UseSerilog();
builder.Host.UseSerilog();
#endregion
#region
var _configuration = builder.Configuration;
//手动注册服务
builder.Services.ConfigureServices(_configuration);
builder.Services.AddHostedService<HangfireHostService>();
//minimal api 异常处理
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
//builder.Services.AddProblemDetails();
//健康检查
builder.Services.AddHealthChecks();
builder.Services.AddSerilog();
//本地化
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>();
//options.Filters.Add<EncreptApiResultFilter>(10);
options.Filters.Add<LimitUserRequestAuthorization>();
options.Filters.Add<TrialGlobalLimitActionFilter>();
})
.AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化 处理
builder.Services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig"));
builder.Services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
builder.Services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
builder.Services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
builder.Services.AddOptions().Configure<IRCEncreptOption>(_configuration.GetSection("EncrypteResponseConfig"));
builder.Services.AddOptions().Configure<SystemPacsConfig>(_configuration.GetSection("SystemPacsConfig"));
builder.Services.AddOptions().Configure<DicomSCPServiceOption>(_configuration.GetSection("DicomSCPServiceConfig"));
builder.Services.Configure<IRaCISBasicConfigOption>(_configuration.GetSection("IRaCISBasicConfig"));
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
// Panda动态WebApi + UnifiedApiResultFilter + 省掉控制器代码
builder.Services.AddDynamicWebApiSetup();
//MinimalAPI
builder.Services.AddMasaMinimalAPiSetUp();
//AutoMapper
builder.Services.AddAutoMapperSetup();
//EF ORM QueryWithNoLock
@@ -142,91 +122,40 @@ builder.Services.AddSwaggerSetup();
//JWT Token 验证
builder.Services.AddJWTAuthSetup(_configuration);
// MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系
//builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<ConsistencyVerificationHandler>());
#region MassTransit
//masstransit组件 也支持MediatR 中介者模式,但是支持分布式,考虑后续,所以在次替代MediatR
//参考链接:https://masstransit.io/documentation/concepts/mediator#scoped-mediator
builder.Services.AddMediator(cfg =>
{
cfg.AddConsumer<ConsistencyCheckConsumer>();
cfg.AddConsumer<AddSubjectTriggerConsumer>();
cfg.AddConsumer<AddSubjectTriggerConsumer2>();
//cfg.ConfigureMediator((context, cfg) => cfg.UseHttpContextScopeFilter(context));
});
//添加 MassTransit 和 InMemory 传输
builder.Services.AddMassTransit(cfg =>
{
// 注册消费者
cfg.AddConsumer<AddSubjectTriggerConsumer>(); // 替换为你的消费者类
cfg.AddConsumer<AddSubjectTriggerConsumer2>();
// 使用 InMemory 作为消息传递机制
cfg.UsingInMemory((context, cfg) =>
{
// 这里可以进行额外的配置
cfg.ConfigureEndpoints(context); // 自动配置所有消费者的端点
});
});
#endregion
#region FusionCache
//MassTransit
builder.Services.AddMassTransitSetup();
// FusionCache
builder.Services.AddFusionCache();
#endregion
// EasyCaching 缓存
//builder.Services.AddEasyCachingSetup(_configuration);
// hangfire 定时任务框架 有界面,更友好~
builder.Services.AddhangfireSetup(_configuration);
//Serilog 日志可视化 LogDashboard日志
builder.Services.AddLogDashboardSetup();
builder.Services.AddJsonConfigSetup(_configuration);
//转发头设置 获取真实IP
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
//Dicom影像渲染图片 跨平台
builder.Services.AddDicomSetup();
builder.Services.AddFellowOakDicom().AddTranscoderManager<NativeTranscoderManager>()
//.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>()
.AddImageManager<ImageSharpImageManager>();
//builder.Services.AddDicomSetup();
new DicomSetupBuilder()
.SkipValidation()
.Build();
// 实时应用
builder.Services.AddSignalR();
builder.Services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
builder.Services.AddSingleton<ISearcher>(new Searcher(CachePolicy.Content, Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, "ip2region.xdb")));
//builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
//builder.Services.AddProblemDetails();
#region
//builder.Services.AddMemoryCache();
////上传限制 配置
//builder.Services.Configure<FormOptions>(options =>
//// 添加反伪造服务
//builder.Services.AddAntiforgery(options =>
//{
// options.MultipartBodyLengthLimit = int.MaxValue;
// options.ValueCountLimit = int.MaxValue;
// options.ValueLengthLimit = int.MaxValue;
// // 可选:设置自定义的头部名称以支持 AJAX 请求等
// options.HeaderName = "X-XSRF-TOKEN";
//});
//IP 限流 可设置白名单 或者黑名单
//services.AddIpPolicyRateLimitSetup(_configuration);
// 用户类型 策略授权
//services.AddAuthorizationPolicySetup(_configuration);
#endregion
//builder.Services.AddAntiforgery();
#endregion
@@ -235,9 +164,8 @@ var env = app.Environment;
#region
app.UseMiddleware<EncryptionRequestMiddleware>();
// Configure the HTTP request pipeline.
app.UseMiddleware<EncryptionRequestMiddleware>();
#region 400 -500
@@ -260,54 +188,8 @@ app.UseStatusCodePages(async context =>
});
//app.UseExceptionHandler(o => { });
//这里没生效,原因未知,官方文档也是这种写法,也用了GlobalExceptionHandler 尝试,还是不行,怀疑框架bug
//app.UseExceptionHandler(configure =>
//{
// configure.Run(async context =>
// {
// var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
//var ex = exceptionHandlerPathFeature?.Error;
//context.Response.ContentType = "application/json";
//if (ex != null)
//{
// var errorInfo = $"Exception: {ex.Message}[{ex.StackTrace}]" + (ex.InnerException != null ? $" InnerException: {ex.InnerException.Message}[{ex.InnerException.StackTrace}]" : "");
// await context.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk($"{ex?.Message}")));
// Log.Logger.Error(errorInfo);
//}
// });
//});
#endregion
//本地化
app.UseLocalization();
app.UseForwardedHeaders();
//响应压缩
app.UseResponseCompression();
//不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();
//LogDashboard
app.UseLogDashboard("/LogDashboard");
//hangfire
app.UseHangfireConfig(env);
//app.UseExceptionHandler();
app.UseExceptionHandler(o => { });
#region
@@ -322,46 +204,60 @@ app.UseHangfireConfig(env);
//{
// //app.UseHsts();
//}
//app.UseIRacisHostStaticFileStore(env);
#endregion
#endregion
app.UseIRacisHostStaticFileStore(env);
//本地化
await app.UseLocalization(app.Services);
app.UseForwardedHeaders();
//响应压缩
app.UseResponseCompression();
//不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();
//hangfire
app.UseHangfireConfig(env);
// Swagger
SwaggerSetup.Configure(app, env);
////serilog 记录请求的用户信息
//serilog 记录请求的用户信息
app.UseSerilogConfig(env);
app.UseRouting();
app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
//app.UseIRacisHostStaticFileStore(env);
app.UseAuthentication();
app.UseAuthorization();
//Map MinimalAPI routes
app.MapMasaMinimalAPIs();
//// 这里添加反伪造中间件
//app.UseAntiforgery();
app.MapControllers();
app.MapHub<UploadHub>("/UploadHub");
app.MapHub<DownloadHub>("/DownloadHub");
app.MapHealthChecks("/health");
// Serilog
SerilogExtension.AddSerilogSetup(enviromentName, app.Services);
var hangfireJobService = app.Services.GetRequiredService<IIRaCISHangfireJob>();
await hangfireJobService.InitHangfireJobTaskAsync();
#endregion
try
{
#region
@@ -381,9 +277,6 @@ try
Log.Logger.Warning($"当前部署平台环境:OSX or FreeBSD");
}
#endregion
Log.Logger.Warning($"ContentRootPath{env.ContentRootPath}");
@@ -394,10 +287,18 @@ try
//Log.Logger.Warning($"ContentRootPath——GetParent{Directory.GetParent(env.ContentRootPath).Parent.FullName}");
//Log.Logger.Warning($"ContentRootPath——xx{Path.GetDirectoryName(Path.GetDirectoryName(env.ContentRootPath))}");
#endregion
DicomSetupBuilder.UseServiceProvider(app.Services);
var logger = app.Services.GetService<Microsoft.Extensions.Logging.ILogger<Program>>();
var server = DicomServerFactory.Create<DicomSCPService>(_configuration.GetSection("DicomSCPServiceConfig").GetValue<int>("ServerPort"), userState: app.Services, logger: logger);
app.Run();
}
catch (Exception e)
{
+9 -30
View File
@@ -16,60 +16,39 @@
"ASPNETCORE_ENVIRONMENT": "Test_IRC"
}
},
"IRaCIS.Test_IRC": {
"Uat_HIR": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Test_IRC"
"ASPNETCORE_ENVIRONMENT": "Uat_HIR"
},
"applicationUrl": "http://localhost:6100"
},
"IRaCIS.Test_IRC_PGSQL": {
"Prod_HIR": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Test_IRC_PGSQL"
"ASPNETCORE_ENVIRONMENT": "Prod_HIR"
},
"applicationUrl": "http://localhost:6100"
},
"IRaCIS.Event_IRC": {
"US_HIR": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Event_IRC"
"ASPNETCORE_ENVIRONMENT": "US_HIR"
},
"applicationUrl": "http://localhost:6100"
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
"publishAllPorts": true
},
"IRaCIS.Uat_IRC": {
"Test_HIR": {
"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_Uat_IRC": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "US_Uat_IRC"
"ASPNETCORE_ENVIRONMENT": "Test_HIR"
},
"applicationUrl": "http://localhost:6100"
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 73 MiB

+38 -6
View File
@@ -3,24 +3,27 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
namespace IRaCIS.Core.API
{
public interface IUploadClient
{
Task ReceivProgressAsync(string studyInstanceUid, int haveReceivedCount);
}
public class IRaCISUserIdProvider : IUserIdProvider
{
public virtual string GetUserId(HubConnectionContext connection)
{
return connection.User?.FindFirst(JwtIRaCISClaimType.Id)?.Value!;
return connection.User?.FindFirst(JwtIRaCISClaimType.IdentityUserId)?.Value!;
}
}
public interface IUploadClient
{
Task ReceivProgressAsync(string studyInstanceUid, int haveReceivedCount);
}
[AllowAnonymous]
[DisableCors]
public class UploadHub : Hub<IUploadClient>
@@ -38,7 +41,7 @@ namespace IRaCIS.Core.API
public override Task OnConnectedAsync()
{
//base.Context.User.id
_logger.LogError("连接: " + Context.ConnectionId);
@@ -53,5 +56,34 @@ namespace IRaCIS.Core.API
// await Clients.All.ReceivProgressAsync(studyInstanceUid, haveReceivedCount);
//}
}
public interface IDownloadClient
{
Task ReceivProgressAsync(string downloadId, object percent);
}
[AllowAnonymous]
[DisableCors]
public class DownloadHub : Hub<IDownloadClient>
{
public ILogger<DownloadHub> _logger { get; set; }
public DownloadHub(ILogger<DownloadHub> logger)
{
_logger = logger;
}
public override Task OnConnectedAsync()
{
_logger.LogError("连接: " + Context.ConnectionId);
return base.OnConnectedAsync();
}
}
}
@@ -1,18 +0,0 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
namespace IRaCIS.Core.API.Filter
{
public class EnableBufferingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
context.HttpContext.Request.EnableBuffering();
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
}
-270
View File
@@ -1,270 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Net.Http.Headers;
namespace IRaCIS.Core.API.Utility
{
public static class FileHelpers
{
private static readonly byte[] _allowedChars = { };
// For more file signatures, see the File Signatures Database (https://www.filesignatures.net/)
// and the official specifications for the file types you wish to add.
private static readonly Dictionary<string, List<byte[]>> _fileSignature = new Dictionary<string, List<byte[]>>
{
{ ".gif", new List<byte[]> { new byte[] { 0x47, 0x49, 0x46, 0x38 } } },
{ ".png", new List<byte[]> { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A } } },
{ ".jpeg", new List<byte[]>
{
new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE2 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE3 },
}
},
{ ".jpg", new List<byte[]>
{
new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE1 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE8 },
}
},
{ ".zip", new List<byte[]>
{
new byte[] { 0x50, 0x4B, 0x03, 0x04 },
new byte[] { 0x50, 0x4B, 0x4C, 0x49, 0x54, 0x45 },
new byte[] { 0x50, 0x4B, 0x53, 0x70, 0x58 },
new byte[] { 0x50, 0x4B, 0x05, 0x06 },
new byte[] { 0x50, 0x4B, 0x07, 0x08 },
new byte[] { 0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70 },
}
},
};
// **WARNING!**
// In the following file processing methods, the file's content isn't scanned.
// In most production scenarios, an anti-virus/anti-malware scanner API is
// used on the file before making the file available to users or other
// systems. For more information, see the topic that accompanies this sample
// app.
public static async Task<byte[]> ProcessFormFile<T>(IFormFile formFile,
ModelStateDictionary modelState, string[] permittedExtensions,
long sizeLimit)
{
var fieldDisplayName = string.Empty;
// Use reflection to obtain the display name for the model
// property associated with this IFormFile. If a display
// name isn't found, error messages simply won't show
// a display name.
MemberInfo property =
typeof(T).GetProperty(
formFile.Name.Substring(formFile.Name.IndexOf(".",
StringComparison.Ordinal) + 1));
if (property != null)
{
if (property.GetCustomAttribute(typeof(DisplayAttribute)) is
DisplayAttribute displayAttribute)
{
fieldDisplayName = $"{displayAttribute.Name} ";
}
}
// Don't trust the file name sent by the client. To display
// the file name, HTML-encode the value.
var trustedFileNameForDisplay = WebUtility.HtmlEncode(
formFile.FileName);
// Check the file length. This check doesn't catch files that only have
// a BOM as their content.
if (formFile.Length == 0)
{
modelState.AddModelError(formFile.Name,
$"{fieldDisplayName}({trustedFileNameForDisplay}) is empty.");
return new byte[0];
}
if (formFile.Length > sizeLimit)
{
var megabyteSizeLimit = sizeLimit / 1048576;
modelState.AddModelError(formFile.Name,
$"{fieldDisplayName}({trustedFileNameForDisplay}) exceeds " +
$"{megabyteSizeLimit:N1} MB.");
return new byte[0];
}
try
{
using (var memoryStream = new MemoryStream())
{
await formFile.CopyToAsync(memoryStream);
// Check the content length in case the file's only
// content was a BOM and the content is actually
// empty after removing the BOM.
if (memoryStream.Length == 0)
{
modelState.AddModelError(formFile.Name,
$"{fieldDisplayName}({trustedFileNameForDisplay}) is empty.");
}
if (!IsValidFileExtensionAndSignature(
formFile.FileName, memoryStream, permittedExtensions))
{
modelState.AddModelError(formFile.Name,
$"{fieldDisplayName}({trustedFileNameForDisplay}) file " +
"type isn't permitted or the file's signature " +
"doesn't match the file's extension.");
}
else
{
return memoryStream.ToArray();
}
}
}
catch (Exception ex)
{
modelState.AddModelError(formFile.Name,
$"{fieldDisplayName}({trustedFileNameForDisplay}) upload failed. " +
$"Please contact the Help Desk for support. Error: {ex.HResult}");
}
return new byte[0];
}
public static async Task<byte[]> ProcessStreamedFile(
MultipartSection section, ContentDispositionHeaderValue contentDisposition,
ModelStateDictionary modelState, string[] permittedExtensions, long sizeLimit)
{
try
{
using (var memoryStream = new MemoryStream())
{
await section.Body.CopyToAsync(memoryStream);
// Check if the file is empty or exceeds the size limit.
if (memoryStream.Length == 0)
{
modelState.AddModelError("File", "The file is empty.");
}
else if (memoryStream.Length > sizeLimit)
{
var megabyteSizeLimit = sizeLimit / 1048576;
modelState.AddModelError("File",
$"The file exceeds {megabyteSizeLimit:N1} MB.");
}
else if (!IsValidFileExtensionAndSignature(
contentDisposition.FileName.Value, memoryStream,
permittedExtensions))
{
modelState.AddModelError("File",
"The file type isn't permitted or the file's " +
"signature doesn't match the file's extension.");
}
else
{
return memoryStream.ToArray();
}
}
}
catch (Exception ex)
{
modelState.AddModelError("File",
"The upload failed. Please contact the Help Desk " +
$" for support. Error: {ex.HResult}");
// Log the exception
}
return new byte[0];
}
private static bool IsValidFileExtensionAndSignature(string fileName, Stream data, string[] permittedExtensions)
{
if (string.IsNullOrEmpty(fileName) || data == null || data.Length == 0)
{
return false;
}
var ext = Path.GetExtension(fileName).ToLowerInvariant();
if (string.IsNullOrEmpty(ext) || !permittedExtensions.Contains(ext))
{
return false;
}
data.Position = 0;
using (var reader = new BinaryReader(data))
{
if (ext.Equals(".txt") || ext.Equals(".csv") || ext.Equals(".prn"))
{
if (_allowedChars.Length == 0)
{
// Limits characters to ASCII encoding.
for (var i = 0; i < data.Length; i++)
{
if (reader.ReadByte() > sbyte.MaxValue)
{
return false;
}
}
}
else
{
// Limits characters to ASCII encoding and
// values of the _allowedChars array.
for (var i = 0; i < data.Length; i++)
{
var b = reader.ReadByte();
if (b > sbyte.MaxValue ||
!_allowedChars.Contains(b))
{
return false;
}
}
}
return true;
}
// Uncomment the following code block if you must permit
// files whose signature isn't provided in the _fileSignature
// dictionary. We recommend that you add file signatures
// for files (when possible) for all file types you intend
// to allow on the system and perform the file signature
// check.
//if (!_fileSignature.ContainsKey(ext))
//{
// return true;
//}
// File signature check
// --------------------
// With the file signatures provided in the _fileSignature
// dictionary, the following code tests the input content's
// file signature.
//var signatures = _fileSignature[ext];
//var headerBytes = reader.ReadBytes(signatures.Max(m => m.Length));
//return signatures.Any(signature =>
// headerBytes.Take(signature.Length).SequenceEqual(signature));
//test
return true;
}
}
}
}
@@ -1,12 +1,9 @@
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt
{
@@ -1,13 +1,10 @@
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Threading.Tasks;
namespace ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt
{
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt
namespace ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt
{
public interface ICustomJWTService
{
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt
namespace ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt
{
public class JWTTokenOptions
{
-4
View File
@@ -1,10 +1,6 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
namespace ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt
{
@@ -1,54 +0,0 @@
using System;
using System.IO;
using Microsoft.Net.Http.Headers;
namespace IRaCIS.Core.API.Utility
{
public static class MultipartRequestHelper
{
// Content-Type: multipart/form-data; boundary="----WebKitFormBoundarymx2fSWqWSd0OxQqq"
// The spec at https://tools.ietf.org/html/rfc2046#section-5.1 states that 70 characters is a reasonable limit.
public static string GetBoundary(MediaTypeHeaderValue contentType, int lengthLimit)
{
var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary).Value;
if (string.IsNullOrWhiteSpace(boundary))
{
throw new InvalidDataException(
"Missing content-type boundary.");
}
if (boundary.Length > lengthLimit)
{
throw new InvalidDataException(
$"Multipart boundary length limit {lengthLimit} exceeded.");
}
return boundary;
}
public static bool IsMultipartContentType(string contentType)
{
return !string.IsNullOrEmpty(contentType)
&& contentType.IndexOf("multipart/", StringComparison.OrdinalIgnoreCase) >= 0;
}
public static bool HasFormDataContentDisposition(ContentDispositionHeaderValue contentDisposition)
{
// Content-Disposition: form-data; name="key";
return contentDisposition != null
&& contentDisposition.DispositionType.Equals("form-data")
&& string.IsNullOrEmpty(contentDisposition.FileName.Value)
&& string.IsNullOrEmpty(contentDisposition.FileNameStar.Value);
}
public static bool HasFileContentDisposition(ContentDispositionHeaderValue contentDisposition)
{
// Content-Disposition: form-data; name="myfile1"; filename="Misc 002.jpg"
return contentDisposition != null
&& contentDisposition.DispositionType.Equals("form-data")
&& (!string.IsNullOrEmpty(contentDisposition.FileName.Value)
|| !string.IsNullOrEmpty(contentDisposition.FileNameStar.Value));
}
}
}
@@ -1,9 +1,6 @@
using Hangfire;
using Hangfire.Dashboard;
using Hangfire.Dashboard.BasicAuthorization;
using IRaCIS.Core.Application.Service.BackGroundJob;
using IRaCIS.Core.API.Filter;
using IRaCIS.Core.Application.Helper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@@ -39,7 +36,7 @@ namespace IRaCIS.Core.API
})
},
DashboardTitle ="后台任务管理",
DashboardTitle = "后台任务管理",
//Authorization = new BasicAuthAuthorizationFilter[] {
@@ -1,21 +1,12 @@
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;
using Microsoft.Extensions.Hosting;
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;
using System.Threading.Tasks;
@@ -32,7 +23,7 @@ namespace IRaCIS.Core.API
private string iRaCISDefaultDataFolder = string.Empty;
public MultiDiskStaticFilesMiddleware(RequestDelegate next, IWebHostEnvironment hostingEnv, ILoggerFactory loggerFactory)
public MultiDiskStaticFilesMiddleware(RequestDelegate next, IWebHostEnvironment hostingEnv, ILoggerFactory loggerFactory)
{
_next = next;
_hostingEnv = hostingEnv;
@@ -89,7 +80,7 @@ namespace IRaCIS.Core.API
if (defaultFileProvider.GetFileInfo(path).Exists)
{
var actrualPath = defaultFileProvider.GetFileInfo(path).PhysicalPath;
var actrualPath = defaultFileProvider.GetFileInfo(path).PhysicalPath;
await context.Response.SendFileAsync(new PhysicalFileInfo(new FileInfo(actrualPath)));
@@ -110,7 +101,7 @@ namespace IRaCIS.Core.API
.Where(d => d.IsReady && d.DriveType == DriveType.Fixed)/*.Where(t => !t.Name.Contains("C") && !t.Name.Contains("c"))*/
.OrderBy(d => d.AvailableFreeSpace)
.Select(d => d.RootDirectory.FullName)
.ToArray().Where(t=>!t.Contains(defaultRoot));
.ToArray().Where(t => !t.Contains(defaultRoot));
foreach (var item in disks)
@@ -121,10 +112,10 @@ namespace IRaCIS.Core.API
{
continue;
}
var otherFileProvider= new PhysicalFileProvider(otherFileStoreFolder);
var otherFileProvider = new PhysicalFileProvider(otherFileStoreFolder);
if (otherFileProvider.GetFileInfo(path).Exists)
{
@@ -132,7 +123,7 @@ namespace IRaCIS.Core.API
var actrualPath = otherFileProvider.GetFileInfo(path).PhysicalPath;
//方式一
await context.Response.SendFileAsync( new PhysicalFileInfo(new FileInfo(actrualPath)));
await context.Response.SendFileAsync(new PhysicalFileInfo(new FileInfo(actrualPath)));
#region otherFileProvider /{StaticData.Folder.IRaCISDataFolder}
//var otherStaticFileOptions = new StaticFileOptions
@@ -158,7 +149,7 @@ namespace IRaCIS.Core.API
await context.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk("File not found")));
}
// 如果所有磁盘都不存在所请求的文件,则将请求传递给下一个中间件组件。
await _next.Invoke(context);
@@ -1,19 +1,28 @@
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Localization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
namespace IRaCIS.Core.API
{
public static class LocalizationConfig
{
public static void UseLocalization(this IApplicationBuilder app)
public static async Task UseLocalization(this IApplicationBuilder app,IServiceProvider serviceProvider)
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo(StaticData.CultureInfo.en_US),
new CultureInfo(StaticData.CultureInfo.zh_CN)
};
@@ -31,6 +40,28 @@ namespace IRaCIS.Core.API
//options.RequestCultureProviders.RemoveAt(1);
app.UseRequestLocalization(options);
//设置国际化I18n
var localizer = serviceProvider.GetRequiredService<IStringLocalizer>();
I18n.SetLocalizer(localizer);
//初始化国际化
var _internationalizationRepository = serviceProvider.GetRequiredService<IRepository<Internationalization>>();
//查询数据库的数据
var toJsonList = await _internationalizationRepository.Where(t => t.InternationalizationType == 1).Select(t => new IRCGlobalInfoDTO()
{
Code = t.Code,
Value = t.Value,
ValueCN = t.ValueCN,
Description = t.Description
}).ToListAsync();
await InternationalizationHelper.BatchAddJsonKeyValueAsync(toJsonList);
}
}
}
@@ -1,15 +0,0 @@
using LogDashboard;
using LogDashboard.Authorization;
namespace IRaCIS.Core.API.Filter
{
public class LogDashBoardAuthFilter : ILogDashboardAuthorizationFilter
{
//在此可以利用 本系统的UerTypeEnum 判断
public bool Authorization(LogDashboardContext context)
{
return context.HttpContext.User.Identity.IsAuthenticated;
}
}
}
@@ -1,5 +1,4 @@
using Microsoft.AspNetCore.Http;
using Serilog;
using Serilog.Context;
using System;
using System.IO;
@@ -1,13 +1,14 @@
using Hangfire;
using Hangfire.Dashboard;
using IRaCIS.Core.API._PipelineExtensions.Serilog;
using IRaCIS.Core.API._PipelineExtensions.Serilog;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Serilog;
using System.Linq;
namespace IRaCIS.Core.API
{
public static class SerilogConfig
{
@@ -19,8 +20,67 @@ namespace IRaCIS.Core.API
app.UseSerilogRequestLogging(opts
=>
{
opts.MessageTemplate = "{TokenUserRealName} {TokenUserTypeShortName} {ClientIp} {LocalIP} {Host} {Protocol} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
opts.EnrichDiagnosticContext = SerilogHelper.EnrichFromRequest;
opts.MessageTemplate = "{FullName} {UserType} {UserIp} {Host} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
opts.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
{
var request = httpContext.Request;
// Set all the common properties available for every request
diagnosticContext.Set("Host", request.Host.Value);
// Only set it if available. You're not sending sensitive data in a querystring right?!
if (request.QueryString.HasValue)
{
diagnosticContext.Set("QueryString", request.QueryString.Value);
}
diagnosticContext.Set("FullName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.FullName)?.Value);
diagnosticContext.Set("UserType", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value);
var clientIp = httpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault() ??
httpContext.Connection.RemoteIpAddress?.ToString();
if (clientIp.StartsWith("::ffff:"))
{
clientIp = clientIp.Substring(7); // 移除前缀
}
diagnosticContext.Set("UserIp", clientIp);
#region
//diagnosticContext.Set("Protocol", request.Protocol);
//diagnosticContext.Set("Scheme", request.Scheme);
//// Retrieve the IEndpointFeature selected for the request
//var endpoint = httpContext.GetEndpoint();
//if (endpoint is object) // endpoint != null
//{
// diagnosticContext.Set("EndpointName", endpoint.DisplayName);
//}
// Set the content-type of the Response at this point
//diagnosticContext.Set("ContentType", httpContext.Response.ContentType);
#endregion
#region old
//这种获取的Ip不准 配置服务才行
//diagnosticContext.Set("RequestIP", httpContext.Connection.RemoteIpAddress.ToString());
//这种方式可以,但是serilog提供了 就不用了
//diagnosticContext.Set("TestIP", httpContext.GetUserIp());
//这种方式不行 读取的body为空字符串 必须在中间件中读取
//diagnosticContext.Set("RequestBody", await ReadRequestBody(httpContext.Request));
//diagnosticContext.Set("RequestBody", RequestPayload);
#endregion
};
});
@@ -1,61 +0,0 @@
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Http;
using Serilog;
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.API
{
public class SerilogHelper
{
//public static string RequestPayload = "";
public static void EnrichFromRequest(IDiagnosticContext diagnosticContext, HttpContext httpContext)
{
var request = httpContext.Request;
// Set all the common properties available for every request
diagnosticContext.Set("Host", request.Host);
diagnosticContext.Set("Protocol", request.Protocol);
diagnosticContext.Set("Scheme", request.Scheme);
#region old
//这种获取的Ip不准 配置服务才行
//diagnosticContext.Set("RequestIP", httpContext.Connection.RemoteIpAddress.ToString());
//这种方式可以,但是serilog提供了 就不用了
//diagnosticContext.Set("TestIP", httpContext.GetUserIp());
//这种方式不行 读取的body为空字符串 必须在中间件中读取
//diagnosticContext.Set("RequestBody", await ReadRequestBody(httpContext.Request));
//diagnosticContext.Set("RequestBody", RequestPayload);
#endregion
// Only set it if available. You're not sending sensitive data in a querystring right?!
if (request.QueryString.HasValue)
{
diagnosticContext.Set("QueryString", request.QueryString.Value);
}
// Set the content-type of the Response at this point
diagnosticContext.Set("ContentType", httpContext.Response.ContentType);
diagnosticContext.Set("TokenUserRealName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.RealName)?.Value);
diagnosticContext.Set("TokenUserTypeShortName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value);
// Retrieve the IEndpointFeature selected for the request
var endpoint = httpContext.GetEndpoint();
if (endpoint is object) // endpoint != null
{
diagnosticContext.Set("EndpointName", endpoint.DisplayName);
}
}
}
}
@@ -34,7 +34,7 @@ namespace IRaCIS.Core.API
{
policyBuilder.RequireClaim("userTypeEnumInt", ((int)UserTypeEnum.ProjectManager).ToString(), ((int)UserTypeEnum.IQC).ToString());
});
options.AddPolicy(IRaCISPolicy.PM, policyBuilder =>
{
@@ -54,7 +54,7 @@ namespace IRaCIS.Core.API
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());
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 =>
@@ -64,23 +64,23 @@ namespace IRaCIS.Core.API
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());
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(),
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,13 +14,13 @@ namespace IRaCIS.Core.API
public class ApiResponseHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
public IStringLocalizer _localizer;
public ApiResponseHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
IStringLocalizer localizer,
ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder)
public ApiResponseHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
IStringLocalizer localizer,
ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder)
{
_localizer = localizer;
}
}
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
@@ -30,7 +30,7 @@ namespace IRaCIS.Core.API
{
Response.ContentType = "application/json";
Response.StatusCode = StatusCodes.Status401Unauthorized;
//---您无权访问该接口
//---您无权访问该接口
await Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["ApiResponse_NoAccess"], ApiResponseCodeEnum.NoToken)));
}
@@ -38,8 +38,8 @@ namespace IRaCIS.Core.API
{
Response.ContentType = "application/json";
Response.StatusCode = StatusCodes.Status403Forbidden;
//---您的权限不允许进行该操作
await Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["ApiResponse_Permission"],ApiResponseCodeEnum.HaveTokenNotAccess)));
//---您的权限不允许进行该操作
await Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["ApiResponse_Permission"], ApiResponseCodeEnum.HaveTokenNotAccess)));
}
}
@@ -45,7 +45,9 @@ namespace IRaCIS.Core.API
{
OnMessageReceived = (context) =>
{
if (context.Request.Query.TryGetValue("access_token", out StringValues values))
{
var queryToken = values.FirstOrDefault();
@@ -58,10 +60,10 @@ namespace IRaCIS.Core.API
}
}
//仅仅是访问文件的时候才会去取token认证 前端对cookie设置了有效期
if (context.Request.Path.ToString().Contains("IRaCISData") || context.Request.Path.ToString().Contains("SystemData") )
if (context.Request.Path.ToString().Contains("IRaCISData") || context.Request.Path.ToString().Contains("SystemData"))
{
var cookieToken = context.Request.Cookies["access_token"];
@@ -1,68 +0,0 @@
using Autofac;
using IRaCIS.Core.Application;
using IRaCIS.Core.Application.BackGroundJob;
using IRaCIS.Core.Infra.EFCore;
using Microsoft.AspNetCore.Http;
using Panda.DynamicWebApi;
using System;
using System.Linq;
using System.Reflection;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Service;
using IRaCIS.Application.Interfaces;
using AutoMapper;
namespace IRaCIS.Core.API
{
// ReSharper disable once IdentifierTypo
public class AutofacModuleSetup : Autofac.Module
{
protected override void Load(ContainerBuilder containerBuilder)
{
#region byzhouhang 20210917 Domain层 Infra.EFcore
containerBuilder.RegisterGeneric(typeof(Repository<>))
.As(typeof(IRepository<>)).InstancePerLifetimeScope();//注册泛型仓储
containerBuilder.RegisterType<Repository>().As<IRepository>().InstancePerLifetimeScope();
#endregion
#region autofac https://www.cnblogs.com/xwhqwer/p/15320838.html
//获取所有控制器类型并使用属性注入
containerBuilder.RegisterAssemblyTypes(typeof(BaseService).Assembly)
.Where(type => typeof(IDynamicWebApi).IsAssignableFrom(type))
.PropertiesAutowired();
#endregion
Assembly application = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "IRaCIS.Core.Application.dll");
containerBuilder.RegisterAssemblyTypes(application).Where(t => t.FullName.Contains("Service"))
.PropertiesAutowired().AsImplementedInterfaces();
//containerBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
//containerBuilder.RegisterType<UserInfo>().As<IUserInfo>().InstancePerLifetimeScope();
//注册hangfire任务 依赖注入
containerBuilder.RegisterType<ObtainTaskAutoCancelJob>().As<IObtainTaskAutoCancelJob>().InstancePerDependency();
}
}
}
@@ -1,6 +1,7 @@
using FellowOakDicom;
using FellowOakDicom.Imaging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace IRaCIS.Core.API
{
@@ -9,12 +10,14 @@ namespace IRaCIS.Core.API
public static void AddDicomSetup(this IServiceCollection services)
{
new DicomSetupBuilder()
.RegisterServices(s => s.AddFellowOakDicom()
.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>()
.AddImageManager<ImageSharpImageManager>()
.RegisterServices(s => s.AddFellowOakDicom().AddLogging(config => config.AddConsole())
.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>()
//.AddImageManager<ImageSharpImageManager>()
)
.SkipValidation()
.Build();
}
}
}
@@ -1,9 +1,14 @@
using Microsoft.Extensions.DependencyInjection;
using IRaCIS.Core.Application.BusinessFilter;
using IRaCIS.Core.Application.Service.BusinessFilter;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Panda.DynamicWebApi;
using System.Collections.Generic;
namespace IRaCIS.Core.API
{
public static class DynamicWebApiSetup
public static class WebApiSetup
{
//20210910 避免冗余的控制器层代码编写,仅仅包了一层前后台定义的格式 这里采用动态webAPi+IResultFilter 替代大部分情况
public static void AddDynamicWebApiSetup(this IServiceCollection services)
@@ -20,5 +25,38 @@ namespace IRaCIS.Core.API
});
}
public static void AddMasaMinimalAPiSetUp(this IServiceCollection services)
{
services.AddMasaMinimalAPIs(options =>
{
options.Prefix = "";//自定义前缀 默认是api
options.Version = ""; //默认是V1
options.AutoAppendId = false; //路由是否自动附加参数Id 默认是true
options.PluralizeServiceName = false; //服务名称是否启用复数
//options.Assemblies = new List<Assembly>() { typeof(UserSiteSurveySubmitedEventConsumer).Assembly };
options.GetPrefixes = new List<string> { "Get", "Select", "Find" };
options.PostPrefixes = new List<string> { "Post", "Add", "Create", "List" };
options.PutPrefixes = new List<string> { "Put", "Update" };
options.DeletePrefixes = new List<string> { "Delete", "Remove" };
options.RouteHandlerBuilder = t => {
t.RequireAuthorization()
.AddEndpointFilter<LimitUserRequestAuthorizationEndpointFilter>()
.AddEndpointFilter<TrialGlobalLimitEndpointFilter>()
//.AddEndpointFilter<ModelValidationEndpointFilter>()
.AddEndpointFilter<UnifiedApiResultEndpointFilter>()
.WithGroupName("Institution").DisableAntiforgery();
};
options.MapHttpMethodsForUnmatched = new string[] { "Post" };
options.DisableTrimMethodPrefix = true; //禁用去除方法前缀
options.DisableAutoMapRoute = false;//可通过配置true禁用全局自动路由映射或者删除此配置以启用全局自动路由映射
});
}
}
}
+13 -15
View File
@@ -1,6 +1,6 @@
using EntityFramework.Exceptions.SqlServer;
using Hangfire.SqlServer;
using IRaCIS.Core.Application.Triggers;
using IRaCIS.Core.Application.Triggers.AfterSaveTrigger;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infra.EFCore.Interceptor;
@@ -12,14 +12,12 @@ using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StackExchange.Redis;
namespace IRaCIS.Core.API
{
public static class EFSetup
{
public static void AddEFSetup( this IServiceCollection services, IConfiguration configuration,string envName)
public static void AddEFSetup(this IServiceCollection services, IConfiguration configuration, string envName)
{
services.AddHttpContextAccessor();
@@ -37,24 +35,23 @@ namespace IRaCIS.Core.API
// 在控制台
//public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); });
var logFactory = LoggerFactory.Create(builder => { builder.AddDebug(); });
var logFactory = LoggerFactory.Create(builder => { builder.AddDebug(); });
var dbType = configuration.GetSection("ConnectionStrings:Db_Type").Value ;
var dbType = configuration.GetSection("ConnectionStrings:Db_Type").Value;
if (!string.IsNullOrWhiteSpace(dbType) && dbType == "pgsql")
{
options.UseNpgsql(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
options.UseNpgsql(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure().CommandTimeout(90));
}
else
{
options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure().CommandTimeout(90));
}
//迁移的时候,不生成外键
options.ReplaceService<IMigrationsSqlGenerator, NoForeignKeyMigrationsSqlGenerator>();
options.UseLoggerFactory(logFactory);
options.UseExceptionProcessor();
@@ -66,17 +63,13 @@ namespace IRaCIS.Core.API
options.UseProjectables();
//options.AddInterceptors(new AuditingInterceptor(configuration.GetSection("ConnectionStrings:RemoteNew").Value));
//options.UseTriggers(triggerOptions => triggerOptions.AddTrigger<SubjectVisitImageDateTrigger>());
//options.UseTriggers(triggerOptions => triggerOptions.AddAssemblyTriggers(typeof(SubjectVisitTrigger).Assembly));
options.UseTriggers(triggerOptions =>
{
triggerOptions.AddTrigger<SubjectTrigger>();
triggerOptions.AddTrigger<ChallengeStateTrigger>();
triggerOptions.AddTrigger<ChallengeStateTrigger>();
triggerOptions.AddTrigger<SubjectVisitTrigger>();
triggerOptions.AddTrigger<SubjectVisitScanDateTrigger>();
triggerOptions.AddTrigger<TrialCriterionSignTrigger>();
@@ -87,13 +80,18 @@ namespace IRaCIS.Core.API
triggerOptions.AddTrigger<UserLogTrigger>();
triggerOptions.AddTrigger<UserAddTrigger>();
triggerOptions.AddTrigger<IdenttiyUserRoleInfoTrigger>();
triggerOptions.AddTrigger<UserLogAfterTrigger>();
});
});
// Register an additional context factory as a Scoped service, which gets a pooled context from the Singleton factory we registered above,
@@ -1,24 +0,0 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace IRaCIS.Core.API
{
public static class EasyCachingSetup
{
public static void AddEasyCachingSetup(this IServiceCollection services, IConfiguration configuration)
{
//services.AddEasyCaching(options =>
//{
// options.UseInMemory();
// //options.UseRedis(configuration, EasyCachingConstValue.DefaultRedisName).WithMessagePack(EasyCachingConstValue.DefaultRedisName);
//});
////services.ConfigureCastleInterceptor(options => options.CacheProviderName = EasyCachingConstValue.DefaultRedisName);
//services.ConfigureCastleInterceptor(options => options.CacheProviderName = EasyCachingConstValue.DefaultInMemoryName);
}
}
}
@@ -1,8 +1,6 @@
using AspNetCoreRateLimit;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace IRaCIS.Core.API
{
@@ -13,7 +11,7 @@ namespace IRaCIS.Core.API
{
public static void AddIpPolicyRateLimitSetup(this IServiceCollection services, IConfiguration Configuration)
{
// needed to store rate limit counters and ip rules
services.AddMemoryCache();
@@ -1,17 +0,0 @@
using IRaCIS.Core.Domain.Share;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace IRaCIS.Core.API
{
public static class JsonConfigSetup
{
public static void AddJsonConfigSetup(this IServiceCollection services, IConfiguration configuration)
{
services.Configure<ServiceVerifyConfigOption>(configuration.GetSection("BasicSystemConfig"));
}
}
}
@@ -1,26 +0,0 @@
using LogDashboard;
using LogDashboard.Authorization.Filters;
using Microsoft.Extensions.DependencyInjection;
namespace IRaCIS.Core.API
{
public static class LogDashboardSetup
{
public static void AddLogDashboardSetup(this IServiceCollection services)
{
//IIS 配置虚拟路径部署,会出现IIS静态文件404
services.AddLogDashboard(opt =>
{
//opt.PathMatch = "/api/LogDashboard";
opt.PathMatch = "/LogDashboard";
//opt.AddAuthorizationFilter(new LogDashboardBasicAuthFilter("admin", "zhizhun2018"));
//opt.AddAuthorizationFilter(new LogDashBoardAuthFilter());
});
}
}
}
@@ -0,0 +1,120 @@
using IRaCIS.Core.API.HostService;
using IRaCIS.Core.Application.MassTransit.Consumer;
using IRaCIS.Core.Domain.BaseModel;
using IRaCIS.Core.Infra.EFCore;
using MassTransit;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
namespace IRaCIS.Core.API
{
public static class MassTransitSetup
{
public static void AddMassTransitSetup(this IServiceCollection services)
{
#region MassTransit
//masstransit组件 也支持MediatR 中介者模式,但是支持分布式,考虑后续,所以在次替代MediatR
//参考链接:https://masstransit.io/documentation/concepts/mediator#scoped-mediator
services.AddMediator(cfg =>
{
cfg.AddConsumers(typeof(UserSiteSurveySubmitedEventConsumer).Assembly);
//cfg.AddConsumer<ConsistencyCheckConsumer>();
//cfg.AddConsumer<AddSubjectTriggerConsumer>();
//cfg.AddConsumer<AddSubjectTriggerConsumer2>();
//cfg.ConfigureMediator((context, cfg) => cfg.UseHttpContextScopeFilter(context));
});
//添加 MassTransit 和 InMemory 传输
services.AddMassTransit(cfg =>
{
cfg.AddConsumers(typeof(UserSiteSurveySubmitedEventConsumer).Assembly);
cfg.AddPublishMessageScheduler();
cfg.AddHangfireConsumers();
// 使用 InMemory 作为消息传递机制
cfg.UsingInMemory((context, cfg) =>
{
cfg.UsePublishMessageScheduler();
cfg.UseConsumeFilter(typeof(ConsumeExceptionFilter<>), context,
x => x.Include(type => type.IsAssignableTo(typeof(DomainEvent))));
cfg.UseConsumeFilter(typeof(CultureInfoFilter<>), context,
x => x.Include(type => type.IsAssignableTo(typeof(DomainEvent))));
cfg.ConfigureEndpoints(context); // 自动配置所有消费者的端点
});
#region rabitmq obsolute
//cfg.UsingRabbitMq((context, cfg) =>
//{
// cfg.UsePublishMessageScheduler();
// cfg.Host(
// host: "106.14.89.110",
// port: 5672,
// virtualHost: "/",
// configure: hostConfig =>
// {
// hostConfig.Username("rabbitmq");
// hostConfig.Password("rabbitmq");
// });
// cfg.ConfigureEndpoints(context);
//});
#endregion
#region Outbox obsolute
//cfg.AddConfigureEndpointsCallback((context, name, cfg) =>
//{
// cfg.UseEntityFrameworkOutbox<IRaCISDBContext>(context);
// //cfg.UseDelayedRedelivery(r => r.Intervals(TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(30)));
// //// 全局重试策略:重试 3 次,每次延迟 5 秒
// //cfg.UseMessageRetry(retryConfig =>
// //{
// // retryConfig.Interval(3, TimeSpan.FromSeconds(10));
// //});
//});
//cfg.AddEntityFrameworkOutbox<IRaCISDBContext>(o =>
//{
// o.UseSqlServer();
// o.UseBusOutbox();
//});
#endregion
});
//services.AddOptions<MassTransitHostOptions>()
// .Configure(options =>
// {
// options.WaitUntilStarted = true;
// options.StartTimeout = TimeSpan.FromMinutes(1);
// options.StopTimeout = TimeSpan.FromMinutes(1);
// });
//services.AddOptions<HostOptions>()
// .Configure(options => options.ShutdownTimeout = TimeSpan.FromMinutes(1));
//services.AddHostedService<RecurringJobConfigurationService>();
#endregion
}
}
}
@@ -2,7 +2,6 @@
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using StackExchange.Redis;
using System;
using System.Globalization;
@@ -14,9 +13,9 @@ namespace IRaCIS.Core.API
public class JSONTimeZoneConverter(IHttpContextAccessor _httpContextAccessor) : DateTimeConverterBase
{
private TimeZoneInfo _clientTimeZone;
private TimeZoneInfo _clientTimeZone;
private string _dateFormat;
private string _dateFormat;
@@ -59,7 +58,7 @@ namespace IRaCIS.Core.API
// 仅支持 DateTime 类型的转换
return objectType == typeof(DateTime)|| objectType == typeof(DateTime?);
return objectType == typeof(DateTime) || objectType == typeof(DateTime?);
}
@@ -93,20 +92,20 @@ namespace IRaCIS.Core.API
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)
@@ -121,8 +120,79 @@ namespace IRaCIS.Core.API
else
{
writer.WriteNull();
}
}
}
}
#region
public class MyDateTimeConverter : JsonConverter<DateTime>
{
public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return reader.ReadAsDateTime().Value;
}
public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
{
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
string dateFormat;
if (!isEn_US)
{
// Chinese date format
dateFormat = "yyyy-MM-dd HH:mm:ss";
}
else
{
// Default or English date format
dateFormat = "MM/dd/yyyy HH:mm:ss";
}
writer.WriteValue(value.ToString(dateFormat));
}
}
public class MyNullableDateTimeConverter : JsonConverter<DateTime?>
{
public override DateTime? ReadJson(JsonReader reader, Type objectType, DateTime? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
var val = reader.ReadAsDateTime();
return val;
}
public override void WriteJson(JsonWriter writer, DateTime? value, JsonSerializer serializer)
{
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
string dateFormat;
if (!isEn_US)
{
// Chinese date format
dateFormat = "yyyy-MM-dd HH:mm:ss";
}
else
{
// Default or English date format
dateFormat = "MM/dd/yyyy HH:mm:ss";
}
if (value.HasValue)
{
writer.WriteValue(value.Value.ToString(dateFormat));
}
else
{
writer.WriteValue(default(DateTime?));
}
}
}
#endregion
}
@@ -1,99 +0,0 @@
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Globalization;
using System.Reflection;
namespace IRaCIS.Core.API
{
//public class CustomContractResolver : DefaultContractResolver
//{
// protected override JsonContract CreateContract(Type objectType)
// {
// var contract = base.CreateContract(objectType);
// // 检查类是否有 LowercaseJsonAttribute 标记
// if (objectType.GetCustomAttribute<LowerCamelCaseJsonAttribute>() != null)
// {
// contract.NamingStrategy = new IRCCamelCaseNamingStrategy();
// }
// return contract;
// }
//}
#region
public class MyDateTimeConverter : JsonConverter<DateTime>
{
public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return reader.ReadAsDateTime().Value;
}
public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
{
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
string dateFormat;
if (!isEn_US)
{
// Chinese date format
dateFormat = "yyyy-MM-dd HH:mm:ss";
}
else
{
// Default or English date format
dateFormat = "MM/dd/yyyy HH:mm:ss";
}
writer.WriteValue(value.ToString(dateFormat));
}
}
public class MyNullableDateTimeConverter : JsonConverter<DateTime?>
{
public override DateTime? ReadJson(JsonReader reader, Type objectType, DateTime? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
var val = reader.ReadAsDateTime();
return val;
}
public override void WriteJson(JsonWriter writer, DateTime? value, JsonSerializer serializer)
{
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
string dateFormat;
if (!isEn_US)
{
// Chinese date format
dateFormat = "yyyy-MM-dd HH:mm:ss";
}
else
{
// Default or English date format
dateFormat = "MM/dd/yyyy HH:mm:ss";
}
if (value.HasValue)
{
writer.WriteValue(value.Value.ToString(dateFormat));
}
else
{
writer.WriteValue(default(DateTime?));
}
}
}
#endregion
}
@@ -1,16 +1,9 @@
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Globalization;
using System.Text.Json;
using Newtonsoft.Json.Serialization;
namespace IRaCIS.Core.API
{
@@ -29,13 +22,6 @@ namespace IRaCIS.Core.API
builder.AddNewtonsoftJson(options =>
{
//大驼峰
//options.SerializerSettings.ContractResolver = new DefaultContractResolver();
//小驼峰
//options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
// 忽略循环引用
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
@@ -47,10 +33,18 @@ namespace IRaCIS.Core.API
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
#region
//大驼峰
//options.SerializerSettings.ContractResolver = new DefaultContractResolver();
//小驼峰
//options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
//二者只能取其一
//options.SerializerSettings.Converters.Add(new MyDateTimeConverter());
//options.SerializerSettings.Converters.Add(new MyNullableDateTimeConverter());
#endregion
//必须放在后面
options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService<JSONTimeZoneConverter>());
@@ -62,6 +56,7 @@ namespace IRaCIS.Core.API
{
o.SuppressModelStateInvalidFilter = true; //自己写验证
#region
////这里是自定义验证结果和返回状态码 因为这里是在[ApiController]控制器层校验,动态webApi的不会校验 所以需要单独写一个Filter
//o.InvalidModelStateResponseFactory = (context) =>
//{
@@ -72,7 +67,7 @@ namespace IRaCIS.Core.API
//return new JsonResult(ResponseOutput.NotOk("The inputs supplied to the API are invalid. " + JsonConvert.SerializeObject( error)));
//};
#endregion
});
@@ -8,34 +8,18 @@ using System.Reflection;
namespace IRaCIS.Core.API
{
/// <summary>
/// LowerCamelCaseJsonAttribute 可以设置类小写返回给前端
/// </summary>
public class NullToEmptyStringResolver : DefaultContractResolver
{
/// <summary>
/// 创建属性
/// </summary>
/// <param name="type">类型</param>
/// <param name="memberSerialization">序列化成员</param>
/// <returns></returns>
//protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
//{
// IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
// foreach (var jsonProperty in properties)
// {
// jsonProperty.DefaultValue = new NullToEmptyStringValueProvider(jsonProperty);
// }
// return properties;
//}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
// 检查类是否有 LowerCamelCaseJsonAttribute 标记 有的话,属性名小写
if (type.GetCustomAttribute<LowerCamelCaseJsonAttribute>() != null)
{
base.NamingStrategy= new LowerCamelCaseNamingStrategy();
base.NamingStrategy = new LowerCamelCaseNamingStrategy();
}
else
{
@@ -46,7 +30,7 @@ namespace IRaCIS.Core.API
IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
var list= type.GetProperties()
var list = type.GetProperties()
.Select(p =>
{
var jp = base.CreateProperty(p, memberSerialization);
@@ -57,12 +41,45 @@ namespace IRaCIS.Core.API
var uu = list.Select(t => t.PropertyName).ToList();
//获取复杂对象属性
properties = properties.TakeWhile(t => !uu.Contains(t.PropertyName)).ToList();
properties = properties.TakeWhile(t => !uu.Contains(t.PropertyName)).ToList();
list.AddRange(properties);
return list;
list.AddRange(properties);
return list;
}
}
public class NullToEmptyStringValueProvider : IValueProvider
{
PropertyInfo _MemberInfo;
public NullToEmptyStringValueProvider(PropertyInfo memberInfo)
{
_MemberInfo = memberInfo;
}
public object GetValue(object target)
{
object result = _MemberInfo.GetValue(target);
if (_MemberInfo.PropertyType == typeof(string) && result == null) result = "";
else if (_MemberInfo.PropertyType == typeof(String[]) && result == null) result = new string[] { };
//else if (_MemberInfo.PropertyType == typeof(Nullable<Int32>) && result == null) result = 0;
//else if (_MemberInfo.PropertyType == typeof(Nullable<Decimal>) && result == null) result = 0.00M;
return result;
}
public void SetValue(object target, object value)
{
if (_MemberInfo.PropertyType == typeof(string))
{
//去掉前后空格
_MemberInfo.SetValue(target, value == null ? string.Empty : value.ToString() == string.Empty ? value : value/*.ToString().Trim()*/);
}
else
{
_MemberInfo.SetValue(target, value);
}
}
}
}
@@ -1,42 +0,0 @@
using System;
using System.Reflection;
using Newtonsoft.Json.Serialization;
namespace IRaCIS.Core.API
{
public class NullToEmptyStringValueProvider : IValueProvider
{
PropertyInfo _MemberInfo;
public NullToEmptyStringValueProvider(PropertyInfo memberInfo)
{
_MemberInfo = memberInfo;
}
public object GetValue(object target)
{
object result = _MemberInfo.GetValue(target);
if (_MemberInfo.PropertyType == typeof(string) && result == null) result = "";
else if (_MemberInfo.PropertyType == typeof(String[]) && result == null) result = new string[] { };
//else if (_MemberInfo.PropertyType == typeof(Nullable<Int32>) && result == null) result = 0;
else if (_MemberInfo.PropertyType == typeof(Nullable<Decimal>) && result == null) result = 0.00M;
return result;
}
public void SetValue(object target, object value)
{
if(_MemberInfo.PropertyType == typeof(string))
{
//去掉前后空格
_MemberInfo.SetValue(target, value==null?string.Empty: value.ToString()==string.Empty? value:value/*.ToString().Trim()*/);
}
else
{
_MemberInfo.SetValue(target, value);
}
}
}
}
@@ -1,8 +1,5 @@
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;
@@ -14,7 +11,7 @@ namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson
private readonly IOSSService _oSSService;
// 构造函数
public ObjectStorePathConvert( IOSSService oSSService)
public ObjectStorePathConvert(IOSSService oSSService)
{
_oSSService = oSSService;
}
@@ -41,9 +38,9 @@ namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson
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))
if (propertyName.IndexOf("Path") > -1 && value.IndexOf('.') > -1 && guidRegex.IsMatch(value))
{
var tt= _oSSService.GetSignedUrl(value);
var tt = _oSSService.GetSignedUrl(value);
writer.WriteValue(tt);
}
else
@@ -51,13 +48,13 @@ namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson
// 将处理后的字符串写入到 JsonWriter 中
writer.WriteValue(value);
}
}
else
{
writer.WriteNull();
}
}
}
}
@@ -1,29 +0,0 @@
using Microsoft.AspNetCore.Http;
using Serilog;
using Serilog.Configuration;
using Serilog.Core;
using Serilog.Events;
using System;
namespace IRaCIS.Core.API
{
public static class EnricherExtensions
{
public static LoggerConfiguration WithHttpContextInfo(this LoggerEnrichmentConfiguration enrich, IServiceProvider serviceProvider)
{
if (enrich == null)
throw new ArgumentNullException(nameof(enrich));
return enrich.With(new HttpContextEnricher(serviceProvider));
}
public static LoggerConfiguration WithHttpContextInfo(this LoggerEnrichmentConfiguration enrich, IServiceProvider serviceProvider, Action<LogEvent, ILogEventPropertyFactory, HttpContext> enrichAction)
{
if (enrich == null)
throw new ArgumentNullException(nameof(enrich));
return enrich.With(new HttpContextEnricher(serviceProvider, enrichAction));
}
}
}
@@ -1,89 +0,0 @@
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Serilog.Core;
using Serilog.Events;
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.API
{
public class HttpContextEnricher : ILogEventEnricher
{
private readonly IServiceProvider _serviceProvider;
private readonly Action<LogEvent, ILogEventPropertyFactory, HttpContext> _enrichAction;
public HttpContextEnricher(IServiceProvider serviceProvider) : this(serviceProvider, null)
{ }
public HttpContextEnricher(IServiceProvider serviceProvider, Action<LogEvent, ILogEventPropertyFactory, HttpContext> enrichAction)
{
_serviceProvider = serviceProvider;
if (enrichAction == null)
{
_enrichAction = (logEvent, propertyFactory, httpContext) =>
{
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestIP", httpContext.Connection.RemoteIpAddress.ToString()));
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("LocalIP", httpContext.Connection.LocalIpAddress.MapToIPv4().ToString()));
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("TokenUserRealName", httpContext?.User?.FindFirst(ClaimAttributes.RealName)?.Value));
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("TokenUserType", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value));
//这样读取没用
//logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestBody", await ReadRequestBody(httpContext.Request)));
//logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestIP", IPHelper.GetIP(httpContext.Request) ));
//logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Referer", httpContext.Request.Headers["Referer"].ToString()));
//logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("request_path", httpContext.Request.Path));
//logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("request_method", httpContext.Request.Method));
//if (httpContext.Response.HasStarted)
//{
// logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("response_status", httpContext.Response.StatusCode));
//}
};
}
else
{
_enrichAction = enrichAction;
}
}
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
var httpContext = _serviceProvider.GetService<IHttpContextAccessor>()?.HttpContext;
if (null != httpContext)
{
_enrichAction.Invoke(logEvent, propertyFactory, httpContext);
}
}
private async Task<string> ReadRequestBody(HttpRequest request)
{
// Ensure the request's body can be read multiple times (for the next middlewares in the pipeline).
request.EnableBuffering();
using var streamReader = new StreamReader(request.Body, leaveOpen: true);
var requestBody = await streamReader.ReadToEndAsync();
// Reset the request's body stream position for next middleware in the pipeline.
request.Body.Position = 0;
return requestBody==null?String.Empty: requestBody.Trim();
}
private async Task<string> ReadResponseBody(HttpResponse response)
{
response.Body.Seek(0, SeekOrigin.Begin);
string responseBody = await new StreamReader(response.Body).ReadToEndAsync();
response.Body.Seek(0, SeekOrigin.Begin);
return $"{responseBody}";
}
}
}
@@ -1,55 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Serilog;
using Serilog.Events;
//using Serilog.Sinks.Email;
using System;
using System.Net;
namespace IRaCIS.Core.API
{
public class SerilogExtension
{
public static void AddSerilogSetup(string environment, IServiceProvider serviceProvider)
{
var config = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
// 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)
.Enrich.WithClientIp()
.Enrich.FromLogContext()
.Filter.ByExcluding(logEvent =>logEvent.Properties.ContainsKey("RequestPath") && logEvent.Properties["RequestPath"].ToString().Contains("/health"))
//控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning,
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}")
.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day,
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}");
//.WriteTo.MSSqlServer("Data Source=DESKTOP-4TU9A6M;Initial Catalog=CoreFrame;User ID=sa;Password=123456", "logs", autoCreateSqlTable: true, restrictedToMinimumLevel: LogEventLevel.Information)//从左至右四个参数分别是数据库连接字符串、表名、如果表不存在是否创建、最低等级。Serilog会默认创建一些列。
//if (environment == "Production")
//{
// config.WriteTo.Email(new EmailConnectionInfo()
// {
// EmailSubject = "系统警告,请速速查看!",//邮件标题
// FromEmail = "test@extimaging.com",//发件人邮箱
// MailServer = "smtp.qiye.aliyun.com",//smtp服务器地址
// NetworkCredentials = new NetworkCredential("test@extimaging.com", "SHzyyl2021"),//两个参数分别是发件人邮箱与客户端授权码
// Port = 465,//端口号
// ToEmail = "872297557@qq.com"//收件人
// }, restrictedToMinimumLevel: LogEventLevel.Error,
// outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [ {Level} {ClientIp} {ClientAgent} {TokenUserRealName} {TokenUserType} ] || [path: {RequestPath} arguments: {RequestBody}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine})");
//}
//扩展方法 获取上下文的ip 用户名 用户类型
Log.Logger = config.Enrich.WithHttpContextInfo(serviceProvider).CreateLogger();
}
}
}
@@ -0,0 +1,79 @@
using Amazon.SecurityToken.Model;
using DocumentFormat.OpenXml.Bibliography;
using IRaCIS.Core.Domain.Share;
using Microsoft.Extensions.Configuration.Json;
using Microsoft.Extensions.Configuration;
using Serilog;
using Serilog.Events;
using Serilog.Formatting.Compact;
using Serilog.Formatting.Display;
using System;
using System.Collections.Generic;
using System.Net;
namespace IRaCIS.Core.API
{
public class SerilogExtension
{
public static void AddSerilogSetup(string environment)
{
var config = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.MinimumLevel.Override("MassTransit", LogEventLevel.Warning)
//https://github.com/ZiggyCreatures/FusionCache/blob/main/docs/Logging.md
.MinimumLevel.Override("ZiggyCreatures.Caching.Fusion", LogEventLevel.Warning)
// Filter out ASP.NET Core infrastructre logs that are Information and below 日志太多了 一个请求 记录好几条
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Hosting", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Routing", LogEventLevel.Warning)
.MinimumLevel.Override("Hangfire", LogEventLevel.Warning)
.Enrich.FromLogContext()
.Filter.ByExcluding(logEvent => logEvent.Properties.ContainsKey("RequestPath") && logEvent.Properties["RequestPath"].ToString().Contains("/health"))
.WriteTo.Console()
.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day);
#region
//读取配置文件
var configuration = new ConfigurationBuilder().Add(new JsonConfigurationSource { Path = $"appsettings.{environment}.json", ReloadOnChange = true }).Build();
// 手动绑定配置
var emailConfig = new SystemEmailSendConfig();
configuration.GetSection("SystemEmailSendConfig").Bind(emailConfig);
if (emailConfig.IsOpenErrorNoticeEmail)
{
config.WriteTo.Email(options: new Serilog.Sinks.Email.EmailSinkOptions()
{
From = emailConfig.FromEmail,
To = emailConfig.ErrorNoticeEmailList,
Host = emailConfig.Host,
Port = emailConfig.Port,
Subject = new MessageTemplateTextFormatter("Log Alert - 系统发生了异常,请核查"),
Credentials = new NetworkCredential(emailConfig.FromEmail, emailConfig.AuthorizationCode)
}, restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Error);
}
#endregion
Log.Logger = config.CreateLogger();
#region -Json格式的日志
//如果有反向代理并不会获取到用户的真实IP
//.Enrich.WithClientIp()
//.Enrich.WithRequestHeader("User-Agent")
//https://github.com/serilog/serilog-formatting-compact
//// 控制台输出 JSON 格式
//.WriteTo.Console(formatter: new CompactJsonFormatter(), LogEventLevel.Warning),
//// 文件输出 JSON 格式
//.WriteTo.File(new CompactJsonFormatter(), $"{AppContext.BaseDirectory}Serilogs/.json", rollingInterval: RollingInterval.Day);
#endregion
}
}
}
@@ -0,0 +1,137 @@
using IP2Region.Net.Abstractions;
using IP2Region.Net.XDB;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.BackGroundJob;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Panda.DynamicWebApi;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
namespace IRaCIS.Core.API;
public static class ServiceCollectionSetup
{
public static void ConfigureServices(this IServiceCollection services, IConfiguration _configuration)
{
services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig"));
services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
services.AddOptions().Configure<IRCEncreptOption>(_configuration.GetSection("EncrypteResponseConfig"));
services.AddOptions().Configure<SystemPacsConfig>(_configuration.GetSection("SystemPacsConfig"));
services.Configure<IRaCISBasicConfigOption>(_configuration.GetSection("IRaCISBasicConfig"));
services.Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
//转发头设置 获取真实IP
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
services.AddSingleton<ISearcher>(new Searcher(CachePolicy.Content, Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, "ip2region.xdb")));
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
services.AddScoped<IRepository, Repository>();
services.AddScoped<IObtainTaskAutoCancelJob, ObtainTaskAutoCancelJob>();
// 注册以Service 结尾的服务
services.Scan(scan => scan
.FromAssemblies(typeof(BaseService).Assembly)
.AddClasses(classes => classes.Where(t => t.Name.Contains("Service")))
.AsImplementedInterfaces()
.WithScopedLifetime());
#region Register Controllers
// Register all controllers in the assembly that implement IDynamicWebApi
services.Scan(scan => scan
.FromAssemblies(typeof(BaseService).Assembly)
.AddClasses(classes => classes.AssignableTo<IDynamicWebApi>())
.AsSelf()
.WithScopedLifetime());
#endregion
// MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系
//builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<ConsistencyVerificationHandler>());
#region
//builder.Services.AddMemoryCache();
////上传限制 配置
//builder.Services.Configure<FormOptions>(options =>
//{
// options.MultipartBodyLengthLimit = int.MaxValue;
// options.ValueCountLimit = int.MaxValue;
// options.ValueLengthLimit = int.MaxValue;
//});
//IP 限流 可设置白名单 或者黑名单
//services.AddIpPolicyRateLimitSetup(_configuration);
// 用户类型 策略授权
//services.AddAuthorizationPolicySetup(_configuration);
#endregion
}
}
#region Autofac
//public class AutofacModuleSetup : Autofac.Module
//{
// protected override void Load(ContainerBuilder containerBuilder)
// {
// #region byzhouhang 20210917 此处注册泛型仓储 可以减少Domain层 和Infra.EFcore 两层 空的仓储接口定义和 仓储文件定义
// containerBuilder.RegisterGeneric(typeof(Repository<>))
// .As(typeof(IRepository<>)).InstancePerLifetimeScope();//注册泛型仓储
// containerBuilder.RegisterType<Repository>().As<IRepository>().InstancePerLifetimeScope();
// #endregion
// #region 指定控制器也由autofac 来进行实例获取 https://www.cnblogs.com/xwhqwer/p/15320838.html
// //获取所有控制器类型并使用属性注入
// containerBuilder.RegisterAssemblyTypes(typeof(BaseService).Assembly)
// .Where(type => typeof(IDynamicWebApi).IsAssignableFrom(type))
// .PropertiesAutowired();
// #endregion
// Assembly application = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "IRaCIS.Core.Application.dll");
// containerBuilder.RegisterAssemblyTypes(application).Where(t => t.FullName.Contains("Service"))
// .PropertiesAutowired().AsImplementedInterfaces();
// //containerBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
// //containerBuilder.RegisterType<UserInfo>().As<IUserInfo>().InstancePerLifetimeScope();
// //注册hangfire任务 依赖注入
// containerBuilder.RegisterType<ObtainTaskAutoCancelJob>().As<IObtainTaskAutoCancelJob>().InstancePerDependency();
// }
//}
#endregion
@@ -1,18 +0,0 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
namespace IRaCIS.Core.API
{
public static class StaticFileAuthorizationSetup
{
public static void AddStaticFileAuthorizationSetup(this IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
}
}
}
@@ -1,137 +0,0 @@
using IRaCIS.Core.Application.Contracts;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
namespace IRaCIS.Core.API
{
public static class SwaggerSetup
{
public static void AddSwaggerSetup(this IServiceCollection services)
{
services.AddSwaggerGen(options =>
{
//此处的Name 是控制器上分组的名称 Title是界面的大标题
//分组
options.SwaggerDoc("Reviewer", new OpenApiInfo {Title = "医生模块",Version = "Reviewer", });
options.SwaggerDoc("Trial", new OpenApiInfo { Title = "项目模块", Version = "Trial" });
options.SwaggerDoc("Enroll", new OpenApiInfo { Title = "入组模块", Version = "Enroll" });
options.SwaggerDoc("Workload", new OpenApiInfo { Title = "工作量模块", Version = "Workload" });
options.SwaggerDoc("Common", new OpenApiInfo { Title = "通用信息获取", Version = "Common" });
options.SwaggerDoc("Institution", new OpenApiInfo { Title = "机构信息模块", Version = "Institution" });
options.SwaggerDoc("Dashboard&Statistics", new OpenApiInfo { Title = "统计模块", Version = "Dashboard&Statistics" });
options.SwaggerDoc("Financial", new OpenApiInfo { Title = "财务模块", Version = "Financial" });
options.SwaggerDoc("Management", new OpenApiInfo { Title = "管理模块", Version = "Management" });
options.SwaggerDoc("Image", new OpenApiInfo { Title = "影像模块", Version = "Image" });
options.SwaggerDoc("Reading", new OpenApiInfo { Title = "读片模块", Version = "Reading" });
// 接口排序
options.OrderActionsBy(o => o.GroupName);
options.DocInclusionPredicate((docName, apiDes) =>
{
if (!apiDes.TryGetMethodInfo(out MethodInfo methodInfo)) return false;
var versions = methodInfo.DeclaringType.GetCustomAttributes(true)
.OfType<ApiExplorerSettingsAttribute>()
.Select(attr => attr.GroupName);
return versions.Any(v => v.ToString() == docName);
});
var xmlPath = Path.Combine(AppContext.BaseDirectory, "IRaCIS.Core.API.xml");//这个就是刚刚配置的xml文件名
options.IncludeXmlComments(xmlPath, true);
var xmlPath2 = Path.Combine(AppContext.BaseDirectory, "IRaCIS.Core.Application.xml");//这个就是刚刚配置的xml文件名
options.IncludeXmlComments(xmlPath2, true);
//默认的第二个参数是false,这个是controller的注释,记得修改
// 在header中添加token,传递到后台
options.OperationFilter<SecurityRequirementsOperationFilter>();
// 添加登录按钮
options.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme()
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name = "Authorization",
//In = "header",
//Type = "apiKey"
});
//// Bearer
//options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
//{
// Description = "JWT Authorization header using the Bearer scheme.",
// Name = "Authorization",
// In = ParameterLocation.Header,
// Scheme = "bearer",
// Type = SecuritySchemeType.Http,
// BearerFormat = "JWT"
//});
});
}
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(options =>
{
//此处的Name 是页面 选择文档下拉框 显示的名称
options.SwaggerEndpoint($"swagger/Reviewer/swagger.json", "医生模块");
options.SwaggerEndpoint($"swagger/Trial/swagger.json", "项目模块");
options.SwaggerEndpoint($"swagger/Enroll/swagger.json", "入组模块");
options.SwaggerEndpoint($"swagger/Workload/swagger.json", "工作量模块");
options.SwaggerEndpoint($"swagger/Dashboard&Statistics/swagger.json", "统计模块");
options.SwaggerEndpoint($"swagger/Common/swagger.json", "通用模块");
options.SwaggerEndpoint($"swagger/Financial/swagger.json", "财务模块");
options.SwaggerEndpoint($"swagger/Institution/swagger.json", "机构信息模块");
options.SwaggerEndpoint($"swagger/Management/swagger.json", "管理模块");
options.SwaggerEndpoint($"swagger/Image/swagger.json", "影像模块");
options.SwaggerEndpoint($"swagger/Reading/swagger.json", "读片模块");
//路径配置,设置为空,表示直接在根域名(localhost:8001)访问该文件,
//注意localhost:8001/swagger是访问不到的,去launchSettings.json把launchUrl去掉,如果你想换一个路径,直接写名字即可,比如直接写c.Route = "doc";
//options.RoutePrefix = string.Empty;
var data = Assembly.GetExecutingAssembly().Location;
options.IndexStream = () => Assembly.GetExecutingAssembly()
.GetManifestResourceStream("IRaCIS.Core.API.wwwroot.swagger.ui.Index.html");
options.RoutePrefix = string.Empty;
//DocExpansion设置为none可折叠所有方法
options.DocExpansion(DocExpansion.None);
//DefaultModelsExpandDepth设置为 - 1 可不显示models
options.DefaultModelsExpandDepth(-1);
// 引入静态文件添加登录功能
// 清除静态文件缓存
// options.IndexStream = () => null;
});
}
}
}
@@ -0,0 +1,134 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
namespace IRaCIS.Core.API;
public enum SwaggerVersion
{
[Description("HIR修改")]
HIR = -1,
[Description("医生模块")]
Reviewer = 1,
[Description("项目模块")]
Trial = 2,
[Description("入组模块")]
Enroll = 3,
[Description("工作量模块")]
Workload = 4,
[Description("通用信息获取")]
Common = 5,
[Description("机构信息模块")]
Institution = 6,
[Description("统计模块")]
DashboardStatistics = 7,
[Description("财务模块")]
Financial = 8,
[Description("管理模块")]
Management = 9,
[Description("影像模块")]
Image = 10,
[Description("读片模块")]
Reading = 11
};
public static class SwaggerSetup
{
public static void AddSwaggerSetup(this IServiceCollection services)
{
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options =>
{
typeof(SwaggerVersion).GetFields(BindingFlags.Public | BindingFlags.Static).ToList()
.ForEach(field =>
{
var description = field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? field.Name;
options.SwaggerDoc(field.Name, new Microsoft.OpenApi.Models.OpenApiInfo
{
Version = field.Name,
Description = $"{field.Name} API",
Title = description // 使用Description作为Title
});
});
// 接口排序
options.OrderActionsBy(o => o.GroupName);
//添加注释
var basePath = AppContext.BaseDirectory;
var xmlPath1 = Path.Combine(basePath, "IRaCIS.Core.Application.xml");
var xmlPath2 = Path.Combine(basePath, "IRaCIS.Core.API.xml");
options.IncludeXmlComments(xmlPath1, true);
options.IncludeXmlComments(xmlPath2, true);
// 在header中添加token,传递到后台
options.OperationFilter<SecurityRequirementsOperationFilter>();
// 添加登录按钮
options.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme()
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name = "Authorization",
//In = "header",
//Type = "apiKey"
});
});
}
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSwagger();
app.UseSwaggerUI(options =>
{
typeof(SwaggerVersion).GetFields(BindingFlags.Public | BindingFlags.Static).ToList()
.ForEach(field =>
{
var description = field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? field.Name;
options.SwaggerEndpoint($"swagger/{field.Name}/swagger.json", $"{description}");
});
var data = Assembly.GetExecutingAssembly().Location;
options.IndexStream = () => Assembly.GetExecutingAssembly()
.GetManifestResourceStream("IRaCIS.Core.API.wwwroot.swagger.ui.Index.html");
//路径配置,设置为空,表示直接在根域名(localhost:8001)访问该文件,
//注意localhost:8001/swagger是访问不到的,去launchSettings.json把launchUrl去掉,如果你想换一个路径,直接写名字即可,比如直接写c.Route = "doc";
options.RoutePrefix = string.Empty;
//DocExpansion设置为none可折叠所有方法
options.DocExpansion(DocExpansion.None);
//DefaultModelsExpandDepth设置为 - 1 可不显示models
options.DefaultModelsExpandDepth(-1);
// 关键一句:关闭外网校验
options.ConfigObject.ValidatorUrl = null;
});
}
}
@@ -27,18 +27,10 @@ namespace IRaCIS.Core.API
hangFireConfig.UseSqlServerStorage(hangFireConnStr, new SqlServerStorageOptions()
{
SchemaName = "dbo",
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true
});
}).UseRecommendedSerializerSettings().UseSimpleAssemblyNameTypeSerializer();
}
//hangFireConfig.UseTagsWithSql(); //nuget引入Hangfire.Tags.SqlServer
//.UseHangfireHttpJob();
@@ -46,6 +38,8 @@ namespace IRaCIS.Core.API
services.AddHangfireServer(option =>
{
//默认15s检查一次
option.SchedulePollingInterval = TimeSpan.FromSeconds(5);
option.Queues = new[] { "immediately_once", "default", "sys_init", "not_immediately_once" };
});
@@ -1,72 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"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": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
"BucketName": "zy-irc-store",
"ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"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,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "uat@extimaging.com",
"FromName": "UAT_IRC",
"AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.event.extimaging.com/login",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗",
"IsEnv_US": false
}
}
+67
View File
@@ -0,0 +1,67 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "MinIO",
"MinIO": {
"EndPoint": "hir-oss.tres.extimaging.com",
"Port": "443",
"UseSSL": true,
"AccessKeyId": "fbStsVYCIPKHQneeqMwD",
"SecretAccessKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"BucketName": "hir-images",
"ViewEndpoint": "https://hir-oss.tres.extimaging.com/hir-images"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=mssql,1433;Database=HIR_Prod;User ID=sa;Password=xc_123456;TrustServerCertificate=true",
"Hangfire": "Server=mssql,1433;Database=HIR_Prod_Hangfire;User ID=sa;Password=xc_123456;TrustServerCertificate=true"
},
"BasicSystemConfig": {
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 120,
"AESKey": "HIR_System_AES_Key_Info",
"CmoveIntervalMinutes": 1,
"CmoveInstanceIntervalMinutes": 1,
// 是否强制用户定期修改密码
"IsNeedChangePassWord": true,
// 密码有效期(天),到期后必须修改
"ChangePassWordDays": 1000,
"OpenImageShare": true
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "test@extimaging.com",
"FromName": "BCTOP",
"AuthorizationCode": "SHzyyl2021",
"SiteUrl": "https://bctop.tres.extimaging.com/login",
"CompanyName": "BCTOP",
"CompanyNameCN": "BCTOP",
"CompanyShortName": "BCTOP",
"CompanyShortNameCN": "BCTOP",
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
},
"DicomSCPServiceConfig": {
"IsSupportThirdService": true,
"ThirdSearchPacsAE": "XCPACS",
"ThirdCallningAE": "LYAE",
"CalledAEList": [
"HIRSCUAE",
"HIRSCPAE"
],
"ServerPort": 11112
}
}
-79
View File
@@ -1,79 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
//"RemoteNew": "Server=101.132.193.237,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
//"Hangfire": "Server=101.132.193.237,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
"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",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH",
"AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH",
"RoleArn": "acs:ram::1899121822495495:role/irc-oss-access",
"BucketName": "zy-irc-store",
"ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"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": 360,
"OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "IRC@extimaging.com",
"FromName": "IRC",
"AuthorizationCode": "ExtImg@2022",
"SiteUrl": "http://irc.extimaging.com/login",
"OrganizationName": "Extlmaging",
"OrganizationNameCN": "Extlmaging",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗",
"IsEnv_US": false
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "101.132.193.237"
}
}
@@ -0,0 +1,62 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "MinIO",
"MinIO": {
"EndPoint": "192.168.40.99",
"Port": "9000",
"UseSSL": false,
"AccessKeyId": "Jnywl9aIw83yewZIJKod",
"SecretAccessKey": "N83bTzoJGkg4OLW8x54IZRwwSvdxcdYi9UZ2BYII",
"BucketName": "tj-hir",
"ViewEndpoint": "http://192.168.40.99:9000/tj-hir"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=192.168.40.98,1433;Database=TJ_Prod_HIR;User ID=sa;Password=xc_123456;TrustServerCertificate=true",
"Hangfire": "Server=192.168.40.98,1433;Database=TJ_Prod_HIR_Hangfire;User ID=sa;Password=xc_123456;TrustServerCertificate=true"
},
"BasicSystemConfig": {
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": false,
"OpenTrialRelationDelete": false,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 120,
"AESKey": "HIR_System_AES_Key_Info",
"CmoveIntervalMinutes": 1,
"CmoveInstanceIntervalMinutes": 1
},
"SystemHospitalConfig": {
"HospitalCode": "EI",
"HospitalLogoPath": "/System/GeneralDocuments/1716453306898_图片2.png",
"TrialKeepCount": 60,
"HospitalName": "上海展影医疗科技有限公司",
"HospitalAliasName": "展影医疗",
"Country": "中国",
"City": "上海",
"Province": "上海",
"Address": "上海市杨浦区国泰路复旦科技园",
"Phone": "021-60702575",
"IsCanConnectInternet": false
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "test-study@extimaging.com",
"FromName": "Test_HIR",
"AuthorizationCode": "zhanying123",
"SiteUrl": "http://hir.test.extimaging.com/login"
}
}
+71
View File
@@ -0,0 +1,71 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "MinIO",
"MinIO": {
"EndPoint": "hir-oss.test.extimaging.com",
"Port": "443",
"UseSSL": true,
//"endPoint": "106.14.89.110",
//"port": "9001",
//"useSSL": false,
"AccessKeyId": "fbStsVYCIPKHQneeqMwD",
"SecretAccessKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"BucketName": "hir-test",
//"viewEndpoint": "https://hir.test.extimaging.com/oss/hir-test"
"ViewEndpoint": "https://hir-oss.test.extimaging.com/hir-test"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_HIR_New;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=106.14.89.110,1435;Database=Test_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"BasicSystemConfig": {
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 120,
"AESKey": "HIR_System_AES_Key_Info",
"CmoveIntervalMinutes": 1,
"CmoveInstanceIntervalMinutes": 1,
// 是否强制用户定期修改密码
"IsNeedChangePassWord": true,
// 密码有效期(天),到期后必须修改
"ChangePassWordDays": 1000,
"OpenImageShare": true
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "test-study@extimaging.com",
"FromName": "Test_HIR",
"AuthorizationCode": "zhanying123",
"SiteUrl": "http://hir.test.extimaging.com/login",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗",
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
},
"DicomSCPServiceConfig": {
"IsSupportThirdService": true,
"ThirdSearchPacsAE": "XCPACS",
"ThirdCallningAE": "LYAE",
"CalledAEList": [
"HIRSCUAE",
"HIRSCPAE"
],
"ServerPort": 11112
}
}
+6 -2
View File
@@ -72,7 +72,9 @@
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
"ChangePassWordDays": 90,
"ThirdPdfUrl": "http://106.14.89.110:30088/api/v1/convert/file/pdf"
},
"SystemEmailSendConfig": {
@@ -89,7 +91,9 @@
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗",
"IsEnv_US": false
"IsEnv_US": false,
"IsOpenErrorNoticeEmail": false,
"ErrorNoticeEmailList": ["872297557@qq.com"]
},
"SystemPacsConfig": {
@@ -1,95 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"Db_Type": "pgsql",
"RemoteNew": "Host=106.14.89.110;Port=5432;Username=sa;Password=pgsql_pwd;Database=Test2_PG",
"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",
"internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"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": "hir-oss.test.extimaging.com",
"port": "443",
"useSSL": true,
"accessKey": "fbStsVYCIPKHQneeqMwD",
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"bucketName": "irc-test",
"viewEndpoint": "https://hir-oss.test.extimaging.com/irc-test"
},
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": true,
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
"secretKey": "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",
"bucketName": "ei-irc-test-store",
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
}
},
"BasicSystemConfig": {
"OpenUserComplexPassword": false,
"OpenSignDocumentBeforeWork": false,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 1,
"AutoLoginOutMinutes": 1,
"OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "test@extimaging.com",
"FromName": "Test_IRC",
"AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.test.extimaging.com/login",
"OrganizationName": "Extlmaging",
"OrganizationNameCN": "Extlmaging",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗"
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "106.14.89.110"
}
}
+68
View File
@@ -0,0 +1,68 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "MinIO",
"MinIO": {
"EndPoint": "hir-minio.uat.elevateimaging.ai",
"Port": "443",
"UseSSL": true,
"AccessKeyId": "7rvVIHs7D6pbyscRcJhz",
"SecretAccessKey": "DQsCQldHFL3QRjlnaLWV7oM4E9PtsO21QPC2h9BD",
"BucketName": "hir-us",
//"viewEndpoint": "https://hir.test.extimaging.com/oss/hir-test"
"ViewEndpoint": "https://hir-minio.uat.elevateimaging.ai/hir-us"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=3.226.182.187,1435;Database=US_HIR;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=3.226.182.187,1435;Database=US_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"BasicSystemConfig": {
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 120,
"AESKey": "HIR_System_AES_Key_Info",
"CmoveIntervalMinutes": 1,
"CmoveInstanceIntervalMinutes": 1,
// 是否强制用户定期修改密码
"IsNeedChangePassWord": true,
// 密码有效期(天),到期后必须修改
"ChangePassWordDays": 1000,
"OpenImageShare": true
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "uat-study@extimaging.com",
"FromName": "Uat_HIR",
"AuthorizationCode": "zhanying123",
"SiteUrl": "https://hir.uat.elevateimaging.ai/login",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗",
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
},
"DicomSCPServiceConfig": {
"IsSupportThirdService": true,
"ThirdSearchPacsAE": "XCPACS",
"ThirdCallningAE": "LYAE",
"CalledAEList": [
"HIRSCUAE",
"HIRSCPAE"
],
"ServerPort": 11112
}
}
@@ -1,85 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=us-prod-mssql-service,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=us-prod-mssql-service,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
//"RemoteNew": "Server=44.210.231.169,1435;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
//"Hangfire": "Server=44.210.231.169,1435;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
},
"ObjectStoreService": {
"ObjectStoreUse": "AWS",
"MinIO": {
"endPoint": "44.210.231.169",
"port": "9001",
"useSSL": false,
"accessKey": "e9bT1isTOqSAUxb6wd4n",
"secretKey": "b5TaDzNdQCBtCvfm8eZ3dR6yY7tfZu2JYze2Po1i",
"bucketName": "prod-irc-us",
"viewEndpoint": "http://44.210.231.169:9001/prod-irc-us/"
},
"AWS": {
"Region": "us-east-1",
"EndPoint": "s3.us-east-1.amazonaws.com",
"UseSSL": true,
"RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access",
"AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM",
"SecretAccessKey": "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",
"BucketName": "ei-med-s3-lili-store",
"ViewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com",
"DurationSeconds": 7200
}
},
"BasicSystemConfig": {
"OpenUserComplexPassword": false,
"OpenSignDocumentBeforeWork": false,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
},
"SystemEmailSendConfig": {
"Port": 587,
"Host": "smtp-mail.outlook.com",
"FromEmail": "donotreply@elevateimaging.ai",
"FromName": "LiLi",
"AuthorizationCode": "Q#669869497420ul",
"OrganizationName": "Elevate Imaging",
"OrganizationNameCN": "Elevate Imaging",
"CompanyName": "Elevate Imaging Inc.",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Elevate Imaging",
"CompanyShortNameCN": "展影医疗",
"SiteUrl": "https://lili.elevateimaging.ai/login",
"IsEnv_US": true
},
"SystemPacsConfig": {
"Port": "104",
"IP": "44.210.231.169"
}
}
@@ -1,93 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"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": "AWS",
"MinIO": {
//"endPoint": "hir-oss.uat.extimaging.com",
//"port": "443",
//"useSSL": true,
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/hir-uat",
"endPoint": "47.117.164.182",
"port": "9001",
"useSSL": false,
"viewEndpoint": "http://47.117.164.182:9001/test-irc-us",
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
"bucketName": "test-irc-us"
},
"AWS": {
"Region": "us-east-1",
"EndPoint": "s3.us-east-1.amazonaws.com",
"UseSSL": true,
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
"SecretAccessKey": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
"DurationSeconds": 7200
}
},
"BasicSystemConfig": {
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90,
"OpenLoginMFA": true
},
"SystemEmailSendConfig": {
"Port": 587,
"Host": "smtp-mail.outlook.com",
"FromEmail": "donotreply@elevateimaging.ai",
"FromName": "LiLi",
"AuthorizationCode": "Q#669869497420ul",
"OrganizationName": "Elevate Imaging",
"OrganizationNameCN": "Elevate Imaging",
"CompanyName": "Elevate Imaging Inc.",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Elevate Imaging",
"CompanyShortNameCN": "展影医疗",
"SiteUrl": "https://lili.test.elevateimaging.ai/login",
"IsEnv_US": true
},
"SystemPacsConfig": {
"Port": "104",
"IP": "3.226.182.187"
}
}
@@ -1,97 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
//"RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
//"Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
"RemoteNew": "Server=3.226.182.187,1435;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=3.226.182.187,1435;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"ObjectStoreService": {
"ObjectStoreUse": "AWS",
"MinIO": {
//"endPoint": "hir-minio.uat.elevateimaging.ai",
//"port": "443",
//"useSSL": true,
//"viewEndpoint": "https://hir-minio.uat.elevateimaging.ai/uat-irc-us",
"endPoint": "3.226.182.187",
"port": "9001",
"useSSL": false,
"viewEndpoint": "http://44.218.11.19:9001/uat-irc-us",
"accessKey": "lH8DkKskLuDqPaiubuSQ",
"secretKey": "pdPdicvvLeH7xAC5yFUrI7odMyBfOXxvVWMvKYV4",
"bucketName": "uat-irc-us"
},
"AWS": {
"Region": "us-east-1",
"EndPoint": "s3.us-east-1.amazonaws.com",
"UseSSL": true,
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
"SecretAccessKey": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
"DurationSeconds": 7200
}
},
"BasicSystemConfig": {
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenTrialRelationDelete": true,
"OpenLoginLimit": false,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90,
"OpenLoginMFA": false
},
"SystemEmailSendConfig": {
"Port": 587,
"Host": "smtp-mail.outlook.com",
"FromEmail": "donotreply@elevateimaging.ai",
"FromName": "LiLi",
"AuthorizationCode": "Q#669869497420ul",
"OrganizationName": "Elevate Imaging",
"OrganizationNameCN": "Elevate Imaging",
"CompanyName": "Elevate Imaging Inc.",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Elevate Imaging",
"CompanyShortNameCN": "展影医疗",
"SiteUrl": "https://lili.test.elevateimaging.ai/login",
"IsEnv_US": true
},
"SystemPacsConfig": {
"Port": "104",
"IP": "3.226.182.187"
}
}
+69
View File
@@ -0,0 +1,69 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "MinIO",
"MinIO": {
"EndPoint": "hir-oss.uat.extimaging.com",
"Port": "443",
"UseSSL": true,
//"endPoint": "106.14.89.110",
//"port": "9001",
//"useSSL": false,
"AccessKeyId": "L6owzRVeDJJw3PcRmK2c",
"SecretAccessKey": "2XvFDYSH7EyHQNtpDCgk4efgdsdarQmRKgx1LlOI",
"BucketName": "hir-uat",
"ViewEndpoint": "https://hir-oss.uat.extimaging.com/hir-uat"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_HIR_New;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=101.132.253.119,1435;Database=Uat_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"BasicSystemConfig": {
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": false,
"OpenTrialRelationDelete": false,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 120,
"AESKey": "HIR_System_AES_Key_Info",
"CmoveIntervalMinutes": 1,
"CmoveInstanceIntervalMinutes": 1,
// 是否强制用户定期修改密码
"IsNeedChangePassWord": true,
// 密码有效期(天),到期后必须修改
"ChangePassWordDays": 1000,
"OpenImageShare": true
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "test-study@extimaging.com",
"FromName": "Test_HIR",
"AuthorizationCode": "zhanying123",
"SiteUrl": "http://hir.test.extimaging.com/login",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗",
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
},
"DicomSCPServiceConfig": {
"IsSupportThirdService": true,
"ThirdSearchPacsAE": "XCPACS",
"ThirdCallningAE": "LYAE",
"CalledAEList": [
"HIRSCUAE",
"HIRSCPAE"
],
"ServerPort": 11112
}
}
-98
View File
@@ -1,98 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"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",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
"BucketName": "zy-irc-uat-store",
"ViewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"MinIO": {
"endPoint": "hir-oss.uat.extimaging.com",
"port": "80",
"useSSL": false,
"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
//"port": "443",
//"useSSL": true,
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
"bucketName": "irc-uat"
},
"AWS": {
"Region": "us-east-1",
"EndPoint": "s3.us-east-1.amazonaws.com",
"UseSSL": true,
"RoleArn": "arn:aws:iam::471112624751:role/sts_s3_upload",
"AccessKeyId": "AKIAW3MEAFJXWRCGSX5Z",
"SecretAccessKey": "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",
"BucketName": "ei-med-s3-lili-uat-store",
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
"DurationSeconds": 7200
}
},
"BasicSystemConfig": {
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 60,
"OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"FromEmail": "uat@extimaging.com",
"FromName": "UAT_IRC",
"AuthorizationCode": "SHzyyl2021",
"SiteUrl": "http://irc.uat.extimaging.com/login",
"OrganizationName": "Extlmaging",
"OrganizationNameCN": "Extlmaging",
"CompanyName": "Extensive Imaging",
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗",
"IsEnv_US": false
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "47.117.164.182"
}
}
+9 -1
View File
@@ -3,7 +3,7 @@
"SecurityKey": "ShangHaiZhanYing_SecurityKey_SHzyyl@2021",
"Issuer": "Extimaging",
"Audience": "EICS",
"TokenExpireDays": "7"
"TokenExpireMinute": "10080" //7天
},
"IpRateLimiting": {
"EnableEndpointRateLimiting": true,
@@ -66,5 +66,13 @@
"ApiPathList": [
"/test/get"
]
},
"oauth": {
"github": {
"app_id": "github_app_id",
"app_key": "github_app_key",
"redirect_uri": "https://oauthlogin.net/oauth/githubcallback",
"scope": "repo"
}
}
}

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