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 Details

IRC_NewDev
he 2024-09-02 17:13:14 +08:00
commit 5d946d820e
34 changed files with 886 additions and 468 deletions

View File

@ -7,26 +7,25 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" /> <PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" /> <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="DistributedLock.Core" Version="1.0.6" /> <PackageReference Include="DistributedLock.Core" Version="1.0.7" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.4" /> <PackageReference Include="DistributedLock.SqlServer" Version="1.0.5" />
<PackageReference Include="fo-dicom" Version="5.1.2" /> <PackageReference Include="fo-dicom" Version="5.1.3" />
<PackageReference Include="fo-dicom.Codecs" Version="5.12.0" /> <PackageReference Include="fo-dicom.Codecs" Version="5.14.5" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.2" /> <PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.4" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.8" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
<PackageReference Include="AutoMapper" Version="13.0.1" /> <PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Minio" Version="6.0.2" /> <PackageReference Include="Minio" Version="6.0.3" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0"> <PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
<TreatAsUsed>true</TreatAsUsed> <TreatAsUsed>true</TreatAsUsed>
</PackageReference> </PackageReference>
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" /> <PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.0.3" /> <PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.1.1" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="8.0.0" /> <PackageReference Include="Serilog.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -75,12 +75,12 @@
<PackageReference Include="Hangfire.SqlServer" Version="1.8.14" /> <PackageReference Include="Hangfire.SqlServer" Version="1.8.14" />
<PackageReference Include="Invio.Extensions.Authentication.JwtBearer" Version="2.0.1" /> <PackageReference Include="Invio.Extensions.Authentication.JwtBearer" Version="2.0.1" />
<PackageReference Include="LogDashboard" Version="1.4.8" /> <PackageReference Include="LogDashboard" Version="1.4.8" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.8" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" /> <PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.0.3" /> <PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.6.2" /> <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.7.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -41,7 +41,7 @@ namespace IRaCIS.Core.API
var dbType = configuration.GetSection("ConnectionStrings:Db_Type").Value ; var dbType = configuration.GetSection("ConnectionStrings:Db_Type").Value ;
if (!string.IsNullOrWhiteSpace(dbType) && dbType == "pgsql") if (!string.IsNullOrWhiteSpace(dbType) && dbType == "pgsql")
{ {
options.UseNpgsql(@"Host=106.14.89.110;Port=5432;Username=sa;Password=pgsql_pwd;Database=Test2_PG"); options.UseNpgsql(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
} }
else else

View File

@ -58,24 +58,24 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" /> <PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="DocX" Version="3.0.1" /> <PackageReference Include="DocX" Version="3.0.1" />
<PackageReference Include="FreeSpire.Doc" Version="12.2.0" /> <PackageReference Include="FreeSpire.Doc" Version="12.2.0" />
<PackageReference Include="Hangfire.Core" Version="1.8.14" /> <PackageReference Include="Hangfire.Core" Version="1.8.14" />
<PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.1.0" /> <PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
<PackageReference Include="EasyCaching.Redis" Version="1.9.2" /> <PackageReference Include="EasyCaching.Redis" Version="1.9.2" />
<PackageReference Include="EasyCaching.InMemory" Version="1.9.2" /> <PackageReference Include="EasyCaching.InMemory" Version="1.9.2" />
<PackageReference Include="ExcelDataReader" Version="3.6.0" /> <PackageReference Include="ExcelDataReader" Version="3.7.0" />
<PackageReference Include="ExcelDataReader.DataSet" Version="3.6.0" /> <PackageReference Include="ExcelDataReader.DataSet" Version="3.7.0" />
<PackageReference Include="DistributedLock.Redis" Version="1.0.3" /> <PackageReference Include="DistributedLock.Redis" Version="1.0.3" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.4" /> <PackageReference Include="DistributedLock.SqlServer" Version="1.0.5" />
<PackageReference Include="fo-dicom" Version="5.1.3" /> <PackageReference Include="fo-dicom" Version="5.1.3" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.3" /> <PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.3" />
<PackageReference Include="fo-dicom.Codecs" Version="5.14.4" /> <PackageReference Include="fo-dicom.Codecs" Version="5.14.5" />
<PackageReference Include="IP2Region.Net" Version="2.0.2" /> <PackageReference Include="IP2Region.Net" Version="2.0.2" />
<PackageReference Include="MailKit" Version="4.2.0" /> <PackageReference Include="MailKit" Version="4.2.0" />
<PackageReference Include="MimeKit" Version="4.2.0" /> <PackageReference Include="MimeKit" Version="4.2.0" />
<PackageReference Include="MiniExcel" Version="1.32.0" /> <PackageReference Include="MiniExcel" Version="1.34.1" />
<PackageReference Include="Minio" Version="6.0.3" /> <PackageReference Include="Minio" Version="6.0.3" />
<PackageReference Include="MiniWord" Version="0.8.0" /> <PackageReference Include="MiniWord" Version="0.8.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0"> <PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">

View File

@ -523,6 +523,25 @@
系统模板文档配置表 系统模板文档配置表
</summary> </summary>
</member> </member>
<member name="T:IRaCIS.Core.Application.Service.Common.DevelopService">
<summary>
开始时候一些帮助 比如根据配置的字典生成枚举
</summary>
<param name="_dictionaryRepository"></param>
</member>
<member name="M:IRaCIS.Core.Application.Service.Common.DevelopService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Dictionary})">
<summary>
开始时候一些帮助 比如根据配置的字典生成枚举
</summary>
<param name="_dictionaryRepository"></param>
</member>
<member name="M:IRaCIS.Core.Application.Service.Common.DevelopService.BackDicGenerateEnum(System.String)">
<summary>
根据配置的字典名生成后端枚举
</summary>
<param name="dicName"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.TrialUserListExport(IRaCIS.Application.Contracts.TrialMaintenanceExportQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument},IRaCIS.Application.Interfaces.IDictionaryService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUser})"> <member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.TrialUserListExport(IRaCIS.Application.Contracts.TrialMaintenanceExportQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument},IRaCIS.Application.Interfaces.IDictionaryService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUser})">
<summary> <summary>
项目参与人员导出 项目参与人员导出
@ -15359,6 +15378,13 @@
<param name="inDto"></param> <param name="inDto"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Application.Services.ReadModuleService.GetReadModuleList_new(IRaCIS.Core.Application.Service.Reading.Dto.GetReadModuleDto)">
<summary>
用ef 实现之前视图的功能
</summary>
<param name="inQuery"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Application.Services.ReadModuleService.GetReadModuleList(IRaCIS.Core.Application.Service.Reading.Dto.GetReadModuleDto)"> <member name="M:IRaCIS.Application.Services.ReadModuleService.GetReadModuleList(IRaCIS.Core.Application.Service.Reading.Dto.GetReadModuleDto)">
<summary> <summary>
获取读片模块 //加了标准参数 获取读片模块 //加了标准参数

View File

@ -1,4 +1,5 @@
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
@ -263,13 +264,20 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public string? TrialSiteCode { get; set; } public string? TrialSiteCode { get; set; }
public string? SiteCode { get; set; }
public Guid? TrialSiteId { get; set; } public Guid? TrialSiteId { get; set; }
public Guid? SubjectId { get; set; } public Guid? SubjectId { get; set; }
public List<ReadModuleView> Data { get; set; } public List<ReadModuleView> Data { get; set; } = new List<ReadModuleView>();
//public List<ReadModuleView> Data => VisitData.Union(ReadMouduleData).ToList();
[JsonIgnore]
public List<ReadModuleView> VisitData { get; set; } = new List<ReadModuleView>();
[JsonIgnore]
public List<ReadModuleView> ReadMouduleData { get; set; } = new List<ReadModuleView>();
} }

View File

@ -9,6 +9,8 @@ using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using Microsoft.Identity.Client;
using NPOI.SS.Formula.Functions;
namespace IRaCIS.Application.Services namespace IRaCIS.Application.Services
{ {
@ -50,7 +52,7 @@ namespace IRaCIS.Application.Services
&& x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ReadingTaskState == ReadingTaskState.HaveSigned
&& x.ReadingCategory == ReadingCategory.Visit && x.ReadingCategory == ReadingCategory.Visit
&& x.SubjectId == inDto.SubjectId && x.SubjectId == inDto.SubjectId
&& x.TaskState == TaskState.Effect).OrderByDescending(x => x.VisitTaskNum).Select(x=> x.VisitTaskNum).FirstOrDefaultAsync(); && x.TaskState == TaskState.Effect).OrderByDescending(x => x.VisitTaskNum).Select(x => x.VisitTaskNum).FirstOrDefaultAsync();
var visitQuery = _subjectVisitRepository.Where(x => x.SubjectId == inDto.SubjectId && x.LatestScanDate != null && !x.IsLostVisit); var visitQuery = _subjectVisitRepository.Where(x => x.SubjectId == inDto.SubjectId && x.LatestScanDate != null && !x.IsLostVisit);
@ -91,70 +93,28 @@ namespace IRaCIS.Application.Services
throw new BusinessValidationFailedException(_localizer["ReadModule_CRCConfirmCanNtoEdit"]); throw new BusinessValidationFailedException(_localizer["ReadModule_CRCConfirmCanNtoEdit"]);
} }
await _readModuleRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.Id, x => new ReadModule() { await _readModuleRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.Id, x => new ReadModule()
SubjectVisitId=inDto.SubjectVisitIdId, {
ModuleName=inDto.Name, SubjectVisitId = inDto.SubjectVisitIdId,
ModuleName = inDto.Name,
}); });
return await _readModuleRepository.SaveChangesAsync(); return await _readModuleRepository.SaveChangesAsync();
} }
/// <summary> /// <summary>
/// 获取读片模块 //加了标准参数 /// 用ef 实现之前视图的功能
/// </summary> /// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost] [HttpPost]
public async Task<(PageOutput<GetReadModuleDtoOut>,object)> GetReadModuleList(GetReadModuleDto dto) public async Task<IResponseOutput<PageOutput<GetReadModuleDtoOut>>> GetReadModuleList(GetReadModuleDto inQuery)
{ {
#region MyRegion var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId).Select(x => new
if (dto.SortField.IsNullOrEmpty())
{
dto.SortField = nameof(ReadModuleView.SubjectCode);
dto.Asc = true;
}
dto.SortField = dto.Asc ? dto.SortField : dto.SortField + " desc";
var subjectQuery = _readModuleViewRepository.Where(x => x.TrialReadingCriterionId == dto.TrialReadingCriterionId)
.WhereIf(dto.TrialId != null, x => x.TrialId == dto.TrialId)
.WhereIf(dto.SubjectId != null, x => x.SubjectId == dto.SubjectId)
.WhereIf(dto.TrialSiteCode != null && dto.TrialSiteCode != string.Empty, x => x.TrialSiteCode.Contains(dto.TrialSiteCode))
.WhereIf(dto.SubjectCode != null && dto.SubjectCode != string.Empty, x => x.SubjectCode.Contains(dto.SubjectCode))
.WhereIf(dto.ModuleType != null, x => x.ModuleType == dto.ModuleType)
.WhereIf(dto.CompleteClinicalData == CompleteClinicalDataEnum.NA, x => x.NeedSignClinicalDataCount == 0)
.WhereIf(dto.CompleteClinicalData == CompleteClinicalDataEnum.NotComplete, x => x.NeedSignClinicalDataCount != x.SignClinicalDataCount)
.WhereIf(dto.CompleteClinicalData == CompleteClinicalDataEnum.Complete, x => x.NeedSignClinicalDataCount != 0 && x.NeedSignClinicalDataCount == x.SignClinicalDataCount)
.WhereIf(dto.ReadingStatus != null, x => x.ReadingStatus == dto.ReadingStatus);
//.WhereIf(dto.Name != null, x => x.Name.Contains(dto.Name!)).OrderBy(x => x.SiteCode);
var subjectIds = await subjectQuery.OrderBy(dto.SortField).Select(x => x.SubjectId).Distinct().Skip((dto.PageIndex - 1) * dto.PageSize).Take(dto.PageSize).ToListAsync();
List<ReadModuleView> ReadModuleViewList = await subjectQuery.Where(x => subjectIds.Contains(x.SubjectId)).OrderBy(dto.SortField).ToListAsync();
List<GetReadModuleDtoOut> getReadList = ReadModuleViewList.GroupBy(x => new { x.SubjectId, x.TrialSiteId, x.TrialSiteCode, x.SubjectCode })
.Select(x => new GetReadModuleDtoOut()
{
TrialSiteCode = x.Key.TrialSiteCode,
TrialSiteId = x.Key.TrialSiteId,
SubjectCode = x.Key.SubjectCode,
SubjectId = x.Key.SubjectId,
Data = x.OrderBy(x=>x.ModuleType).ThenBy(x=>x.VisitNum).ToList(),
}).ToList();
PageOutput<GetReadModuleDtoOut> pageOutput = new PageOutput<GetReadModuleDtoOut>()
{
PageSize = dto.PageSize,
CurrentPageData = getReadList,
PageIndex = dto.PageIndex,
TotalCount = await subjectQuery.Select(x => x.SubjectId).Distinct().CountAsync(),
};
var maxcount = 0;
pageOutput.CurrentPageData.ForEach(x =>
{
maxcount = maxcount < x.Data.Count ? x.Data.Count : maxcount;
});
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == dto.TrialReadingCriterionId).Select(x => new
{ {
x.CriterionName,
x.ReadingType,
x.IsReadingTaskViewInOrder, x.IsReadingTaskViewInOrder,
x.IsOncologyReading, x.IsOncologyReading,
x.IsGlobalReading, x.IsGlobalReading,
@ -162,26 +122,677 @@ namespace IRaCIS.Application.Services
x.ReadingInfoSignTime, x.ReadingInfoSignTime,
}).FirstNotNullAsync(); }).FirstNotNullAsync();
return (pageOutput, new var readingType = (int)criterionInfo.ReadingType;
{
MaxLength = maxcount, var isFilterModuleType = inQuery.ModuleType != null;
IsReadingTaskViewInOrder= criterionInfo.IsReadingTaskViewInOrder, var isFilterCompleteClinicalData = inQuery.CompleteClinicalData != null;
IsClinicalReading = criterionInfo.IsOncologyReading, var isFilterReadingStatus = inQuery.ReadingStatus != null;
// OnlyExistsMedicalHistory = !(await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataSetName != "既往局部治疗史" && x.IsConfirm)), var isFilterName = !string.IsNullOrWhiteSpace(inQuery.Name);
IsExistsSubjectClinicalData= await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId&&x.ClinicalDataLevel== ClinicalLevel.Subject && x.IsConfirm&&x.TrialClinicalDataSetCriteriaList.Any(y=>y.TrialReadingCriterionId== dto.TrialReadingCriterionId)),
IsExistsVisitClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataLevel == ClinicalLevel.SubjectVisit && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == dto.TrialReadingCriterionId)),
IsExistsStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataLevel == ClinicalLevel.Study && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == dto.TrialReadingCriterionId)), #region 方式一
IsExistsReadingClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataLevel == ClinicalLevel.ImageRead && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == dto.TrialReadingCriterionId)),
IsExistsOncologyReadClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataLevel == ClinicalLevel.OncologyRead && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == dto.TrialReadingCriterionId)),
IsGlobalReading = criterionInfo.IsGlobalReading,
IsReadingPeriod=criterionInfo.IsReadingPeriod, //var query = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId)
ReadingInfoSignTime=criterionInfo.ReadingInfoSignTime, // .WhereIf(inQuery.SubjectId != null, x => x.Id == inQuery.SubjectId)
ExistClinicalData=await _clinicalDataTrialSetRepository.AnyAsync(x => x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == dto.TrialReadingCriterionId)), // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteCode), x => x.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode))
}) ; // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), x => x.Code.Contains(inQuery.SubjectCode))
// .Select(t => new GetReadModuleDtoOut()
// {
// SubjectCode = t.Code,
// SubjectId = t.Id,
// TrialSiteCode = t.TrialSite.TrialSiteCode,
// TrialSiteId = t.TrialSiteId,
// #region 分开不用union 在属性里面union
// //访视要查询不失访的其次要查在 <= 截止访视的,截止访视没有就查这个受试者所有的
// VisitData = t.SubjectVisitList.Where(t => t.IsLostVisit == false)
// .Where(sv => t.FinalSubjectVisitId == null ? true : sv.VisitNum < t.LatestSubjectVisit.VisitNum).Select(sv => new ReadModuleView()
// {
// Id = sv.Id,
// CreateTime = sv.CreateTime,
// PDState = sv.PDState,
// IsBaseLine = sv.IsBaseLine,
// SubjectCode = sv.Subject.Code,
// IsEnrollmentConfirm = sv.IsEnrollmentConfirm,
// IsFinalVisit = sv.IsFinalVisit,
// SubjectId = sv.SubjectId,
// SubjectVisitId = sv.Id,
// IsUrgent = sv.IsUrgent,
// SubjectVisitName = sv.VisitName,
// IsVisit = true,
// Name = sv.VisitName,
// TrialSiteId = sv.TrialSiteId,
// TrialSiteCode = sv.TrialSite.TrialSiteCode,
// TrialId = sv.TrialId,
// VisitNum = sv.VisitNum,
// TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
// OutPlanPreviousVisitId = sv.OutPlanPreviousVisitId,
// OutPlanPreviousVisitName = sv.OutPlanPreviousVisit.VisitName,
// ModuleType = sv.InPlan ? ModuleTypeEnum.InPlanSubjectVisit : ModuleTypeEnum.OutPlanSubjectVisit,
// //只有阅片期有
// CutOffVisitId = null,
// CutOffVisitName = null,
// ReadingSetType = null,
// ReadModuleId = null,
// ReadModuleName = "",
// ///阅片状态 0 1 2 保持访视的任务全做完了就是5 没完成就是4 否则就是3
// ReadingStatus = sv.ReadingStatus < ReadingStatusEnum.TaskAllocate ? sv.ReadingStatus :
// (sv.VisitTaskList.Count(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned
// && t.ReadingCategory != ReadingCategory.Judge && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) == readingType ? ReadingStatusEnum.ReadCompleted :
// (sv.VisitTaskList.Count(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated
// && t.ReadingCategory != ReadingCategory.Judge && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) == readingType ? ReadingStatusEnum.ImageReading : ReadingStatusEnum.TaskAllocate)),
// //是否是截止访视?
// IsCanChangeCutOffVisit = false,
// //需要签名数量计算 基线包含subject+访视级别的
// NeedSignClinicalDataCount = sv.Trial.TrialReadingCriterionList.Where(t => t.Id == inQuery.TrialReadingCriterionId).SelectMany(u => u.TrialClinicalDataSetCriterionList.Select(t => t.TrialClinicalDataSet)).Where(t => t.IsConfirm == true).
// Where(t => sv.IsBaseLine ? t.ClinicalDataLevel <= ClinicalLevel.SubjectVisit : t.ClinicalDataLevel == ClinicalLevel.SubjectVisit).Count()
// + (sv.Trial.TrialReadingCriterionList.Where(t => t.Id == inQuery.TrialReadingCriterionId).SelectMany(u => u.TrialClinicalDataSetCriterionList.Select(t => t.TrialClinicalDataSet)).Where(t => t.IsConfirm == true)
// .Any(t => t.ClinicalDataLevel == ClinicalLevel.Study) ? 1 : 0),
// //签名的数量
// SignClinicalDataCount = sv.ReadingClinicalDataList.Where(t => t.IsSign == true && t.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.Study &&
// t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)).Count()
// +
// (sv.SubmitState == SubmitStateEnum.Submitted && sv.Trial.ClinicalDataTrialSetList
// .Any(t => t.ClinicalDataLevel == ClinicalLevel.Study && t.TrialClinicalDataSetCriteriaList.Any(u => u.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) ? 1 : 0),
// //标准名 应该是可以不查询的,只要保证逻辑正确
// CriterionName = criterionInfo.CriterionName
// })
// .Where(t => isFilterModuleType ? t.ModuleType == inQuery.ModuleType : true)
// .Where(t => isFilterName ? t.Name == inQuery.Name : true)
// .Where(t => isFilterReadingStatus ? t.ReadingStatus == inQuery.ReadingStatus : true)
// .Where(t => isFilterCompleteClinicalData && inQuery.CompleteClinicalData == CompleteClinicalDataEnum.NA ? t.NeedSignClinicalDataCount == 0 : true)
// .Where(t => isFilterCompleteClinicalData && inQuery.CompleteClinicalData == CompleteClinicalDataEnum.NotComplete ? t.NeedSignClinicalDataCount != t.SignClinicalDataCount : true)
// .Where(t => isFilterCompleteClinicalData && inQuery.CompleteClinicalData == CompleteClinicalDataEnum.Complete ? t.NeedSignClinicalDataCount == t.SignClinicalDataCount : true)
// //搜索条件报错
// //.WhereIf(inQuery.ModuleType != null, t => t.ModuleType == inQuery.ModuleType)
// //.WhereIf(inQuery.CompleteClinicalData == CompleteClinicalDataEnum.NA, x => x.NeedSignClinicalDataCount == 0)
// //.WhereIf(inQuery.CompleteClinicalData == CompleteClinicalDataEnum.NotComplete, x => x.NeedSignClinicalDataCount != x.SignClinicalDataCount)
// //.WhereIf(inQuery.CompleteClinicalData == CompleteClinicalDataEnum.Complete, x => x.NeedSignClinicalDataCount != 0 && x.NeedSignClinicalDataCount == x.SignClinicalDataCount)
// //.WhereIf(inQuery.ReadingStatus != null, x => x.ReadingStatus == inQuery.ReadingStatus)
// .ToList(),
// //阅片期
// ReadMouduleData = t.ReadModuleList.Select(rm => new ReadModuleView()
// {
// Id = rm.Id,
// CreateTime = rm.CreateTime,
// PDState = PDStateEnum.None,
// IsBaseLine = false,
// SubjectCode = rm.SubjectVisit.Subject.Code,
// IsEnrollmentConfirm = false,
// IsFinalVisit = false,
// SubjectId = rm.SubjectId,
// SubjectVisitId = rm.SubjectVisitId,
// IsUrgent = rm.SubjectVisit.IsUrgent,
// SubjectVisitName = rm.SubjectVisit.VisitName,
// IsVisit = false,
// Name = rm.ModuleName,
// TrialSiteId = rm.Subject.TrialSiteId,
// TrialSiteCode = rm.Subject.TrialSite.TrialSiteCode,
// TrialId = rm.TrialId,
// VisitNum = rm.SubjectVisit.VisitNum,
// TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
// OutPlanPreviousVisitId = null,
// OutPlanPreviousVisitName = null,
// ModuleType = rm.ModuleType,
// //只有阅片期有
// CutOffVisitId = rm.SubjectVisit.Id,
// CutOffVisitName = rm.SubjectVisit.VisitName,
// ReadingSetType = null,
// //之前视图返回的null 应该是没用的?
// ReadModuleId = rm.Id,
// ReadModuleName = rm.ModuleName,
// //是否是截止访视?
// IsCanChangeCutOffVisit = false,
// ///阅片状态 0 1 2 保持访视的任务全做完了就是5 没完成就是4 否则就是3
// ReadingStatus = rm.ReadingStatus < ReadingStatusEnum.TaskAllocate ? rm.ReadingStatus :
// (rm.ModuleTaskList.Count(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned
// && t.ReadingCategory != ReadingCategory.Judge && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) == readingType ? ReadingStatusEnum.ReadCompleted :
// (rm.ModuleTaskList.Count(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated
// && t.ReadingCategory != ReadingCategory.Judge && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) == readingType ? ReadingStatusEnum.ImageReading : ReadingStatusEnum.TaskAllocate
// )
// ),
// ////需要签名数量计算 基线包含subject+访视级别的
// NeedSignClinicalDataCount = rm.Trial.TrialReadingCriterionList.Where(t => t.Id == inQuery.TrialReadingCriterionId).SelectMany(u => u.TrialClinicalDataSetCriterionList.Select(z => z.TrialClinicalDataSet))
// .Where(t => t.IsConfirm == true && t.UploadRole == UploadRole.PM && (t.ClinicalDataLevel == ClinicalLevel.SubjectVisit || t.ClinicalDataLevel == ClinicalLevel.ImageRead || t.ClinicalDataLevel == ClinicalLevel.OncologyRead)).Count()
// +
// (rm.Trial.TrialReadingCriterionList.Where(t => t.Id == inQuery.TrialReadingCriterionId).SelectMany(u => u.TrialClinicalDataSetCriterionList.Select(z => z.TrialClinicalDataSet))
// .Where(t => t.IsConfirm == true && t.UploadRole == UploadRole.CRC &&
// (t.ClinicalDataLevel == ClinicalLevel.SubjectVisit || t.ClinicalDataLevel == ClinicalLevel.ImageRead || t.ClinicalDataLevel == ClinicalLevel.OncologyRead)).Any() ? 1 : 0)
// ,
// //签名的数量
// SignClinicalDataCount = rm.ReadingClinicalDataList.Where(t => t.IsSign == true && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM &&
// t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)).Count()
// +
// (rm.IsPMConfirm ? 1 : 0),
// //标准名 应该是可以不查询的,只要保证逻辑正确
// CriterionName = criterionInfo.CriterionName
// })
// .Where(t => isFilterModuleType ? t.ModuleType == inQuery.ModuleType : true)
// .Where(t => isFilterName ? t.Name == inQuery.Name : true)
// .Where(t => isFilterReadingStatus ? t.ReadingStatus == inQuery.ReadingStatus : true)
// .Where(t => isFilterCompleteClinicalData && inQuery.CompleteClinicalData == CompleteClinicalDataEnum.NA ? t.NeedSignClinicalDataCount == 0 : true)
// .Where(t => isFilterCompleteClinicalData && inQuery.CompleteClinicalData == CompleteClinicalDataEnum.NotComplete ? t.NeedSignClinicalDataCount != t.SignClinicalDataCount : true)
// .Where(t => isFilterCompleteClinicalData && inQuery.CompleteClinicalData == CompleteClinicalDataEnum.Complete ? t.NeedSignClinicalDataCount == t.SignClinicalDataCount : true)
// .ToList()
// #endregion
// #region 用union 报错不行的
// ////访视要查询不失访的其次要查在 <= 截止访视的,截止访视没有就查这个受试者所有的
// //Data = t.SubjectVisitList.Where(t => t.IsLostVisit == false)
// //.Where(sv => t.FinalSubjectVisitId == null ? true : sv.VisitNum < t.LatestSubjectVisit.VisitNum).Select(sv => new ReadModuleView()
// //{
// // Id = sv.Id,
// // CreateTime = sv.CreateTime,
// // PDState = sv.PDState,
// // IsBaseLine = sv.IsBaseLine,
// // SubjectCode = sv.Subject.Code,
// // IsEnrollmentConfirm = sv.IsEnrollmentConfirm,
// // IsFinalVisit = sv.IsFinalVisit,
// // SubjectId = sv.SubjectId,
// // SubjectVisitId = sv.Id,
// // IsUrgent = sv.IsUrgent,
// // SubjectVisitName = sv.VisitName,
// // IsVisit = true,
// // Name = sv.VisitName,
// // TrialSiteId = sv.TrialSiteId,
// // TrialSiteCode = sv.TrialSite.TrialSiteCode,
// // TrialId = sv.TrialId,
// // VisitNum = sv.VisitNum,
// // TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
// // OutPlanPreviousVisitId = sv.OutPlanPreviousVisitId,
// // OutPlanPreviousVisitName = sv.OutPlanPreviousVisit.VisitName,
// // ModuleType = sv.InPlan ? ModuleTypeEnum.InPlanSubjectVisit : ModuleTypeEnum.OutPlanSubjectVisit,
// // //只有阅片期有
// // CutOffVisitId = null,
// // CutOffVisitName = null,
// // ReadingSetType = null,
// // ReadModuleId = null,
// // ReadModuleName = "",
// // ///阅片状态 0 1 2 保持访视的任务全做完了就是5 没完成就是4 否则就是3
// // ReadingStatus = sv.ReadingStatus < ReadingStatusEnum.TaskAllocate ? sv.ReadingStatus :
// // (sv.VisitTaskList.Count(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned
// // && t.ReadingCategory != ReadingCategory.Judge && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) == readingType ? ReadingStatusEnum.ReadCompleted :
// // (sv.VisitTaskList.Count(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated
// // && t.ReadingCategory != ReadingCategory.Judge && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) == readingType ? ReadingStatusEnum.ImageReading : ReadingStatusEnum.TaskAllocate)),
// // //是否是截止访视?
// // IsCanChangeCutOffVisit = false,
// // //需要签名数量计算 基线包含subject+访视级别的
// // NeedSignClinicalDataCount = sv.Trial.TrialReadingCriterionList.Where(t => t.Id == inQuery.TrialReadingCriterionId).SelectMany(u => u.TrialClinicalDataSetCriterionList).Where(t => t.TrialClinicalDataSet.IsConfirm == true).
// // Where(t => sv.IsBaseLine ? t.TrialClinicalDataSet.ClinicalDataLevel <= ClinicalLevel.SubjectVisit : t.TrialClinicalDataSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit).Count()
// // + (sv.Trial.TrialReadingCriterionList.Where(t => t.Id == inQuery.TrialReadingCriterionId).SelectMany(u => u.TrialClinicalDataSetCriterionList).Where(t => t.TrialClinicalDataSet.IsConfirm == true)
// // .Any(t => t.TrialClinicalDataSet.ClinicalDataLevel == ClinicalLevel.Study) ? 1 : 0),
// // //签名的数量
// // SignClinicalDataCount = sv.ReadingClinicalDataList.Where(t => t.IsSign == true && t.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.Study &&
// // t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)).Count()
// // +
// // (sv.SubmitState == SubmitStateEnum.Submitted && sv.Trial.ClinicalDataTrialSetList
// // .Any(t => t.ClinicalDataLevel == ClinicalLevel.Study && t.TrialClinicalDataSetCriteriaList.Any(u => u.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) ? 1 : 0),
// // //标准名 应该是可以不查询的,只要保证逻辑正确
// // CriterionName = criterionInfo.CriterionName
// //})
// //.Union(t.ReadModuleList.AsQueryable().Select(rm => new ReadModuleView()
// //{
// // Id = rm.Id,
// // CreateTime = rm.CreateTime,
// // PDState = PDStateEnum.None,
// // IsBaseLine = false,
// // SubjectCode = rm.SubjectVisit.Subject.Code,
// // IsEnrollmentConfirm = false,
// // IsFinalVisit = false,
// // SubjectId = rm.SubjectId,
// // SubjectVisitId = rm.SubjectVisitId,
// // IsUrgent = rm.SubjectVisit.IsUrgent,
// // SubjectVisitName = rm.SubjectVisit.VisitName,
// // IsVisit = false,
// // Name = rm.ModuleName,
// // TrialSiteId = rm.Subject.TrialSiteId,
// // TrialSiteCode = rm.Subject.TrialSite.TrialSiteCode,
// // TrialId = rm.TrialId,
// // VisitNum = rm.SubjectVisit.VisitNum,
// // TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
// // OutPlanPreviousVisitId = null,
// // OutPlanPreviousVisitName = null,
// // ModuleType = rm.ModuleType,
// // //只有阅片期有
// // CutOffVisitId = rm.SubjectVisit.Id,
// // CutOffVisitName = rm.SubjectVisit.VisitName,
// // ReadingSetType = null,
// // //之前视图返回的null 应该是没用的?
// // ReadModuleId = rm.Id,
// // ReadModuleName = rm.ModuleName,
// // //是否是截止访视?
// // IsCanChangeCutOffVisit = false,
// // ///阅片状态 0 1 2 保持访视的任务全做完了就是5 没完成就是4 否则就是3
// // ReadingStatus = rm.ReadingStatus < ReadingStatusEnum.TaskAllocate ? rm.ReadingStatus :
// // (rm.ModuleTaskList.Count(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned
// // && t.ReadingCategory != ReadingCategory.Judge && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) == readingType ? ReadingStatusEnum.ReadCompleted :
// // (rm.ModuleTaskList.Count(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated
// // && t.ReadingCategory != ReadingCategory.Judge && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) == readingType ? ReadingStatusEnum.ImageReading : ReadingStatusEnum.TaskAllocate
// // )
// // ),
// // //需要签名数量计算 基线包含subject+访视级别的
// // NeedSignClinicalDataCount = rm.Trial.TrialReadingCriterionList.Where(t => t.Id == inQuery.TrialReadingCriterionId).SelectMany(u => u.TrialClinicalDataSetCriterionList.Select(z => z.TrialClinicalDataSet))
// // .Where(t => t.IsConfirm == true && t.UploadRole == UploadRole.PM && (t.ClinicalDataLevel == ClinicalLevel.SubjectVisit || t.ClinicalDataLevel == ClinicalLevel.ImageRead || t.ClinicalDataLevel == ClinicalLevel.OncologyRead)).Count()
// // +
// // (rm.Trial.TrialReadingCriterionList.Where(t => t.Id == inQuery.TrialReadingCriterionId).SelectMany(u => u.TrialClinicalDataSetCriterionList.Select(z => z.TrialClinicalDataSet))
// // .Where(t => t.IsConfirm == true && t.UploadRole == UploadRole.CRC &&
// // (t.ClinicalDataLevel == ClinicalLevel.SubjectVisit || t.ClinicalDataLevel == ClinicalLevel.ImageRead || t.ClinicalDataLevel == ClinicalLevel.OncologyRead)).Any() ? 1 : 0)
// // ,
// // //签名的数量
// // SignClinicalDataCount = rm.ReadingClinicalDataList.Where(t => t.IsSign == true && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM &&
// // t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)).Count()
// // +
// // (rm.IsPMConfirm ? 1 : 0),
// // //标准名 应该是可以不查询的,只要保证逻辑正确
// // CriterionName = criterionInfo.CriterionName
// //})).ToList()
// #endregion
// });
//var pageList = await query/*.Where(t=> (t.VisitData.Count + t.ReadMouduleData.Count)>0)*//*.AsSplitQuery()*/
// .ToPagedListAsync(inQuery, nameof(GetReadModuleDtoOut.SubjectCode));
#endregion #endregion
#region 方式二
var subjectVisitQuery = _subjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId).Where(t => t.IsLostVisit == false)
.Where(sv => sv.Subject.FinalSubjectVisitId == null ? true : sv.VisitNum < sv.Subject.LatestSubjectVisit.VisitNum).Select(sv => new ReadModuleView()
{
Id = sv.Id,
CreateTime = sv.CreateTime,
PDState = sv.PDState,
IsBaseLine = sv.IsBaseLine,
SubjectCode = sv.Subject.Code,
IsEnrollmentConfirm = sv.IsEnrollmentConfirm,
IsFinalVisit = sv.IsFinalVisit,
SubjectId = sv.SubjectId,
SubjectVisitId = sv.Id,
IsUrgent = sv.IsUrgent,
SubjectVisitName = sv.VisitName,
IsVisit = true,
Name = sv.VisitName,
TrialSiteId = sv.TrialSiteId,
TrialSiteCode = sv.TrialSite.TrialSiteCode,
TrialId = sv.TrialId,
VisitNum = sv.VisitNum,
TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
OutPlanPreviousVisitId = sv.OutPlanPreviousVisitId,
OutPlanPreviousVisitName = sv.OutPlanPreviousVisit.VisitName,
ModuleType = sv.InPlan ? ModuleTypeEnum.InPlanSubjectVisit : ModuleTypeEnum.OutPlanSubjectVisit,
//只有阅片期有
CutOffVisitId = null,
CutOffVisitName = null,
ReadingSetType = null,
ReadModuleId = null,
ReadModuleName = "",
///阅片状态 0 1 2 保持访视的任务全做完了就是5 没完成就是4 否则就是3
ReadingStatus = sv.ReadingStatus < ReadingStatusEnum.TaskAllocate ? sv.ReadingStatus :
(sv.VisitTaskList.Count(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned
&& t.ReadingCategory != ReadingCategory.Judge && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) == readingType ? ReadingStatusEnum.ReadCompleted :
(sv.VisitTaskList.Count(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated
&& t.ReadingCategory != ReadingCategory.Judge && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) == readingType ? ReadingStatusEnum.ImageReading : ReadingStatusEnum.TaskAllocate)),
//是否是截止访视?
IsCanChangeCutOffVisit = false,
//需要签名数量计算 基线包含subject+访视级别的
NeedSignClinicalDataCount = sv.Trial.TrialReadingCriterionList.Where(t => t.Id == inQuery.TrialReadingCriterionId).SelectMany(u => u.TrialClinicalDataSetCriterionList.Select(t => t.TrialClinicalDataSet)).Where(t => t.IsConfirm == true).
Where(t => sv.IsBaseLine ? t.ClinicalDataLevel <= ClinicalLevel.SubjectVisit : t.ClinicalDataLevel == ClinicalLevel.SubjectVisit).Count()
+ (sv.Trial.TrialReadingCriterionList.Where(t => t.Id == inQuery.TrialReadingCriterionId).SelectMany(u => u.TrialClinicalDataSetCriterionList.Select(t => t.TrialClinicalDataSet)).Where(t => t.IsConfirm == true)
.Any(t => t.ClinicalDataLevel == ClinicalLevel.Study) ? 1 : 0),
//签名的数量
SignClinicalDataCount = sv.ReadingClinicalDataList.Where(t => t.IsSign == true && t.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.Study &&
t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)).Count()
+
(sv.SubmitState == SubmitStateEnum.Submitted && sv.Trial.ClinicalDataTrialSetList
.Any(t => t.ClinicalDataLevel == ClinicalLevel.Study && t.TrialClinicalDataSetCriteriaList.Any(u => u.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) ? 1 : 0),
//标准名 应该是可以不查询的,只要保证逻辑正确
CriterionName = criterionInfo.CriterionName
});
var readMouduleQuery = _readModuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.TrialReadingCriterionId==inQuery.TrialReadingCriterionId)
.Select(rm => new ReadModuleView()
{
Id = rm.Id,
CreateTime = rm.CreateTime,
PDState = PDStateEnum.None,
IsBaseLine = false,
SubjectCode = rm.SubjectVisit.Subject.Code,
IsEnrollmentConfirm = false,
IsFinalVisit = false,
SubjectId = rm.SubjectId,
SubjectVisitId = rm.SubjectVisitId,
IsUrgent = rm.SubjectVisit.IsUrgent,
SubjectVisitName = rm.SubjectVisit.VisitName,
IsVisit = false,
Name = rm.ModuleName,
TrialSiteId = rm.Subject.TrialSiteId,
TrialSiteCode = rm.Subject.TrialSite.TrialSiteCode,
TrialId = rm.TrialId,
VisitNum = rm.SubjectVisit.VisitNum,
TrialReadingCriterionId = rm.TrialReadingCriterionId,
OutPlanPreviousVisitId = null,
OutPlanPreviousVisitName = null,
ModuleType = rm.ModuleType,
//只有阅片期有
CutOffVisitId = rm.SubjectVisit.Id,
CutOffVisitName = rm.SubjectVisit.VisitName,
ReadingSetType = null,
//之前视图返回的null 应该是没用的?
ReadModuleId = rm.Id,
ReadModuleName = rm.ModuleName,
//阅片期切换访视 限制1、阅片期访视已完成了任务不能如果本身是肿瘤学不能或者本身是全局后续有肿瘤学
IsCanChangeCutOffVisit = !(rm.ModuleTaskList.Any(t => t.TaskState == TaskState.Effect) && rm.ReadingSetType == ReadingSetType.TumorReading &&
rm.SubjectVisit.ReadModuleList.Any(t => t.ReadingSetType == ReadingSetType.TumorReading)),
///阅片状态 0 1 2 保持访视的任务全做完了就是5 没完成就是4 否则就是3
ReadingStatus = rm.ReadingStatus < ReadingStatusEnum.TaskAllocate ? rm.ReadingStatus :
(rm.ModuleTaskList.Count(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned
&& t.ReadingCategory != ReadingCategory.Judge && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) == readingType ? ReadingStatusEnum.ReadCompleted :
(rm.ModuleTaskList.Count(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated
&& t.ReadingCategory != ReadingCategory.Judge && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) == readingType ? ReadingStatusEnum.ImageReading : ReadingStatusEnum.TaskAllocate
)
),
////需要签名数量计算 基线包含subject+访视级别的
NeedSignClinicalDataCount = rm.Trial.TrialReadingCriterionList.Where(t => t.Id == inQuery.TrialReadingCriterionId).SelectMany(u => u.TrialClinicalDataSetCriterionList.Select(z => z.TrialClinicalDataSet))
.Where(t => t.IsConfirm == true && t.UploadRole == UploadRole.PM && (rm.ReadingSetType == ReadingSetType.ImageReading ? t.ClinicalDataLevel == ClinicalLevel.ImageRead : t.ClinicalDataLevel == ClinicalLevel.OncologyRead)).Count()
+
(rm.Trial.TrialReadingCriterionList.Where(t => t.Id == inQuery.TrialReadingCriterionId).SelectMany(u => u.TrialClinicalDataSetCriterionList.Select(z => z.TrialClinicalDataSet))
.Where(t => t.IsConfirm == true && t.UploadRole == UploadRole.CRC &&
(rm.ReadingSetType == ReadingSetType.ImageReading ? t.ClinicalDataLevel == ClinicalLevel.ImageRead : t.ClinicalDataLevel == ClinicalLevel.OncologyRead)).Any() ? 1 : 0)
,
//签名的数量
SignClinicalDataCount = rm.ReadingClinicalDataList.Where(t => t.IsSign == true && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM &&
t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)).Count()
+
(rm.IsPMConfirm ? 1 : 0),
//标准名 应该是可以不查询的,只要保证逻辑正确
CriterionName = criterionInfo.CriterionName
});
var query = subjectVisitQuery.Union(readMouduleQuery)
.WhereIf(inQuery.SubjectId != null, x => x.Id == inQuery.SubjectId)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteCode), x => x.TrialSiteCode.Contains(inQuery.TrialSiteCode))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), x => x.SubjectCode.Contains(inQuery.SubjectCode))
.WhereIf(isFilterModuleType, t => t.ModuleType == inQuery.ModuleType)
.WhereIf(isFilterName, t => t.Name == inQuery.Name)
.WhereIf(isFilterReadingStatus, t => t.ReadingStatus == inQuery.ReadingStatus)
.WhereIf(isFilterCompleteClinicalData && inQuery.CompleteClinicalData == CompleteClinicalDataEnum.NA, t => t.NeedSignClinicalDataCount == 0)
.WhereIf(isFilterCompleteClinicalData && inQuery.CompleteClinicalData == CompleteClinicalDataEnum.NotComplete, t => t.NeedSignClinicalDataCount != t.SignClinicalDataCount)
.WhereIf(isFilterCompleteClinicalData && inQuery.CompleteClinicalData == CompleteClinicalDataEnum.Complete, t => t.NeedSignClinicalDataCount == t.SignClinicalDataCount);
inQuery.SortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(ReadModuleView.SubjectCode) : inQuery.SortField;
var subjectIdQuery = query.OrderBy(inQuery.SortField).Select(x => x.SubjectId).Distinct();
var subjectIds = await subjectIdQuery.Skip((inQuery.PageIndex - 1) * inQuery.PageSize).Take(inQuery.PageSize).ToListAsync();
var subjectCount = subjectIdQuery.Count();
var viewList = await query.Where(x => subjectIds.Contains(x.SubjectId)).SortToListAsync(inQuery);
var list = viewList.GroupBy(x => new { x.SubjectId, x.TrialSiteId, x.TrialSiteCode, x.SubjectCode })
.Select(x => new GetReadModuleDtoOut()
{
TrialSiteCode = x.Key.TrialSiteCode,
TrialSiteId = x.Key.TrialSiteId,
SubjectCode = x.Key.SubjectCode,
SubjectId = x.Key.SubjectId,
Data = x.OrderBy(x => x.ModuleType).ThenBy(x => x.VisitNum).ToList(),
}).ToList();
var pageOutput = new PageOutput<GetReadModuleDtoOut>()
{
PageSize = inQuery.PageSize,
CurrentPageData = list,
PageIndex = inQuery.PageIndex,
TotalCount = subjectCount,
};
#endregion
return ResponseOutput.Ok(pageOutput, new
{
MaxLength = pageOutput.CurrentPageData.MaxOrDefault(t => t.Data.Count(), 0),
IsReadingTaskViewInOrder = criterionInfo.IsReadingTaskViewInOrder,
IsClinicalReading = criterionInfo.IsOncologyReading,
// OnlyExistsMedicalHistory = !(await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataSetName != "既往局部治疗史" && x.IsConfirm)),
IsExistsSubjectClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == inQuery.TrialId && x.ClinicalDataLevel == ClinicalLevel.Subject && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)),
IsExistsVisitClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == inQuery.TrialId && x.ClinicalDataLevel == ClinicalLevel.SubjectVisit && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)),
IsExistsStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == inQuery.TrialId && x.ClinicalDataLevel == ClinicalLevel.Study && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)),
IsExistsReadingClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == inQuery.TrialId && x.ClinicalDataLevel == ClinicalLevel.ImageRead && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)),
IsExistsOncologyReadClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == inQuery.TrialId && x.ClinicalDataLevel == ClinicalLevel.OncologyRead && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)),
IsGlobalReading = criterionInfo.IsGlobalReading,
IsReadingPeriod = criterionInfo.IsReadingPeriod,
ReadingInfoSignTime = criterionInfo.ReadingInfoSignTime,
ExistClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)),
});
} }
///// <summary>
///// 获取读片模块 //加了标准参数
///// </summary>
//[HttpPost]
//public async Task<IResponseOutput<PageOutput<GetReadModuleDtoOut>>> GetReadModuleList(GetReadModuleDto dto)
//{
// #region MyRegion
// if (dto.SortField.IsNullOrEmpty())
// {
// dto.SortField = nameof(ReadModuleView.SubjectCode);
// dto.Asc = true;
// }
// dto.SortField = dto.Asc ? dto.SortField : dto.SortField + " desc";
// var subjectQuery = _readModuleViewRepository.Where(x => x.TrialReadingCriterionId == dto.TrialReadingCriterionId)
// .WhereIf(dto.TrialId != null, x => x.TrialId == dto.TrialId)
// .WhereIf(dto.SubjectId != null, x => x.SubjectId == dto.SubjectId)
// .WhereIf(dto.TrialSiteCode != null && dto.TrialSiteCode != string.Empty, x => x.TrialSiteCode.Contains(dto.TrialSiteCode))
// .WhereIf(dto.SubjectCode != null && dto.SubjectCode != string.Empty, x => x.SubjectCode.Contains(dto.SubjectCode))
// .WhereIf(dto.ModuleType != null, x => x.ModuleType == dto.ModuleType)
// .WhereIf(dto.CompleteClinicalData == CompleteClinicalDataEnum.NA, x => x.NeedSignClinicalDataCount == 0)
// .WhereIf(dto.CompleteClinicalData == CompleteClinicalDataEnum.NotComplete, x => x.NeedSignClinicalDataCount != x.SignClinicalDataCount)
// .WhereIf(dto.CompleteClinicalData == CompleteClinicalDataEnum.Complete, x => x.NeedSignClinicalDataCount != 0 && x.NeedSignClinicalDataCount == x.SignClinicalDataCount)
// .WhereIf(dto.ReadingStatus != null, x => x.ReadingStatus == dto.ReadingStatus);
// //.WhereIf(dto.Name != null, x => x.Name.Contains(dto.Name!)).OrderBy(x => x.SiteCode);
// var subjectIds = await subjectQuery.OrderBy(dto.SortField).Select(x => x.SubjectId).Distinct().Skip((dto.PageIndex - 1) * dto.PageSize).Take(dto.PageSize).ToListAsync();
// List<ReadModuleView> ReadModuleViewList = await subjectQuery.Where(x => subjectIds.Contains(x.SubjectId)).OrderBy(dto.SortField).ToListAsync();
// List<GetReadModuleDtoOut> getReadList = ReadModuleViewList.GroupBy(x => new { x.SubjectId, x.TrialSiteId, x.TrialSiteCode, x.SubjectCode })
// .Select(x => new GetReadModuleDtoOut()
// {
// TrialSiteCode = x.Key.TrialSiteCode,
// TrialSiteId = x.Key.TrialSiteId,
// SubjectCode = x.Key.SubjectCode,
// SubjectId = x.Key.SubjectId,
// Data = x.OrderBy(x => x.ModuleType).ThenBy(x => x.VisitNum).ToList(),
// }).ToList();
// PageOutput<GetReadModuleDtoOut> pageOutput = new PageOutput<GetReadModuleDtoOut>()
// {
// PageSize = dto.PageSize,
// CurrentPageData = getReadList,
// PageIndex = dto.PageIndex,
// TotalCount = await subjectQuery.Select(x => x.SubjectId).Distinct().CountAsync(),
// };
// var maxcount = 0;
// pageOutput.CurrentPageData.ForEach(x =>
// {
// maxcount = maxcount < x.Data.Count ? x.Data.Count : maxcount;
// });
// var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == dto.TrialReadingCriterionId).Select(x => new
// {
// x.IsReadingTaskViewInOrder,
// x.IsOncologyReading,
// x.IsGlobalReading,
// x.IsReadingPeriod,
// x.ReadingInfoSignTime,
// }).FirstNotNullAsync();
// return ResponseOutput.Ok(pageOutput, new
// {
// MaxLength = maxcount,
// IsReadingTaskViewInOrder = criterionInfo.IsReadingTaskViewInOrder,
// IsClinicalReading = criterionInfo.IsOncologyReading,
// // OnlyExistsMedicalHistory = !(await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataSetName != "既往局部治疗史" && x.IsConfirm)),
// IsExistsSubjectClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataLevel == ClinicalLevel.Subject && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == dto.TrialReadingCriterionId)),
// IsExistsVisitClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataLevel == ClinicalLevel.SubjectVisit && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == dto.TrialReadingCriterionId)),
// IsExistsStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataLevel == ClinicalLevel.Study && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == dto.TrialReadingCriterionId)),
// IsExistsReadingClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataLevel == ClinicalLevel.ImageRead && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == dto.TrialReadingCriterionId)),
// IsExistsOncologyReadClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataLevel == ClinicalLevel.OncologyRead && x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == dto.TrialReadingCriterionId)),
// IsGlobalReading = criterionInfo.IsGlobalReading,
// IsReadingPeriod = criterionInfo.IsReadingPeriod,
// ReadingInfoSignTime = criterionInfo.ReadingInfoSignTime,
// ExistClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.IsConfirm && x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == dto.TrialReadingCriterionId)),
// });
// #endregion
//}
/// <summary> /// <summary>
@ -195,11 +806,11 @@ namespace IRaCIS.Application.Services
var data = await GetReadModuleList(new GetReadModuleDto() var data = await GetReadModuleList(new GetReadModuleDto()
{ {
SubjectId = dto.SubjectId, SubjectId = dto.SubjectId,
TrialId=dto.TrialId, TrialId = dto.TrialId,
TrialReadingCriterionId=dto.TrialReadingCriterionId, TrialReadingCriterionId = dto.TrialReadingCriterionId,
}); });
GetReadModuleSingleOutdto? readModule = data.Item1.CurrentPageData.FirstOrDefault().Data.Where(x => x.Id == dto.Id).Select(x => new GetReadModuleSingleOutdto() GetReadModuleSingleOutdto? readModule = data.Data.CurrentPageData.FirstOrDefault().Data.Where(x => x.Id == dto.Id).Select(x => new GetReadModuleSingleOutdto()
{ {
Id = x.Id, Id = x.Id,
ModuleType = x.ModuleType, ModuleType = x.ModuleType,
@ -212,7 +823,7 @@ namespace IRaCIS.Application.Services
var stakeholderIds = new List<Guid>(); var stakeholderIds = new List<Guid>();
var subjectVisit =await _subjectVisitRepository.FirstOrDefaultAsync(x => x.Id == readModule.SubjectVisitId); var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(x => x.Id == readModule.SubjectVisitId);
switch (readModule.Status) switch (readModule.Status)
{ {
@ -239,7 +850,7 @@ namespace IRaCIS.Application.Services
case ReadingStatusEnum.ImageReading: case ReadingStatusEnum.ImageReading:
case ReadingStatusEnum.ReadCompleted: case ReadingStatusEnum.ReadCompleted:
var doctorUserId = await _visitTaskRepository.Where(x => (x.SouceReadModuleId == dto.Id || x.SourceSubjectVisitId == dto.Id)&&x.TaskState==TaskState.Effect) var doctorUserId = await _visitTaskRepository.Where(x => (x.SouceReadModuleId == dto.Id || x.SourceSubjectVisitId == dto.Id) && x.TaskState == TaskState.Effect)
.Where(x => x.DoctorUserId != null).Select(x => x.DoctorUserId.Value).ToListAsync(); .Where(x => x.DoctorUserId != null).Select(x => x.DoctorUserId.Value).ToListAsync();
stakeholderIds.AddRange(doctorUserId); stakeholderIds.AddRange(doctorUserId);
@ -261,26 +872,26 @@ namespace IRaCIS.Application.Services
public async Task<List<GetSubjectReadVisitsOutDto>> GetSubjectReadVisitList(GetSubjectReadVisitsInDto inDto) public async Task<List<GetSubjectReadVisitsOutDto>> GetSubjectReadVisitList(GetSubjectReadVisitsInDto inDto)
{ {
//增加标准 //增加标准
var maxReadVisit = await _readModuleRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ReadingSetType==inDto.ReadingSetType && x.TrialReadingCriterionId==inDto.TrialReadingCriterionId).Include(x=>x.SubjectVisit).OrderByDescending(x=>x.SubjectVisit.VisitNum).FirstOrDefaultAsync(); var maxReadVisit = await _readModuleRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ReadingSetType == inDto.ReadingSetType && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId).Include(x => x.SubjectVisit).OrderByDescending(x => x.SubjectVisit.VisitNum).FirstOrDefaultAsync();
var maxReadVisitNum= maxReadVisit==null?-1:maxReadVisit.SubjectVisit.VisitNum; var maxReadVisitNum = maxReadVisit == null ? -1 : maxReadVisit.SubjectVisit.VisitNum;
var visitQuery = _subjectVisitRepository.Where(x => x.SubjectId == inDto.SubjectId && x.LatestScanDate != null && !x.IsLostVisit); var visitQuery = _subjectVisitRepository.Where(x => x.SubjectId == inDto.SubjectId && x.LatestScanDate != null && !x.IsLostVisit);
var finalVisitNum = await visitQuery.Where(x => x.IsFinalVisit).Select(x => x.VisitNum).FirstOrDefaultAsync(); var finalVisitNum = await visitQuery.Where(x => x.IsFinalVisit).Select(x => x.VisitNum).FirstOrDefaultAsync();
//增加标准 //增加标准
var readModulequery = _readModuleRepository.AsQueryable().Where(x=>x.TrialReadingCriterionId == inDto.TrialReadingCriterionId); var readModulequery = _readModuleRepository.AsQueryable().Where(x => x.TrialReadingCriterionId == inDto.TrialReadingCriterionId);
var resultlist= await visitQuery.WhereIf(finalVisitNum!=0, x => x.VisitNum <= finalVisitNum) var resultlist = await visitQuery.WhereIf(finalVisitNum != 0, x => x.VisitNum <= finalVisitNum)
.WhereIf(inDto.ReadingSetType== ReadingSetType.TumorReading, x => readModulequery.Where(y => y.SubjectVisitId == x.Id&&y.TrialReadingCriterionId== inDto.TrialReadingCriterionId && y.ReadingSetType == ReadingSetType.ImageReading).Count() > 0) .WhereIf(inDto.ReadingSetType == ReadingSetType.TumorReading, x => readModulequery.Where(y => y.SubjectVisitId == x.Id && y.TrialReadingCriterionId == inDto.TrialReadingCriterionId && y.ReadingSetType == ReadingSetType.ImageReading).Count() > 0)
.Where(x=>x.VisitNum> maxReadVisitNum) .Where(x => x.VisitNum > maxReadVisitNum)
.Where(x=>!x.IsBaseLine) // 排除基线 .Where(x => !x.IsBaseLine) // 排除基线
.Where(x => readModulequery.Where(y => y.SubjectVisitId == x.Id&& y.TrialReadingCriterionId == inDto.TrialReadingCriterionId && y.ReadingSetType == inDto.ReadingSetType).Count() == 0).OrderBy(x => finalVisitNum) .Where(x => readModulequery.Where(y => y.SubjectVisitId == x.Id && y.TrialReadingCriterionId == inDto.TrialReadingCriterionId && y.ReadingSetType == inDto.ReadingSetType).Count() == 0).OrderBy(x => finalVisitNum)
.Select(x => new GetSubjectReadVisitsOutDto() .Select(x => new GetSubjectReadVisitsOutDto()
{ {
SubjectVisitId = x.Id, SubjectVisitId = x.Id,
VisitName = x.VisitName, VisitName = x.VisitName,
VisitNum = x.VisitNum, VisitNum = x.VisitNum,
}).OrderBy(x=>x.VisitNum).ToListAsync(); }).OrderBy(x => x.VisitNum).ToListAsync();
return resultlist; return resultlist;
} }
@ -296,7 +907,7 @@ namespace IRaCIS.Application.Services
{ {
var visitQuery = _subjectVisitRepository.Where(x => x.SubjectId == dto.SubjectId); var visitQuery = _subjectVisitRepository.Where(x => x.SubjectId == dto.SubjectId);
visitQuery = visitQuery visitQuery = visitQuery
//.WhereIf(dto.ExpirationDate != null, x => x.LatestScanDate <= dto.ExpirationDate.Value) //.WhereIf(dto.ExpirationDate != null, x => x.LatestScanDate <= dto.ExpirationDate.Value)
@ -308,9 +919,9 @@ namespace IRaCIS.Application.Services
if (visit != null) if (visit != null)
{ {
if (await _readModuleRepository.AnyAsync(x => x.SubjectVisitId == visit.Id&&x.ModuleType== moduleType && x.TrialReadingCriterionId == dto.TrialReadingCriterionId)) if (await _readModuleRepository.AnyAsync(x => x.SubjectVisitId == visit.Id && x.ModuleType == moduleType && x.TrialReadingCriterionId == dto.TrialReadingCriterionId))
{ {
//---当前访视已经添加过阅片期 //---当前访视已经添加过阅片期
throw new BusinessValidationFailedException(_localizer["ReadModule_AlreadyAdded"]); throw new BusinessValidationFailedException(_localizer["ReadModule_AlreadyAdded"]);
} }
var readModuleData = new ReadModule() var readModuleData = new ReadModule()
@ -338,8 +949,8 @@ namespace IRaCIS.Application.Services
{ {
case ModuleTypeEnum.Global: case ModuleTypeEnum.Global:
//增加标准 //增加标准
var taskListInfo = await _visitTaskRepository.Where(x => x.SourceSubjectVisitId == readModuleData.SubjectVisitId&&x.TaskState==TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned var taskListInfo = await _visitTaskRepository.Where(x => x.SourceSubjectVisitId == readModuleData.SubjectVisitId && x.TaskState == TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned
&&!x.IsAnalysisCreate && x.TrialReadingCriterionId==dto.TrialReadingCriterionId && !x.IsAnalysisCreate && x.TrialReadingCriterionId == dto.TrialReadingCriterionId
).ToListAsync(); ).ToListAsync();
foreach (var taskInfo in taskListInfo) foreach (var taskInfo in taskListInfo)
@ -375,13 +986,13 @@ namespace IRaCIS.Application.Services
//增加标准 //增加标准
var globalModule = await _readModuleRepository.Where(x => x.SubjectId == readModuleData.SubjectId && x.SubjectVisitId == readModuleData.SubjectVisitId&& x.ModuleType == ModuleTypeEnum.Global && x.TrialReadingCriterionId == dto.TrialReadingCriterionId).FirstOrDefaultAsync(); var globalModule = await _readModuleRepository.Where(x => x.SubjectId == readModuleData.SubjectId && x.SubjectVisitId == readModuleData.SubjectVisitId && x.ModuleType == ModuleTypeEnum.Global && x.TrialReadingCriterionId == dto.TrialReadingCriterionId).FirstOrDefaultAsync();
if (globalModule != null) if (globalModule != null)
{ {
var globalTaskInfoList = await _visitTaskRepository.Where(x => x.SouceReadModuleId == globalModule.Id var globalTaskInfoList = await _visitTaskRepository.Where(x => x.SouceReadModuleId == globalModule.Id
&& x.TrialReadingCriterionId == dto.TrialReadingCriterionId && x.TrialReadingCriterionId == dto.TrialReadingCriterionId
&& x.TaskState == TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned&&!x.IsAnalysisCreate).ToListAsync(); && x.TaskState == TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned && !x.IsAnalysisCreate).ToListAsync();
if (globalTaskInfoList.Count() > 0 && globalTaskInfoList.Count == (int)criterionInfo.ReadingType) if (globalTaskInfoList.Count() > 0 && globalTaskInfoList.Count == (int)criterionInfo.ReadingType)
{ {
@ -422,7 +1033,7 @@ namespace IRaCIS.Application.Services
} }
else else
{ {
//---请先添加全局阅片 //---请先添加全局阅片
return ResponseOutput.NotOk(_localizer["ReadModule_AddGlobalFirst"]); return ResponseOutput.NotOk(_localizer["ReadModule_AddGlobalFirst"]);
} }
break; break;
@ -455,7 +1066,7 @@ namespace IRaCIS.Application.Services
var readModule = await _readModuleRepository.Where(x => x.Id == readModuleId).FirstNotNullAsync(); var readModule = await _readModuleRepository.Where(x => x.Id == readModuleId).FirstNotNullAsync();
if(await _readingClinicalDataRepository.Where(t => t.ReadingId == readModuleId).AnyAsync(t => t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned)) if (await _readingClinicalDataRepository.Where(t => t.ReadingId == readModuleId).AnyAsync(t => t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned))
{ {
//---临床资料已签名,不允许删除 //---临床资料已签名,不允许删除
return ResponseOutput.NotOk(_localizer["ReadModule_SignedDataCannotDelete"]); return ResponseOutput.NotOk(_localizer["ReadModule_SignedDataCannotDelete"]);
@ -463,27 +1074,27 @@ namespace IRaCIS.Application.Services
if (await _readModuleRepository.AnyAsync(x => x.Id == readModuleId&&x.IsCRCConfirm)) if (await _readModuleRepository.AnyAsync(x => x.Id == readModuleId && x.IsCRCConfirm))
{ {
//---CRC已经确认临床数据 不允许删除 //---CRC已经确认临床数据 不允许删除
return ResponseOutput.NotOk(_localizer["ReadModule_CRCConfirmClinicalData"]); return ResponseOutput.NotOk(_localizer["ReadModule_CRCConfirmClinicalData"]);
} }
//增加标准 //增加标准
if (readModule.ModuleType==ModuleTypeEnum.Global&&(await _readModuleRepository.AnyAsync(x=>x.ModuleType==ModuleTypeEnum.Oncology&&x.SubjectVisitId== readModule.SubjectVisitId && x.TrialReadingCriterionId==readModule.TrialReadingCriterionId))) if (readModule.ModuleType == ModuleTypeEnum.Global && (await _readModuleRepository.AnyAsync(x => x.ModuleType == ModuleTypeEnum.Oncology && x.SubjectVisitId == readModule.SubjectVisitId && x.TrialReadingCriterionId == readModule.TrialReadingCriterionId)))
{ {
//---当前访视存在肿瘤学阅片,请先删除肿瘤学阅片 //---当前访视存在肿瘤学阅片,请先删除肿瘤学阅片
throw new BusinessValidationFailedException(_localizer["ReadModule_TumorExists"]); throw new BusinessValidationFailedException(_localizer["ReadModule_TumorExists"]);
} }
if (await _visitTaskRepository.AnyAsync(x => readModuleId==x.SouceReadModuleId)) if (await _visitTaskRepository.AnyAsync(x => readModuleId == x.SouceReadModuleId))
{ {
//---当前阅片已生成任务,操作失败。 //---当前阅片已生成任务,操作失败。
throw new BusinessValidationFailedException(_localizer["ReadModule_TaskGenerated"]); throw new BusinessValidationFailedException(_localizer["ReadModule_TaskGenerated"]);
} }
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => readModuleId==x.SouceReadModuleId, x => new VisitTask() await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => readModuleId == x.SouceReadModuleId, x => new VisitTask()
{ {
TaskState = TaskState.Adbandon TaskState = TaskState.Adbandon
}); });

View File

@ -164,8 +164,8 @@ namespace IRaCIS.Core.Application.Service
CreateMap<Domain.Models.Trial, TrialConfigDTO>().ForMember(t => t.TrialId, u => u.MapFrom(c => c.Id)) CreateMap<Domain.Models.Trial, TrialConfigDTO>().ForMember(t => t.TrialId, u => u.MapFrom(c => c.Id))
.ForMember(t => t.TrialCriterionIds, u => u.MapFrom(c => c.TrialReadingCriterionList.Where(v => v.IsConfirm).OrderBy(x => x.ShowOrder).Select(r => r.Id))) .ForMember(t => t.TrialCriterionIds, u => u.MapFrom(c => c.TrialReadingCriterionList.Where(v => v.IsConfirm).OrderBy(x => x.ShowOrder).Select(r => r.Id)))
.ForMember(t => t.TrialCriterionNames, u => u.MapFrom(c => c.TrialReadingCriterionList.Where(v => v.IsConfirm).OrderBy(x => x.ShowOrder).Select(r => r.CriterionName))) .ForMember(t => t.TrialCriterionNames, u => u.MapFrom(c => c.TrialReadingCriterionList.Where(v => v.IsConfirm).OrderBy(x => x.ShowOrder).Select(r => r.CriterionName)))
.ForMember(t => t.ClinicalDataTrialSetIds, u => u.MapFrom(c => c.clinicalDataTrialSets.Where(v => v.IsConfirm).Select(r => r.Id))) .ForMember(t => t.ClinicalDataTrialSetIds, u => u.MapFrom(c => c.ClinicalDataTrialSetList.Where(v => v.IsConfirm).Select(r => r.Id)))
.ForMember(t => t.ClinicalDataSetNames, u => u.MapFrom(c => c.clinicalDataTrialSets.Where(v => v.IsConfirm).Select(r => isEn_Us ? r.ClinicalDataSetEnName : r.ClinicalDataSetName))) .ForMember(t => t.ClinicalDataSetNames, u => u.MapFrom(c => c.ClinicalDataTrialSetList.Where(v => v.IsConfirm).Select(r => isEn_Us ? r.ClinicalDataSetEnName : r.ClinicalDataSetName)))
//.ForMember(t => t.CriterionIds, u => u.MapFrom(c => c.TrialDicList.Where(v => v.KeyName == StaticData.Criterion).Select(r => r.DictionaryId))) //.ForMember(t => t.CriterionIds, u => u.MapFrom(c => c.TrialDicList.Where(v => v.KeyName == StaticData.Criterion).Select(r => r.DictionaryId)))
; ;
CreateMap<Domain.Models.Trial, TrialSubjectConfig>(); CreateMap<Domain.Models.Trial, TrialSubjectConfig>();

View File

@ -16,6 +16,12 @@ namespace IRaCIS.Core.Domain.Models
} }
//针对dicom
public interface IEntitySeqId
{
public Guid SeqId { get; set; }
}
public abstract class Entity : IEntity<Guid> public abstract class Entity : IEntity<Guid>
{ {
[Key] [Key]
@ -28,6 +34,7 @@ namespace IRaCIS.Core.Domain.Models
private readonly List<DomainEvent> _domainEvents = []; private readonly List<DomainEvent> _domainEvents = [];
[JsonIgnore]
[NotMapped] [NotMapped]
public IReadOnlyCollection<DomainEvent> DomainEvents => _domainEvents.AsReadOnly(); public IReadOnlyCollection<DomainEvent> DomainEvents => _domainEvents.AsReadOnly();

View File

@ -17,7 +17,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="EntityFrameworkCore.Projectables.Abstractions" Version="3.0.4" /> <PackageReference Include="EntityFrameworkCore.Projectables.Abstractions" Version="3.0.4" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
</ItemGroup> </ItemGroup>

View File

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models namespace IRaCIS.Core.Domain.Models
{ {
[Table("DicomInstance")] [Table("DicomInstance")]
public class DicomInstance : BaseFullAuditEntity public class DicomInstance : BaseFullAuditEntity, IEntitySeqId
{ {
#region 导航属性 #region 导航属性
[JsonIgnore] [JsonIgnore]
@ -18,7 +18,6 @@ namespace IRaCIS.Core.Domain.Models
#endregion #endregion
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid SeqId { get; set; } public Guid SeqId { get; set; }
public Guid StudyId { get; set; } public Guid StudyId { get; set; }

View File

@ -6,7 +6,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models namespace IRaCIS.Core.Domain.Models
{ {
[Table("DicomSeries")] [Table("DicomSeries")]
public class DicomSeries : BaseFullDeleteAuditEntity public class DicomSeries : BaseFullDeleteAuditEntity, IEntitySeqId
{ {
#region 导航属性 #region 导航属性
[JsonIgnore] [JsonIgnore]
@ -22,7 +22,6 @@ namespace IRaCIS.Core.Domain.Models
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid SeqId { get; set; } public Guid SeqId { get; set; }
public Guid StudyId { get; set; } public Guid StudyId { get; set; }
public string StudyInstanceUid { get; set; } public string StudyInstanceUid { get; set; }

View File

@ -6,7 +6,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models namespace IRaCIS.Core.Domain.Models
{ {
[Table("DicomStudy")] [Table("DicomStudy")]
public class DicomStudy : BaseFullDeleteAuditEntity public class DicomStudy : BaseFullDeleteAuditEntity, IEntitySeqId
{ {
#region 导航属性 #region 导航属性
//一个检查 由多个人管理 //一个检查 由多个人管理
@ -41,7 +41,6 @@ namespace IRaCIS.Core.Domain.Models
#endregion #endregion
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid SeqId { get; set; } public Guid SeqId { get; set; }
public Guid TrialId { get; set; } public Guid TrialId { get; set; }

View File

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models namespace IRaCIS.Core.Domain.Models
{ {
[Table("SCPInstance")] [Table("SCPInstance")]
public class SCPInstance : BaseFullAuditEntity public class SCPInstance : BaseFullAuditEntity, IEntitySeqId
{ {
#region 导航属性 #region 导航属性
[JsonIgnore] [JsonIgnore]
@ -18,7 +18,6 @@ namespace IRaCIS.Core.Domain.Models
#endregion #endregion
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid SeqId { get; set; } public Guid SeqId { get; set; }
public Guid StudyId { get; set; } public Guid StudyId { get; set; }

View File

@ -6,7 +6,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models namespace IRaCIS.Core.Domain.Models
{ {
[Table("SCPSeries")] [Table("SCPSeries")]
public class SCPSeries : BaseFullDeleteAuditEntity public class SCPSeries : BaseFullDeleteAuditEntity, IEntitySeqId
{ {
#region 导航属性 #region 导航属性
[JsonIgnore] [JsonIgnore]
@ -18,7 +18,6 @@ namespace IRaCIS.Core.Domain.Models
#endregion #endregion
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid SeqId { get; set; } public Guid SeqId { get; set; }
public Guid StudyId { get; set; } public Guid StudyId { get; set; }
public string StudyInstanceUid { get; set; } public string StudyInstanceUid { get; set; }

View File

@ -6,7 +6,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models namespace IRaCIS.Core.Domain.Models
{ {
[Table("SCPStudy")] [Table("SCPStudy")]
public class SCPStudy : BaseFullDeleteAuditEntity public class SCPStudy : BaseFullDeleteAuditEntity, IEntitySeqId
{ {
#region 导航属性 #region 导航属性
@ -31,9 +31,6 @@ namespace IRaCIS.Core.Domain.Models
//0 未知 1 单重 2 双重 //0 未知 1 单重 2 双重
public bool IsDoubleReview { get; set; } public bool IsDoubleReview { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid SeqId { get; set; } public Guid SeqId { get; set; }
[ForeignKey("PatientId")] [ForeignKey("PatientId")]

View File

@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models namespace IRaCIS.Core.Domain.Models
{ {
public class TaskInstance : BaseFullAuditEntity public class TaskInstance : BaseFullAuditEntity, IEntitySeqId
{ {
#region 导航属性 #region 导航属性
[JsonIgnore] [JsonIgnore]
@ -17,7 +17,6 @@ namespace IRaCIS.Core.Domain.Models
#endregion #endregion
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid SeqId { get; set; } public Guid SeqId { get; set; }
public Guid StudyId { get; set; } public Guid StudyId { get; set; }

View File

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models namespace IRaCIS.Core.Domain.Models
{ {
public class TaskSeries : BaseFullDeleteAuditEntity public class TaskSeries : BaseFullDeleteAuditEntity, IEntitySeqId
{ {
#region 导航属性 #region 导航属性
[JsonIgnore] [JsonIgnore]
@ -18,7 +18,6 @@ namespace IRaCIS.Core.Domain.Models
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid SeqId { get; set; } public Guid SeqId { get; set; }
public Guid StudyId { get; set; } public Guid StudyId { get; set; }
public string StudyInstanceUid { get; set; } public string StudyInstanceUid { get; set; }

View File

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models namespace IRaCIS.Core.Domain.Models
{ {
public class TaskStudy : BaseFullDeleteAuditEntity public class TaskStudy : BaseFullDeleteAuditEntity, IEntitySeqId
{ {
#region 导航属性 #region 导航属性
[JsonIgnore] [JsonIgnore]
@ -33,8 +33,6 @@ namespace IRaCIS.Core.Domain.Models
#endregion #endregion
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid SeqId { get; set; } public Guid SeqId { get; set; }
public Guid TrialId { get; set; } public Guid TrialId { get; set; }

View File

@ -32,6 +32,10 @@ namespace IRaCIS.Core.Domain.Models
public List<VisitTask> VisitTaskList { get; set; } public List<VisitTask> VisitTaskList { get; set; }
[JsonIgnore]
public List<TrialClinicalDataSetCriterion> TrialClinicalDataSetCriterionList { get; set; }
#endregion #endregion
/// <summary> /// <summary>
/// 系统标准ID /// 系统标准ID

View File

@ -47,14 +47,18 @@ namespace IRaCIS.Core.Domain.Models
public List<ReadModuleCriterionFrom> ReadModuleCriterionFromList { get; set; } = new List<ReadModuleCriterionFrom>(); public List<ReadModuleCriterionFrom> ReadModuleCriterionFromList { get; set; } = new List<ReadModuleCriterionFrom>();
[JsonIgnore] [JsonIgnore]
public List<VisitTask> ModuleTaskList { get; set; } public List<VisitTask> ModuleTaskList { get; set; }
[JsonIgnore] [JsonIgnore]
public ReadingQuestionCriterionTrial TrialReadingCriterion { get; set; } public ReadingQuestionCriterionTrial TrialReadingCriterion { get; set; }
[JsonIgnore]
public List<ReadingClinicalData> ReadingClinicalDataList { get; set; }
#endregion #endregion
public Guid SubjectId { get; set; } public Guid SubjectId { get; set; }
public Guid TrialReadingCriterionId { get; set; } public Guid TrialReadingCriterionId { get; set; }

View File

@ -75,9 +75,12 @@ namespace IRaCIS.Core.Domain.Models
[ForeignKey("ReviewModeId")] [ForeignKey("ReviewModeId")]
public Dictionary ReviewMode { get; set; } public Dictionary ReviewMode { get; set; }
[JsonIgnore] //[JsonIgnore]
public List<ClinicalDataTrialSet> clinicalDataTrialSets { get; set; } = new List<ClinicalDataTrialSet> { }; //public List<TrialClinicalDataSetCriterion> TrialClinicalDataSetCriterionList { get; set; }
[JsonIgnore]
public List<ClinicalDataTrialSet> ClinicalDataTrialSetList { get; set; } = new List<ClinicalDataTrialSet> { };
[JsonIgnore] [JsonIgnore]
public List<TrialStatusDetail> ClinicalTrialProjectDetails { get; set; } = new List<TrialStatusDetail> { }; public List<TrialStatusDetail> ClinicalTrialProjectDetails { get; set; } = new List<TrialStatusDetail> { };
[JsonIgnore] [JsonIgnore]

View File

@ -53,6 +53,9 @@ namespace IRaCIS.Core.Domain.Models
public Trial Trial { get; set; } public Trial Trial { get; set; }
[JsonIgnore]
public List<ReadModule> ReadModuleList { get; set; }
[JsonIgnore] [JsonIgnore]
[ForeignKey("SubjectId")] [ForeignKey("SubjectId")]

View File

@ -1,56 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using IRaCIS.Core.Domain.Models;
namespace IRaCIS.Core.Infra.EFCore
{
#region AuditContext
public class AuditContext : DbContext
{
//传递委托进来写日志
private readonly string _connectionString;
public AuditContext(string connectionString)
{
_connectionString = connectionString;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer(_connectionString);
public DbSet<SaveChangesAudit> SaveChangesAudits { get; set; }
}
public class SaveChangesAudit
{
public Guid Id { get; set; }
//public Guid AuditId { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public bool Succeeded { get; set; } = false;
public string ErrorMessage { get; set; } = string.Empty;
public ICollection<EntityAudit> Entities { get; } = new List<EntityAudit>();
}
public class EntityAudit: IAuditAddWithUserName
{
public Guid Id { get; set; }
public Guid AlterId { get; set; }=Guid.Empty;
public Guid SaveChangesAuditId { get; set; }
public EntityState State { get; set; }
public string AuditMessage { get; set; }
public SaveChangesAudit SaveChangesAudit { get; set; }
public string CreateUser { get; set; } = string.Empty;
public Guid CreateUserId { get; set; }=Guid.Empty;
public DateTime CreateTime { get; set; }=DateTime.Now;
}
#endregion
}

View File

@ -56,15 +56,13 @@ namespace IRaCIS.Core.Infra.EFCore
public class IRaCISDBContext : DbContext public class IRaCISDBContext : DbContext
{ {
private IUserInfo _userInfo;
private readonly ILogger<IRaCISDBContext> _logger; private readonly ILogger<IRaCISDBContext> _logger;
public IRaCISDBContext(DbContextOptions<IRaCISDBContext> options, IUserInfo userInfo, ILogger<IRaCISDBContext> logger public IRaCISDBContext(DbContextOptions<IRaCISDBContext> options, ILogger<IRaCISDBContext> logger
) : base(options) ) : base(options)
{ {
_userInfo = userInfo;
_logger = logger; _logger = logger;
} }
@ -72,6 +70,7 @@ namespace IRaCIS.Core.Infra.EFCore
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
{ {
//遍历实体模型手动配置 //遍历实体模型手动配置
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(q => q.GetInterface(typeof(IEntityTypeConfiguration<>).FullName) != null); var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(q => q.GetInterface(typeof(IEntityTypeConfiguration<>).FullName) != null);
foreach (var type in typesToRegister) foreach (var type in typesToRegister)
@ -95,6 +94,10 @@ namespace IRaCIS.Core.Infra.EFCore
{ {
modelBuilder.Entity(entityType.ClrType).Property<Guid>(nameof(Entity.Id)).HasValueGenerator<MySequentialGuidValueGenerator>(); modelBuilder.Entity(entityType.ClrType).Property<Guid>(nameof(Entity.Id)).HasValueGenerator<MySequentialGuidValueGenerator>();
} }
if (typeof(IEntitySeqId).IsAssignableFrom(entityType.ClrType))
{
modelBuilder.Entity(entityType.ClrType).Property<Guid>(nameof(IEntitySeqId.SeqId)).HasValueGenerator<MySequentialGuidValueGenerator>();
}
} }
} }
@ -155,15 +158,13 @@ namespace IRaCIS.Core.Infra.EFCore
}); });
} }
return tableColumList.OrderBy(t=>t.Name).ToList(); return tableColumList.OrderBy(t => t.Name).ToList();
} }
#endregion #endregion
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{ {
// 采用触发器的方式 设置 CreateUserId CreateTime UpdateTime UpdateUserId 稽查实体里面没有这四个字段的值 因为先后顺序的原因
await AddAudit();
try try
{ {
@ -222,28 +223,7 @@ namespace IRaCIS.Core.Infra.EFCore
} }
public async Task AddAudit()
{
//触发器里面提交事务 业务方法里面提交事务 会记录两次
var inspectionGeneralIdList = ChangeTracker.Entries().Where(t => typeof(DataInspection).IsAssignableFrom(t.Entity.GetType())).Select(t => ((DataInspection)t.Entity).GeneralId).ToList();
var entities = ChangeTracker.Entries().Where(u => (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added))
.Where(t => !typeof(DataInspection).IsAssignableFrom(t.Entity.GetType()) && !inspectionGeneralIdList.Contains(((Entity)t.Entity).Id))
.ToList();
AuditingData auditingData = new AuditingData(this, _userInfo);
//await auditingData.IncomingEntitys(entities);
if (entities.Count > 0)
{
await auditingData.InsertAddEntitys(entities);
}
}
#region Doctor #region Doctor
public virtual DbSet<Dictionary> Dictionary { get; set; } public virtual DbSet<Dictionary> Dictionary { get; set; }
@ -399,7 +379,6 @@ namespace IRaCIS.Core.Infra.EFCore
public virtual DbSet<TrialAudit> TrialAudit { get; set; } public virtual DbSet<TrialAudit> TrialAudit { get; set; }
public virtual DbSet<UserType> UserType { get; set; } public virtual DbSet<UserType> UserType { get; set; }
public virtual DbSet<SaveChangesAudit> SaveChangesAudits { get; set; }

View File

@ -0,0 +1,18 @@
using IRaCIS.Core.Domain.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace IRaCIS.Core.Infra.EFCore.EntityConfigration
{
public class ReadModuleConfigration : IEntityTypeConfiguration<ReadModule>
{
public void Configure(EntityTypeBuilder<ReadModule> builder)
{
builder.HasOne(t => t.SubjectVisit).WithMany(t => t.ReadModuleList);
}
}
}

View File

@ -19,11 +19,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="EFCore.BulkExtensions" Version="8.0.1" /> <PackageReference Include="EFCore.BulkExtensions" Version="8.1.0" />
<PackageReference Include="EntityFrameworkCore.Triggered" Version="3.2.2" /> <PackageReference Include="EntityFrameworkCore.Triggered" Version="3.2.2" />
<PackageReference Include="EntityFrameworkCore.Projectables" Version="3.0.4" /> <PackageReference Include="EntityFrameworkCore.Projectables" Version="3.0.4" />
<PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="8.0.0" /> <PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="8.1.3" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.8" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
</ItemGroup> </ItemGroup>

View File

@ -1,6 +1,9 @@
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using Microsoft.AspNetCore.Mvc.Diagnostics;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Diagnostics;
using System; using System;
using System.Linq; using System.Linq;
@ -23,8 +26,12 @@ public class AuditEntityInterceptor(IUserInfo _userInfo) : SaveChangesIntercepto
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData,
InterceptionResult<int> result, CancellationToken cancellationToken = default) InterceptionResult<int> result, CancellationToken cancellationToken = default)
{ {
//审计时间
AuditEntities(eventData.Context); AuditEntities(eventData.Context);
//IRC稽查 放在savechange 之前 不影响之前的逻辑
IRCDataInspection(eventData.Context);
return base.SavingChangesAsync(eventData, result, cancellationToken); return base.SavingChangesAsync(eventData, result, cancellationToken);
} }
public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result) public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
@ -38,7 +45,7 @@ public class AuditEntityInterceptor(IUserInfo _userInfo) : SaveChangesIntercepto
if (context == null) return; if (context == null) return;
// 获取所有更改,删除,新增的实体,但排除审计实体(避免死循环) // 获取所有更改,删除,新增的实体,但排除审计实体(避免死循环)
foreach (var entry in context.ChangeTracker.Entries().Where(u => (u.State == EntityState.Modified || u.State == EntityState.Added)) foreach (var entry in context.ChangeTracker.Entries().Where(u => (u.State == EntityState.Modified || u.State == EntityState.Added))
.Where(x => !typeof(DataInspection).IsAssignableFrom(x.Entity.GetType())).ToList()) .Where(x => !typeof(DataInspection).IsAssignableFrom(x.Entity.GetType())).ToList())
{ {
switch (entry.State) switch (entry.State)
@ -103,7 +110,23 @@ public class AuditEntityInterceptor(IUserInfo _userInfo) : SaveChangesIntercepto
break; break;
} }
} }
}
public void IRCDataInspection(DbContext? context)
{
//触发器里面提交事务 业务方法里面提交事务 会记录两次
var inspectionGeneralIdList = context.ChangeTracker.Entries().Where(t => typeof(DataInspection).IsAssignableFrom(t.Entity.GetType())).Select(t => ((DataInspection)t.Entity).GeneralId).ToList();
var entities = context.ChangeTracker.Entries().Where(u => (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added))
.Where(t => !typeof(DataInspection).IsAssignableFrom(t.Entity.GetType()) && !inspectionGeneralIdList.Contains(((Entity)t.Entity).Id))
.ToList();
AuditingData auditingData = new AuditingData((IRaCISDBContext)context, _userInfo);
if (entities.Count > 0)
{
auditingData.InsertAddEntitys(entities).GetAwaiter().GetResult();
}
} }
} }

View File

@ -11,6 +11,8 @@ using MassTransit;
namespace IRaCIS.Core.Infra.EFCore.Interceptor namespace IRaCIS.Core.Infra.EFCore.Interceptor
{ {
// ISendEndpoint提供了Send方法用于发送命令。
//IPublishEndpoint提供了Publish方法用于发布事件。
public class DispatchDomainEventsInterceptor(IPublishEndpoint publishEndpoint) : SaveChangesInterceptor public class DispatchDomainEventsInterceptor(IPublishEndpoint publishEndpoint) : SaveChangesInterceptor
{ {

View File

@ -1,148 +0,0 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infra.EFCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Diagnostics;
public class AuditingInterceptor : ISaveChangesInterceptor
{
private readonly string _connectionString;
private SaveChangesAudit _audit;
public AuditingInterceptor(string connectionString)
{
_connectionString = connectionString;
}
#region SavingChanges
public async ValueTask<InterceptionResult<int>> SavingChangesAsync(
DbContextEventData eventData,
InterceptionResult<int> result,
CancellationToken cancellationToken = default)
{
_audit = CreateAudit(eventData.Context);
await Task.CompletedTask;
return result;
}
public InterceptionResult<int> SavingChanges(
DbContextEventData eventData,
InterceptionResult<int> result)
{
_audit = CreateAudit(eventData.Context);
return result;
}
#endregion
#region SavedChanges
public async ValueTask<int> SavedChangesAsync(
SaveChangesCompletedEventData eventData,
int result,
CancellationToken cancellationToken = default)
{
if (_audit.Entities.Count > 0)
{
var auditContext = eventData.Context as IRaCISDBContext;
_audit.Succeeded = true;
auditContext.SaveChangesAudits.Add(_audit);
_audit.EndTime = DateTime.Now;
await auditContext.SaveChangesAsync();
}
return result;
}
#endregion
#region SaveChangesFailed
public void SaveChangesFailed(DbContextErrorEventData eventData)
{
using (var auditContext = new AuditContext(_connectionString))
{
auditContext.Attach(_audit);
_audit.Succeeded = false;
_audit.EndTime = DateTime.Now;
_audit.ErrorMessage = eventData.Exception.Message;
auditContext.SaveChanges();
}
}
public async Task SaveChangesFailedAsync(
DbContextErrorEventData eventData,
CancellationToken cancellationToken = default)
{
using (var auditContext = new AuditContext(_connectionString))
{
auditContext.Attach(_audit);
_audit.Succeeded = false;
_audit.EndTime = DateTime.Now;
_audit.ErrorMessage = eventData.Exception.InnerException?.Message;
await auditContext.SaveChangesAsync(cancellationToken);
}
}
#endregion
#region CreateAudit
private static bool NeedAudit(EntityEntry entityEntry)
{
var type = entityEntry.Entity.GetType();
return type != typeof(EntityAudit) && type != typeof(SaveChangesAudit) && type != typeof(DicomSeries) && type != typeof(DicomInstance) && type != typeof(TrialAudit);
}
private static SaveChangesAudit CreateAudit(DbContext context)
{
context.ChangeTracker.DetectChanges();
var audit = new SaveChangesAudit { StartTime = DateTime.Now };
foreach (var entry in context.ChangeTracker.Entries().Where(t => NeedAudit(t)))
{
var auditMessage = entry.State switch
{
EntityState.Deleted => CreateDeletedMessage(entry),
EntityState.Modified => CreateModifiedMessage(entry),
EntityState.Added => CreateAddedMessage(entry),
_ => null
};
if (auditMessage != null)
{
var alterIdStr = entry.CurrentValues["Id"].ToString();
audit.Entities.Add(new EntityAudit { State = entry.State, AuditMessage = auditMessage, AlterId = Guid.Parse(alterIdStr) });
}
}
return audit;
string CreateAddedMessage(EntityEntry entry)
=>
entry.Properties.Aggregate(
$"Inserting {entry.Metadata.DisplayName()} with ",
(auditString, property) => auditString + $"{property.Metadata.Name}: '{property.CurrentValue}' ");
string CreateModifiedMessage(EntityEntry entry)
=> entry.Properties.Where(property => property.IsModified || property.Metadata.IsPrimaryKey()).Aggregate(
$"Updating {entry.Metadata.DisplayName()} with ",
(auditString, property) => auditString + $"{property.Metadata.Name}: '{property.CurrentValue}' ");
string CreateDeletedMessage(EntityEntry entry)
=> entry.Properties.Where(property => property.Metadata.IsPrimaryKey()).Aggregate(
$"Deleting {entry.Metadata.DisplayName()} with ",
(auditString, property) => auditString + $"{property.Metadata.Name}: '{property.CurrentValue}' ");
}
#endregion
}

View File

@ -11,14 +11,14 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" /> <PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="10.0.0" /> <PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="10.0.0" />
<PackageReference Include="MassTransit" Version="8.2.4" /> <PackageReference Include="MassTransit" Version="8.2.5" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.8" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
<PackageReference Include="SharpCompress" Version="0.37.2" /> <PackageReference Include="SharpCompress" Version="0.37.2" />
<PackageReference Include="SharpZipLib" Version="1.4.2" /> <PackageReference Include="SharpZipLib" Version="1.4.2" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.3" /> <PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.5" />
</ItemGroup> </ItemGroup>

View File

@ -5,12 +5,11 @@ namespace IRaCIS.Core.Infrastructure.Extention
/// <summary> /// <summary>
/// 分页信息输入 /// 分页信息输入
/// </summary> /// </summary>
public class PageInput public class PageInput: SortInput
{ {
public int PageIndex { get; set; } = 1; public int PageIndex { get; set; } = 1;
public int PageSize { set; get; } = 10; public int PageSize { set; get; } = 10;
public bool Asc { get; set; } = true;
public string SortField { get; set; } = "";
} }
public class SortInput public class SortInput

View File

@ -12,16 +12,6 @@
<OutputPath>..\bin</OutputPath> <OutputPath>..\bin</OutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup> <ItemGroup>
<None Update="TT_Template\IRaCIS .Core.ServiceAsync.tt"> <None Update="TT_Template\IRaCIS .Core.ServiceAsync.tt">
<LastGenOutput>IRaCIS .Core.ServiceAsync.cs</LastGenOutput> <LastGenOutput>IRaCIS .Core.ServiceAsync.cs</LastGenOutput>
@ -105,6 +95,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Test\Audit\" />
<Folder Include="TT_Template\Dto_New\" /> <Folder Include="TT_Template\Dto_New\" />
<Folder Include="TT_Template\IServices_New\" /> <Folder Include="TT_Template\IServices_New\" />
<Folder Include="TT_Template\Models_New\" /> <Folder Include="TT_Template\Models_New\" />

View File

@ -1,43 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
#region AuditContext
public class AuditContext : DbContext
{
private readonly string _connectionString;
public AuditContext(string connectionString)
{
_connectionString = connectionString;
}
//protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
// => optionsBuilder.Usesq(_connectionString);
public DbSet<SaveChangesAudit> SaveChangesAudits { get; set; }
}
public class SaveChangesAudit
{
public int Id { get; set; }
public Guid AuditId { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public bool Succeeded { get; set; }
public string ErrorMessage { get; set; }
public ICollection<EntityAudit> Entities { get; } = new List<EntityAudit>();
}
public class EntityAudit
{
public int Id { get; set; }
public EntityState State { get; set; }
public string AuditMessage { get; set; }
public SaveChangesAudit SaveChangesAudit { get; set; }
}
#endregion