Compare commits

...

139 Commits

Author SHA1 Message Date
hang 8580c64ef7 非dicom bodyPart 修改 2025-11-24 15:24:25 +08:00
hang 64c657d233 修改检查部位bug 2025-11-24 14:35:47 +08:00
hang 73b7aae6c0 提交后允许删除检查特殊逻辑修改
continuous-integration/drone/push Build is passing Details
2025-11-13 16:25:54 +08:00
he 14e212c4a8 覆盖TrialImageDownloadService
continuous-integration/drone/push Build is passing Details
2025-10-16 13:33:42 +08:00
he 344146a46e 验证修改
continuous-integration/drone/push Build is failing Details
2025-10-16 13:24:25 +08:00
he cd5a1fcbb7 修改 2025-10-16 13:24:03 +08:00
he 424448db2f 添加表格预设 2025-10-16 13:23:46 +08:00
he 629116cb6a 合并
continuous-integration/drone/push Build is failing Details
2025-10-16 13:20:01 +08:00
hang 64c3d96807 修改维护统计数字问题
continuous-integration/drone/push Build is passing Details
2025-09-23 09:37:26 +08:00
hang d607018832 数据库存在脏数据,导致归档失败
continuous-integration/drone/push Build is passing Details
2025-09-22 16:04:07 +08:00
hang 0d65625caa 修改维护数据代码-3测试
continuous-integration/drone/push Build is passing Details
2025-09-22 15:41:34 +08:00
hang 2b82044213 修改维护数据代码-2
continuous-integration/drone/push Build is passing Details
2025-09-22 14:49:51 +08:00
hang 2769cf7efd 修改请求方式
continuous-integration/drone/push Build is passing Details
2025-09-18 17:24:25 +08:00
hang 1c84a374a1 参数必填限制
continuous-integration/drone/push Build is passing Details
2025-09-18 17:22:09 +08:00
hang 2a59cfe3b5 修改实际恢复情况
continuous-integration/drone/push Build is passing Details
2025-09-18 13:44:44 +08:00
hang 0dff3d6e4b 记录重复修改
continuous-integration/drone/push Build is passing Details
2025-09-18 13:17:18 +08:00
hang 1d6731e3a4 设置文件大小
continuous-integration/drone/push Build is passing Details
2025-09-18 08:58:14 +08:00
hang 224318e0c4 配置文件修改
continuous-integration/drone/push Build is passing Details
2025-09-17 17:08:30 +08:00
hang 7096062d76 增加日志测试
continuous-integration/drone/push Build is passing Details
2025-09-17 17:05:40 +08:00
hang a0b06fbc28 修改维护数据
continuous-integration/drone/push Build is passing Details
2025-09-17 16:44:00 +08:00
hang 4a76705ec7 Uat 分支维护数据提交
continuous-integration/drone/push Build is passing Details
2025-09-17 16:02:29 +08:00
hang 7676e3cc4d 维护数据第二次提交
continuous-integration/drone/push Build is passing Details
2025-09-16 10:18:16 +08:00
hang 234a5706a8 下载删除标记方法提交
continuous-integration/drone/push Build is passing Details
2025-09-15 17:49:12 +08:00
he 956e214632 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-08-18 11:44:27 +08:00
he 974adb4367 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-08-15 13:18:39 +08:00
he 00189b992f 修改稽查 2025-08-15 13:18:37 +08:00
hang f192219621 合并问题
continuous-integration/drone/push Build is passing Details
2025-08-07 11:37:24 +08:00
hang 4b0d6fe8b9 Test 合并到Uat 冲突解决
continuous-integration/drone/push Build is failing Details
2025-08-07 11:30:37 +08:00
hang bb6dc19924 更新里面有添加bug
continuous-integration/drone/push Build is passing Details
2025-07-29 15:21:18 +08:00
hang ec9af97742 初审通过bug 修改
continuous-integration/drone/push Build is passing Details
2025-07-29 09:07:55 +08:00
hang a5472e1509 取tag 做判断
continuous-integration/drone/push Build is passing Details
2025-07-25 10:30:31 +08:00
hang a1bb730cfe Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-07-23 15:00:27 +08:00
hang 1aa411c0f8 下一个任务不会跳复核任务 2025-07-23 15:00:25 +08:00
he 10de82132d Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-07-23 13:34:56 +08:00
he db11656862 邮件修改 区分CRC与CRA 2025-07-23 13:34:54 +08:00
hang a47ac76729 复核指派bug修改
continuous-integration/drone/push Build is passing Details
2025-07-22 15:29:09 +08:00
hang f86a88332c 复核稽查修改016
continuous-integration/drone/push Build is passing Details
2025-07-18 13:15:23 +08:00
hang f6be5e4355 复核稽查修改015
continuous-integration/drone/push Build is failing Details
2025-07-18 13:04:58 +08:00
hang 8deeb0290a 复核稽查修改014
continuous-integration/drone/push Build is failing Details
2025-07-18 12:17:55 +08:00
hang fb6231373b 复核稽查修改013
continuous-integration/drone/push Build is passing Details
2025-07-18 11:34:13 +08:00
hang a407313a95 复核稽查修改012
continuous-integration/drone/push Build is passing Details
2025-07-18 09:25:56 +08:00
hang b1806d2eff 复核稽查修改011
continuous-integration/drone/push Build is passing Details
2025-07-17 17:25:45 +08:00
hang 19351f34e1 复核稽查修改010
continuous-integration/drone/push Build is passing Details
2025-07-17 17:10:06 +08:00
hang e0f708082d 复核稽查修改009
continuous-integration/drone/push Build is passing Details
2025-07-17 16:49:20 +08:00
hang 44464a809d 复核稽查修改008
continuous-integration/drone/push Build is passing Details
2025-07-17 15:26:28 +08:00
hang c7c01b7ba3 复核稽查修改007
continuous-integration/drone/push Build is passing Details
2025-07-17 15:08:11 +08:00
hang 38b71d5267 复核稽查修改006
continuous-integration/drone/push Build is passing Details
2025-07-17 14:00:03 +08:00
hang 3950a3453a 复核稽查修改005
continuous-integration/drone/push Build is passing Details
2025-07-17 13:26:44 +08:00
hang 7aa59da586 复核稽查修改004
continuous-integration/drone/push Build is passing Details
2025-07-17 11:51:41 +08:00
hang 9b2fbdb13f 复核稽查修改003
continuous-integration/drone/push Build is passing Details
2025-07-17 11:28:47 +08:00
hang c98b9e1bd4 复核稽查修改002
continuous-integration/drone/push Build is passing Details
2025-07-17 11:08:02 +08:00
hang 9522461508 复核稽查修改
continuous-integration/drone/push Build is passing Details
2025-07-17 10:34:15 +08:00
hang 5bb99180b6 修改复核-退回-003
continuous-integration/drone/push Build is passing Details
2025-07-16 17:59:42 +08:00
hang 62ec1e4955 修改复核查询接口-002
continuous-integration/drone/push Build is passing Details
2025-07-16 17:34:09 +08:00
hang 58e1af24c9 修改复核查询接口-001
continuous-integration/drone/push Build is passing Details
2025-07-16 16:30:03 +08:00
hang a7394e7119 指派其他质控-uat-13
continuous-integration/drone/push Build is passing Details
2025-07-16 10:30:55 +08:00
hang a93d81de0d 指派其他质控-uat-12 2025-07-16 10:30:51 +08:00
hang 6aafe02c6c 指派其他质控-uat-11 2025-07-16 10:30:48 +08:00
hang 1511ef1608 修改QC复核 -二次提交-uat-10 2025-07-16 10:30:43 +08:00
hang 1141439c8e 修改QC复核 -二次提交-uat-9 2025-07-16 10:30:32 +08:00
hang 559663082b 修改QC复核 -二次提交-uat-8 2025-07-16 10:26:30 +08:00
hang 3a298518f9 修改QC复核 -二次提交-uat-7 2025-07-16 10:26:25 +08:00
hang 7f20232401 修改QC复核 -二次提交-uat-6 2025-07-16 10:26:21 +08:00
hang 20b0849b40 修改QC复核 -二次提交-uat-5 2025-07-16 10:26:16 +08:00
hang db951e9195 修改QC复核 -二次提交-uat-4 2025-07-16 10:26:13 +08:00
hang d5d78a99d2 QC复核 -二次提交-uat-3 2025-07-16 10:26:08 +08:00
hang 1609a7a88a QC复核 -二次提交-uat-3 2025-07-16 10:26:03 +08:00
hang 289831fce8 QC复核 -二次提交-uat-2 2025-07-16 10:25:59 +08:00
hang dde058be18 QC 审核提交--迁移uat 2025-07-16 10:25:26 +08:00
hang be8b730ee4 返回文件大小
continuous-integration/drone/push Build is passing Details
2025-07-14 15:00:36 +08:00
hang 28360861aa 修改subject 随机阅片下载影像重阅bug
continuous-integration/drone/push Build is passing Details
2025-07-14 13:36:27 +08:00
hang 3e097fa42b uat 序列获取Instance 增加文件大小 2025-07-14 13:32:21 +08:00
hang b8a7cd6ebc 修改非dicom 设置删除,检查上的数量不变更 2025-07-14 13:32:16 +08:00
hang a9aefaf240 修改预览看到阅片影像 修改后受试者随机bug修改 4 2025-07-14 13:32:10 +08:00
hang 266a0c5dd5 修改后受试者随机bug修改 3 2025-07-14 13:32:05 +08:00
hang 54822ae038 修改后受试者随机bug修改 2 2025-07-14 13:31:07 +08:00
hang 05203d6716 受试者随机bug修改 2025-07-14 13:31:00 +08:00
hang 2ce8edde80 uat升级excel 组件测试
continuous-integration/drone/push Build is passing Details
2025-07-05 13:34:09 +08:00
hang 3c30f5dc14 完全随机跟下载关联
continuous-integration/drone/push Build is passing Details
2025-07-03 14:54:23 +08:00
hang e4ad1c0653 增加失访可读配置-uat
continuous-integration/drone/push Build is passing Details
2025-06-25 15:31:59 +08:00
he 84df49ca07 单位修改2
continuous-integration/drone/push Build is passing Details
2025-06-24 14:58:39 +08:00
he 400edd0b70 修改单位1 2025-06-24 14:58:37 +08:00
he c4add1ecc8 修改单位 2025-06-24 14:58:35 +08:00
he d5879e28d7 修改OCT计算触发逻辑
continuous-integration/drone/push Build is passing Details
2025-06-24 14:07:31 +08:00
he 37e083face 阅片标准默认值修改 2025-06-24 14:07:28 +08:00
he 290506a060 保存测量值
continuous-integration/drone/push Build is passing Details
2025-06-24 09:28:27 +08:00
he 1b4bc3690a 稽查保存Ivus和Oct 2025-06-24 09:28:25 +08:00
he 6374781d26 修改阅片期计划的排序
continuous-integration/drone/push Build is failing Details
2025-06-20 17:33:23 +08:00
he b28013a02f 阅片期计划可以选择基线 2025-06-20 17:32:07 +08:00
he fe429d2bdc 修改受试者内随机
continuous-integration/drone/push Build is passing Details
2025-06-20 09:37:48 +08:00
he d63af2ed20 修改稽查的单位翻译
continuous-integration/drone/push Build is passing Details
2025-06-19 17:16:42 +08:00
hang cebf9875b1 禁用人员系统查看文档
continuous-integration/drone/push Build is passing Details
2025-06-19 10:31:24 +08:00
hang 131681a0b3 完全随机触发系统盲态名称 2025-06-19 10:22:06 +08:00
hang f833adc710 修改有序阅片生成任务bug 2025-06-19 10:21:59 +08:00
hang df80d1e551 修改影像下载bug
continuous-integration/drone/push Build is passing Details
2025-06-18 10:36:26 +08:00
he 82dc092247 修改阅片期计划生成裁判的逻辑
continuous-integration/drone/push Build is passing Details
2025-06-17 16:42:47 +08:00
he 44894fcaa9 生成阅片期计划的时候 产生裁判
continuous-integration/drone/push Build is passing Details
2025-06-17 16:24:00 +08:00
hang 083bebdc03 真实随机阅片导表-1
continuous-integration/drone/push Build is passing Details
2025-06-17 10:06:41 +08:00
hang e808764dd6 随机阅片排序-5 2025-06-17 10:06:33 +08:00
hang 77d198cb09 随机阅片-NextTask-5 2025-06-17 10:05:55 +08:00
hang 180b02b28c 随机阅片NextTask-4 2025-06-17 10:04:26 +08:00
hang c49a74d742 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-06-17 10:02:34 +08:00
he c76fc8f052 修改阅片期选择访视下拉框的数据
continuous-integration/drone/push Build is running Details
2025-06-17 10:02:04 +08:00
he 14875dfacc 生成了裁判任务 阅片期不让删除和修改 2025-06-17 10:02:02 +08:00
hang 0a68788c0f 随机阅片序号3 2025-06-17 10:00:39 +08:00
hang b17e5d9ff3 随机阅片序号2 2025-06-17 10:00:34 +08:00
hang 05ce4b7155 随机阅片随机序号 2025-06-17 10:00:28 +08:00
he c8bbb3da48 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-06-16 15:16:20 +08:00
he 65de108ecd 添加阅片期 产生裁判 2025-06-16 15:16:19 +08:00
hang d20c306219 末次访视的展示+ 展示基线选择阅片期
continuous-integration/drone/push Build is passing Details
2025-06-16 14:50:23 +08:00
hang e69991ae37 修改重置阅片稽查3
continuous-integration/drone/push Build is passing Details
2025-06-13 09:57:33 +08:00
hang e1e2544ee3 修改阅片重置稽查 2025-06-13 09:57:30 +08:00
hang 318333bae4 修改重置阅片稽查 2025-06-13 09:57:26 +08:00
hang d569de4dfe 确认浏览临床数据
continuous-integration/drone/push Build is passing Details
2025-06-12 10:52:46 +08:00
hang 05627ff126 肿瘤学稽查修改
continuous-integration/drone/push Build is passing Details
2025-06-11 10:03:01 +08:00
hang 627618c854 增加进入阅片中稽查 2025-06-11 10:02:57 +08:00
hang 2711c5eb04 稽查 申请PM 重阅,有SPM 判断 2025-06-11 10:00:57 +08:00
hang a6982f79c3 稽查修改,区分标识 2025-06-11 10:00:53 +08:00
hang 2a542949cd 增加稽查标识 2025-06-11 10:00:49 +08:00
he a8ccbce76f 稽查添加
continuous-integration/drone/push Build is passing Details
2025-06-05 16:46:06 +08:00
he df7cf30aed 测量值可以为空
continuous-integration/drone/push Build is passing Details
2025-06-04 14:25:57 +08:00
he 0664fbdfb7 验证修改
continuous-integration/drone/push Build is passing Details
2025-06-04 09:57:08 +08:00
he 0a6ee05417 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-05-22 18:01:11 +08:00
hang f9bd8c3f5c Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-05-21 15:16:26 +08:00
he cb83c2a737 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-05-21 14:05:30 +08:00
he fdd9afd4f0 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-05-20 15:46:24 +08:00
he 53d26c0445 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-05-20 10:55:36 +08:00
he 40d035e7a7 解决合并的冲突
continuous-integration/drone/push Build is passing Details
2025-05-15 09:33:17 +08:00
he a13807ae5f 合并冲突修改
continuous-integration/drone/push Build is failing Details
2025-05-15 09:29:41 +08:00
he 9d5aaf1e26 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is failing Details
2025-05-15 09:20:22 +08:00
he c347d08e2b 合并
continuous-integration/drone/push Build is failing Details
2025-05-15 09:14:10 +08:00
hang 87f2d0e429 非dicom 删除上传
continuous-integration/drone/push Build is passing Details
2025-04-15 13:27:33 +08:00
he 89d009fcbf Revert "修改"
continuous-integration/drone/push Build is passing Details
This reverts commit 7d65cf5051.
2025-04-09 11:00:45 +08:00
he 7d65cf5051 修改
continuous-integration/drone/push Build is passing Details
2025-04-09 09:45:49 +08:00
he e74427c45c 解决冲突
continuous-integration/drone/push Build is passing Details
2025-04-08 11:05:31 +08:00
he e8825c7efa 修改查询 2025-04-08 11:04:52 +08:00
hang 628e0ad034 修改异地登录bug 设置最后一次登录的iP
continuous-integration/drone/push Build is passing Details
2025-04-03 13:55:04 +08:00
hang 2f3f639918 修改异地登录ip逻辑 2025-04-03 13:55:00 +08:00
hang 87caf24dd1 验证环境生成缩略图测试ok提交
continuous-integration/drone/push Build is passing Details
2025-04-03 13:49:34 +08:00
16 changed files with 20829 additions and 18 deletions

View File

@ -1116,6 +1116,14 @@
<param name="trialId"></param>
<returns></returns>
</member>
<!-- Badly formed XML comment ignored for member "M:IRaCIS.Core.Application.Service.TrialImageDownloadService.TrialImageAddExtralField(System.Guid,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomSeries})" -->
<member name="M:IRaCIS.Core.Application.Service.TrialImageDownloadService.DownloadDeleteTrialImage(System.Guid)">
<summary>
下载已经删除的影像
</summary>
<param name="trialId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.TrialImageDownloadService.WriteTrialNeedDealData(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},System.Guid)">
<summary>
读取该项目的数据,进行维护
@ -10546,6 +10554,11 @@
影像标记
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionTrialAddOrEdit.IsPreinstall">
<summary>
是否预设
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionTrialAddOrEdit.ImageTool">
<summary>
影像工具
@ -10689,6 +10702,11 @@
数值类型
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionSystemAddOrEdit.IsPreinstall">
<summary>
是否预设
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionSystemAddOrEdit.ClassifyType">
<summary>
分类问题类型

View File

@ -1619,7 +1619,6 @@ namespace IRaCIS.Core.Application.Service.Common
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
if (inQuery.IsRandomOrderList == true)
{
list = list.OrderBy(t => t.RandomOrder).ToList();

View File

@ -55,6 +55,8 @@ namespace IRaCIS.Core.Application.Contracts
public string Modality { get; set; } = string.Empty;
public DateTime ImageDate { get; set; }
public string ModifyReason { get; set; }
public string BodyPartForEditOther { get; set; }
}
///<summary> NoneDicomStudyAddOrEdit 列表查询参数模型</summary>

View File

@ -21,6 +21,8 @@ namespace IRaCIS.Core.Application.Contracts.DTO
public string BodyPart { get; set; } = String.Empty;
public string ModifyReason { get; set; }
public string BodyPartForEditOther { get; set; }
}

View File

@ -1050,11 +1050,15 @@ namespace IRaCIS.Core.Application.Image.QA
}
else
{
if (await _subjectVisitRepository.AnyAsync(t => t.Id == updateModalityCommand.SubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted && !t.QCChallengeList.Any(c => c.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload)))
if (!_dicomStudyRepository.Where(t => t.Id == updateModalityCommand.Id).Any(t => t.CreateTime > t.SubjectVisit.SubmitTime))
{
//---提交之后,不允许修改!
throw new BusinessValidationFailedException(_localizer["QCOperation_NoModifyAfterSubmit"]);
if (await _subjectVisitRepository.AnyAsync(t => t.Id == updateModalityCommand.SubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted && !t.QCChallengeList.Any(c => c.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload)))
{
//---提交之后,不允许修改!
throw new BusinessValidationFailedException(_localizer["QCOperation_NoModifyAfterSubmit"]);
}
}
}
@ -1128,13 +1132,19 @@ namespace IRaCIS.Core.Application.Image.QA
public async Task<IResponseOutput> DeleteStudyList(Guid[] ids, Guid subjectVisitId, Guid trialId)
{
//提交了 但是IQC同意的时候 是可以删除的 | 普通提交后也不能删除
if (await _subjectVisitRepository.AnyAsync(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.Submitted &&
(!t.QCChallengeList.Any(u => u.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload))))
if (!_dicomStudyRepository.Where(t => ids.Contains(t.Id)).All(t => t.CreateTime > t.SubjectVisit.SubmitTime))
{
//---CRC已经提交不允许删除。
return ResponseOutput.NotOk(_localizer["QCOperation_CrcNoDelete"]);
//提交了 但是IQC同意的时候 是可以删除的 | 普通提交后也不能删除
if (await _subjectVisitRepository.AnyAsync(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.Submitted &&
(!t.QCChallengeList.Any(u => u.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload))))
{
//---CRC已经提交不允许删除。
return ResponseOutput.NotOk(_localizer["QCOperation_CrcNoDelete"]);
}
}
var waitDeleteStudyList = await _dicomStudyRepository.Where(x => ids.Contains(x.Id), false, true).ToListAsync();
foreach (var item in waitDeleteStudyList)

View File

@ -1005,6 +1005,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public int? PageShowOrder { get; set; }
public bool IsPreinstall { get {
return this.TableQuestions.Questions.Any(x => x.IsPreinstall);
} }
public List<TrialReadQuestionData> Childrens { get; set; }

View File

@ -324,6 +324,12 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public ImageMark? ImageMarkEnum { get; set; }
/// <summary>
/// 是否预设
/// </summary>
public bool IsPreinstall { get; set; } = false;
/// <summary>
/// 影像工具
/// </summary>
@ -513,6 +519,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public ValueOfType? ValueType { get; set; }
/// <summary>
/// 是否预设
/// </summary>
public bool IsPreinstall { get; set; } = false;
public bool IsCopy { get; set; } = false;
@ -1692,6 +1703,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
{
public Guid QuestionId { get; set; }
public string QuestionName { get; set; }
[NotMapped]

View File

@ -847,7 +847,7 @@ namespace IRaCIS.Core.Application.Service
/// <summary>
/// 新增修改想想项目表格问题
/// 新增修改项目表格问题
/// </summary>
/// <param name="indto"></param>
/// <returns></returns>
@ -861,6 +861,13 @@ namespace IRaCIS.Core.Application.Service
//---问题编号重复
throw new BusinessValidationFailedException(_localizer["ReadingQuestion_IdDup"]);
}
if (indto.IsPreinstall)
{
if (await _readingTableQuestionTrialRepository.AnyAsync(x => x.ReadingQuestionId == indto.ReadingQuestionId && x.Id != indto.Id && x.IsPreinstall))
{
throw new BusinessValidationFailedException(_localizer["ReadingQuestion_OnlyOnePreinstall"]);
}
}
indto.ParentTriggerValue = string.Join(',', indto.ParentTriggerValueList);
indto.RelevanceValue = string.Join(',', indto.RelevanceValueList);

View File

@ -1,4 +1,5 @@
using IRaCIS.Core.Application.Service.Reading.Dto;
using DocumentFormat.OpenXml.EMMA;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
@ -366,6 +367,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
var isReadingTaskViewInOrder = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskinfo.TrialReadingCriterionId).Select(x => x.IsReadingTaskViewInOrder).FirstOrDefaultAsync();
var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskinfo.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync();
List<ReadingTableAnswerRowInfo> addRowList = new List<ReadingTableAnswerRowInfo>();
List<ReadingTableQuestionAnswer> addTableQuestionAnswerList = new List<ReadingTableQuestionAnswer>();
// 判断当前任务是否是基线
if (taskinfo.SourceSubjectVisitId != baseLineVisitId && isReadingTaskViewInOrder == ReadingOrder.InOrder)
{
@ -434,13 +437,64 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
var addList = _mapper.Map<List<ReadingTableAnswerRowInfo>>(tableRowAnswers);
await _readingTableAnswerRowInfoRepository.AddRangeAsync(addList);
await _readingTableQuestionAnswerRepository.AddRangeAsync(tableAnswers);
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
addRowList.AddRange(addList);
addTableQuestionAnswerList.AddRange(tableAnswers);
}
}
// 添加 是否预设
var tableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionTrial.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId && x.IsPreinstall).Include(x=>x.ReadingQuestionTrial).ToListAsync();
if (tableQuestionList.Count() > 0)
{
foreach (var tableQuestion in tableQuestionList)
{
var thisTableQuestionList=await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == tableQuestion.ReadingQuestionId).ToListAsync();
decimal index = 1;
foreach (var item in tableQuestion.TypeValue.Split('|'))
{
var newRowId = NewId.NextGuid();
addRowList.Add(new ReadingTableAnswerRowInfo()
{
Id = newRowId,
QuestionId = tableQuestion.ReadingQuestionId,
VisitTaskId = taskinfo.Id,
TrialId = taskinfo.TrialId,
RowIndex = index,
IsCurrentTaskAdd = true,
BlindName = taskinfo.TaskBlindName,
OrderMark = tableQuestion.ReadingQuestionTrial.OrderMark,
FristAddTaskId = taskinfo.Id,
RowMark = tableQuestion.ReadingQuestionTrial.OrderMark + decimal.Parse(index.ToString()).GetLesionMark()
});
foreach (var thisTableQuestion in thisTableQuestionList)
{
addTableQuestionAnswerList.Add(new ReadingTableQuestionAnswer()
{
Answer = thisTableQuestion.Id== tableQuestion.Id? item:string.Empty,
QuestionId = tableQuestion.ReadingQuestionId,
TrialId = taskinfo.TrialId,
VisitTaskId = taskinfo.Id,
RowId = newRowId,
RowIndex = index,
TableQuestionId = thisTableQuestion.Id,
});
}
index++;
}
}
}
await _readingTableAnswerRowInfoRepository.AddRangeAsync(addRowList);
await _readingTableQuestionAnswerRepository.AddRangeAsync(addTableQuestionAnswerList);
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
return new AddTaskLesionAnswerFromLastTaskOutDto()
{

View File

@ -441,6 +441,308 @@ namespace IRaCIS.Core.Application.Service
[AllowAnonymous]
public async Task<IResponseOutput> RestoreDBOSSDate(
[FromServices] IOSSService _oSSService, [FromServices] IWebHostEnvironment _hostEnvironment, [FromServices] IRepository<DicomStudy> _studyRepository)
{
var folder = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
var outputFile = Path.Combine(folder, $"{Guid.NewGuid()}_deleteKey_info.txt");
var outputFile2 = Path.Combine(folder, $"{Guid.NewGuid()}_deleteKeyExport_info.txt");
var outputErrorFile = Path.Combine(folder, $"{Guid.NewGuid()}_deleteKeyerror.txt");
var outputErrorFile2 = Path.Combine(folder, $"{Guid.NewGuid()}_deleteKeyerrorStudy.txt");
var aliConfig = _oSSService.ObjectStoreServiceOptions.AliyunOSS;
var tempToken = _oSSService.GetObjectStoreTempToken();
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint,
tempToken.AliyunOSS.AccessKeyId,
tempToken.AliyunOSS.AccessKeySecret,
tempToken.AliyunOSS.SecurityToken);
var allVersions = new List<ObjectVersionSummary>();
var allDeleteMarkers = new List<DeleteMarkerSummary>();
var request = new ListObjectVersionsRequest(tempToken.AliyunOSS.BucketName)
{
Prefix = "01000000-ac13-0242-6397-08dcd2d2a091/Image",
//Prefix = "01000000-ac13-0242-6397-08dcd2d2a091/Image/08dd9c04-c1b2-c2da-0242-ac1301000000/01000000-ac13-0242-235b-08dd9c04c1b3",
MaxKeys = 1000,
};
ObjectVersionList result;
do
{
result = _ossClient.ListObjectVersions(request);
if (result.ObjectVersionSummaries != null)
allVersions.AddRange(result.ObjectVersionSummaries);
if (result.DeleteMarkerSummaries != null)
allDeleteMarkers.AddRange(result.DeleteMarkerSummaries);
request.KeyMarker = result.NextKeyMarker;
request.VersionIdMarker = result.NextVersionIdMarker;
} while (result.IsTruncated);
Console.WriteLine($"共找到 {allDeleteMarkers.Count} 个删除标记");
int total = allDeleteMarkers.Count;
int processed = 0;
double lastPercent = 0;
// 按 Key 分组,找每个删除标记前的最近版本
var versionsByKey = allVersions
.GroupBy(v => v.Key)
.ToDictionary(g => g.Key, g => g.OrderByDescending(x => x.LastModified).ToList());
foreach (var del in allDeleteMarkers)
{
#region 防止阿里云过期
if (tempToken.AliyunOSS.Expiration.AddSeconds(10) <= DateTime.Now)
{
tempToken = _oSSService.GetObjectStoreTempToken();
_ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint,
tempToken.AliyunOSS.AccessKeyId,
tempToken.AliyunOSS.AccessKeySecret,
tempToken.AliyunOSS.SecurityToken);
}
#endregion
if (!versionsByKey.TryGetValue(del.Key, out var versions))
continue; // 没有历史版本无法恢复
var prevVersion = versions.FirstOrDefault(v => v.LastModified < del.LastModified);
if (prevVersion == null)
continue; // 没找到可恢复版本
try
{
await File.AppendAllTextAsync(outputFile, $"{prevVersion.Key},{prevVersion.VersionId}" + Environment.NewLine);
var getReq = new GetObjectRequest(tempToken.AliyunOSS.BucketName, prevVersion.Key)
{
VersionId = prevVersion.VersionId
};
using (var getResult = _ossClient.GetObject(getReq))
using (var memStream = new MemoryStream())
{
// 先把 OSS 流复制到内存流
getResult.Content.CopyTo(memStream);
memStream.Position = 0;
// 读取 DICOM 信息
var dicomFile = DicomFile.Open(memStream);
var studyInstanceUID = dicomFile.Dataset.GetString(DicomTag.StudyInstanceUID);
var findInfo = await _studyRepository.Where(t => t.StudyInstanceUid == studyInstanceUID && t.TrialId == Guid.Parse("01000000-ac13-0242-6397-08dcd2d2a091"))
.Select(t => new { t.StudyInstanceUid, t.Subject.Code, t.SubjectVisit.VisitName, t.SubjectId, t.SubjectVisitId }).FirstOrDefaultAsync();
if (findInfo != null)
{
// 再保存到另一个路径(可以使用 fo-dicom 保存)
var fileName = Path.GetFileNameWithoutExtension(prevVersion.Key);
var anotherPath = Path.Combine(folder, findInfo.Code, findInfo.VisitName, studyInstanceUID, fileName);
// 去掉 folder 部分,得到相对路径
var relativePath = Path.GetRelativePath(folder, anotherPath);
Directory.CreateDirectory(Path.GetDirectoryName(anotherPath));
dicomFile.Save(anotherPath);
await File.AppendAllTextAsync(outputFile2, $"{findInfo.SubjectId},{findInfo.SubjectVisitId},{prevVersion.Key},{prevVersion.VersionId},{relativePath},{findInfo.Code},{findInfo.VisitName},{findInfo.StudyInstanceUid},{fileName}" + Environment.NewLine);
}
else
{
await File.AppendAllTextAsync(outputErrorFile2, $"{studyInstanceUID},{prevVersion.Key},{prevVersion.VersionId}" + Environment.NewLine);
}
//Console.WriteLine($"读取到 studyInstanceUID: {studyInstanceUID}");
//var localPath = Path.Combine(folder, prevVersion.Key.Trim('/').Replace('/', Path.DirectorySeparatorChar));
//Directory.CreateDirectory(Path.GetDirectoryName(localPath));
//// 保存到原本路径
//memStream.Position = 0;
//using (var fs = File.Create(localPath))
//{
// memStream.CopyTo(fs);
//}
}
//Console.WriteLine($"✅ 下载成功: {prevVersion.Key} (version={prevVersion.VersionId})");
}
catch (Exception ex)
{
Console.WriteLine($"❌ 下载失败: {prevVersion.Key}, 错误: {ex.Message}");
await File.AppendAllTextAsync(outputErrorFile, $"{prevVersion.Key},{prevVersion.VersionId}" + Environment.NewLine);
}
finally
{
processed++;
double percent = processed * 100.0 / total;
// 每提升 5% 或完成时输出
if (percent - lastPercent >= 2.0 || processed == total)
{
lastPercent = percent;
Console.WriteLine($"{DateTime.Now} 进度: {processed}/{total} ({percent:F2}%)");
}
}
// 使用 CopyObject 把历史版本拷贝为最新版本(恢复)
//var copyReq = new CopyObjectRequest
//{
// Bucket = bucketName,
// Key = prevVersion.Key,
// SourceBucket = bucketName,
// SourceKey = prevVersion.Key,
// SourceVersionId = prevVersion.VersionId
//};
//try
//{
// var copyResult = client.CopyObject(copyReq);
// Console.WriteLine($"✅ 恢复成功: {prevVersion.Key} -> newVersionId={copyResult.VersionId}");
//}
//catch (Exception ex)
//{
// Console.WriteLine($"❌ 恢复失败: {prevVersion.Key}, 错误: {ex.Message}");
//}
}
return ResponseOutput.Ok();
}
public async Task<IResponseOutput> OSSDeleteReStorre([FromServices] IOSSService _oSSService, [FromServices] IWebHostEnvironment _hostEnvironment)
{
var aliConfig = _oSSService.ObjectStoreServiceOptions.AliyunOSS;
var tempToken = _oSSService.GetObjectStoreTempToken();
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint,
tempToken.AliyunOSS.AccessKeyId,
tempToken.AliyunOSS.AccessKeySecret,
tempToken.AliyunOSS.SecurityToken);
var allVersions = new List<ObjectVersionSummary>();
var allDeleteMarkers = new List<DeleteMarkerSummary>();
var request = new ListObjectVersionsRequest(tempToken.AliyunOSS.BucketName)
{
Prefix = "test-delete-restore",
//Prefix = "01000000-ac13-0242-6397-08dcd2d2a091/Image/08dd9c04-c1b2-c2da-0242-ac1301000000/01000000-ac13-0242-235b-08dd9c04c1b3",
MaxKeys = 1000,
};
ObjectVersionList result;
do
{
result = _ossClient.ListObjectVersions(request);
if (result.ObjectVersionSummaries != null)
allVersions.AddRange(result.ObjectVersionSummaries);
if (result.DeleteMarkerSummaries != null)
allDeleteMarkers.AddRange(result.DeleteMarkerSummaries);
request.KeyMarker = result.NextKeyMarker;
request.VersionIdMarker = result.NextVersionIdMarker;
} while (result.IsTruncated);
Console.WriteLine($"共找到 {allDeleteMarkers.Count} 个删除标记");
var versionsByKey = allVersions
.GroupBy(v => v.Key)
.ToDictionary(g => g.Key, g => g.OrderByDescending(x => x.LastModified).ToList());
foreach (var del in allDeleteMarkers)
{
#region 防止阿里云过期
if (tempToken.AliyunOSS.Expiration.AddSeconds(10) <= DateTime.Now)
{
tempToken = _oSSService.GetObjectStoreTempToken();
_ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint,
tempToken.AliyunOSS.AccessKeyId,
tempToken.AliyunOSS.AccessKeySecret,
tempToken.AliyunOSS.SecurityToken);
}
#endregion
if (!versionsByKey.TryGetValue(del.Key, out var versions))
continue; // 没有历史版本无法恢复
var prevVersion = versions.FirstOrDefault(v => v.LastModified < del.LastModified);
if (prevVersion == null)
continue; // 没找到可恢复版本
// 创建 CopyObject 请求
// 先用构造函数指定源和目标
var copyReq = new CopyObjectRequest(
sourceBucketName: tempToken.AliyunOSS.BucketName,
sourceKey: prevVersion.Key,
destinationBucketName: tempToken.AliyunOSS.BucketName,
destinationKey: prevVersion.Key // 覆盖到同名 Key达到“恢复”的效果
);
// 再设置版本号
copyReq.SourceVersionId = prevVersion.VersionId;
try
{
var copyResult = _ossClient.CopyObject(copyReq);
Console.WriteLine($"✅ 恢复成功: {prevVersion.Key}, 新版本ID={copyResult.VersionId}");
}
catch (Exception ex)
{
Console.WriteLine($"❌ 恢复失败: {prevVersion.Key}, 错误: {ex.Message}");
}
}
return ResponseOutput.Ok();
}
[AllowAnonymous]
public async Task<IResponseOutput> UserCreateSourceDeal([FromServices] IRepository<IdentityUser> _identityUserRepository,
[FromServices] IRepository<TrialUserRole> _trialUserRoleRepository)

View File

@ -167,6 +167,12 @@ public class ReadingTableQuestionSystem : BaseAddAuditEntity
[Comment("导出结果")]
public string ExportResultStr { get; set; } = "[]";
/// <summary>
/// 是否预设
/// </summary>
public bool IsPreinstall { get; set; } = false;
[NotMapped]
public List<ExportResult> ExportResult
{

View File

@ -192,6 +192,11 @@ public class ReadingTableQuestionTrial : BaseAddAuditEntity
/// </summary>
public string ImageTool { get; set; } = string.Empty;
/// <summary>
/// 是否预设
/// </summary>
public bool IsPreinstall { get; set; } = false;
/// <summary>
/// 影像工具属性
/// </summary>

View File

@ -3860,8 +3860,6 @@ namespace IRaCIS.Core.Infra.EFCore.Common
entity.RowMark = entity.OrderMark+ entity.RowIndex.GetLesionMark();
string extraIdentification = string.Empty;
var readingQuestion = await _dbContext.ReadingQuestionTrial.Where(t => t.Id == entity.QuestionId).Include(x => x.ReadingQuestionCriterionTrial).FirstNotNullAsync();
@ -3869,7 +3867,7 @@ namespace IRaCIS.Core.Infra.EFCore.Common
{
extraIdentification = "/Nontumorous";
}
if (readingQuestion.ReadingQuestionCriterionTrial.CriterionType == CriterionType.SelfDefine)
{
extraIdentification = "/SelfDefine";

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace IRaCIS.Core.Infra.EFCore.Migrations
{
/// <inheritdoc />
public partial class IsPreinstall : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsPreinstall",
table: "ReadingTableQuestionTrial",
type: "bit",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<bool>(
name: "IsPreinstall",
table: "ReadingTableQuestionSystem",
type: "bit",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsPreinstall",
table: "ReadingTableQuestionTrial");
migrationBuilder.DropColumn(
name: "IsPreinstall",
table: "ReadingTableQuestionSystem");
}
}
}

View File

@ -7105,6 +7105,9 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.HasColumnType("bit")
.HasComment("是否启用");
b.Property<bool>("IsPreinstall")
.HasColumnType("bit");
b.Property<int>("IsRequired")
.HasColumnType("int");
@ -7337,6 +7340,9 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
b.Property<bool>("IsEnable")
.HasColumnType("bit");
b.Property<bool>("IsPreinstall")
.HasColumnType("bit");
b.Property<int>("IsRequired")
.HasColumnType("int");
@ -15450,7 +15456,7 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.IsRequired();
b.HasOne("IRaCIS.Core.Domain.Models.IdentityUser", "IdentityUser")
.WithMany()
.WithMany("AuditRecordList")
.HasForeignKey("IdentityUserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
@ -19951,6 +19957,8 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
modelBuilder.Entity("IRaCIS.Core.Domain.Models.IdentityUser", b =>
{
b.Navigation("AuditRecordList");
b.Navigation("SystemDocConfirmedList");
b.Navigation("UserRoleList");