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

@ -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,22 +56,21 @@ 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;
} }
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,12 +94,16 @@ 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>();
}
} }
} }
#region 获取表名 和字段名 优化 #region 获取表名 和字段名 优化
/// <summary> /// <summary>
/// 直接获取代码定义的模型以及表上定义的Description 获取表信息 以及备注 /// 直接获取代码定义的模型以及表上定义的Description 获取表信息 以及备注
/// </summary> /// </summary>
@ -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