From 603f6e095c0813a348c09786335708be1fdfeb19 Mon Sep 17 00:00:00 2001 From: hang <87227557@qq.com> Date: Thu, 12 Sep 2024 23:51:51 +0800 Subject: [PATCH 01/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Domain/Trial/Trial.cs | 19 +- .../CodeFirstTest/CodeFirst使用说明 | 9 + .../Convention/MaxStringLengthConvention .cs | 27 ++- .../CodeFirstTest/MSSQL/IRCContext.cs | 5 +- .../20240912145208_test.Designer.cs | 146 ++++++++++++++ .../MSSQL/Migrations/20240912145208_test.cs | 40 ++++ .../20240912152420_testSTR.Designer.cs | 183 ++++++++++++++++++ .../Migrations/20240912152420_testSTR.cs | 40 ++++ .../Migrations/IRCContextModelSnapshot.cs | 50 ++++- .../CodeFirstTest/MSSQL/TrialImageDownload.cs | 14 ++ .../Convention/MaxStringLengthConvention .cs | 50 +++++ .../NoForeignKeyMigrationsSqlGenerator.cs | 20 ++ .../CodeFirstTest/PGSQL/PGContext.cs | 32 ++- .../CodeFirstTest/PGSQL/Subject.cs | 84 -------- IRaCIS.Core.Test/Program.cs | 4 +- 15 files changed, 616 insertions(+), 107 deletions(-) create mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.Designer.cs create mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.cs create mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.Designer.cs create mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.cs create mode 100644 IRaCIS.Core.Test/CodeFirstTest/PGSQL/Convention/MaxStringLengthConvention .cs create mode 100644 IRaCIS.Core.Test/CodeFirstTest/PGSQL/Convention/NoForeignKeyMigrationsSqlGenerator.cs delete mode 100644 IRaCIS.Core.Test/CodeFirstTest/PGSQL/Subject.cs diff --git a/IRaCIS.Core.Domain/Trial/Trial.cs b/IRaCIS.Core.Domain/Trial/Trial.cs index f80e1657b..184c754a0 100644 --- a/IRaCIS.Core.Domain/Trial/Trial.cs +++ b/IRaCIS.Core.Domain/Trial/Trial.cs @@ -13,13 +13,15 @@ namespace IRaCIS.Core.Domain.Models { #region 导航属性 [JsonIgnore] + [ForeignKey("SponsorId")] + public Sponsor Sponsor { get; set; } + [JsonIgnore] + [ForeignKey("CROId")] + public CRO CRO { get; set; } + [JsonIgnore] public List TrialBodyPartList { get; set; } - - [JsonIgnore] public List TaskMedicalReviewList { get; set; } - - [JsonIgnore] public List TaskConsistentRuleList { get; set; } [JsonIgnore] @@ -56,21 +58,12 @@ namespace IRaCIS.Core.Domain.Models public List ReadModuleList { get; set; } = new List(); [JsonIgnore] public List UserFeedBackList { get; set; } = new List(); - [JsonIgnore] [ForeignKey("IndicationTypeId")] public Dictionary IndicationType { get; set; } - [JsonIgnore] [ForeignKey("PhaseId")] public Dictionary Phase { get; set; } - - [JsonIgnore] - [ForeignKey("SponsorId")] - public Sponsor Sponsor { get; set; } - [JsonIgnore] - [ForeignKey("CROId")] - public CRO CRO { get; set; } [JsonIgnore] [ForeignKey("ReviewModeId")] public Dictionary ReviewMode { get; set; } diff --git a/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 b/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 index f2828578e..0693d6509 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 +++ b/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 @@ -21,3 +21,12 @@ https://www.cnblogs.com/cqpanda/p/16815263.html dotnet ef database update ijǨƵǰһǨ -p IRaCIS.Core.Test -c IRCContext dotnet ef migrations add RemoveForeignKey -p IRaCIS.Core.Test -c IRCContext -o CodeFirstTest/MSSQL/Migrations + + + + + + PGSQL ָ + dotnet ef migrations add testSTR -p IRaCIS.Core.Test -c PGContext -o CodeFirstTest/PGSQL/Migrations + + dotnet ef migrations remove -p IRaCIS.Core.Test -c PGContext \ No newline at end of file diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/MaxStringLengthConvention .cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/MaxStringLengthConvention .cs index a7ab7624a..f7198ecad 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/MaxStringLengthConvention .cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/MaxStringLengthConvention .cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using System; +using System.ComponentModel.DataAnnotations; using System.Linq; namespace IRaCIS.Core.Test @@ -17,7 +19,30 @@ namespace IRaCIS.Core.Test .Where( property => property.ClrType == typeof(string)))) { - property.Builder.HasMaxLength(200); + + // 获取 MaxLength 特性 + var maxLengthAttribute = property.PropertyInfo?.GetCustomAttributes(typeof(MaxLengthAttribute), false) + .FirstOrDefault() as MaxLengthAttribute; + + // 获取 StringLength 特性 + var stringLengthAttribute = property.PropertyInfo?.GetCustomAttributes(typeof(StringLengthAttribute), false) + .FirstOrDefault() as StringLengthAttribute; + + // 输出调试信息,看看是哪种特性生效 + if (stringLengthAttribute != null) + { + //Console.WriteLine($"{property.Name}: StringLength({stringLengthAttribute.MaximumLength})"); + property.Builder.HasMaxLength(stringLengthAttribute.MaximumLength); + } + else if (maxLengthAttribute != null) + { + //Console.WriteLine($"{property.Name}: MaxLength (no specific length, allowing max)"); + } + else + { + //Console.WriteLine($"{property.Name}: Default length 200"); + property.Builder.HasMaxLength(200); + } } } } diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs index 2792bb81c..d89991305 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs @@ -26,11 +26,14 @@ public partial class IRCContext : DbContext //public virtual DbSet ReadModule { get; set; } //public virtual DbSet TestStringLength { get; set; } + + + public virtual DbSet TestStr { get; set; } public virtual DbSet Project { get; set; } public virtual DbSet ProjectUser { get; set; } public virtual DbSet ProjectUser2 { get; set; } - + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.Designer.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.Designer.cs new file mode 100644 index 000000000..d0f7385ae --- /dev/null +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.Designer.cs @@ -0,0 +1,146 @@ +// +using System; +using IRaCIS.Core.Test.CodeFirstTest.MSSQL; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations +{ + [DbContext(typeof(IRCContext))] + [Migration("20240912145208_test")] + partial class test + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("Project"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name2") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OtherName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectUser"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectUser2"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => + { + b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => + { + b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.cs new file mode 100644 index 000000000..f4e031f05 --- /dev/null +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations +{ + /// + public partial class test : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "Name", + table: "ProjectUser", + newName: "OtherName"); + + migrationBuilder.AddColumn( + name: "Name2", + table: "ProjectUser", + type: "nvarchar(200)", + maxLength: 200, + nullable: false, + defaultValue: ""); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Name2", + table: "ProjectUser"); + + migrationBuilder.RenameColumn( + name: "OtherName", + table: "ProjectUser", + newName: "Name"); + } + } +} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.Designer.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.Designer.cs new file mode 100644 index 000000000..9c516cb77 --- /dev/null +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.Designer.cs @@ -0,0 +1,183 @@ +// +using System; +using IRaCIS.Core.Test.CodeFirstTest.MSSQL; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations +{ + [DbContext(typeof(IRCContext))] + [Migration("20240912152420_testSTR")] + partial class testSTR + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("Project"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name2") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OtherName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectUser"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectUser2"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DefineLength") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("DefualtLength") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("MaxLength") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("TestStr"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => + { + b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => + { + b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.cs new file mode 100644 index 000000000..6b04291ac --- /dev/null +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.cs @@ -0,0 +1,40 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations +{ + /// + public partial class testSTR : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "TestStr", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + DefualtLength = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + MaxLength = table.Column(type: "nvarchar(max)", nullable: false), + DefineLength = table.Column(type: "nvarchar(400)", maxLength: 400, nullable: false), + CreateUserId = table.Column(type: "uniqueidentifier", nullable: false), + CreateTime = table.Column(type: "datetime2", nullable: false), + UpdateUserId = table.Column(type: "uniqueidentifier", nullable: false), + UpdateTime = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TestStr", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "TestStr"); + } + } +} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs index 2a1d0e054..58210d549 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs @@ -42,7 +42,7 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.HasKey("Id"); - b.ToTable("Project", (string)null); + b.ToTable("Project"); }); modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => @@ -62,7 +62,12 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.Property("CreateUserId") .HasColumnType("uniqueidentifier"); - b.Property("Name") + b.Property("Name2") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OtherName") .IsRequired() .HasMaxLength(200) .HasColumnType("nvarchar(200)"); @@ -80,7 +85,7 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.HasIndex("ProjectId"); - b.ToTable("ProjectUser", (string)null); + b.ToTable("ProjectUser"); }); modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => @@ -108,7 +113,44 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.HasIndex("ProjectId"); - b.ToTable("ProjectUser2", (string)null); + b.ToTable("ProjectUser2"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DefineLength") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("DefualtLength") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("MaxLength") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("TestStr"); }); modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs index 876fedd1c..1a9805d06 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs @@ -180,5 +180,19 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL } #endregion + #region 测试字符串长度 + + public class TestStr: BaseFullAuditEntity + { + public string DefualtLength { get; set; } + + [MaxLength] + public string MaxLength { get; set; } + + [StringLength(400)] + public string DefineLength { get; set;} + } + #endregion + } diff --git a/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Convention/MaxStringLengthConvention .cs b/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Convention/MaxStringLengthConvention .cs new file mode 100644 index 000000000..e59564802 --- /dev/null +++ b/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Convention/MaxStringLengthConvention .cs @@ -0,0 +1,50 @@ +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using System; +using System.ComponentModel.DataAnnotations; +using System.Linq; + +namespace IRaCIS.Core.Test.CodeFirstTest.PGSQL.Migrations +{ + /// + /// Efcore 最新支持批量配置字符串类型长度作为保底的 官网参考:https://learn.microsoft.com/zh-cn/ef/core/modeling/bulk-configuration#conventions + /// + public class MaxStringLengthConvention : IModelFinalizingConvention + { + public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext context) + { + foreach (var property in modelBuilder.Metadata.GetEntityTypes() + .SelectMany( + entityType => entityType.GetDeclaredProperties() + .Where( + property => property.ClrType == typeof(string)))) + { + + // 获取 MaxLength 特性 + var maxLengthAttribute = property.PropertyInfo?.GetCustomAttributes(typeof(MaxLengthAttribute), false) + .FirstOrDefault() as MaxLengthAttribute; + + // 获取 StringLength 特性 + var stringLengthAttribute = property.PropertyInfo?.GetCustomAttributes(typeof(StringLengthAttribute), false) + .FirstOrDefault() as StringLengthAttribute; + + // 输出调试信息,看看是哪种特性生效 + if (stringLengthAttribute != null) + { + Console.WriteLine($"{property.Name}: StringLength({stringLengthAttribute.MaximumLength})"); + property.Builder.HasMaxLength(stringLengthAttribute.MaximumLength); + } + else if (maxLengthAttribute != null) + { + Console.WriteLine($"{property.Name}: MaxLength (no specific length, allowing max)"); + } + else + { + Console.WriteLine($"{property.Name}: Default length 200"); + property.Builder.HasMaxLength(200); + } + } + } + } + +} diff --git a/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Convention/NoForeignKeyMigrationsSqlGenerator.cs b/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Convention/NoForeignKeyMigrationsSqlGenerator.cs new file mode 100644 index 000000000..ba493df11 --- /dev/null +++ b/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Convention/NoForeignKeyMigrationsSqlGenerator.cs @@ -0,0 +1,20 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations.Operations; + +namespace IRaCIS.Core.Test.CodeFirstTest.PGSQL.Migrations +{ + public class NoForeignKeyMigrationsSqlGenerator : MigrationsSqlGenerator + { + public NoForeignKeyMigrationsSqlGenerator( + MigrationsSqlGeneratorDependencies dependencies) : base(dependencies) + { + } + + protected override void Generate(Microsoft.EntityFrameworkCore.Migrations.Operations.CreateTableOperation operation, IModel? model, MigrationCommandListBuilder builder, bool terminate = true) + { + operation.ForeignKeys.Clear(); + base.Generate(operation, model, builder, terminate); + } + } +} diff --git a/IRaCIS.Core.Test/CodeFirstTest/PGSQL/PGContext.cs b/IRaCIS.Core.Test/CodeFirstTest/PGSQL/PGContext.cs index 73dffe521..0437fa656 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/PGSQL/PGContext.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/PGSQL/PGContext.cs @@ -1,8 +1,29 @@ using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using Microsoft.EntityFrameworkCore; -namespace IRaCIS.Core.Test.PGModelFolder; +namespace IRaCIS.Core.Test.CodeFirstTest.PGSQL.Migrations; + +public abstract class BaseFullAuditEntity +{ + [Key] + public Guid Id { get; set; } + public Guid CreateUserId { get; set; } + public DateTime CreateTime { get; set; } + public Guid UpdateUserId { get; set; } + public DateTime UpdateTime { get; set; } +} +public class TestStr : BaseFullAuditEntity +{ + public string DefualtLength { get; set; } + + [MaxLength] + public string MaxLength { get; set; } + + [StringLength(400)] + public string DefineLength { get; set; } +} public partial class PGContext : DbContext { @@ -15,7 +36,7 @@ public partial class PGContext : DbContext { } - public virtual DbSet Subjects { get; set; } + public virtual DbSet TestStr { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseNpgsql("Host=106.14.89.110;Port=5432;Username=sa;Password=pgsql_pwd;Database=Test6_PG"); @@ -44,6 +65,13 @@ public partial class PGContext : DbContext OnModelCreatingPartial(modelBuilder); } + protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) + { + + //configurationBuilder.Conventions.Add(_ => new NoForeignKeyConvention()); + //针对字符串使用默认的长度配置 + configurationBuilder.Conventions.Add(_ => new MaxStringLengthConvention()); + } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); } diff --git a/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Subject.cs b/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Subject.cs deleted file mode 100644 index 8ac7a14d8..000000000 --- a/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Subject.cs +++ /dev/null @@ -1,84 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; - -namespace IRaCIS.Core.Test.PGModelFolder; - -public partial class Subject -{ - public Guid Id { get; set; } - - [MaxLength(200)] - public string LastName { get; set; } - - public int StudyCount { get; set; } - - public DateTime? DeletedTime { get; set; } - - public DateTime? BirthDate { get; set; } - - public DateTime? FirstGiveMedicineTime { get; set; } - - public bool IsMissingImages { get; set; } - - public string MedicalNo { get; set; } - [MaxLength(200)] - public string ShortName { get; set; } - - public string Reason { get; set; } - - public Guid? FinalSubjectVisitId { get; set; } - - public string Height { get; set; } - - [Comment("subject 编号")] - [MaxLength(100)] - public string Code { get; set; } - - public int? Age { get; set; } - - public string Modalities { get; set; } - - public DateTime? SignDate { get; set; } - - public DateTime UpdateTime { get; set; } - - public Guid CreateUserId { get; set; } - - public string Sex { get; set; } - - public Guid? LatestSubjectVisitId { get; set; } - - public bool IsEnrollmentConfirm { get; set; } - - public Guid? DeleteUserId { get; set; } - - public string Weight { get; set; } - - public DateTime? OutEnrollmentTime { get; set; } - - public DateTime CreateTime { get; set; } - - public string FirstName { get; set; } - - public bool IsUrgent { get; set; } - - public long Status { get; set; } - - public DateTime? VisitOverTime { get; set; } - - public Guid UpdateUserId { get; set; } - - public bool IsDeleted { get; set; } - - public Guid TrialId { get; set; } - - public bool IsEnrollment { get; set; } - - public bool IsAssignDoctorUser { get; set; } - - public bool IsReReadingOrBackInfluenceAnalysis { get; set; } - - public Guid TrialSiteId { get; set; } -} diff --git a/IRaCIS.Core.Test/Program.cs b/IRaCIS.Core.Test/Program.cs index b2b5d4a75..64f171a7c 100644 --- a/IRaCIS.Core.Test/Program.cs +++ b/IRaCIS.Core.Test/Program.cs @@ -58,9 +58,9 @@ partial class Program // 要生成的表名数组 var tableNames = new List(args); - var argsStr = args.ToString()??string.Empty; + var argsStr = string.Join("", args) ??string.Empty; - if (argsStr.Contains(".") || argsStr.Contains("-")|| argsStr.Contains("application")|| argsStr.Contains("IR")) + if ( argsStr.Contains("-")|| argsStr.Contains("application") || argsStr.Contains("Test") || argsStr.Contains(".")) { tableNames = new List(); } From daac69c0d10ccbbcc5e565d1ab9bb0024cc6fb83 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 09:16:30 +0800 Subject: [PATCH 02/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=84=E9=97=B4?= =?UTF-8?q?=E4=B8=80=E8=87=B4=E6=80=A7=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/DownloadAndUploadService.cs | 3 ++- .../Service/ImageAndDoc/_MapConfig.cs | 4 ++-- IRaCIS.Core.Application/TestService.cs | 13 ++++--------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 16ec18d5e..5941c0d16 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -135,7 +135,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc CriterionModalitys = u.TrialReadingCriterion.CriterionModalitys, - SubjectCode = u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code, + SubjectCode = u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code, TaskBlindName = u.TaskBlindName, TaskName = u.TaskName, @@ -183,6 +183,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var list = await query.Where(t => t.SubjectCode == inQuery.SubjectCode).ToListAsync(); + return ResponseOutput.Ok(list); } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/_MapConfig.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/_MapConfig.cs index 5ba39efb7..863fa4c51 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/_MapConfig.cs @@ -130,7 +130,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.VisitTaskId, u => u.MapFrom(s => s.Id)) .ForMember(d => d.IsImageFilter, u => u.MapFrom(s => s.TrialReadingCriterion.IsImageFilter)) .ForMember(d => d.CriterionModalitys, u => u.MapFrom(s => s.TrialReadingCriterion.CriterionModalitys)) - .ForMember(d => d.SubjectCode, u => u.MapFrom(u => u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code)); + .ForMember(d => d.SubjectCode, u => u.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code)); CreateMap(); CreateMap(); @@ -138,7 +138,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.VisitTaskId, u => u.MapFrom(s => s.Id)) .ForMember(d => d.IsImageFilter, u => u.MapFrom(s => s.TrialReadingCriterion.IsImageFilter)) .ForMember(d => d.CriterionModalitys, u => u.MapFrom(s => s.TrialReadingCriterion.CriterionModalitys)) - .ForMember(d => d.SubjectCode, u => u.MapFrom(u => u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code)) + .ForMember(d => d.SubjectCode, u => u.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code)) .ForMember(d => d.DicomStudyList, u => u.MapFrom(s => s.SourceSubjectVisit.StudyList)) .ForMember(d => d.NoneDicomStudyList, u => u.MapFrom(s => s.SourceSubjectVisit.NoneDicomStudyList)) ; diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index 07b667ab0..ea68d33da 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -78,29 +78,24 @@ namespace IRaCIS.Application.Services await _visitTaskRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == true); - await _readingConsistentClinicalDataPDFRepository.BatchDeleteNoTrackingAsync(t => consistentSubjectIdList.Contains(t.ReadingConsistentClinicalData.SubjectId)); await _readingConsistentClinicalDataRepository.BatchDeleteNoTrackingAsync(t => consistentSubjectIdList.Contains(t.SubjectId)); - await _readingConsistentClinicalDataRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } - public async Task DeleteOSSDate([FromServices] IOSSService _oSSService, [FromServices] IWebHostEnvironment _hostEnvironment) + public async Task DeleteOSSDate(string trialId, + [FromServices] IOSSService _oSSService, [FromServices] IWebHostEnvironment _hostEnvironment) { - var deleteIdList = _trialRepository.Where(t => t.IsDeleted == true, false, true).Select(t => t.Id).ToList(); - + //var deleteIdList = _trialRepository.Where(t => t.IsDeleted == true, false, true).Select(t => t.Id).ToList(); //foreach (var deleteId in deleteIdList) //{ // await _oSSService.DeleteFromPrefix($"{deleteId}"); - //} - await _oSSService.DeleteFromPrefix($"01000000-0a00-0242-0d73-08dcac46a4bf"); - - + await _oSSService.DeleteFromPrefix($"{trialId}"); return ResponseOutput.Ok(); } From 29842f484be8d0b0d4c9a5fb739df307d9b0cdd9 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 09:28:37 +0800 Subject: [PATCH 03/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BD=B1=E5=83=8F?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/QC/QCListService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index eab79edba..f3b3b2d89 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -62,7 +62,7 @@ namespace IRaCIS.Core.Application.Image.QA .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(SubjectVisit.SubjectId), nameof(SubjectVisit.VisitNum) }; + var defalutSortArray = new string[] { nameof(QCCRCVisitViewModel.IsUrgent) + " desc", nameof(QCCRCVisitViewModel.SubjectCode), nameof(QCCRCVisitViewModel.VisitNum) }; var pageList = await query.ToPagedListAsync(inQuery, defalutSortArray); var config = await _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); From 7404fabcda03804675b190f3f7ce6c1e31217b5a Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 09:40:24 +0800 Subject: [PATCH 04/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/TaskConsistentRuleService.cs | 2 +- .../Service/Allocation/TaskMedicalReviewService.cs | 6 +++--- .../Service/Allocation/VisitTaskService.cs | 12 ++++++------ IRaCIS.Core.Application/Service/QC/QCListService.cs | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs index db1f15367..23fdf23b1 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs @@ -96,7 +96,7 @@ namespace IRaCIS.Core.Application.Service .WhereIf(inQuery.EndSignTime != null, t => t.SignTime <= inQuery.EndSignTime) .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; + var defalutSortArray = new string[] { nameof(AnalysisTaskView.IsUrgent) + " desc", nameof(AnalysisTaskView.SubjectCode), nameof(AnalysisTaskView.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); #region 统计一致性分析临床数据数量 diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs index 6d352635f..393edc9a0 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs @@ -66,7 +66,7 @@ namespace IRaCIS.Core.Application.Service .WhereIf(inQuery.EndAuditSignTime != null, t => t.AuditSignTime <= inQuery.EndAuditSignTime) .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.AuditState), nameof(TaskMedicalReviewView.SubjectId), nameof(TaskMedicalReviewView.ArmEnum) , nameof(TaskMedicalReviewView.VisitTaskNum) }; + var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.AuditState), nameof(TaskMedicalReviewView.SubjectCode), nameof(TaskMedicalReviewView.ArmEnum) , nameof(TaskMedicalReviewView.VisitTaskNum) }; var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery, defalutSortArray); return pageList; @@ -102,7 +102,7 @@ namespace IRaCIS.Core.Application.Service .WhereIf(inQuery.EndSignTime != null, t => t.SignTime < inQuery.EndSignTime) .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(GenerateMedicalReviewTaskView.IsUrgent) + " desc", nameof(GenerateMedicalReviewTaskView.SubjectId) }; + var defalutSortArray = new string[] { nameof(GenerateMedicalReviewTaskView.IsUrgent) + " desc", nameof(GenerateMedicalReviewTaskView.SubjectCode) }; var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); @@ -239,7 +239,7 @@ namespace IRaCIS.Core.Application.Service .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.SubjectId), nameof(TaskMedicalReviewView.ArmEnum), nameof(TaskMedicalReviewView.VisitTaskNum) }; + var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.SubjectCode), nameof(TaskMedicalReviewView.ArmEnum), nameof(TaskMedicalReviewView.VisitTaskNum) }; var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery, defalutSortArray); return ResponseOutput.Ok(pageList, new diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index 55193572a..8a4e35553 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -679,7 +679,7 @@ namespace IRaCIS.Core.Application.Service.Allocation .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; + var defalutSortArray = new string[] { nameof(VisitTaskView.IsUrgent) + " desc", nameof(VisitTaskView.SubjectCode), nameof(VisitTaskView.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); @@ -718,7 +718,7 @@ namespace IRaCIS.Core.Application.Service.Allocation .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTaskView.VisitTaskNum) }; + var defalutSortArray = new string[] { nameof(JudgeVisitTaskView.IsUrgent) + " desc", nameof(JudgeVisitTaskView.SubjectCode), nameof(JudgeVisitTaskView.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); @@ -766,7 +766,7 @@ namespace IRaCIS.Core.Application.Service.Allocation .WhereIf(inQuery.EndSignTime != null, t => t.SignTime < inQuery.EndSignTime) .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; + var defalutSortArray = new string[] { nameof(ReadingTaskView.IsUrgent) + " desc", nameof(ReadingTaskView.SubjectCode), nameof(ReadingTaskView.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); @@ -825,7 +825,7 @@ namespace IRaCIS.Core.Application.Service.Allocation nameof(ReReadingTaskView.RequestReReadingResultEnum) , nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.TaskState), - nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId),nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; + nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectCode),nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; @@ -872,7 +872,7 @@ namespace IRaCIS.Core.Application.Service.Allocation - var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; + var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectCode), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); @@ -1243,7 +1243,7 @@ namespace IRaCIS.Core.Application.Service.Allocation .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; + var defalutSortArray = new string[] { nameof(IRHaveReadView.IsUrgent) + " desc", nameof(IRHaveReadView.SubjectCode), nameof(IRHaveReadView.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index f3b3b2d89..1731cfaee 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -157,7 +157,7 @@ namespace IRaCIS.Core.Application.Image.QA .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.SubjectVisit.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .ProjectTo(_mapper.ConfigurationProvider); - var pageList = await query.ToPagedListAsync(inQuery, new string[] { "IsUrgent desc", "CreateTime asc" }); + var pageList = await query.ToPagedListAsync(inQuery, new string[] { nameof(QCCRCChallengeViewModel.IsUrgent)+ " desc", nameof(QCCRCChallengeViewModel.CreateTime)}); var config = await _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return ResponseOutput.Ok (pageList, config); @@ -195,7 +195,7 @@ namespace IRaCIS.Core.Application.Image.QA .WhereIf(inQuery.IsOverTime != null && inQuery.IsOverTime == false, t => t.IsClosed ? t.ClosedTime < t.DeadlineTime : DateTime.Now < t.DeadlineTime) .ProjectTo(_mapper.ConfigurationProvider); - var pageList = await query.ToPagedListAsync(inQuery, new string[] { "IsUrgent desc", "IsClosed asc" }); + var pageList = await query.ToPagedListAsync(inQuery, new string[] { nameof(QCCRCChallengeViewModel.IsUrgent) + " desc", nameof(QCCRCChallengeViewModel.CreateTime) }); var config = await _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return (pageList, config); @@ -233,9 +233,9 @@ namespace IRaCIS.Core.Application.Image.QA var svExpression = QCCommon.GetSubjectVisitFilter(inQuery.VisitPlanArray); var query = _subjectVisitRepository.Where(x => x.TrialId == inQuery.TrialId) - .WhereIf(inQuery.VisitId != null, t => t.Id == inQuery.VisitId) - .WhereIf(inQuery.CurrentActionUserId != null, t => t.CurrentActionUserId == inQuery.CurrentActionUserId) - .WhereIf(inQuery.ChallengeState != null, t => t.ChallengeState == inQuery.ChallengeState) + .WhereIf(inQuery.VisitId != null, t => t.Id == inQuery.VisitId) + .WhereIf(inQuery.CurrentActionUserId != null, t => t.CurrentActionUserId == inQuery.CurrentActionUserId) + .WhereIf(inQuery.ChallengeState != null, t => t.ChallengeState == inQuery.ChallengeState) .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) .WhereIf(inQuery.SubjectId != null, t => t.Subject.Id == inQuery.SubjectId) .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectInfo), t => /*t.Subject.FirstName.Contains(subjectInfo) || t.Subject.LastName.Contains(subjectInfo) ||*/ t.Subject.Code.Contains(inQuery.SubjectInfo)) @@ -260,7 +260,7 @@ namespace IRaCIS.Core.Application.Image.QA //.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(QCVisitViewModel.IsUrgent) + " desc", nameof(QCVisitViewModel.SubjectId), nameof(QCVisitViewModel.VisitNum) }; + var defalutSortArray = new string[] { nameof(QCVisitViewModel.IsUrgent) + " desc", nameof(QCVisitViewModel.SubjectCode), nameof(QCVisitViewModel.VisitNum) }; //var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(QCVisitViewModel.AuditState) +" asc" }; var pageList = await query.ToPagedListAsync(inQuery, defalutSortArray); From a3296a1ab99b4f8abd523161d068c84bd784800f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 10:06:36 +0800 Subject: [PATCH 05/59] =?UTF-8?q?=E6=B8=85=E7=90=86oss=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/TestService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index ea68d33da..fa8b47db7 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -85,7 +85,7 @@ namespace IRaCIS.Application.Services await _readingConsistentClinicalDataRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } - public async Task DeleteOSSDate(string trialId, + public async Task DeleteOSSDate(string rootFolder, [FromServices] IOSSService _oSSService, [FromServices] IWebHostEnvironment _hostEnvironment) { @@ -95,7 +95,7 @@ namespace IRaCIS.Application.Services // await _oSSService.DeleteFromPrefix($"{deleteId}"); //} - await _oSSService.DeleteFromPrefix($"{trialId}"); + await _oSSService.DeleteFromPrefix($"{rootFolder}"); return ResponseOutput.Ok(); } From 48427f27402b52218fe3c6bf73cc3d23ec7b01ad Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 10:44:34 +0800 Subject: [PATCH 06/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=B4=E6=97=B6?= =?UTF-8?q?=E5=87=AD=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Test_IRC.json | 6 +++--- IRaCIS.Core.API/appsettings.Uat_IRC.json | 6 +++--- IRaCIS.Core.Application/TestService.cs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 078086d1d..b99124cde 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -19,10 +19,10 @@ "RegionId": "cn-shanghai", "InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", "EndPoint": "https://oss-cn-shanghai.aliyuncs.com", - "AccessKeyId": "LTAI5tJV76pYX5yPg1N9QVE8", - "AccessKeySecret": "roRNLa9YG1of4pYruJGCNKBXEWTAWa", + "AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm", + "AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV", + "RoleArn": "acs:ram::1899121822495495:role/dev-oss-access", "BucketName": "zy-irc-test-store", - "RoleArn": "acs:ram::1899121822495495:role/webdirect", "ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", "Region": "oss-cn-shanghai", "DurationSeconds": 7200 diff --git a/IRaCIS.Core.API/appsettings.Uat_IRC.json b/IRaCIS.Core.API/appsettings.Uat_IRC.json index 1493f5f84..087236feb 100644 --- a/IRaCIS.Core.API/appsettings.Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.Uat_IRC.json @@ -18,10 +18,10 @@ "RegionId": "cn-shanghai", "InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", "EndPoint": "https://oss-cn-shanghai.aliyuncs.com", - "AccessKeyId": "LTAI5tJV76pYX5yPg1N9QVE8", - "AccessKeySecret": "roRNLa9YG1of4pYruJGCNKBXEWTAWa", + "AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm", + "AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV", + "RoleArn": "acs:ram::1899121822495495:role/dev-oss-access", "BucketName": "zy-irc-uat-store", - "RoleArn": "acs:ram::1899121822495495:role/webdirect", "ViewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com", "Region": "oss-cn-shanghai", "DurationSeconds": 7200 diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index fa8b47db7..d8876bcac 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -67,7 +67,7 @@ namespace IRaCIS.Application.Services public async Task DeleteConsistentDate(Guid trialReadingCriterionId, [FromServices] IRepository _taskConsistentRuleRepository, [FromServices] IRepository _readingConsistentClinicalDataPDFRepository, - [FromServices] IRepository _readingConsistentClinicalDataRepository + [FromServices] IRepository _readingConsistentClinicalDataRepository ) { From 40d4806f22db95d1bcd6bffd4f9ec9214493a04e Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 11:08:46 +0800 Subject: [PATCH 07/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Prod_IRC.json | 19 ++++++++++--------- .../Service/QC/QCListService.cs | 3 ++- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Prod_IRC.json b/IRaCIS.Core.API/appsettings.Prod_IRC.json index 293d9933e..4d24a5408 100644 --- a/IRaCIS.Core.API/appsettings.Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.Prod_IRC.json @@ -15,15 +15,16 @@ "ObjectStoreService": { "ObjectStoreUse": "AliyunOSS", "AliyunOSS": { - "regionId": "cn-shanghai", - "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", - "endpoint": "https://oss-cn-shanghai.aliyuncs.com", - "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", - "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", - "bucketName": "zy-irc-store", - "roleArn": "acs:ram::1899121822495495:role/oss-upload", - "viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com", - "region": "oss-cn-shanghai" + "RegionId": "cn-shanghai", + "InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", + "EndPoint": "https://oss-cn-shanghai.aliyuncs.com", + "AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH", + "AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH", + "RoleArn": "acs:ram::1899121822495495:role/irc-oss-access", + "BucketName": "zy-irc-store", + "ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com", + "Region": "oss-cn-shanghai", + "DurationSeconds": 7200 }, "MinIO": { "endpoint": "http://192.168.3.68", diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index 1731cfaee..fd8b3456c 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -638,8 +638,9 @@ namespace IRaCIS.Core.Application.Image.QA public async Task> GetSubjectVisitSelectList(Guid subjectId) { - var maxNum = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TaskState == TaskState.Effect && t.SignTime != null && t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.InOrder).MaxAsync(x => (decimal?)x.VisitTaskNum)??0; + //var maxNum = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TaskState == TaskState.Effect && t.SignTime != null && t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.InOrder).MaxAsync(x => (decimal?)x.VisitTaskNum)??0; + var maxNum=await _subjectVisitRepository.Where(t=>t.SubjectId == subjectId && t.SubmitState==SubmitStateEnum.Submitted).MaxAsync(x => (decimal?)x.VisitNum) ?? 0; return await _subjectVisitRepository.Where(t => t.SubjectId == subjectId&&t.VisitNum>= maxNum).OrderBy(T => T.VisitNum).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); } From d4cef1148b11d41558b58f42a4bc21c144e4c75a Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 11:47:05 +0800 Subject: [PATCH 08/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9oss=20=E5=90=84?= =?UTF-8?q?=E4=B8=AA=E7=8E=AF=E5=A2=83=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Event_IRC.json | 19 +++++++------ IRaCIS.Core.API/appsettings.Test_IRC.json | 6 ++-- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 15 ++++++---- IRaCIS.Core.API/appsettings.US_Test_IRC.json | 29 +++++++------------- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 15 ++++++---- 5 files changed, 41 insertions(+), 43 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Event_IRC.json b/IRaCIS.Core.API/appsettings.Event_IRC.json index fa5674cb6..e1994bdde 100644 --- a/IRaCIS.Core.API/appsettings.Event_IRC.json +++ b/IRaCIS.Core.API/appsettings.Event_IRC.json @@ -13,15 +13,16 @@ "ObjectStoreService": { "ObjectStoreUse": "AliyunOSS", "AliyunOSS": { - "regionId": "cn-shanghai", - "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", - "endpoint": "https://oss-cn-shanghai.aliyuncs.com", - "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", - "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", - "bucketName": "zy-irc-store", - "roleArn": "acs:ram::1899121822495495:role/oss-upload", - "viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com", - "region": "oss-cn-shanghai" + "RegionId": "cn-shanghai", + "InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", + "EndPoint": "https://oss-cn-shanghai.aliyuncs.com", + "AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH", + "AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH", + "RoleArn": "acs:ram::1899121822495495:role/irc-oss-access", + "BucketName": "zy-irc-store", + "ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com", + "Region": "oss-cn-shanghai", + "DurationSeconds": 7200 }, "MinIO": { "endpoint": "http://192.168.3.68", diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index b99124cde..91d796c38 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -40,9 +40,9 @@ "Region": "us-east-1", "EndPoint": "s3.us-east-1.amazonaws.com", "UseSSL": true, - "RoleArn": "arn:aws:iam::471112624751:role/sts_s3_upload", - "AccessKeyId": "AKIAW3MEAFJXWRCGSX5Z", - "SecretAccessKey": "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", + "RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access", + "AccessKeyId": "AKIAW3MEAFJXWBCTBBAC", + "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", "DurationSeconds": 7200 diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index a27844759..60875f62f 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -38,12 +38,15 @@ }, "AWS": { - "endPoint": "s3.us-east-1.amazonaws.com", - "useSSL": true, - "accessKey": "AKIAW3MEAFJX5P32P6NA", - "secretKey": "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", - "bucketName": "ei-med-s3-lili-store", - "viewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com/" + "Region": "us-east-1", + "EndPoint": "s3.us-east-1.amazonaws.com", + "UseSSL": true, + "RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access", + "AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM", + "SecretAccessKey": "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", + "BucketName": "ei-med-s3-lili-uat-store", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", + "DurationSeconds": 7200 } }, "BasicSystemConfig": { diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json index b45479ed8..9dae73d21 100644 --- a/IRaCIS.Core.API/appsettings.US_Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -13,19 +13,7 @@ "ObjectStoreService": { - "ObjectStoreUse": "MinIO", - "AliyunOSS": { - "regionId": "cn-shanghai", - "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", - "endPoint": "https://oss-cn-shanghai.aliyuncs.com", - "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", - "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", - "bucketName": "zy-irc-test-store", - "roleArn": "acs:ram::1899121822495495:role/oss-upload", - "viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", - "region": "oss-cn-shanghai" - }, - + "ObjectStoreUse": "AWS", "MinIO": { //"endPoint": "hir-oss.uat.extimaging.com", //"port": "443", @@ -44,12 +32,15 @@ }, "AWS": { - "endPoint": "s3.us-east-1.amazonaws.com", - "useSSL": true, - "accessKey": "AKIAZQ3DRSOHFPJJ6FEU", - "secretKey": "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", - "bucketName": "ei-irc-test-store", - "viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/" + "Region": "us-east-1", + "EndPoint": "s3.us-east-1.amazonaws.com", + "UseSSL": true, + "RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access", + "AccessKeyId": "AKIAW3MEAFJXWBCTBBAC", + "SecretAccessKey": "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", + "BucketName": "ei-med-s3-lili-uat-store", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", + "DurationSeconds": 7200 } }, "BasicSystemConfig": { diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index faf47a861..4ad061ec1 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -36,12 +36,15 @@ }, "AWS": { - "endPoint": "s3.us-east-1.amazonaws.com", - "useSSL": true, - "accessKey": "AKIAW3MEAFJXUO6XYFYN", - "secretKey": "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", - "bucketName": "ei-med-s3-lili-uat-store", - "viewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/" + "Region": "us-east-1", + "EndPoint": "s3.us-east-1.amazonaws.com", + "UseSSL": true, + "RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access", + "AccessKeyId": "AKIAW3MEAFJXWBCTBBAC", + "SecretAccessKey": "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", + "BucketName": "ei-med-s3-lili-uat-store", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", + "DurationSeconds": 7200 } }, "BasicSystemConfig": { From 0cdc489278a00761a184bba3905b15764c694f21 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 14:38:32 +0800 Subject: [PATCH 09/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Test_IRC.json | 14 ++++++++------ IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 10 +++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json index 9dae73d21..b580aa183 100644 --- a/IRaCIS.Core.API/appsettings.US_Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -36,8 +36,8 @@ "EndPoint": "s3.us-east-1.amazonaws.com", "UseSSL": true, "RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access", - "AccessKeyId": "AKIAW3MEAFJXWBCTBBAC", - "SecretAccessKey": "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", + "AccessKeyId": "AKIAW3MEAFJX7IPXISP4", + "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", "DurationSeconds": 7200 @@ -45,13 +45,13 @@ }, "BasicSystemConfig": { - "OpenUserComplexPassword": false, + "OpenUserComplexPassword": true, - "OpenSignDocumentBeforeWork": false, + "OpenSignDocumentBeforeWork": true, "OpenTrialRelationDelete": true, - "OpenLoginLimit": false, + "OpenLoginLimit": true, "LoginMaxFailCount": 5, @@ -63,7 +63,9 @@ "ReadingRestTimeMin": 10, "IsNeedChangePassWord": true, - "ChangePassWordDays": 90 + "ChangePassWordDays": 90, + + "OpenLoginMFA": true }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index 4ad061ec1..f78e2794d 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -40,8 +40,8 @@ "EndPoint": "s3.us-east-1.amazonaws.com", "UseSSL": true, "RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access", - "AccessKeyId": "AKIAW3MEAFJXWBCTBBAC", - "SecretAccessKey": "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", + "AccessKeyId": "AKIAW3MEAFJX7IPXISP4", + "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", "DurationSeconds": 7200 @@ -49,13 +49,13 @@ }, "BasicSystemConfig": { - "OpenUserComplexPassword": false, + "OpenUserComplexPassword": true, - "OpenSignDocumentBeforeWork": false, + "OpenSignDocumentBeforeWork": true, "OpenTrialRelationDelete": true, - "OpenLoginLimit": false, + "OpenLoginLimit": true, "LoginMaxFailCount": 5, From 8b8b52e0ccc4003133cc7997a02420c3c0ebb043 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 14:45:26 +0800 Subject: [PATCH 10/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Controllers/ExtraController.cs | 2 -- IRaCIS.Core.API/appsettings.Test_IRC.json | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs index 000f81c25..3fc8ac010 100644 --- a/IRaCIS.Core.API/Controllers/ExtraController.cs +++ b/IRaCIS.Core.API/Controllers/ExtraController.cs @@ -312,8 +312,6 @@ namespace IRaCIS.Api.Controllers var result = await _oSSService.GetObjectStoreTempToken(); - result.AWS =await GetAWSTemToken(options.CurrentValue); - return ResponseOutput.Ok(result); } diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 91d796c38..b42343431 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -41,8 +41,8 @@ "EndPoint": "s3.us-east-1.amazonaws.com", "UseSSL": true, "RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access", - "AccessKeyId": "AKIAW3MEAFJXWBCTBBAC", - "SecretAccessKey": "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", + "AccessKeyId": "AKIAW3MEAFJX7IPXISP4", + "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", "DurationSeconds": 7200 From 7d39bf43fe2c4545c8368a104599abb988c0f72d Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 15:10:11 +0800 Subject: [PATCH 11/59] =?UTF-8?q?=E7=BC=93=E5=AD=98bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Controllers/ExtraController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs index 3fc8ac010..4851eb3e6 100644 --- a/IRaCIS.Core.API/Controllers/ExtraController.cs +++ b/IRaCIS.Core.API/Controllers/ExtraController.cs @@ -143,9 +143,9 @@ namespace IRaCIS.Api.Controllers // 验证阅片休息时间 await readingImageTaskService.ResetReadingRestTime(userId); - await _fusionCache.SetAsync(userId.ToString(), loginReturn.JWTStr, TimeSpan.FromDays(7)); + await _fusionCache.SetAsync(CacheKeys.UserToken(userId), loginReturn.JWTStr, TimeSpan.FromDays(7)); - await _fusionCache.SetAsync($"{userId.ToString()}_Online", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes)); + await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(userId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes)); return ResponseOutput.Ok(loginReturn); From 8dcd1f2f56c69a06deda1bd5ecf3deb2c89e1706 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 16:01:50 +0800 Subject: [PATCH 12/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9scp=20=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Test_IRC.json | 2 +- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 10 +++---- .../Allocation/TaskAllocationRuleService.cs | 26 +++++++++---------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json index b580aa183..3b4866fda 100644 --- a/IRaCIS.Core.API/appsettings.US_Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -86,7 +86,7 @@ "SystemPacsConfig": { "Port": "11113", - "IP": "3.226.182.187,1435" + "IP": "3.226.182.187" } } diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index f78e2794d..f04b1dfa2 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -7,11 +7,11 @@ } }, "ConnectionStrings": { - "RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", - "Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + //"RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + //"Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" - //"RemoteNew": "Server=3.226.182.187,1435;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", - //"Hangfire": "Server=3.226.182.187,1435;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + "RemoteNew": "Server=3.226.182.187,1435;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=3.226.182.187,1435;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" }, "ObjectStoreService": { @@ -90,7 +90,7 @@ "SystemPacsConfig": { "Port": "11113", - "IP": "3.226.182.187,1435" + "IP": "3.226.182.187" } } diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskAllocationRuleService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskAllocationRuleService.cs index 89d943028..226e8ac94 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskAllocationRuleService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskAllocationRuleService.cs @@ -27,13 +27,13 @@ namespace IRaCIS.Core.Application.Service { - + /// /// 获取计划列表 医生带阅片类型 /// /// /// - public async Task<(List,object)> GetDoctorPlanAllocationRuleList(Guid trialId) + public async Task>> GetDoctorPlanAllocationRuleList(Guid trialId) { var list = await _taskAllocationRuleRepository.Where(t => t.TrialId == trialId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); @@ -41,7 +41,7 @@ namespace IRaCIS.Core.Application.Service //所有标准都是一样 后台只返回任意一个标准的就好了 var trialTaskConfig = await _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsConfirm).ProjectTo(_mapper.ConfigurationProvider).FirstNotNullAsync(); - return (list, trialTaskConfig); + return ResponseOutput.Ok(list, trialTaskConfig); } @@ -103,9 +103,9 @@ namespace IRaCIS.Core.Application.Service // return ResponseOutput.Ok(); //} - public async Task> GetSubjectCancelDoctorHistoryList(Guid subjectId,Guid trialReadingCriterionId) + public async Task> GetSubjectCancelDoctorHistoryList(Guid subjectId, Guid trialReadingCriterionId) { - var list = await _subjectCanceDoctorRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId==trialReadingCriterionId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + var list = await _subjectCanceDoctorRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); return list; } @@ -139,7 +139,7 @@ namespace IRaCIS.Core.Application.Service }; - return await query.ToListAsync(); + return await query.ToListAsync(); } @@ -150,8 +150,8 @@ namespace IRaCIS.Core.Application.Service var query = from allocationRule in _taskAllocationRuleRepository.Where(t => t.TrialId == selectQuery.TrialId && t.IsEnable) .WhereIf(selectQuery.ReadingCategory != null && selectQuery.TrialReadingCriterionId == null, t => t.Enroll.EnrollReadingCategoryList.Any(t => t.ReadingCategory == selectQuery.ReadingCategory)) .WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory == null, t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId)) - .WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory !=null, - t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && t.ReadingCategory==selectQuery.ReadingCategory)) + .WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory != null, + t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && t.ReadingCategory == selectQuery.ReadingCategory)) join user in _userRepository.AsQueryable() on allocationRule.DoctorUserId equals user.Id select new TrialDoctorUserSelectView() { @@ -162,12 +162,12 @@ namespace IRaCIS.Core.Application.Service UserName = user.UserName, UserTypeEnum = user.UserTypeRole.UserTypeEnum, - ReadingCategoryList = selectQuery.TrialReadingCriterionId == null ? - - allocationRule.Enroll.EnrollReadingCategoryList.Where(t=> (selectQuery.ReadingCategory == null ?true: t.ReadingCategory == selectQuery.ReadingCategory) ).Select(t => t.ReadingCategory).OrderBy(t => t).ToList() : - + ReadingCategoryList = selectQuery.TrialReadingCriterionId == null ? + + allocationRule.Enroll.EnrollReadingCategoryList.Where(t => (selectQuery.ReadingCategory == null ? true : t.ReadingCategory == selectQuery.ReadingCategory)).Select(t => t.ReadingCategory).OrderBy(t => t).ToList() : + allocationRule.Enroll.EnrollReadingCategoryList - .Where(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && (selectQuery.ReadingCategory == null?true : t.ReadingCategory == selectQuery.ReadingCategory) ) + .Where(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && (selectQuery.ReadingCategory == null ? true : t.ReadingCategory == selectQuery.ReadingCategory)) .Select(t => t.ReadingCategory).OrderBy(t => t).ToList() }; From f9f3a1422f92e4c54495b4778be5cd1efec0c71d Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 17:38:49 +0800 Subject: [PATCH 13/59] aws bug --- .../NewtonsoftJson/JSONTimeZoneConverter.cs | 4 +++- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 2 +- IRaCIS.Core.Application/Helper/OSSService.cs | 9 ++++++--- .../Service/QC/ClinicalDataService.cs | 2 +- IRaCIS.Core.Domain/QC/ClinicalData/PreviousHistory.cs | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONTimeZoneConverter.cs b/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONTimeZoneConverter.cs index ce758306c..0fada0af4 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONTimeZoneConverter.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONTimeZoneConverter.cs @@ -35,7 +35,9 @@ namespace IRaCIS.Core.API else { // Default or English date format - _dateFormat = "MM/dd/yyyy HH:mm:ss"; + //_dateFormat = "MM/dd/yyyy HH:mm:ss"; + + _dateFormat = "yyyy-MM-dd HH:mm:ss"; } #endregion diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index f04b1dfa2..b0d9c7b34 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -69,7 +69,7 @@ "ChangePassWordDays": 90, - "OpenLoginMFA": true + "OpenLoginMFA": false }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.Application/Helper/OSSService.cs b/IRaCIS.Core.Application/Helper/OSSService.cs index 50d346ab3..f4609a16e 100644 --- a/IRaCIS.Core.Application/Helper/OSSService.cs +++ b/IRaCIS.Core.Application/Helper/OSSService.cs @@ -28,6 +28,7 @@ using MassTransit; using AlibabaCloud.SDK.Sts20150401; using Amazon.SecurityToken; using Amazon.SecurityToken.Model; +using Amazon; namespace IRaCIS.Core.Application.Helper { @@ -235,13 +236,15 @@ namespace IRaCIS.Core.Application.Helper { var awsConfig = ObjectStoreServiceOptions.AWS; - // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); + var credentials = new SessionAWSCredentials( AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken); + + //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config { - ServiceURL = awsConfig.EndPoint + RegionEndpoint = RegionEndpoint.USEast1, + UseHttp =true, }; var amazonS3Client = new AmazonS3Client(credentials, clientConfig); diff --git a/IRaCIS.Core.Application/Service/QC/ClinicalDataService.cs b/IRaCIS.Core.Application/Service/QC/ClinicalDataService.cs index 6ac863684..c4c186183 100644 --- a/IRaCIS.Core.Application/Service/QC/ClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/QC/ClinicalDataService.cs @@ -51,7 +51,7 @@ namespace IRaCIS.Core.Application.Contracts return await previousHistoryQueryable.ToListAsync(); } - [HttpPost("{trialId:guid}")] + [HttpPost] public async Task> AddOrUpdatePreviousHistory(PreviousHistoryAddOrEdit addOrEditPreviousHistory) { await _qCCommon.VerifyIsCRCSubmmitAsync(_subjectVisitRepository, _userInfo, addOrEditPreviousHistory.SubjectVisitId); diff --git a/IRaCIS.Core.Domain/QC/ClinicalData/PreviousHistory.cs b/IRaCIS.Core.Domain/QC/ClinicalData/PreviousHistory.cs index 84e40c327..8e57f50bd 100644 --- a/IRaCIS.Core.Domain/QC/ClinicalData/PreviousHistory.cs +++ b/IRaCIS.Core.Domain/QC/ClinicalData/PreviousHistory.cs @@ -12,7 +12,7 @@ namespace IRaCIS.Core.Domain.Models ///PreviousHistory /// [Table("PreviousHistory")] - public class PreviousHistory : BaseAddAuditEntityWithUserName + public class PreviousHistory : BaseAddAuditEntity { #region 导航属性 [JsonIgnore] From dcfe28d950ee3e7637363d553d759d138c38a16f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 17:51:02 +0800 Subject: [PATCH 14/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 10 +++++----- IRaCIS.Core.Domain/QC/ClinicalData/PreviousOther.cs | 2 +- IRaCIS.Core.Domain/QC/ClinicalData/PreviousSurgery.cs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index b0d9c7b34..23f74a7ba 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -7,11 +7,11 @@ } }, "ConnectionStrings": { - //"RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", - //"Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + "RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" - "RemoteNew": "Server=3.226.182.187,1435;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", - "Hangfire": "Server=3.226.182.187,1435;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + //"RemoteNew": "Server=3.226.182.187,1435;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + //"Hangfire": "Server=3.226.182.187,1435;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" }, "ObjectStoreService": { @@ -55,7 +55,7 @@ "OpenTrialRelationDelete": true, - "OpenLoginLimit": true, + "OpenLoginLimit": false, "LoginMaxFailCount": 5, diff --git a/IRaCIS.Core.Domain/QC/ClinicalData/PreviousOther.cs b/IRaCIS.Core.Domain/QC/ClinicalData/PreviousOther.cs index 4628c79f1..ae0b47033 100644 --- a/IRaCIS.Core.Domain/QC/ClinicalData/PreviousOther.cs +++ b/IRaCIS.Core.Domain/QC/ClinicalData/PreviousOther.cs @@ -12,7 +12,7 @@ namespace IRaCIS.Core.Domain.Models ///PreviousOther /// [Table("PreviousOther")] - public class PreviousOther : BaseAddAuditEntityWithUserName + public class PreviousOther : BaseAddAuditEntity { #region 导航属性 diff --git a/IRaCIS.Core.Domain/QC/ClinicalData/PreviousSurgery.cs b/IRaCIS.Core.Domain/QC/ClinicalData/PreviousSurgery.cs index 330e4fbe4..377e24016 100644 --- a/IRaCIS.Core.Domain/QC/ClinicalData/PreviousSurgery.cs +++ b/IRaCIS.Core.Domain/QC/ClinicalData/PreviousSurgery.cs @@ -12,7 +12,7 @@ namespace IRaCIS.Core.Domain.Models ///PreviousSurgery /// [Table("PreviousSurgery")] - public class PreviousSurgery : BaseAddAuditEntityWithUserName + public class PreviousSurgery : BaseAddAuditEntity { #region 导航属性 From 095db5786b8bb0dac6569c4c590dfc85ce50a49d Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 13 Sep 2024 17:54:55 +0800 Subject: [PATCH 15/59] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/QC/_MapConfig.cs | 9 ++++++--- IRaCIS.Core.Domain/BaseModel/Entity.cs | 12 ------------ 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index 7420acff1..e6b935fe5 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -486,11 +486,14 @@ namespace IRaCIS.Core.Application.Service // 临床数据上传 路径拼接返回 CreateMap() - .ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token)); + .ForMember(d => d.CreateUser, u => u.MapFrom(s => s.CreateUser.FullName)) + .ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path )); CreateMap() - .ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token)); + .ForMember(d => d.CreateUser, u => u.MapFrom(s => s.CreateUser.FullName)) + .ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path )); CreateMap() - .ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token)); + .ForMember(d => d.CreateUser, u => u.MapFrom(s => s.CreateUser.FullName)) + .ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path )); diff --git a/IRaCIS.Core.Domain/BaseModel/Entity.cs b/IRaCIS.Core.Domain/BaseModel/Entity.cs index ce7dfc8c8..bb525e696 100644 --- a/IRaCIS.Core.Domain/BaseModel/Entity.cs +++ b/IRaCIS.Core.Domain/BaseModel/Entity.cs @@ -116,18 +116,6 @@ namespace IRaCIS.Core.Domain.Models public User CreateUser { get; set; } } - - - public abstract class BaseAddAuditEntityWithUserName : Entity, IAuditAddWithUserName - { - public string CreateUser { get; set; } = string.Empty; - - public Guid CreateUserId { get; set; } - public DateTime CreateTime { get; set; } - - - } - public abstract class BaseAuditUpdateEntity : Entity, IAuditUpdate { public Guid UpdateUserId { get; set; } From e5be375308a516536bb24dd2d43404ec55c2110f Mon Sep 17 00:00:00 2001 From: hang <87227557@qq.com> Date: Fri, 13 Sep 2024 21:45:42 +0800 Subject: [PATCH 16/59] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=AE=9E=E4=BD=93=E7=9A=84=E6=A8=A1=E5=9E=8B=EF=BC=8C?= =?UTF-8?q?=E9=95=BF=E5=BA=A6200=E7=9A=84=E4=B8=8D=E6=A0=87=E6=B3=A8?= =?UTF-8?q?=EF=BC=8Cnvarcharmax=20=E6=A0=87=E6=B3=A8=20MaxLength=20?= =?UTF-8?q?=E5=85=B6=E4=BB=96=E9=95=BF=E5=BA=A6=E6=A0=87=E6=B3=A8StringLen?= =?UTF-8?q?gth?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CodeTemplates/EFCore/EntityType.t4 | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 b/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 index 65b856ee7..6246b3f15 100644 --- a/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 +++ b/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 @@ -49,7 +49,7 @@ namespace <#= NamespaceHint #>; if (!string.IsNullOrEmpty(EntityType.GetComment())) { #> -[comment("<#= code.XmlComment(EntityType.GetComment()) #>")] +[Comment("<#= code.XmlComment(EntityType.GetComment()) #>")] <# } @@ -86,8 +86,32 @@ public partial class <#= EntityType.Name #>: BaseFullAuditEntity if (Options.UseDataAnnotations) { - var dataAnnotations = property.GetDataAnnotations(annotationCodeGenerator) - .Where(a => !(a.Type == typeof(RequiredAttribute) && Options.UseNullableReferenceTypes && !property.ClrType.IsValueType)); + // ǷΪַͣMaxLengthǷ[StringLength]ע + if (property.ClrType == typeof(string)) + { + var maxLength = property.GetMaxLength(); + + if (maxLength.HasValue && maxLength != 200) // ȲΪ200ʱ[StringLength] + { + + +#> + [StringLength(<#= maxLength.Value #>)] +<# + + + + } + else + { +#> + [MaxLength] +<# + } + } + var dataAnnotations = property.GetDataAnnotations(annotationCodeGenerator) + .Where(a => !(a.Type == typeof(RequiredAttribute) && Options.UseNullableReferenceTypes && !property.ClrType.IsValueType) + && a.Type != typeof(StringLengthAttribute)); // ų StringLengthAttribute foreach (var dataAnnotation in dataAnnotations) { #> From b31821848d3599e6b4c009d34a772d5127b260c0 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 09:19:16 +0800 Subject: [PATCH 17/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9scp=20=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/IRC.Core.SCP.csproj | 4 + IRC.Core.SCP/Service/OSSService.cs | 501 +++++++++++++++---- IRC.Core.SCP/appsettings.Prod_IRC_SCP.json | 19 +- IRC.Core.SCP/appsettings.Test_IRC_SCP.json | 29 +- IRC.Core.SCP/appsettings.US_Prod_SCP.json | 15 +- IRC.Core.SCP/appsettings.US_Uat_SCP.json | 15 +- IRC.Core.SCP/appsettings.Uat_IRC_SCP.json | 19 +- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 12 - 8 files changed, 469 insertions(+), 145 deletions(-) diff --git a/IRC.Core.SCP/IRC.Core.SCP.csproj b/IRC.Core.SCP/IRC.Core.SCP.csproj index 0413c62d6..5db7866bd 100644 --- a/IRC.Core.SCP/IRC.Core.SCP.csproj +++ b/IRC.Core.SCP/IRC.Core.SCP.csproj @@ -7,8 +7,12 @@ + + + + diff --git a/IRC.Core.SCP/Service/OSSService.cs b/IRC.Core.SCP/Service/OSSService.cs index eb34ec64f..897a62386 100644 --- a/IRC.Core.SCP/Service/OSSService.cs +++ b/IRC.Core.SCP/Service/OSSService.cs @@ -14,48 +14,75 @@ using System.Security.AccessControl; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; +using System.Text.Json.Serialization; +using Minio.ApiEndpoints; +using System.Reactive.Linq; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infrastructure.NewtonsoftJson; +using Amazon.Runtime; +using Amazon.SecurityToken; +using Amazon.SecurityToken.Model; +using Amazon; +using Amazon.S3; +using Amazon.S3.Model; +using MassTransit; +using AlibabaCloud.SDK.Sts20150401; namespace IRaCIS.Core.SCP { + #region 绑定和返回模型 + + [LowerCamelCaseJson] public class MinIOOptions : AWSOptions { - public int port { get; set; } + public int Port { get; set; } } + public class AWSOptions { - public string endPoint { get; set; } - public bool useSSL { get; set; } - public string accessKey { get; set; } - public string secretKey { get; set; } - public string bucketName { get; set; } - public string viewEndpoint { get; set; } + public string EndPoint { get; set; } + public bool UseSSL { get; set; } + public string AccessKeyId { get; set; } + public string RoleArn { get; set; } + public string SecretAccessKey { get; set; } + public string BucketName { get; set; } + public string ViewEndpoint { get; set; } + public int DurationSeconds { get; set; } + public string Region { get; set; } } public class AliyunOSSOptions { - public string regionId { get; set; } - public string accessKeyId { get; set; } - public string accessKeySecret { get; set; } + public string RegionId { get; set; } + public string AccessKeyId { get; set; } + public string AccessKeySecret { get; set; } - public string internalEndpoint { get; set; } + public string InternalEndpoint { get; set; } - public string endPoint { get; set; } - public string bucketName { get; set; } + public string EndPoint { get; set; } + public string BucketName { get; set; } - public string roleArn { get; set; } + public string RoleArn { get; set; } + + public string Region { get; set; } + + public string ViewEndpoint { get; set; } + + public int DurationSeconds { get; set; } - public string region { get; set; } - public string viewEndpoint { get; set; } } public class ObjectStoreServiceOptions { public string ObjectStoreUse { get; set; } + public AliyunOSSOptions AliyunOSS { get; set; } + + public MinIOOptions MinIO { get; set; } public AWSOptions AWS { get; set; } @@ -66,27 +93,46 @@ namespace IRaCIS.Core.SCP { public string ObjectStoreUse { get; set; } - public AliyunOSSOptions AliyunOSS { get; set; } + + public AliyunOSSTempToken AliyunOSS { get; set; } public MinIOOptions MinIO { get; set; } - public AWSOptions AWS { get; set; } + public AWSTempToken AWS { get; set; } } + [LowerCamelCaseJson] public class AliyunOSSTempToken { public string AccessKeyId { get; set; } public string AccessKeySecret { get; set; } - public string SecurityToken { get; set; } - public string Expiration { get; set; } + + public string EndPoint { get; set; } + public string BucketName { get; set; } public string Region { get; set; } - public string BucketName { get; set; } + public string ViewEndpoint { get; set; } + + public string SecurityToken { get; set; } + public DateTime Expiration { get; set; } + + } - + [LowerCamelCaseJson] + public class AWSTempToken + { + public string Region { get; set; } + public string SessionToken { get; set; } + public string EndPoint { get; set; } + public string AccessKeyId { get; set; } + public string SecretAccessKey { get; set; } + public string BucketName { get; set; } + public string ViewEndpoint { get; set; } + public DateTime Expiration { get; set; } + } public enum ObjectStoreUse { @@ -95,6 +141,10 @@ namespace IRaCIS.Core.SCP AWS = 2, } + #endregion + + // aws 参考链接 https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/S3/S3_Basics + public interface IOSSService { public Task UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true); @@ -106,6 +156,9 @@ namespace IRaCIS.Core.SCP public Task GetSignedUrl(string ossRelativePath); + public Task DeleteFromPrefix(string prefix); + + public Task GetObjectStoreTempToken(); } @@ -113,10 +166,16 @@ namespace IRaCIS.Core.SCP { public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; } + private AliyunOSSTempToken AliyunOSSTempToken { get; set; } + + private AWSTempToken AWSTempToken { get; set; } + public OSSService(IOptionsMonitor options) { ObjectStoreServiceOptions = options.CurrentValue; + + GetObjectStoreTempToken().GetAwaiter().GetResult(); } /// @@ -130,8 +189,6 @@ namespace IRaCIS.Core.SCP public async Task UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true) { var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}"; - //var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}"; - //var ossRelativePath = oosFolderPath + "/" + fileRealName; try { @@ -148,12 +205,12 @@ namespace IRaCIS.Core.SCP { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken); // 上传文件 - var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, memoryStream); + var result = _ossClient.PutObject(aliConfig.BucketName, ossRelativePath, memoryStream); } else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") @@ -161,12 +218,12 @@ namespace IRaCIS.Core.SCP var minIOConfig = ObjectStoreServiceOptions.MinIO; - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") - .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}") + .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL) .Build(); var putObjectArgs = new PutObjectArgs() - .WithBucket(minIOConfig.bucketName) + .WithBucket(minIOConfig.BucketName) .WithObject(ossRelativePath) .WithStreamData(memoryStream) .WithObjectSize(memoryStream.Length); @@ -175,20 +232,29 @@ namespace IRaCIS.Core.SCP } else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") { - var minIOConfig = ObjectStoreServiceOptions.AWS; + var awsConfig = ObjectStoreServiceOptions.AWS; + + var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken); - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") - .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) - .Build(); - var putObjectArgs = new PutObjectArgs() - .WithBucket(minIOConfig.bucketName) - .WithObject(ossRelativePath) - .WithStreamData(memoryStream) - .WithObjectSize(memoryStream.Length); + //提供awsEndPoint(域名)进行访问配置 + var clientConfig = new AmazonS3Config + { + RegionEndpoint = RegionEndpoint.USEast1, + UseHttp = true, + }; - await minioClient.PutObjectAsync(putObjectArgs); + var amazonS3Client = new AmazonS3Client(credentials, clientConfig); + + var putObjectRequest = new Amazon.S3.Model.PutObjectRequest() + { + BucketName = awsConfig.BucketName, + InputStream = memoryStream, + Key = ossRelativePath, + }; + + await amazonS3Client.PutObjectAsync(putObjectRequest); } else { @@ -216,6 +282,7 @@ namespace IRaCIS.Core.SCP /// /// /// + /// /// /// public async Task UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true) @@ -225,17 +292,14 @@ namespace IRaCIS.Core.SCP var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}"; - //var ossRelativePath = oosFolderPath + "/" + localFileName; - - if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken); // 上传文件 - var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, localFilePath); + var result = _ossClient.PutObject(aliConfig.BucketName, ossRelativePath, localFilePath); } else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") @@ -243,12 +307,12 @@ namespace IRaCIS.Core.SCP var minIOConfig = ObjectStoreServiceOptions.MinIO; - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") - .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}") + .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL) .Build(); var putObjectArgs = new PutObjectArgs() - .WithBucket(minIOConfig.bucketName) + .WithBucket(minIOConfig.BucketName) .WithObject(ossRelativePath) .WithFileName(localFilePath); @@ -256,19 +320,28 @@ namespace IRaCIS.Core.SCP } else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") { - var minIOConfig = ObjectStoreServiceOptions.AWS; + var awsConfig = ObjectStoreServiceOptions.AWS; + // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 + var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") - .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) - .Build(); + //提供awsEndPoint(域名)进行访问配置 + var clientConfig = new AmazonS3Config + { + ServiceURL = awsConfig.EndPoint + }; - var putObjectArgs = new PutObjectArgs() - .WithBucket(minIOConfig.bucketName) - .WithObject(ossRelativePath) - .WithFileName(localFilePath); + var amazonS3Client = new AmazonS3Client(credentials, clientConfig); + + var putObjectRequest = new Amazon.S3.Model.PutObjectRequest() + { + BucketName = awsConfig.BucketName, + FilePath = localFilePath, + Key = ossRelativePath, + }; + + await amazonS3Client.PutObjectAsync(putObjectRequest); - await minioClient.PutObjectAsync(putObjectArgs); } else { @@ -291,10 +364,10 @@ namespace IRaCIS.Core.SCP { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken); // 上传文件 - var result = _ossClient.GetObject(aliConfig.bucketName, ossRelativePath); + var result = _ossClient.GetObject(aliConfig.BucketName, ossRelativePath); // 将下载的文件流保存到本地文件 using (var fs = File.OpenWrite(localFilePath)) @@ -308,12 +381,12 @@ namespace IRaCIS.Core.SCP { var minIOConfig = ObjectStoreServiceOptions.MinIO; - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") - .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}") + .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL) .Build(); var getObjectArgs = new GetObjectArgs() - .WithBucket(minIOConfig.bucketName) + .WithBucket(minIOConfig.BucketName) .WithObject(ossRelativePath) .WithFile(localFilePath); @@ -322,18 +395,29 @@ namespace IRaCIS.Core.SCP } else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") { - var minIOConfig = ObjectStoreServiceOptions.AWS; + var awsConfig = ObjectStoreServiceOptions.AWS; - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") - .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) - .Build(); + // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 + var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); + + //提供awsEndPoint(域名)进行访问配置 + var clientConfig = new AmazonS3Config + { + ServiceURL = awsConfig.EndPoint + }; + + var amazonS3Client = new AmazonS3Client(credentials, clientConfig); + + var getObjectArgs = new Amazon.S3.Model.GetObjectRequest() + { + BucketName = awsConfig.BucketName, + Key = ossRelativePath, + }; + + + await (await amazonS3Client.GetObjectAsync(getObjectArgs)).WriteResponseStreamToFileAsync(localFilePath, true, CancellationToken.None); - var getObjectArgs = new GetObjectArgs() - .WithBucket(minIOConfig.bucketName) - .WithObject(ossRelativePath) - .WithFile(localFilePath); - await minioClient.GetObjectAsync(getObjectArgs); } else { @@ -363,10 +447,10 @@ namespace IRaCIS.Core.SCP { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken); // 生成签名URL。 - var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get) + var req = new GeneratePresignedUriRequest(aliConfig.BucketName, ossRelativePath, SignHttpMethod.Get) { // 设置签名URL过期时间,默认值为3600秒。 Expiration = DateTime.Now.AddHours(1), @@ -380,13 +464,13 @@ namespace IRaCIS.Core.SCP { var minIOConfig = ObjectStoreServiceOptions.MinIO; - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") - .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}") + .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL) .Build(); var args = new PresignedGetObjectArgs() - .WithBucket(minIOConfig.bucketName) + .WithBucket(minIOConfig.BucketName) .WithObject(ossRelativePath) .WithExpiry(3600) /*.WithHeaders(reqParams)*/; @@ -403,18 +487,26 @@ namespace IRaCIS.Core.SCP } else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") { - var minIOConfig = ObjectStoreServiceOptions.AWS; + var awsConfig = ObjectStoreServiceOptions.AWS; - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") - .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) - .Build(); - var args = new PresignedGetObjectArgs() - .WithBucket(minIOConfig.bucketName) - .WithObject(ossRelativePath) - .WithExpiry(3600); + // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 + var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); - var presignedUrl = await minioClient.PresignedGetObjectAsync(args); + //提供awsEndPoint(域名)进行访问配置 + var clientConfig = new AmazonS3Config + { + ServiceURL = awsConfig.EndPoint + }; + + var amazonS3Client = new AmazonS3Client(credentials, clientConfig); + + var presignedUrl = await amazonS3Client.GetPreSignedURLAsync(new GetPreSignedUrlRequest() + { + BucketName = awsConfig.BucketName, + Key = ossRelativePath, + Expires = DateTime.UtcNow.AddMinutes(120) + }); Uri uri = new Uri(presignedUrl); @@ -435,8 +527,247 @@ namespace IRaCIS.Core.SCP } } + + /// + /// 删除某个目录的文件 + /// + /// + /// + public async Task DeleteFromPrefix(string prefix) + { + if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") + { + var aliConfig = ObjectStoreServiceOptions.AliyunOSS; + + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken); + + + try + { + ObjectListing objectListing = null; + string nextMarker = null; + do + { + // 使用 prefix 模拟目录结构,设置 MaxKeys 和 NextMarker + objectListing = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(aliConfig.BucketName) + { + Prefix = prefix, + MaxKeys = 1000, + Marker = nextMarker + }); + + List keys = objectListing.ObjectSummaries.Select(t => t.Key).ToList(); + + // 删除获取到的文件 + if (keys.Count > 0) + { + _ossClient.DeleteObjects(new Aliyun.OSS.DeleteObjectsRequest(aliConfig.BucketName, keys, false)); + } + + // 设置 NextMarker 以获取下一页的数据 + nextMarker = objectListing.NextMarker; + + } while (objectListing.IsTruncated); + } + catch (Exception ex) + { + Console.WriteLine($"Error: {ex.Message}"); + } + + + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") + { + var minIOConfig = ObjectStoreServiceOptions.MinIO; + + + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}") + .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL) + .Build(); + + + var listArgs = new ListObjectsArgs().WithBucket(minIOConfig.BucketName).WithPrefix(prefix).WithRecursive(true); + + + + // 创建一个空列表用于存储对象键 + var objects = new List(); + + // 使用 await foreach 来异步迭代对象列表 + await foreach (var item in minioClient.ListObjectsEnumAsync(listArgs)) + { + objects.Add(item.Key); + } + + + if (objects.Count > 0) + { + var objArgs = new RemoveObjectsArgs() + .WithBucket(minIOConfig.BucketName) + .WithObjects(objects); + + // 删除对象 + await minioClient.RemoveObjectsAsync(objArgs); + } + + + + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") + { + + var awsConfig = ObjectStoreServiceOptions.AWS; + + + // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 + var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); + + //提供awsEndPoint(域名)进行访问配置 + var clientConfig = new AmazonS3Config + { + ServiceURL = awsConfig.EndPoint + }; + + var amazonS3Client = new AmazonS3Client(credentials, clientConfig); + + // 列出指定前缀下的所有对象 + var listObjectsRequest = new ListObjectsV2Request + { + BucketName = awsConfig.BucketName, + Prefix = prefix + }; + + var listObjectsResponse = await amazonS3Client.ListObjectsV2Async(listObjectsRequest); + + if (listObjectsResponse.S3Objects.Count > 0) + { + // 准备删除请求 + var deleteObjectsRequest = new Amazon.S3.Model.DeleteObjectsRequest + { + BucketName = awsConfig.BucketName, + Objects = new List() + }; + + foreach (var s3Object in listObjectsResponse.S3Objects) + { + deleteObjectsRequest.Objects.Add(new KeyVersion + { + Key = s3Object.Key + }); + } + + // 批量删除对象 + var deleteObjectsResponse = await amazonS3Client.DeleteObjectsAsync(deleteObjectsRequest); + } + + + + } + else + { + throw new BusinessValidationFailedException("未定义的存储介质类型"); + } + } + + + + + public async Task GetObjectStoreTempToken() + { + var ossOptions = ObjectStoreServiceOptions.AliyunOSS; + + if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") + { + var client = new Client(new AlibabaCloud.OpenApiClient.Models.Config() + { + AccessKeyId = ossOptions.AccessKeyId, + AccessKeySecret = ossOptions.AccessKeySecret, + //AccessKeyId = "LTAI5tJV76pYX5yPg1N9QVE8", + //AccessKeySecret = "roRNLa9YG1of4pYruJGCNKBXEWTAWa", + + Endpoint = "sts.cn-hangzhou.aliyuncs.com" + }); + + var assumeRoleRequest = new AlibabaCloud.SDK.Sts20150401.Models.AssumeRoleRequest(); + // 将设置为自定义的会话名称,例如oss-role-session。 + assumeRoleRequest.RoleSessionName = $"session-name-{NewId.NextGuid()}"; + // 将替换为拥有上传文件到指定OSS Bucket权限的RAM角色的ARN。 + assumeRoleRequest.RoleArn = ossOptions.RoleArn; + //assumeRoleRequest.RoleArn = "acs:ram::1899121822495495:role/webdirect"; + assumeRoleRequest.DurationSeconds = ossOptions.DurationSeconds; + var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions(); + var response = client.AssumeRoleWithOptions(assumeRoleRequest, runtime); + var credentials = response.Body.Credentials; + + var tempToken = new AliyunOSSTempToken() + { + AccessKeyId = credentials.AccessKeyId, + AccessKeySecret = credentials.AccessKeySecret, + + //转为服务器时区,最后统一转为客户端时区 + Expiration = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse(credentials.Expiration), TimeZoneInfo.Local), + SecurityToken = credentials.SecurityToken, + + + Region = ossOptions.Region, + BucketName = ossOptions.BucketName, + EndPoint = ossOptions.EndPoint, + ViewEndpoint = ossOptions.ViewEndpoint, + + }; + + AliyunOSSTempToken = tempToken; + + return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, AliyunOSS = tempToken }; + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") + { + return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, MinIO = ObjectStoreServiceOptions.MinIO }; + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") + { + var awsOptions = ObjectStoreServiceOptions.AWS; + + //aws 临时凭证 + // 创建 STS 客户端 + var stsClient = new AmazonSecurityTokenServiceClient(awsOptions.AccessKeyId, awsOptions.SecretAccessKey); + + // 使用 AssumeRole 请求临时凭证 + var assumeRoleRequest = new AssumeRoleRequest + { + + RoleArn = awsOptions.RoleArn, // 角色 ARN + RoleSessionName = $"session-name-{NewId.NextGuid()}", + DurationSeconds = awsOptions.DurationSeconds // 临时凭证有效期 + }; + + var assumeRoleResponse = await stsClient.AssumeRoleAsync(assumeRoleRequest); + + var credentials = assumeRoleResponse.Credentials; + + var tempToken = new AWSTempToken() + { + AccessKeyId = credentials.AccessKeyId, + SecretAccessKey = credentials.SecretAccessKey, + SessionToken = credentials.SessionToken, + Expiration = credentials.Expiration, + Region = awsOptions.Region, + BucketName = awsOptions.BucketName, + EndPoint = awsOptions.EndPoint, + ViewEndpoint = awsOptions.ViewEndpoint, + + }; + + AWSTempToken = tempToken; + return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, AWS = tempToken }; + } + else + { + throw new BusinessValidationFailedException("未定义的存储介质类型"); + } + } + } - } diff --git a/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json b/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json index 218d5a2c8..9d7cf60ac 100644 --- a/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json +++ b/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json @@ -9,15 +9,16 @@ "ObjectStoreService": { "ObjectStoreUse": "AliyunOSS", "AliyunOSS": { - "regionId": "cn-shanghai", - "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", - "endpoint": "https://oss-cn-shanghai.aliyuncs.com", - "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", - "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", - "bucketName": "zy-irc-store", - "roleArn": "acs:ram::1899121822495495:role/oss-upload", - "viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com", - "region": "oss-cn-shanghai" + "RegionId": "cn-shanghai", + "InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", + "EndPoint": "https://oss-cn-shanghai.aliyuncs.com", + "AccessKeyId": "LTAI5tNRTsqL6aWmHkDmTwoH", + "AccessKeySecret": "7mtGz3qrYWI6JMMBZiLeC119VWicZH", + "RoleArn": "acs:ram::1899121822495495:role/irc-oss-access", + "BucketName": "zy-irc-store", + "ViewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com", + "Region": "oss-cn-shanghai", + "DurationSeconds": 7200 } }, diff --git a/IRC.Core.SCP/appsettings.Test_IRC_SCP.json b/IRC.Core.SCP/appsettings.Test_IRC_SCP.json index 077a9194a..022a47cd3 100644 --- a/IRC.Core.SCP/appsettings.Test_IRC_SCP.json +++ b/IRC.Core.SCP/appsettings.Test_IRC_SCP.json @@ -9,15 +9,16 @@ "ObjectStoreService": { "ObjectStoreUse": "AliyunOSS", "AliyunOSS": { - "regionId": "cn-shanghai", - "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", - "endPoint": "https://oss-cn-shanghai.aliyuncs.com", - "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", - "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", - "bucketName": "zy-irc-test-store", - "roleArn": "acs:ram::1899121822495495:role/oss-upload", - "viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", - "region": "oss-cn-shanghai" + "RegionId": "cn-shanghai", + "InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", + "EndPoint": "https://oss-cn-shanghai.aliyuncs.com", + "AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm", + "AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV", + "RoleArn": "acs:ram::1899121822495495:role/dev-oss-access", + "BucketName": "zy-irc-test-store", + "ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", + "Region": "oss-cn-shanghai", + "DurationSeconds": 7200 }, "MinIO": { @@ -28,16 +29,8 @@ "secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy", "bucketName": "hir-test", "viewEndpoint": "http://106.14.89.110:9001/hir-test/" - }, - - "AWS": { - "endPoint": "s3.us-east-1.amazonaws.com", - "useSSL": false, - "accessKey": "AKIAZQ3DRSOHFPJJ6FEU", - "secretKey": "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", - "bucketName": "ei-irc-test-store", - "viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/" } + }, "ConnectionStrings": { diff --git a/IRC.Core.SCP/appsettings.US_Prod_SCP.json b/IRC.Core.SCP/appsettings.US_Prod_SCP.json index 3387edb1d..e56626eb7 100644 --- a/IRC.Core.SCP/appsettings.US_Prod_SCP.json +++ b/IRC.Core.SCP/appsettings.US_Prod_SCP.json @@ -9,12 +9,15 @@ "ObjectStoreService": { "ObjectStoreUse": "AWS", "AWS": { - "endPoint": "s3.us-east-1.amazonaws.com", - "useSSL": true, - "accessKey": "AKIAW3MEAFJX5P32P6NA", - "secretKey": "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", - "bucketName": "ei-med-s3-lili-store", - "viewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com/" + "Region": "us-east-1", + "EndPoint": "s3.us-east-1.amazonaws.com", + "UseSSL": true, + "RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access", + "AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM", + "SecretAccessKey": "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", + "BucketName": "ei-med-s3-lili-uat-store", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", + "DurationSeconds": 7200 } }, "ConnectionStrings": { diff --git a/IRC.Core.SCP/appsettings.US_Uat_SCP.json b/IRC.Core.SCP/appsettings.US_Uat_SCP.json index 1d15fadf7..78dcb50e7 100644 --- a/IRC.Core.SCP/appsettings.US_Uat_SCP.json +++ b/IRC.Core.SCP/appsettings.US_Uat_SCP.json @@ -9,12 +9,15 @@ "ObjectStoreService": { "ObjectStoreUse": "AWS", "AWS": { - "endPoint": "s3.us-east-1.amazonaws.com", - "useSSL": true, - "accessKey": "AKIAW3MEAFJXUO6XYFYN", - "secretKey": "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", - "bucketName": "ei-med-s3-lili-uat-store", - "viewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/" + "Region": "us-east-1", + "EndPoint": "s3.us-east-1.amazonaws.com", + "UseSSL": true, + "RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access", + "AccessKeyId": "AKIAW3MEAFJX7IPXISP4", + "SecretAccessKey": "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", + "BucketName": "ei-med-s3-lili-uat-store", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", + "DurationSeconds": 7200 } }, "ConnectionStrings": { diff --git a/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json b/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json index 18a92a53b..2d2fa6c9e 100644 --- a/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json +++ b/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json @@ -9,15 +9,16 @@ "ObjectStoreService": { "ObjectStoreUse": "AliyunOSS", "AliyunOSS": { - "regionId": "cn-shanghai", - "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", - "endpoint": "https://oss-cn-shanghai.aliyuncs.com", - "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", - "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", - "bucketName": "zy-irc-uat-store", - "roleArn": "acs:ram::1899121822495495:role/oss-upload", - "viewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com", - "region": "oss-cn-shanghai" + "RegionId": "cn-shanghai", + "InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", + "EndPoint": "https://oss-cn-shanghai.aliyuncs.com", + "AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm", + "AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV", + "RoleArn": "acs:ram::1899121822495495:role/dev-oss-access", + "BucketName": "zy-irc-uat-store", + "ViewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com", + "Region": "oss-cn-shanghai", + "DurationSeconds": 7200 } }, "ConnectionStrings": { diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index 60875f62f..b76577877 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -15,18 +15,6 @@ "ObjectStoreService": { "ObjectStoreUse": "AWS", - "AliyunOSS": { - "regionId": "cn-shanghai", - "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", - "endPoint": "https://oss-cn-shanghai.aliyuncs.com", - "accessKeyId": "", - "accessKeySecret": "", - "bucketName": "zy-irc-test-store", - "roleArn": "acs:ram::1899121822495495:role/oss-upload", - "viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", - "region": "oss-cn-shanghai" - }, - "MinIO": { "endPoint": "44.210.231.169", "port": "9001", From 0fdcc7c56e66160c939b7bbde87c0356134e7874 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 09:45:29 +0800 Subject: [PATCH 18/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AF=B9=E6=8E=A5bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Document/Interface/ITrialDocumentService.cs | 6 +++--- .../Service/Document/TrialDocumentService.cs | 7 +++---- .../Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs | 6 ++++-- .../Service/ImageAndDoc/DownloadAndUploadService.cs | 1 + IRaCIS.Core.Application/Service/QC/ClinicalDataService.cs | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Document/Interface/ITrialDocumentService.cs b/IRaCIS.Core.Application/Service/Document/Interface/ITrialDocumentService.cs index 9060e8f1a..4ff621279 100644 --- a/IRaCIS.Core.Application/Service/Document/Interface/ITrialDocumentService.cs +++ b/IRaCIS.Core.Application/Service/Document/Interface/ITrialDocumentService.cs @@ -16,10 +16,10 @@ namespace IRaCIS.Core.Application.Contracts Task UserAbandonDoc(Guid documentId, bool isSystemDoc); Task AddOrUpdateTrialDocument(AddOrEditTrialDocument addOrEditTrialDocument); Task DeleteTrialDocument(Guid trialDocumentId, Guid trialId); - Task<(PageOutput, object)> GetDocumentConfirmList(DocumentTrialUnionQuery querySystemDocument); + Task>> GetDocumentConfirmList(DocumentTrialUnionQuery querySystemDocument); Task> GetTrialDocumentList(TrialDocumentQuery queryTrialDocument); - - Task> > GetUserDocumentList(TrialUserDocUnionQuery querySystemDocument); + + Task>> GetUserDocumentList(TrialUserDocUnionQuery querySystemDocument); Task SetFirstViewDocumentTime(Guid documentId, bool isSystemDoc); Task UserConfirm(UserConfirmCommand userConfirmCommand); Task> GetTrialUserSelect(Guid trialId); diff --git a/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs b/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs index 8e13c0287..da0bbf23c 100644 --- a/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs +++ b/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs @@ -225,7 +225,6 @@ namespace IRaCIS.Core.Application.Services //系统文档查询 var systemDocumentQueryable = from needConfirmedUserType in _systemDocNeedConfirmedUserTypeRepository.Where(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId) - //.Where(u => u.UserTypeRole.UserList.SelectMany(cc => cc.UserTrials.Where(t => t.TrialId == querySystemDocument.TrialId)).Any(e => e.Trial.TrialFinishedTime < u.SystemDocument.CreateTime)) .WhereIf(trialInfo.TrialFinishedTime != null, u => u.SystemDocument.CreateTime < trialInfo.TrialFinishedTime) .WhereIf(!_userInfo.IsAdmin, t => t.SystemDocument.IsDeleted == false || (t.SystemDocument.IsDeleted == true && t.SystemDocument.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id))) @@ -356,7 +355,7 @@ namespace IRaCIS.Core.Application.Services /// /// [HttpPost] - public async Task<(PageOutput, object)> GetDocumentConfirmList(DocumentTrialUnionQuery inQuery) + public async Task>> GetDocumentConfirmList(DocumentTrialUnionQuery inQuery) { @@ -393,7 +392,7 @@ namespace IRaCIS.Core.Application.Services #endregion - var trialInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync()); + var trialInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId,ignoreQueryFilters:true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync()); var trialDocQuery = from trialDocumentNeedConfirmedUserType in _trialDocNeedConfirmedUserTypeRepository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) join trialUser in _trialUserRepository.Where(t => t.TrialId == inQuery.TrialId) @@ -486,7 +485,7 @@ namespace IRaCIS.Core.Application.Services .CountAsync(); - return (result, new { NeedSignCount = needSignTrialDocCount + needSignSystemDocCount, NeedSignTrialDocCount = needSignTrialDocCount, NeedSignSystemDocCount = needSignSystemDocCount, TrialStatusStr = trialInfo.TrialStatusStr }); + return ResponseOutput.Ok (result, new { NeedSignCount = needSignTrialDocCount + needSignSystemDocCount, NeedSignTrialDocCount = needSignTrialDocCount, NeedSignSystemDocCount = needSignSystemDocCount, TrialStatusStr = trialInfo.TrialStatusStr }); } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs index 071affd3e..a639dc0f5 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs @@ -382,7 +382,7 @@ namespace IRaCIS.Core.Application.Contracts public string HtmlPath { get; set; } = string.Empty; - public long FileSize { get; set; } + public long FileSize { get; set; } } public class CRCUploadTaskQuery @@ -578,7 +578,7 @@ namespace IRaCIS.Core.Application.Contracts } - public class TrialIamgeDownQuery:PageInput + public class TrialIamgeDownQuery : PageInput { [NotDefault] public Guid TrialId { get; set; } @@ -595,6 +595,8 @@ namespace IRaCIS.Core.Application.Contracts public DateTime? DownloadEndTime { get; set; } public string? IP { get; set; } + + public string? Name { get; set} } public class SubjectVisitTaskInfo diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 5941c0d16..1bf154b8a 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -997,6 +997,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var query = _trialImageDownloadRepository.Where(t => t.TrialId == inQuery.TrialId) .WhereIf(inQuery.SubjectCode.IsNotNullOrEmpty(), t => t.SubjectCode.Contains(inQuery.SubjectCode)) .WhereIf(inQuery.IP.IsNotNullOrEmpty(), t => t.IP.Contains(inQuery.IP)) + .WhereIf(inQuery.Name.IsNotNullOrEmpty(), t => t.CreateUser.UserName.Contains(inQuery.Name) || t.CreateUser.FullName.Contains(inQuery.Name)) .WhereIf(inQuery.ImageType != null, t => t.ImageType == inQuery.ImageType) .WhereIf(inQuery.UserType != null, t => t.CreateUser.UserTypeEnum == inQuery.UserType) .WhereIf(inQuery.IsSuccess != null, t => t.IsSuccess == inQuery.IsSuccess) diff --git a/IRaCIS.Core.Application/Service/QC/ClinicalDataService.cs b/IRaCIS.Core.Application/Service/QC/ClinicalDataService.cs index c4c186183..6ac863684 100644 --- a/IRaCIS.Core.Application/Service/QC/ClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/QC/ClinicalDataService.cs @@ -51,7 +51,7 @@ namespace IRaCIS.Core.Application.Contracts return await previousHistoryQueryable.ToListAsync(); } - [HttpPost] + [HttpPost("{trialId:guid}")] public async Task> AddOrUpdatePreviousHistory(PreviousHistoryAddOrEdit addOrEditPreviousHistory) { await _qCCommon.VerifyIsCRCSubmmitAsync(_subjectVisitRepository, _userInfo, addOrEditPreviousHistory.SubjectVisitId); From 86864ae5756591fdfff530f8795bf72af5c32fa3 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 09:47:13 +0800 Subject: [PATCH 19/59] =?UTF-8?q?=E7=BC=96=E8=AF=91=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Document/Interface/ITrialDocumentService.cs | 2 +- .../Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Document/Interface/ITrialDocumentService.cs b/IRaCIS.Core.Application/Service/Document/Interface/ITrialDocumentService.cs index 4ff621279..b3fce366c 100644 --- a/IRaCIS.Core.Application/Service/Document/Interface/ITrialDocumentService.cs +++ b/IRaCIS.Core.Application/Service/Document/Interface/ITrialDocumentService.cs @@ -16,7 +16,7 @@ namespace IRaCIS.Core.Application.Contracts Task UserAbandonDoc(Guid documentId, bool isSystemDoc); Task AddOrUpdateTrialDocument(AddOrEditTrialDocument addOrEditTrialDocument); Task DeleteTrialDocument(Guid trialDocumentId, Guid trialId); - Task>> GetDocumentConfirmList(DocumentTrialUnionQuery querySystemDocument); + //Task>> GetDocumentConfirmList(DocumentTrialUnionQuery querySystemDocument); Task> GetTrialDocumentList(TrialDocumentQuery queryTrialDocument); Task>> GetUserDocumentList(TrialUserDocUnionQuery querySystemDocument); diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs index a639dc0f5..31f02fd6f 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs @@ -596,7 +596,7 @@ namespace IRaCIS.Core.Application.Contracts public string? IP { get; set; } - public string? Name { get; set} + public string? Name { get; set; } } public class SubjectVisitTaskInfo From d50091ed6bf98b94221fc6f934669fcdd30b294f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 10:24:17 +0800 Subject: [PATCH 20/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E6=A1=A3bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Document/DTO/SystemDocumentViewModel.cs | 2 +- .../Service/Document/SystemDocumentService.cs | 3 ++- .../Service/Document/TrialDocumentService.cs | 4 ++-- IRaCIS.Core.Application/Service/Document/_MapConfig.cs | 6 ++++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Document/DTO/SystemDocumentViewModel.cs b/IRaCIS.Core.Application/Service/Document/DTO/SystemDocumentViewModel.cs index 99d2470ad..1082bfa7f 100644 --- a/IRaCIS.Core.Application/Service/Document/DTO/SystemDocumentViewModel.cs +++ b/IRaCIS.Core.Application/Service/Document/DTO/SystemDocumentViewModel.cs @@ -105,7 +105,7 @@ namespace IRaCIS.Core.Application.Contracts public class SystemDocumentQuery : PageInput { - + public bool? IsDeleted { get; set; } public Guid? SystemDocumentId { get; set; } public Guid? FileTypeId { get; set; } diff --git a/IRaCIS.Core.Application/Service/Document/SystemDocumentService.cs b/IRaCIS.Core.Application/Service/Document/SystemDocumentService.cs index 8ea2c4670..cd4f3c8a0 100644 --- a/IRaCIS.Core.Application/Service/Document/SystemDocumentService.cs +++ b/IRaCIS.Core.Application/Service/Document/SystemDocumentService.cs @@ -36,7 +36,8 @@ namespace IRaCIS.Core.Application.Services var systemDocumentQueryable = _systemDocumentRepository.AsQueryable(true) .WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name)) .WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId) - .ProjectTo(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken, userId = _userInfo.Id }); + .WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted) + .ProjectTo(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us, userId = _userInfo.Id }); return await systemDocumentQueryable.ToPagedListAsync(inQuery); } diff --git a/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs b/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs index da0bbf23c..4d5f238a7 100644 --- a/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs +++ b/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs @@ -224,7 +224,7 @@ namespace IRaCIS.Core.Application.Services var trialInfo = await ( _trialRepository.Where(t => t.Id == inQuery.TrialId, ignoreQueryFilters: true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync()); //系统文档查询 - var systemDocumentQueryable = from needConfirmedUserType in _systemDocNeedConfirmedUserTypeRepository.Where(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId) + var systemDocumentQueryable = from needConfirmedUserType in _systemDocNeedConfirmedUserTypeRepository.Where(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId,ignoreQueryFilters:true) .WhereIf(trialInfo.TrialFinishedTime != null, u => u.SystemDocument.CreateTime < trialInfo.TrialFinishedTime) .WhereIf(!_userInfo.IsAdmin, t => t.SystemDocument.IsDeleted == false || (t.SystemDocument.IsDeleted == true && t.SystemDocument.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id))) @@ -464,7 +464,7 @@ namespace IRaCIS.Core.Application.Services FullFilePath = needConfirmEdUserType.SystemDocument.Path }; - var unionQuery = trialDocQuery.Union(systemDocQuery) + var unionQuery = trialDocQuery.Union(systemDocQuery).IgnoreQueryFilters().Where(t=>!(t.IsDeleted == true && t.ConfirmUserId == null)) .WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name)) .WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId) .WhereIf(inQuery.IsConfirmed == true, t => t.ConfirmTime != null) diff --git a/IRaCIS.Core.Application/Service/Document/_MapConfig.cs b/IRaCIS.Core.Application/Service/Document/_MapConfig.cs index f01322122..1c00c3be8 100644 --- a/IRaCIS.Core.Application/Service/Document/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Document/_MapConfig.cs @@ -4,6 +4,8 @@ using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Models; +using IRaCIS.Core.Domain.Share; +using System.Globalization; namespace IRaCIS.Core.Application.Service { @@ -13,10 +15,10 @@ namespace IRaCIS.Core.Application.Service { var userId = Guid.Empty; - var token = string.Empty; var isEn_Us = false; + CreateMap() - .ForMember(d => d.FileType, u => u.MapFrom(s => s.FileType.Value)) + .ForMember(d => d.FileType, u => u.MapFrom(s => isEn_Us ? s.FileType.Value: s.FileType.ValueCN)) .ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path)); CreateMap() From 8fed969becf12abc7c313803580e3bbfdb75d926 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 10:36:17 +0800 Subject: [PATCH 21/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 2 +- IRaCIS.Core.API/appsettings.US_Test_IRC.json | 2 +- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index b76577877..a2fa640b5 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -77,7 +77,7 @@ }, "SystemPacsConfig": { - "Port": "11113", + "Port": "104", "IP": "44.210.231.169" } diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json index 3b4866fda..8625d51d0 100644 --- a/IRaCIS.Core.API/appsettings.US_Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -85,7 +85,7 @@ }, "SystemPacsConfig": { - "Port": "11113", + "Port": "104", "IP": "3.226.182.187" } diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index 23f74a7ba..4de8fbf1c 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -89,7 +89,7 @@ }, "SystemPacsConfig": { - "Port": "11113", + "Port": "104", "IP": "3.226.182.187" } From 3840627ce7bdcad96efe35fcd8c7906d25b3073d Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 10:49:50 +0800 Subject: [PATCH 22/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9scp=20=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/CStoreSCPService.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index 86c09af4e..fe1f91e00 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -176,6 +176,13 @@ namespace IRaCIS.Core.SCP.Service await _SCPImageUploadRepository.AddAsync(_upload, true); + + var _studyRepository = _serviceProvider.GetService>(); + //将检查设置为传输结束 + await _studyRepository.BatchUpdateNoTrackingAsync(t => _SCPStudyIdList.Contains(t.Id), u => new SCPStudy() { IsUploadFinished = true }); + + await _studyRepository.SaveChangesAndClearAllTrackingAsync(); + await SendAssociationReleaseResponseAsync(); } @@ -236,11 +243,11 @@ namespace IRaCIS.Core.SCP.Service //奇怪的bug 上传的时候,用王捷修改的影像,会关闭,重新连接,导致检查id 丢失,然后状态不一致 if (exception == null) { - var _studyRepository = _serviceProvider.GetService>(); - //将检查设置为传输结束 - await _studyRepository.BatchUpdateNoTrackingAsync(t => _SCPStudyIdList.Contains(t.Id), u => new SCPStudy() { IsUploadFinished = true }); + //var _studyRepository = _serviceProvider.GetService>(); + ////将检查设置为传输结束 + //await _studyRepository.BatchUpdateNoTrackingAsync(t => _SCPStudyIdList.Contains(t.Id), u => new SCPStudy() { IsUploadFinished = true }); - await _studyRepository.SaveChangesAndClearAllTrackingAsync(); + //await _studyRepository.SaveChangesAndClearAllTrackingAsync(); } Log.Logger.Warning($"连接关闭 {exception?.Message} {exception?.InnerException?.Message}"); From bfa2d8afce36ff8d055a751628cb6081906b9ce2 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 11:05:02 +0800 Subject: [PATCH 23/59] =?UTF-8?q?=E5=A2=9E=E5=8A=A0tiralSiteId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/TrialMaintenanceService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs index 57f4ad08c..f414ee2b0 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs @@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Authorization; using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Application.Contracts; using DocumentFormat.OpenXml.Office2010.ExcelAc; +using IRaCIS.Core.Domain.Models; namespace IRaCIS.Application.Services { @@ -67,7 +68,7 @@ namespace IRaCIS.Application.Services .WhereIf(inQuery.UserTypeId != null, t => t.User.UserTypeId == inQuery.UserTypeId) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.UserRealName), t => (t.User.FullName).Contains(inQuery.UserRealName)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.OrganizationName), t => t.User.OrganizationName.Contains(inQuery.OrganizationName)) - .ProjectTo(_mapper.ConfigurationProvider); + .ProjectTo(_mapper.ConfigurationProvider,new { trialSiteId =inQuery.TrialSiteId}); return await query.ToPagedListAsync(inQuery); From e997cb2a8f0b39bb7cdd92252a327c764f08086d Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 11:14:10 +0800 Subject: [PATCH 24/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9api=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/Dto/ReadingImageTaskViewModel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index 13ff07419..8910fd89c 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -613,7 +613,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto { public Guid Id { get; set; } - public string Answer { get; set; } + public string Answer { get; set; } = string.Empty; } public class DicomReadingQuestionAnswer : ReadingQuestionTrial { @@ -1205,9 +1205,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public Guid? OtherStudyId { get; set; } - public string OtherMarkTool { get; set; } + public string OtherMarkTool { get; set; } = string.Empty; - public string OtherPicturePath { get; set; } + public string OtherPicturePath { get; set; } = string.Empty; public int? OtherNumberOfFrames { get; set; } public string OtherMeasureData { get; set; } = string.Empty; From d507e625c6632e2182aae95cc62f18ce5d0db860 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 11:18:11 +0800 Subject: [PATCH 25/59] =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/Dto/ReadingImageTaskViewModel.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index 8910fd89c..2daf6f3ca 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -1093,10 +1093,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// MeasureData /// - public string MeasureData { get; set; } + public string MeasureData { get; set; } = string.Empty; - public string OtherMeasureData { get; set; } + public string OtherMeasureData { get; set; } = string.Empty; public int ShowOrder { get; set; } @@ -1119,9 +1119,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public Guid? OtherStudyId { get; set; } - public string OtherMarkTool { get; set; } + public string OtherMarkTool { get; set; } = string.Empty; - public string OtherPicturePath { get; set; } + public string OtherPicturePath { get; set; } = string.Empty; public int? OtherNumberOfFrames { get; set; } From bbc737811a6f661aedd261ea975e3b883cf6e74b Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 11:41:53 +0800 Subject: [PATCH 26/59] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=88=AA=E5=9B=BE?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Management/UserFeedBackService.cs | 2 ++ IRaCIS.Core.Application/Service/Management/_MapConfig.cs | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs index 86919aca8..89ace6dec 100644 --- a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs @@ -66,6 +66,8 @@ namespace IRaCIS.Core.Application.Service var result = await _userFeedBackRepository.WhereIf(inQuery.Id == null, t => t.VisitTaskId == inQuery.VisitTaskId) .WhereIf(inQuery.VisitTaskId == null, t => t.Id == inQuery.Id).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); + + return ResponseOutput.Ok(result); } diff --git a/IRaCIS.Core.Application/Service/Management/_MapConfig.cs b/IRaCIS.Core.Application/Service/Management/_MapConfig.cs index afc1653ac..d5f865767 100644 --- a/IRaCIS.Core.Application/Service/Management/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Management/_MapConfig.cs @@ -135,7 +135,9 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.SubjectVisitName, c => c.MapFrom(t => t.SubjectVisit.VisitName)) .ForMember(d => d.FeedBackUserName, c => c.MapFrom(t => t.CreateUser.UserName)) .ForMember(d => d.FeedBackFullName, c => c.MapFrom(t => t.CreateUser.FullName)) - .ForMember(d => d.UserTypeEnum, c => c.MapFrom(t => t.CreateUser.UserTypeEnum)); + .ForMember(d => d.UserTypeEnum, c => c.MapFrom(t => t.CreateUser.UserTypeEnum)) + .ForMember(d => d.ScreenshotList, c => c.MapFrom(t => t.FeedBackScreenshotList)) + ; CreateMap().ReverseMap(); } From e065e44ab0bc41a78515834047e79d8c1f4a024c Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 12:33:37 +0800 Subject: [PATCH 27/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=E7=BB=99=E2=80=9C=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/Dto/ClinicalAnswerDto.cs | 2 +- .../Reading/Dto/ReadingCalculateViewModel.cs | 4 +- .../Reading/Dto/ReadingImageTaskViewModel.cs | 74 +++++++++---------- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ClinicalAnswerDto.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ClinicalAnswerDto.cs index c09cbbf25..bb6738c65 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ClinicalAnswerDto.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ClinicalAnswerDto.cs @@ -361,7 +361,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public Guid? ClinicalFormId { get; set; } - public string PicturePath { get; set; } = string.Empty; + public string? PicturePath { get; set; } public Guid SubjectId { get; set; } diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs index dbb1d0538..e9824555b 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs @@ -306,8 +306,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public decimal FristAddTaskNum { get; set; } - public string OtherMeasureData { get; set; } = string.Empty; - public string MeasureData { get; set; } = string.Empty; + public string? OtherMeasureData { get; set; } + public string? MeasureData { get; set; } public List TableQuestionList { get; set; } = new List(); } diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index 2daf6f3ca..8fe7acbd8 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -91,7 +91,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public bool IsCanEditPosition { get; set; } = false; - public string BlindName { get; set; } = string.Empty; + public string BlindName { get; set; } public Guid? RowId { get; set; } @@ -114,12 +114,12 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// 类型值 /// - public string TypeValue { get; set; } + public string? TypeValue { get; set; } /// /// 序号标记 /// - public string OrderMark { get; set; } = string.Empty; + public string? OrderMark { get; set; } /// /// 数值类型 @@ -129,7 +129,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// 自定义单位 /// - public string CustomUnit { get; set; } = string.Empty; + public string? CustomUnit { get; set; } /// /// 单位 @@ -140,7 +140,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public ReportLayType ReportLayType { get; set; } = ReportLayType.Group; - public string ReportMark { get; set; } = string.Empty; + public string? ReportMark { get; set; } /// /// 高亮问题的答案 @@ -310,7 +310,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto { public Guid RowId { get; set; } - public string OrderMarkName { get; set; } + public string? OrderMarkName { get; set; } public Guid? OrganInfoId { get; set; } @@ -500,7 +500,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// MeasureData /// - public string MeasureData { get; set; } + public string? MeasureData { get; set; } /// /// CreateTime @@ -683,7 +683,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// 标记工具 /// - public string MarkTool { get; set; } = string.Empty; + public string? MarkTool { get; set; } /// /// TrialId @@ -738,7 +738,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// MeasureData /// - public string MeasureData { get; set; } = string.Empty; + public string? MeasureDataMeasureData { get; set; } /// /// 是否是当前任务添加 @@ -757,14 +757,14 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public Guid? MergeRowId { get; set; } - public string BlindName { get; set; } = string.Empty; + public string? BlindName { get; set; } - public string OrderMark { get; set; } = string.Empty; + public string? OrderMark { get; set; } /// /// 截图地址 /// - public string PicturePath { get; set; } = string.Empty; + public string? PicturePath { get; set; } /// /// 第一次添加的任务ID @@ -800,11 +800,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// 来自于哪个标记 /// - public string FromMark { get; set; } = string.Empty; + public string? FromMark { get; set; } - public string ReportMark { get; set; } = string.Empty; + public string? ReportMark { get; set; } - public string RowMark { get; set; } = string.Empty; + public string? RowMark { get; set; } } @@ -1000,13 +1000,13 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// 序号标记 /// - public string OrderMark { get; set; } = string.Empty; + public string? OrderMark { get; set; } - public string OrderMarkName { get; set; } = string.Empty; + public string? OrderMarkName { get; set; } - public string FromMark { get; set; } = string.Empty; + public string? FromMark { get; set; } /// /// 病灶类型 @@ -1059,7 +1059,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// RowIndex /// - public string RowIndex { get; set; } + public string? RowIndex { get; set; } /// /// RowIndex @@ -1072,7 +1072,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public bool IsDicomReading { get; set; } = true; - public string BlindName { get; set; } = string.Empty; + public string? BlindName { get; set; } /// @@ -1093,10 +1093,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// MeasureData /// - public string MeasureData { get; set; } = string.Empty; + public string? MeasureData { get; set; } - public string OtherMeasureData { get; set; } = string.Empty; + public string? OtherMeasureData { get; set; } public int ShowOrder { get; set; } @@ -1119,9 +1119,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public Guid? OtherStudyId { get; set; } - public string OtherMarkTool { get; set; } = string.Empty; + public string? OtherMarkTool { get; set; } - public string OtherPicturePath { get; set; } = string.Empty; + public string? OtherPicturePath { get; set; } public int? OtherNumberOfFrames { get; set; } @@ -1165,12 +1165,12 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// MarkTool /// - public string MarkTool { get; set; } = string.Empty; + public string? MarkTool { get; set; } /// /// PicturePath /// - public string PicturePath { get; set; } = string.Empty; + public string? PicturePath { get; set; } /// /// NumberOfFrames @@ -1180,14 +1180,14 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// MeasureData /// - public string MeasureData { get; set; } = string.Empty; + public string? MeasureData { get; set; } public Guid? FirstAddTaskId { get; set; } public QuestionType? QuestionType { get; set; } - public string OrderMarkName { get; set; } = string.Empty; + public string? OrderMarkName { get; set; } /// @@ -1205,12 +1205,12 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public Guid? OtherStudyId { get; set; } - public string OtherMarkTool { get; set; } = string.Empty; + public string? OtherMarkTool { get; set; } - public string OtherPicturePath { get; set; } = string.Empty; + public string? OtherPicturePath { get; set; } public int? OtherNumberOfFrames { get; set; } - public string OtherMeasureData { get; set; } = string.Empty; + public string? OtherMeasureData { get; set; } } public class GetReadingQuestionAndAnswerInDto { @@ -2171,14 +2171,14 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// 标记工具 /// - public string MarkTool { get; set; } = string.Empty; + public string? MarkTool { get; set; } public decimal RowIndex { get; set; } /// /// 截图地址 /// - public string PicturePath { get; set; } = string.Empty; + public string? PicturePath { get; set; } /// /// 任务Id @@ -2190,9 +2190,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public Guid TrialId { get; set; } - public string MeasureData { get; set; } = string.Empty; + public string? MeasureData { get; set; } - public string OtherMeasureData { get; set; } = string.Empty; + public string? OtherMeasureData { get; set; } public Guid? SeriesId { get; set; } @@ -2238,9 +2238,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public Guid? OtherStudyId { get; set; } - public string OtherMarkTool { get; set; } = string.Empty; + public string? OtherMarkTool { get; set; } - public string OtherPicturePath { get; set; } = string.Empty; + public string? OtherPicturePath { get; set; } public int? OtherNumberOfFrames { get; set; } From 564ac4d93111ac97a9cd056debd1ffd4f2b7ae04 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 12:37:47 +0800 Subject: [PATCH 28/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/Dto/ReadingImageTaskViewModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index 8fe7acbd8..596f14cf0 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -738,7 +738,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// /// MeasureData /// - public string? MeasureDataMeasureData { get; set; } + public string? MeasureData { get; set; } /// /// 是否是当前任务添加 From c3daa75e0e520a4c412ab6e77a53a8c54c51c3c0 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 13:13:52 +0800 Subject: [PATCH 29/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=98=85=E7=89=87bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/_MapConfig.cs | 5 ++++- .../Service/WorkLoad/_MapConfig.cs | 4 +++- IRaCIS.Core.Application/TestService.cs | 18 ++++++++++++++++-- IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj | 4 ++-- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/_MapConfig.cs b/IRaCIS.Core.Application/Service/Reading/_MapConfig.cs index 852a75965..8987cd594 100644 --- a/IRaCIS.Core.Application/Service/Reading/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Reading/_MapConfig.cs @@ -68,7 +68,10 @@ namespace IRaCIS.Core.Application.Service #endregion CreateMap(); - CreateMap().ForMember(dest => dest.CreateUser, opt => opt.Ignore()); + CreateMap() + .ForMember(dest => dest.CreateUser, opt => opt.Ignore()) + .ForAllMembers(opts => opts.Condition((src, dest, srcMember) => srcMember != null)); + CreateMap(); CreateMap().ForMember(dest => dest.CreateUser, opt => opt.Ignore()); diff --git a/IRaCIS.Core.Application/Service/WorkLoad/_MapConfig.cs b/IRaCIS.Core.Application/Service/WorkLoad/_MapConfig.cs index 4a855e503..a590b98b4 100644 --- a/IRaCIS.Core.Application/Service/WorkLoad/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/WorkLoad/_MapConfig.cs @@ -2,6 +2,7 @@ using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Service.WorkLoad.DTO; using IRaCIS.Core.Domain.Models; +using static IRaCIS.Application.Services.TestService; namespace IRaCIS.Core.Application.Service { @@ -17,7 +18,8 @@ namespace IRaCIS.Core.Application.Service CreateMap().ReverseMap(); - + CreateMap(); + } } diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index d8876bcac..5f37812f2 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -105,18 +105,32 @@ namespace IRaCIS.Application.Services { public Guid TestId { get; set; } - public string TestName { get; set; } + public string? TestName { get; set; } } + public class TestModel2 + { + public Guid TestId { get; set; } + + public string TestName { get; set; } + } + public async Task TestJson() { + var model1 = new TestModel() { TestId = NewId.NextSequentialGuid(), TestName = null }; + var model2 = new TestModel2() { TestId = NewId.NextSequentialGuid(), TestName = "test2" }; + + //_mapper.Map(from, dbEntity); + + var model4= _mapper.Map(model1, model2); + await _trialBodyPartRepository.FirstOrDefaultAsync(); - await _trialBodyPartRepository.Where(t=>t.Trial.Id==Guid.Empty).FirstOrDefaultAsync(); + await _trialBodyPartRepository.Where(t => t.Trial.Id == Guid.Empty).FirstOrDefaultAsync(); return ResponseOutput.Ok(new TestModel(), IRCEmailPasswordHelper.GenerateRandomPassword(10)); } diff --git a/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj b/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj index 8f65510a5..555fa1854 100644 --- a/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj +++ b/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj @@ -1,7 +1,7 @@  - + net8.0 From 7285a9d672710f0f257198a1bd46fd3f22204f49 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 13:16:15 +0800 Subject: [PATCH 30/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/WorkLoad/_MapConfig.cs | 3 ++- IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/Service/WorkLoad/_MapConfig.cs b/IRaCIS.Core.Application/Service/WorkLoad/_MapConfig.cs index a590b98b4..fa1cbefe3 100644 --- a/IRaCIS.Core.Application/Service/WorkLoad/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/WorkLoad/_MapConfig.cs @@ -18,7 +18,8 @@ namespace IRaCIS.Core.Application.Service CreateMap().ReverseMap(); - CreateMap(); + CreateMap() + .ForAllMembers(opts => opts.Condition((src, dest, srcMember) => srcMember != null)); } diff --git a/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj b/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj index 555fa1854..8f65510a5 100644 --- a/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj +++ b/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj @@ -1,7 +1,7 @@  - + net8.0 From b6d0791f1836f067935ea9a5dd8f9e27cf7828e8 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 13:35:10 +0800 Subject: [PATCH 31/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BD=B1=E5=83=8F?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 2 +- .../ImageAndDoc/NoneDicomStudyService.cs | 10 +++++++-- .../ReadingNoDicomTaskService.cs | 21 +++++++++++-------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 000d081aa..b546b77d7 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -11847,7 +11847,7 @@ NoneDicomStudyService - + NoneDicomStudyService diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs index 45d2f4a3a..4615730d7 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs @@ -9,6 +9,7 @@ using System.ComponentModel.DataAnnotations; using IRaCIS.Core.Application.Service; using IRaCIS.Core.Domain.Share; using Medallion.Threading; +using IRaCIS.Core.Application.Service.Reading.Dto; namespace IRaCIS.Core.Application.Contracts { @@ -22,6 +23,7 @@ namespace IRaCIS.Core.Application.Contracts IRepository _trialRepository, IDistributedLockProvider _distributedLockProvider, IRepository _subjectVisitRepository, + IRepository _visitTaskRepository, QCCommon _qCCommon) : BaseService, INoneDicomStudyService { @@ -40,12 +42,16 @@ namespace IRaCIS.Core.Application.Contracts { noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId).WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) - .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip}); + .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip }); } else { + var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(t => new { t.BlindSubjectCode, t.TrialReadingCriterionId, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync(); + + noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.TaskNoneDicomFileList.Any(t => t.VisitTaskId == visitTaskId)) - .WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) + .Where(t => taskinfo.IsImageFilter ? ("|" + taskinfo.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true) + .WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, visiTaskId = visitTaskId }); } diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingNoDicomTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingNoDicomTaskService.cs index 0276b80f9..1574583dc 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingNoDicomTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingNoDicomTaskService.cs @@ -7,6 +7,7 @@ using IRaCIS.Core.Application.Contracts; using MassTransit; using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Domain.Models; +using DocumentFormat.OpenXml.EMMA; namespace IRaCIS.Application.Services { @@ -89,20 +90,22 @@ namespace IRaCIS.Application.Services var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisistTaskId).Select(t => new { t.BlindSubjectCode, t.TrialReadingCriterionId, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync(); + IQueryable noneDicomStudyQueryable = default; - if (inDto.VisistTaskId == null) - { - noneDicomStudyQueryable = _noneDicomStudyRepository - .Where(t => visitIds.Contains(t.SubjectVisitId) && t.NoneDicomFileList.Any(t => !t.FileType.Contains(StaticData.FileType.Zip))) - .WhereIf(taskinfo.IsImageFilter == true, t => taskinfo.CriterionModalitys.Contains(t.Modality)) - .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = true }); - } - else + + noneDicomStudyQueryable = _noneDicomStudyRepository + .Where(t => visitIds.Contains(t.SubjectVisitId) && t.NoneDicomFileList.Any(t => !t.FileType.Contains(StaticData.FileType.Zip))) + .WhereIf(taskinfo.IsImageFilter == true, t => taskinfo.CriterionModalitys.Contains(t.Modality)) + .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = true }); + + if (inDto.VisistTaskId != null && _noneDicomStudyFileSystem.Any(t => t.VisitTaskId == inDto.VisistTaskId)) { noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.TaskNoneDicomFileList.Any(t => t.VisitTaskId == inDto.VisistTaskId)) - .Where(t => visitIds.Contains(t.SubjectVisitId)) + .Where(t => taskinfo.IsImageFilter ? ("|" + taskinfo.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true) + .Where(t => visitIds.Contains(t.SubjectVisitId)) .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = true, visiTaskId = inDto.VisistTaskId }); } + List result = await noneDicomStudyQueryable.ToListAsync(); From f189f9f361278a8b8154b1fd65e4f8585716d101 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 13:46:48 +0800 Subject: [PATCH 32/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9s3=20=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 2 +- IRaCIS.Core.API/appsettings.US_Test_IRC.json | 2 +- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 2 +- IRaCIS.Core.Application/TestService.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index a2fa640b5..2943de824 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -33,7 +33,7 @@ "AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM", "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", - "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com", "DurationSeconds": 7200 } }, diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json index 8625d51d0..e12bcd647 100644 --- a/IRaCIS.Core.API/appsettings.US_Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -39,7 +39,7 @@ "AccessKeyId": "AKIAW3MEAFJX7IPXISP4", "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", - "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com", "DurationSeconds": 7200 } }, diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index 4de8fbf1c..ac1f534c3 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -43,7 +43,7 @@ "AccessKeyId": "AKIAW3MEAFJX7IPXISP4", "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", - "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com", "DurationSeconds": 7200 } }, diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index 5f37812f2..c36a7c6b5 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -123,7 +123,7 @@ namespace IRaCIS.Application.Services var model1 = new TestModel() { TestId = NewId.NextSequentialGuid(), TestName = null }; var model2 = new TestModel2() { TestId = NewId.NextSequentialGuid(), TestName = "test2" }; - //_mapper.Map(from, dbEntity); + var model4= _mapper.Map(model1, model2); From 67a930a2087fdf1672a2d7b7bfead94895aa38fb Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 13:50:47 +0800 Subject: [PATCH 33/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Controllers/ExtraController.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs index 4851eb3e6..9152ace33 100644 --- a/IRaCIS.Core.API/Controllers/ExtraController.cs +++ b/IRaCIS.Core.API/Controllers/ExtraController.cs @@ -312,6 +312,8 @@ namespace IRaCIS.Api.Controllers var result = await _oSSService.GetObjectStoreTempToken(); + result.AWS = await GetAWSTemToken(options.CurrentValue); + return ResponseOutput.Ok(result); } From f26441719f4d21f6c63578d1ed04de5ebd2eb703 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 13:51:47 +0800 Subject: [PATCH 34/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Test_IRC.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index b42343431..1ccc9c7f2 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -44,7 +44,7 @@ "AccessKeyId": "AKIAW3MEAFJX7IPXISP4", "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", - "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com", "DurationSeconds": 7200 } }, From 5931a67825c9e87a599253d7a8258721342759db Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 14:10:58 +0800 Subject: [PATCH 35/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E8=B0=83=E7=A0=94bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/SiteSurvey/TrialSiteSurveyService.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 63729ed88..0ad23cb5d 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -191,7 +191,9 @@ namespace IRaCIS.Core.Application.Contracts TrialSiteSurvey? currentEntity = null; - var userList = await _trialSiteUserRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId, false, true).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + var list = await _trialSiteUserRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId, false, true).ToListAsync(); + + var userList = _mapper.Map>(list); //普通登录 if (userInfo.IsUpdate == false) From a6a6765d9b423949f3804da72666abb2632aa993 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 14:13:03 +0800 Subject: [PATCH 36/59] x --- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index ac1f534c3..4de8fbf1c 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -43,7 +43,7 @@ "AccessKeyId": "AKIAW3MEAFJX7IPXISP4", "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", - "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", "DurationSeconds": 7200 } }, From 68dc09d969f79bbba5378c0c9c38c21ddc6b920f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 14:38:15 +0800 Subject: [PATCH 37/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E8=B0=83=E7=A0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 2 +- IRaCIS.Core.API/appsettings.US_Test_IRC.json | 2 +- .../Service/SiteSurvey/TrialSiteSurveyService.cs | 4 +--- IRaCIS.Core.Application/Service/SiteSurvey/_MapConfig.cs | 3 ++- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index 2943de824..a2fa640b5 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -33,7 +33,7 @@ "AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM", "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", - "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", "DurationSeconds": 7200 } }, diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json index e12bcd647..8625d51d0 100644 --- a/IRaCIS.Core.API/appsettings.US_Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -39,7 +39,7 @@ "AccessKeyId": "AKIAW3MEAFJX7IPXISP4", "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", - "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", "DurationSeconds": 7200 } }, diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 0ad23cb5d..4b6af2576 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -190,10 +190,8 @@ namespace IRaCIS.Core.Application.Contracts TrialSiteSurvey? currentEntity = null; + var userList = await _trialSiteUserRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId, false, true).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - var list = await _trialSiteUserRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId, false, true).ToListAsync(); - - var userList = _mapper.Map>(list); //普通登录 if (userInfo.IsUpdate == false) diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/_MapConfig.cs b/IRaCIS.Core.Application/Service/SiteSurvey/_MapConfig.cs index a8b1a46a0..e3ac8eb6a 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/_MapConfig.cs @@ -36,7 +36,8 @@ namespace IRaCIS.Core.Application.AutoMapper .ForMember(d => d.IsGenerateAccount, u => u.MapFrom(c => true)) .ForMember(d => d.IsGenerateSuccess, u => u.MapFrom(c => true)) .ForMember(d => d.SystemUserId, u => u.MapFrom(c => c.UserId)) - .ForMember(d => d.IsJoin, u => u.MapFrom(c => !c.IsDeleted)); + .ForMember(d => d.IsJoin, u => u.MapFrom(c => !c.IsDeleted)) + .ForMember(d => d.CreateUser, u => u.Ignore()); //列表 From f7c669a7d74ff7acdaf8cfb6fd2d6375ef09151f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 14:44:56 +0800 Subject: [PATCH 38/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9scp=20=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/appsettings.US_Uat_SCP.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRC.Core.SCP/appsettings.US_Uat_SCP.json b/IRC.Core.SCP/appsettings.US_Uat_SCP.json index 78dcb50e7..28a51b21f 100644 --- a/IRC.Core.SCP/appsettings.US_Uat_SCP.json +++ b/IRC.Core.SCP/appsettings.US_Uat_SCP.json @@ -21,8 +21,8 @@ } }, "ConnectionStrings": { - "RemoteNew": "Server=47.117.164.182,1434;Database=Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", - "Hangfire": "Server=47.117.164.182,1434;Database=Uat_IRC.Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + "RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" }, "DicomSCPServiceConfig": { "CalledAEList": [ From 010fdf6e2c1c21b0a3f38ec09c0036ab9933e2e0 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 16:27:16 +0800 Subject: [PATCH 39/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8E=92=E5=BA=8Fbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 8 ++++---- IRaCIS.Core.Application/IRaCIS.Core.Application.xml | 2 +- .../Service/Document/TrialEmailNoticeConfigService.cs | 2 ++ .../Service/Inspection/InspectionService.cs | 4 ++-- .../Service/TrialSiteUser/TrialService.cs | 5 +++-- IRaCIS.Core.Application/Service/Visit/PatientService.cs | 4 ++-- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index 4de8fbf1c..b978dffcd 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -7,11 +7,11 @@ } }, "ConnectionStrings": { - "RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", - "Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + //"RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + //"Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" - //"RemoteNew": "Server=3.226.182.187,1435;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", - //"Hangfire": "Server=3.226.182.187,1435;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + "RemoteNew": "Server=3.226.182.187,1435;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=3.226.182.187,1435;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" }, "ObjectStoreService": { diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index b546b77d7..72619802a 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -902,7 +902,7 @@ TrialEmailNoticeConfigService - + TrialEmailNoticeConfigService diff --git a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs index dd74124a9..06d10cccc 100644 --- a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs +++ b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs @@ -27,6 +27,7 @@ using System.Runtime.InteropServices; using SharpCompress.Common; using DocumentFormat.OpenXml.Bibliography; using System.Linq.Dynamic.Core; +using Microsoft.Extensions.Options; namespace IRaCIS.Core.Application.Service { @@ -50,6 +51,7 @@ namespace IRaCIS.Core.Application.Service IRepository _subjectVisitRepository, IRepository _readingTaskQuestionAnswerRepository, IRepository _readingQuestionCriterionTrialRepository, + IOptionsMonitor _systemEmailSendConfig, IEmailSendService _emailSendService) : BaseService, ITrialEmailNoticeConfigService { diff --git a/IRaCIS.Core.Application/Service/Inspection/InspectionService.cs b/IRaCIS.Core.Application/Service/Inspection/InspectionService.cs index 374d38fa8..4b885987f 100644 --- a/IRaCIS.Core.Application/Service/Inspection/InspectionService.cs +++ b/IRaCIS.Core.Application/Service/Inspection/InspectionService.cs @@ -135,8 +135,8 @@ namespace IRaCIS.Core.Application.Service.Inspection //UserLastName = leftuser.LastName, ExperimentName = leftrial.ExperimentName, - - SubjectCode = leftvisttask.BlindSubjectCode.IsNullOrEmpty()? leftsubject.Code: leftvisttask.BlindSubjectCode, + //SubjectCode = leftvisttask.BlindSubjectCode.IsNullOrEmpty()? leftsubject.Code: leftvisttask.BlindSubjectCode, + SubjectCode = leftvisttask.IsAnalysisCreate? leftvisttask.BlindSubjectCode: leftsubject.Code , SiteCode = lefttrialSite.TrialSiteCode, ResearchProgramNo = leftrial.ResearchProgramNo, diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs index 7d4ead352..194884c9f 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs @@ -31,8 +31,9 @@ namespace IRaCIS.Application.Services IRepository _visitStageRepository, IRepository _trialPaymentPriceRepository, IRepository _trialDictionaryRepository, - IRepository _trialBodyPartRepository, - IOptionsMonitor _verifyConfig) : BaseService, ITrialService + IRepository _trialBodyPartRepository, + IOptionsMonitor _verifyConfig + ) : BaseService, ITrialService { diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs index 4d8b64bb3..b173a72a9 100644 --- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs +++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs @@ -139,8 +139,8 @@ namespace IRaCIS.Application.Services var query = _patientRepository.Where(t => t.TrialId == inQuery.TrialId) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.PatientName.Contains(inQuery.PatientName)) - .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubejctCode), t => t.Subject.Code.Contains(inQuery.SubejctCode)) - .WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteKeyInfo), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteKeyInfo) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubejctCode), t => t.Subject.Code.Contains(inQuery.SubejctCode)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteKeyInfo), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteKeyInfo) || t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteKeyInfo) || t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteKeyInfo)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.SCPStudyList.Any(t => t.CallingAE == inQuery.CallingAE)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.SCPStudyList.Any(t => t.CalledAE == inQuery.CalledAE)) From 3813158b00b42743a02bb9db2ea7dedb5d88a8df Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sat, 14 Sep 2024 17:41:15 +0800 Subject: [PATCH 40/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9oss=20=20=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/OSSService.cs | 20 ++++++++++++-------- IRaCIS.Core.API/appsettings.Test_IRC.json | 2 +- IRaCIS.Core.Application/Helper/OSSService.cs | 20 ++++++++++++-------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/IRC.Core.SCP/Service/OSSService.cs b/IRC.Core.SCP/Service/OSSService.cs index 897a62386..4af37a247 100644 --- a/IRC.Core.SCP/Service/OSSService.cs +++ b/IRC.Core.SCP/Service/OSSService.cs @@ -323,12 +323,13 @@ namespace IRaCIS.Core.SCP var awsConfig = ObjectStoreServiceOptions.AWS; // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); + var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config { - ServiceURL = awsConfig.EndPoint + RegionEndpoint = RegionEndpoint.USEast1, + UseHttp = true, }; var amazonS3Client = new AmazonS3Client(credentials, clientConfig); @@ -398,12 +399,13 @@ namespace IRaCIS.Core.SCP var awsConfig = ObjectStoreServiceOptions.AWS; // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); + var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config { - ServiceURL = awsConfig.EndPoint + RegionEndpoint = RegionEndpoint.USEast1, + UseHttp = true, }; var amazonS3Client = new AmazonS3Client(credentials, clientConfig); @@ -491,12 +493,13 @@ namespace IRaCIS.Core.SCP // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); + var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config { - ServiceURL = awsConfig.EndPoint + RegionEndpoint = RegionEndpoint.USEast1, + UseHttp = true, }; var amazonS3Client = new AmazonS3Client(credentials, clientConfig); @@ -620,12 +623,13 @@ namespace IRaCIS.Core.SCP // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); + var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config { - ServiceURL = awsConfig.EndPoint + RegionEndpoint = RegionEndpoint.USEast1, + UseHttp = true, }; var amazonS3Client = new AmazonS3Client(credentials, clientConfig); diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 1ccc9c7f2..b42343431 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -44,7 +44,7 @@ "AccessKeyId": "AKIAW3MEAFJX7IPXISP4", "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", - "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", "DurationSeconds": 7200 } }, diff --git a/IRaCIS.Core.Application/Helper/OSSService.cs b/IRaCIS.Core.Application/Helper/OSSService.cs index f4609a16e..76ed3c248 100644 --- a/IRaCIS.Core.Application/Helper/OSSService.cs +++ b/IRaCIS.Core.Application/Helper/OSSService.cs @@ -325,12 +325,13 @@ namespace IRaCIS.Core.Application.Helper var awsConfig = ObjectStoreServiceOptions.AWS; // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); + var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config { - ServiceURL = awsConfig.EndPoint + RegionEndpoint = RegionEndpoint.USEast1, + UseHttp = true, }; var amazonS3Client = new AmazonS3Client(credentials, clientConfig); @@ -400,12 +401,13 @@ namespace IRaCIS.Core.Application.Helper var awsConfig = ObjectStoreServiceOptions.AWS; // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); + var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config { - ServiceURL = awsConfig.EndPoint + RegionEndpoint = RegionEndpoint.USEast1, + UseHttp = true, }; var amazonS3Client = new AmazonS3Client(credentials, clientConfig); @@ -493,12 +495,13 @@ namespace IRaCIS.Core.Application.Helper // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); + var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config { - ServiceURL = awsConfig.EndPoint + RegionEndpoint = RegionEndpoint.USEast1, + UseHttp = true, }; var amazonS3Client = new AmazonS3Client(credentials, clientConfig); @@ -622,12 +625,13 @@ namespace IRaCIS.Core.Application.Helper // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); + var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config { - ServiceURL = awsConfig.EndPoint + RegionEndpoint = RegionEndpoint.USEast1, + UseHttp = true, }; var amazonS3Client = new AmazonS3Client(credentials, clientConfig); From 581e412106d5aa9e034487b6caa92ce98cd79428 Mon Sep 17 00:00:00 2001 From: hang <87227557@qq.com> Date: Tue, 17 Sep 2024 10:13:23 +0800 Subject: [PATCH 41/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 23 +- .../Service/Allocation/VisitTaskService.cs | 5631 ++++++++--------- .../Common/DTO/FrontAuditConfigViewModel.cs | 2 +- .../Inspection/DTO/InspectionViewModel.cs | 73 + .../Inspection/FrontAuditConfigService.cs | 2 +- .../Common/AuditingData.cs | 1 - ...etDictionaryValueDto.cs => AuditingDto.cs} | 136 +- .../Common/Dto/DateDto.cs | 23 - .../Context/IRaCISDBContext.cs | 1 - .../LiquidTemplate/EntityService.liquid | 81 +- .../LiquidTemplate/EntityViewModel.liquid | 54 +- .../LiquidTemplate/IEntityService.liquid | 24 +- 12 files changed, 3013 insertions(+), 3038 deletions(-) create mode 100644 IRaCIS.Core.Application/Service/Inspection/DTO/InspectionViewModel.cs rename IRaCIS.Core.Infra.EFCore/Common/{Dto/SetDictionaryValueDto.cs => AuditingDto.cs} (65%) delete mode 100644 IRaCIS.Core.Infra.EFCore/Common/Dto/DateDto.cs diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 72619802a..063780b32 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -1371,7 +1371,7 @@ - + 获取查询对象 @@ -1384,7 +1384,7 @@ - + 复制配置项及其子项 @@ -1398,14 +1398,14 @@ 数据集 - + 翻译稽查数据 - + 翻译稽查数据 @@ -10839,6 +10839,21 @@ SystemAnonymizationAddOrEdit 列表查询参数模型 + + + 质疑 + + + + + 一致性核查 + + + + + 复制 + + SystemNoticeView 列表视图模型 diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index 8a4e35553..d8345c225 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -24,2667 +24,1812 @@ using MassTransit; using System.Reactive.Subjects; using Subject = IRaCIS.Core.Domain.Models.Subject; -namespace IRaCIS.Core.Application.Service.Allocation +namespace IRaCIS.Core.Application.Service.Allocation; + +/// +/// 访视读片任务 +/// +[ApiExplorerSettings(GroupName = "Trial")] +public class VisitTaskService(IRepository _visitTaskRepository, + IRepository _trialRepository, + IRepository _subjectVisitRepository, + IRepository _taskAllocationRuleRepository, + IRepository _subjectRepository, + IRepository _subjectUserRepository, + IRepository _readModuleRepository, + IRepository _visitTaskReReadingRepository, + IRepository _taskMedicalReviewRepository, + IRepository _readingClinicalDataReposiotry, + IRepository _subjectCriteriaEvaluationRepository, + IRepository _subjectCriteriaEvaluationVisitFilterRepository, + IRepository _trialReadingCriterionRepository, + IRepository _readingQuestionCriterionTrialRepository, + IRepository _readingTaskQuestionAnswerRepository, + IRepository _dicomInstanceRepository, + IRepository _dicomSeriesRepository, + IRepository _subjectCanceDoctorRepository, + IRepository _readingTaskQuestionMarkRepository, + IRepository _readingTableAnswerRowInfoRepository, + IRepository _readingCustomTagRepository, + IRepository _taskInfluenceRepository, + IRepository _trialQCQuestionAnswerRepository, + IRepository _subjectCriteriaEvaluationVisitStudyFilterRepository) : BaseService, IVisitTaskService { + + + /// - /// 访视读片任务 - /// - [ApiExplorerSettings(GroupName = "Trial")] - public class VisitTaskService(IRepository _visitTaskRepository, - IRepository _trialRepository, - IRepository _subjectVisitRepository, - IRepository _taskAllocationRuleRepository, - IRepository _subjectRepository, - IRepository _subjectUserRepository, - IRepository _readModuleRepository, - IRepository _visitTaskReReadingRepository, - IRepository _taskMedicalReviewRepository, - IRepository _readingClinicalDataReposiotry, - IRepository _subjectCriteriaEvaluationRepository, - IRepository _subjectCriteriaEvaluationVisitFilterRepository, - IRepository _trialReadingCriterionRepository, - IRepository _readingQuestionCriterionTrialRepository, - IRepository _readingTaskQuestionAnswerRepository, - IRepository _dicomInstanceRepository, - IRepository _dicomSeriesRepository, - IRepository _subjectCanceDoctorRepository, - IRepository _readingTaskQuestionMarkRepository, - IRepository _readingTableAnswerRowInfoRepository, - IRepository _readingCustomTagRepository, - IRepository _taskInfluenceRepository, - IRepository _trialQCQuestionAnswerRepository, - IRepository _subjectCriteriaEvaluationVisitStudyFilterRepository) : BaseService, IVisitTaskService + /// 设置任务加急 + /// + /// + /// + [HttpPost] + public async Task SetTaskUrgent(SetTaskUrgentInDto inDto) + { + await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask() + { + IsUrgent = inDto.IsUrgent, + TaskUrgentType = inDto.TaskUrgentType, + TaskUrgentRemake = inDto.TaskUrgentRemake, + + }); + + return await _visitTaskRepository.SaveChangesAsync(); + } + + public async Task> GetTrialCriterionList(Guid trialId, bool isHaveSigned = true, bool? isAutoCreate = null) + { + var list = await _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsConfirm) + + .OrderBy(t => t.ShowOrder) + .Select(t => new TrialReadingCriterionDto() + { + TrialReadingCriterionId = t.Id, + IsAutoCreate = t.IsAutoCreate, + IsAdditionalAssessment = t.IsAdditionalAssessment, + TrialReadingCriterionName = t.CriterionName, + CriterionType = t.CriterionType, + ReadingType = t.ReadingType, + ReadingInfoSignTime = t.ReadingInfoSignTime, + IsReadingPeriod = t.IsReadingPeriod, + IsArbitrationReading = t.IsArbitrationReading, + IsGlobalReading = t.IsGlobalReading, + IsOncologyReading = t.IsOncologyReading, + ImageDownloadEnum = t.ImageDownloadEnum, + ImageUploadEnum = t.ImageUploadEnum, + IsReadingTaskViewInOrder = t.IsReadingTaskViewInOrder + }) + .ToListAsync(); + + //if (list.Count == 0) + //{ + // //---该项目还未确认任何一个阅片标准 + // throw new BusinessValidationFailedException(_localizer["VisitTask_VisitTask_TaskAlreadyApplied"]); + + //} + + + return list.AsQueryable().WhereIf(isHaveSigned == true, t => t.ReadingInfoSignTime != null) + .WhereIf(isAutoCreate == false, t => t.IsAutoCreate == isAutoCreate).ToList(); + } + + + + + /// + /// Subject 任务类型 统计 +分配情况 + /// + /// + [HttpPost] + public async Task>> GetSubjectAssignAndTaskStatList(SubjectAssignStatQuery inQuery) + { + + var isAddtinoarlCriterion = await _trialReadingCriterionRepository.AnyAsync(t => t.Id == inQuery.TrialReadingCriterionId && t.IsAutoCreate == false); + + var subjectQuery = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId && t.SubjectVisitTaskList.Any()) + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.Id == inQuery.SubjectId) + .WhereIf(inQuery.DoctorUserId != null, t => t.SubjectDoctorList.Any(t => t.DoctorUserId == inQuery.DoctorUserId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.Code.Contains(inQuery.SubjectCode)) + //未分配 + .WhereIf(inQuery.SubjectAllocateState == 0, t => !t.SubjectDoctorList.Any(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) + //已分配 + .WhereIf(inQuery.SubjectAllocateState == 1, t => t.SubjectDoctorList.Any(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) + + .WhereIf(inQuery.ArmList.Count > 0, t => !inQuery.ArmList.Except(t.SubjectDoctorList.Where(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).Select(c => c.ArmEnum)).Any()) + + + .WhereIf(isAddtinoarlCriterion, t => t.SubjectCriteriaEvaluationList.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).Any(t => t.IsJoinEvaluation)) + + + .ProjectTo(_mapper.ConfigurationProvider, new { trialReadingCriterionId = inQuery.TrialReadingCriterionId }); + + + var pageList = await subjectQuery.ToPagedListAsync(inQuery,nameof(SubjectAssignStat.SubjectId)); + + + + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading, x.IsGlobalReading }).FirstOrDefaultAsync()).IfNullThrowException(); + + return ResponseOutput.Ok(pageList, criterionConfig); + } + + /// + /// 一次性分配所有医生 批量分配(添加),后端现在没限制 + /// + /// + /// + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task BatchAssignDoctorToSubject(BatchAssignDoctorToSubjectCommand command) + { + //var inOrder = _trialRepository.Where(t => t.Id == command.TrialId).Select(t => t.IsReadingTaskViewInOrder).FirstOrDefault(); + + //var inOrder = _trialReadingCriterionRepository.Where(t => t.Id == command.TrialReadingCriterionId).Select(t => t.IsReadingTaskViewInOrder).FirstOrDefault(); + + + foreach (var subjectId in command.SubjectIdList) + { + foreach (var doctorArm in command.DoctorArmList) + { + if (!await _subjectUserRepository.Where(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId).AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId == doctorArm.DoctorUserId && t.ArmEnum == doctorArm.ArmEnum && t.IsConfirmed && t.ReplacedSubjectUserId == null)) + { + await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = command.TrialId, TrialReadingCriterionId = command.TrialReadingCriterionId, ArmEnum = doctorArm.ArmEnum, DoctorUserId = doctorArm.DoctorUserId, SubjectId = subjectId, AssignTime = DateTime.Now }); + + //task.SuggesteFinishedTime = task.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7); + + } + + + Expression> updateWhere = t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectId == subjectId && t.ArmEnum == doctorArm.ArmEnum && t.TrialId == command.TrialId && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false; + + //if (inOrder) + //{ + // //针对有序阅片 只分配< 最小的 不是一致性核查通过状态 和不是失访 的访视 的任务 + // if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == subjectId && t.CheckState != CheckStateEnum.CVPassed && t.IsLostVisit == false)) + // { + // var notCheckPassedMinVisitNum = await _subjectVisitRepository.Where(t => t.SubjectId == subjectId && t.CheckState != CheckStateEnum.CVPassed).OrderBy(t => t.VisitNum).Select(t => t.VisitNum).FirstOrDefaultAsync(); + + // updateWhere = updateWhere.And(t => t.VisitTaskNum < notCheckPassedMinVisitNum); + + // } + + //} + + + await _visitTaskRepository + .UpdatePartialFromQueryAsync(updateWhere, + u => new VisitTask() + { + AllocateTime = DateTime.Now, + DoctorUserId = doctorArm.DoctorUserId, + TaskAllocationState = TaskAllocationState.Allocated, + + SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget), + }); + } + } + + await _subjectUserRepository.SaveChangesAsync(); + + + + + + return ResponseOutput.Ok(); + } + + + + /// + /// 阅片人维度 Subject统计表 + /// + /// + /// + /// + public async Task<(List, object)> GetDoctorSubjectStat(Guid trialId, Guid trialReadingCriterionId) + { + var list = await _taskAllocationRuleRepository.Where(t => t.TrialId == trialId) + .Where(t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == trialReadingCriterionId)) + .ProjectTo(_mapper.ConfigurationProvider, new { trialReadingCriterionId = trialReadingCriterionId }).ToListAsync(); + + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading }).FirstOrDefaultAsync()).IfNullThrowException(); + + return (list, criterionConfig); + } + + + /// + /// 获取Subject 分配医生情况 + /// + /// + /// + /// + public async Task<(List, object)> GetSubjectAssignedDoctorList(Guid subjectId, Guid trialReadingCriterionId) + { + var list = await _subjectUserRepository.Where(t => t.SubjectId == subjectId && t.ReplacedSubjectUserId == null && t.IsConfirmed && t.TrialReadingCriterionId == trialReadingCriterionId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsGlobalReading, x.IsOncologyReading, x.IsArbitrationReading }).FirstOrDefaultAsync()).IfNullThrowException(); + + return (list, criterionConfig); + } + + + /// + /// 取消Subject 分配的医生 + /// + /// + /// + /// + [HttpPost] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task CancelSubjectAssignedDoctor(CancelSubjectDoctorCommand cancelCommand) + { + foreach (var command in cancelCommand.CancelList.Where(t => t.IsCancelAssign)) + { + if (await _visitTaskRepository.AnyAsync(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState != ReadingTaskState.WaitReading)) + { + //---当前医生已开始做该Subject 该标准的任务,不允许取消分配 + throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorConfigNotFound"]); + } + + await _subjectUserRepository.DeleteFromQueryAsync(t => t.Id == command.Id); + + await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState == ReadingTaskState.WaitReading && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false, u => new VisitTask() + { + AllocateTime = null, + DoctorUserId = null, + TaskAllocationState = TaskAllocationState.NotAllocate, + SuggesteFinishedTime = null + }); + } + + var subjectId = cancelCommand.CancelList.First().SubjectId; + + await _subjectCanceDoctorRepository.AddAsync(new SubjectCanceDoctor() { SubjectId = subjectId, Note = cancelCommand.Note, TrialReadingCriterionId = cancelCommand.TrialReadingCriterionId }); + + await _visitTaskRepository.SaveChangesAsync(); + + return ResponseOutput.Ok(); + } + + + + + /// + /// 任务 手动分配 重新分配 确认 取消分配 + /// 分配 + /// + /// + [HttpPost] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task AssignSubjectTaskToDoctor(AssignSubjectTaskToDoctorCommand assignSubjectTaskToDoctorCommand) + { + var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(t => t.Id == assignSubjectTaskToDoctorCommand.Id); + + if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Assign || assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign) + { + //手动分配验证规则 + + if (visitTask.SourceSubjectVisitId != null) + { + + if (await _visitTaskRepository.AnyAsync(t => t.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && t.TaskAllocationState == TaskAllocationState.Allocated && t.DoctorUserId == assignSubjectTaskToDoctorCommand.DoctorUserId && t.Id != visitTask.Id)) + { + //---其中一个任务已分配给该医生,不允许分配 + return ResponseOutput.NotOk(_localizer["VisitTask_BackendDataError"]); + } + } + else if (visitTask.SouceReadModuleId != null) + { + if (await _visitTaskRepository.AnyAsync(t => t.SouceReadModuleId == visitTask.SouceReadModuleId && t.TaskAllocationState == TaskAllocationState.Allocated && t.DoctorUserId == assignSubjectTaskToDoctorCommand.DoctorUserId && t.Id != visitTask.Id)) + { + //---其中一个任务已分配给该医生,不允许分配 + return ResponseOutput.NotOk(_localizer["VisitTask_BackendDataError"]); + } + } + else + { + //---出现脏数据 任务来源字段没有值 + throw new BusinessValidationFailedException(_localizer["VisitTask_DirtyData"]); + } + + //PM 回退了 但是还没生成任务 当前任务编号前有访视进行了回退就不允许分配 + if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == visitTask.SubjectId && t.IsPMBackOrReReading && t.VisitNum <= visitTask.VisitTaskNum)) + { + //---该受试者有访视进入了退回流程,还未经过一致性核查通过,不允许分配 + return ResponseOutput.NotOk(_localizer["VisitTask_MissingTaskSource"]); + } + + + visitTask.AllocateTime = DateTime.Now; + visitTask.DoctorUserId = assignSubjectTaskToDoctorCommand.DoctorUserId; + visitTask.TaskAllocationState = TaskAllocationState.Allocated; + + visitTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); + + + + //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading }); + + //await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading }); + } + + else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign) + { + //验证 是不是两个任务都给了同一个医生 + + + + //是否删除配置规则表里的 Subject 医生绑定关系 重新添加绑定关系 + + //是否其该Subject 其他访视 绑定的医生 也同时变更? + + + } + + else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Confirm) + { + visitTask.TaskAllocationState = TaskAllocationState.Allocated; + } + else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.CancelAssign) + { + visitTask.AllocateTime = null; + visitTask.DoctorUserId = null; + visitTask.TaskAllocationState = TaskAllocationState.NotAllocate; + + //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.TaskAllocate }); + + //await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.TaskAllocate }); + } + await _visitTaskRepository.SaveChangesAsync(); + return ResponseOutput.Ok(); + } + + + + + /// + /// 获取手动分配 未分配的Subject列表(IsHaveAssigned 传递false) + /// + /// + [HttpPost] + public async Task> GetSubjectAssignList(SubjectAssignQuery inQuery) + { + var subjectQuery = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId) + .WhereIf(inQuery.IsJudgeDoctor == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) + .WhereIf(inQuery.IsJudgeDoctor, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) + + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.Id == inQuery.SubjectId) + + .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == true && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) + .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == true && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) + .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == false && inQuery.IsJudgeDoctor == false, t => !t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) + .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == false && inQuery.IsJudgeDoctor, t => !t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) + + + .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == true && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).All(u => u.IsConfirmed)) + .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == true && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).All(u => u.IsConfirmed)) + + .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == false && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(u => u.IsConfirmed == false)) + .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == false && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(u => u.IsConfirmed == false)) + + .WhereIf(inQuery.DoctorUserId != null && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(t => t.DoctorUserId == inQuery.DoctorUserId)) + .WhereIf(inQuery.DoctorUserId != null && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(t => t.DoctorUserId == inQuery.DoctorUserId)) + .ProjectTo(_mapper.ConfigurationProvider, new { isJudgeDoctor = inQuery.IsJudgeDoctor }); + + var pageList = await subjectQuery.ToPagedListAsync(inQuery); + + return pageList; + } + + + /// + /// 批量为 多个Subject 分配医生 手动分配 IsReAssign 为true 批量删除 重新分配 + /// + /// + /// + [HttpPost] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task AssignSubjectDoctor(AssginSubjectDoctorCommand assginSubjectDoctorCommand) + { + var trialId = assginSubjectDoctorCommand.TrialId; + var doctorUserIdList = assginSubjectDoctorCommand.DoctorUserIdArmList.Select(t => t.DoctorUserId).ToList(); + + if (assginSubjectDoctorCommand.IsJudgeDoctor) + { + if (assginSubjectDoctorCommand.IsReAssign) + { + + //if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null && t.ArmEnum == Arm.JudgeArm)) + //{ + // throw new BusinessValidationFailedException("有Subject任务已应用,不允许重新分配"); + //} + + + await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.ArmEnum == Arm.JudgeArm); + } + + + } + else + { + if (assginSubjectDoctorCommand.IsReAssign) + { + + //if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm)) + //{ + // throw new BusinessValidationFailedException("有Subject任务已应用,不允许重新分配"); + //} + + + await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.ArmEnum != Arm.JudgeArm); + } + + + + } + foreach (var subjectId in assginSubjectDoctorCommand.SubjectIdList) + { + foreach (var doctorUserId in doctorUserIdList) + { + + var armEnum = assginSubjectDoctorCommand.DoctorUserIdArmList.Where(t => t.DoctorUserId == doctorUserId).First().ArmEnum; + + + if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum != armEnum && t.ReplacedSubjectUserId == null)) + { + //---有Subject 在其他Arm组已有该医生,不允许在新的组添加该医生 + throw new BusinessValidationFailedException(_localizer["VisitTask_InconsistentSubjectStatus"]); + } + + if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum == armEnum && t.ReplacedSubjectUserId == null)) + { + //---有Subject 已有该Arm组的医生,不允许继续分配,请刷新页面,确认页面数据是否过期 + throw new BusinessValidationFailedException(_localizer["VisitTask_DuplicateDoctorInArm"]); + } + else + { + await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subjectId, DoctorUserId = doctorUserId, ArmEnum = armEnum, AssignTime = DateTime.Now }); + + } + + } + + } + + + await _subjectUserRepository.SaveChangesAsync(); + + return ResponseOutput.Ok(); + } + + /// + /// 批量取消Subject 分配的医生 + /// + /// 数量 + [HttpPost] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task CancelSubjectAssignDoctor(CancelSubjectAssignCommand cancelSubjectAssignCommand) + { + if (cancelSubjectAssignCommand.IsJudgeDoctor) + { + foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList) + { + if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null && t.ArmEnum == Arm.JudgeArm)) + { + //---有Subject任务已应用,不允许取消分配 + throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorAlreadyInArm"]); + } + + await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId && t.ArmEnum == Arm.JudgeArm); + } + } + else + { + foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList) + { + if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm)) + { + //---有Subject任务已应用,不允许取消分配 + throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorAlreadyInArm"]); + } + + await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId && t.ArmEnum != Arm.JudgeArm); + } + } + + await _subjectUserRepository.SaveChangesAsync(); + + return ResponseOutput.Ok(); + } + + + /// + /// 手动分配确认 绑定该Subject的已存在的任务给医生 + /// + /// + /// + [HttpPost] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task ManualAssignDoctorApplyTask(AssignConfirmCommand assignConfirmCommand) + { + var trialId = assignConfirmCommand.TrialId; + + //获取项目配置 判断应该分配几个医生 + //var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.ReadingType, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync()).IfNullThrowException(); + + //需要确认的Subject + var subjectIdList = assignConfirmCommand.SubjectDoctorUserList.Select(t => t.SubjectId).ToList(); + + //将关系确认 + if (assignConfirmCommand.SubjectDoctorUserList.Count == 0) + { + await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.ReplacedSubjectUserId == null, u => new SubjectUser() { IsConfirmed = true }); + } + else + { + await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.ReplacedSubjectUserId == null + && subjectIdList.Contains(t.SubjectId), u => new SubjectUser() { IsConfirmed = true }); + } + + + var taskList = _visitTaskRepository.Where(t => t.TrialId == assignConfirmCommand.TrialId && t.DoctorUserId == null, true) + .WhereIf(subjectIdList.Count > 0 && assignConfirmCommand.IsJudgeDoctor == false, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) + .WhereIf(subjectIdList.Count > 0 && assignConfirmCommand.IsJudgeDoctor, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) + //过滤掉 那些回退的subject + .Where(t => !t.Subject.SubjectVisitList.Any(t => t.IsPMBackOrReReading)) + + .ToList(); + + + foreach (var subjectTaskGroup in taskList.GroupBy(t => t.SubjectId)) + { + var subjectId = subjectTaskGroup.Key; + + + + //如果数据为空 那么就是确认所有已分配的 + List subjectDoctorIdArmList = new List(); + + if (assignConfirmCommand.SubjectDoctorUserList.Count == 0) + { + subjectDoctorIdArmList = _subjectUserRepository.Where(t => t.SubjectId == subjectId && t.ReplacedSubjectUserId == null).Select(t => new DoctorArm() { DoctorUserId = t.DoctorUserId, ArmEnum = t.ArmEnum }).ToList(); + } + else + { + subjectDoctorIdArmList = assignConfirmCommand.SubjectDoctorUserList.Where(t => t.SubjectId == subjectId).First().DoctorUserIdArmList; + } + + + foreach (var task in subjectTaskGroup.OrderBy(t => t.ArmEnum).ToList()) + { + + var subjectDoctorArm = subjectDoctorIdArmList.Where(t => t.ArmEnum == task.ArmEnum).FirstOrDefault(); + + if (subjectDoctorArm != null) + { + task.DoctorUserId = subjectDoctorArm.DoctorUserId; + task.AllocateTime = DateTime.Now; + task.TaskAllocationState = TaskAllocationState.Allocated; + + task.SuggesteFinishedTime = /*task.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7)*/ GetSuggessFinishTime(true, UrgentType.NotUrget); + + await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading }); + + await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading }); + + + } + else + { + //---在配置表中未找到配置的医生,无法应用绑定,请核对数据 + throw new BusinessValidationFailedException(_localizer["VisitTask_TaskAlreadyApplied"]); + } + + } + } + + + + await _visitTaskRepository.SaveChangesAsync(); + + return ResponseOutput.Ok(); + } + + + + /// + /// 访视任务 + /// + /// + /// + /// + [HttpPost] + public async Task> GetVisitTaskList(VisitTaskQuery inQuery, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) + { + //以前访视未产生任务的,在查询这里要产生 + var svIdList = await _subjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId && t.CheckState == CheckStateEnum.CVPassed && t.IsVisitTaskGenerated == false).Select(t => t.Id).ToListAsync(); + + //之前没有生成任务的逻辑 但是现在加了,任务要自动生成 + await _visitTaskCommonService.GenerateVisitTaskAsync(inQuery.TrialId, svIdList); + + + var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) + .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) + .WhereIf(inQuery.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge) + + .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) + .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) + .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) + + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + .ProjectTo(_mapper.ConfigurationProvider); + + var defalutSortArray = new string[] { nameof(VisitTaskView.IsUrgent) + " desc", nameof(VisitTaskView.SubjectCode), nameof(VisitTaskView.VisitTaskNum) }; + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); + return pageList; + } + + + + /// + /// 裁判任务 + /// + /// + /// + [HttpPost] + public async Task/*, object)*/> GetJudgeVisitTaskList(VisitTaskQuery inQuery) + { + + var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) + .Where(t => t.ReadingCategory == ReadingCategory.Judge) + + .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) + .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) + .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + .ProjectTo(_mapper.ConfigurationProvider); + + var defalutSortArray = new string[] { nameof(JudgeVisitTaskView.IsUrgent) + " desc", nameof(JudgeVisitTaskView.SubjectCode), nameof(JudgeVisitTaskView.VisitTaskNum) }; + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + return pageList; + //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); + + //return (pageList, trialTaskConfig); + } + + + /// + /// PM阅片跟踪 + /// + /// + /// + [HttpPost] + public async Task>> GetReadingTaskList(VisitTaskQuery inQuery) + { + var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) + //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null) + + .WhereIf(inQuery.IsEffect == true, t => t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) + .WhereIf(inQuery.IsEffect == false, t => t.TaskState == TaskState.Adbandon || t.TaskState == TaskState.HaveReturned) + + .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) + .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) + .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + .WhereIf(inQuery.ReReadingApplyState != null, t => t.ReReadingApplyState == inQuery.ReReadingApplyState) + + .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.Complete, t => t.IsClinicalDataSign && t.IsNeedClinicalDataSign == true) + .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NotComplete, t => t.IsClinicalDataSign == false && t.IsNeedClinicalDataSign == true) + .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NA, t => t.IsNeedClinicalDataSign == false) + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate) + .WhereIf(inQuery.BeginSignTime != null, t => t.SignTime > inQuery.BeginSignTime) + .WhereIf(inQuery.EndSignTime != null, t => t.SignTime < inQuery.EndSignTime) + .ProjectTo(_mapper.ConfigurationProvider); + + var defalutSortArray = new string[] { nameof(ReadingTaskView.IsUrgent) + " desc", nameof(ReadingTaskView.SubjectCode), nameof(ReadingTaskView.VisitTaskNum) }; + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + var trialTaskConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); + + return ResponseOutput.Ok(pageList, trialTaskConfig); + } + + + /// + /// PM 重阅追踪 + /// + /// + /// + [HttpPost] + public async Task> GetReReadingTaskList(VisitTaskQuery inQuery) { + var visitTaskQueryable = _visitTaskReReadingRepository + .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/) + .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) + .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) + .WhereIf(inQuery.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == inQuery.ReReadingApplyState) + .WhereIf(inQuery.RequestReReadingType != null, t => t.RequestReReadingType == inQuery.RequestReReadingType) + .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.ArmEnum != null, t => t.OriginalReReadingTask.ArmEnum == inQuery.ArmEnum) + .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + .WhereIf(inQuery.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == inQuery.ReadingCategory) - /// - /// 设置任务加急 - /// - /// - /// - [HttpPost] - public async Task SetTaskUrgent(SetTaskUrgentInDto inDto) + .WhereIf(!string.IsNullOrEmpty(inQuery.RequestReReadingReason), t => t.RequestReReadingReason.Contains(inQuery.RequestReReadingReason)) + + .WhereIf(inQuery.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == inQuery.RequestReReadingResultEnum) + + + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => ((t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) || t.OriginalReReadingTask.Subject.MedicalNo.Contains(inQuery.SubjectCode)) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + + .WhereIf(inQuery.BeginRequestReReadingTime != null, t => t.RequestReReadingTime >= inQuery.BeginRequestReReadingTime) + .WhereIf(inQuery.EndRequestReReadingTime != null, t => t.RequestReReadingTime <= inQuery.EndRequestReReadingTime!.Value.AddDays(1)) + + .ProjectTo(_mapper.ConfigurationProvider); + + //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; + + var defalutSortArray = new string[] { + nameof(ReReadingTaskView.RequestReReadingResultEnum) , + nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", + nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.TaskState), + nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectCode),nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; + + + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + return pageList; + } + + + /// + /// 获取IR 重阅影像阅片列表 + /// + /// + /// + [HttpPost] + public async Task> GetIRReReadingTaskList(VisitTaskQuery inQuery) + { + + var visitTaskQueryable = _visitTaskReReadingRepository + .Where(t => t.RequestReReadingType == RequestReReadingType.DocotorApply) + .Where(t => t.OriginalReReadingTask.DoctorUserId == _userInfo.Id) + .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId) + .WhereIf(inQuery.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == inQuery.RequestReReadingResultEnum) + .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) + .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) + .WhereIf(inQuery.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == inQuery.ReadingCategory) + .WhereIf(inQuery.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == inQuery.ReReadingApplyState) + .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + + + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + .ProjectTo(_mapper.ConfigurationProvider); + + + + var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectCode), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + return pageList; + } + + + //SPM 能看到项目组申请记录 + [HttpPost] + public async Task> GetSPMReReadingTaskList(VisitTaskQuery inQuery) + { + var visitTaskQueryable = _visitTaskReReadingRepository.Where(t => t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.OriginalReReadingTask.IsAnalysisCreate == false) + .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId) + .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) + .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) + .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) + + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + .ProjectTo(_mapper.ConfigurationProvider); + + var defalutSortArray = new string[] { nameof(ReReadingTaskView.RequestReReadingTime) }; + + //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + return pageList; + } + + + + /// + /// IR 待阅片任务列表 + /// + /// + [HttpPost] + public async Task>> GetIRUnReadSubjectTaskList(IRUnReadSubjectQuery inQuery) + { + + var trialId = inQuery.TrialId; + var subjectCode = inQuery.SubjectCode; + + var trialReadingCriterionId = inQuery.TrialReadingCriterionId; + + var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).FirstNotNullAsync(); + + var readingTool = criterionConfig.ReadingTool; + var isReadingTaskViewInOrder = criterionConfig.IsReadingTaskViewInOrder; + + + var result = new PageOutput() { - await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask() - { - IsUrgent = inDto.IsUrgent, - TaskUrgentType = inDto.TaskUrgentType, - TaskUrgentRemake = inDto.TaskUrgentRemake, + PageSize = inQuery.PageSize, + PageIndex = inQuery.PageIndex, + TotalCount = 0, + CurrentPageData = null, + }; + IRUnReadOutDto iRUnReadOut = new IRUnReadOutDto(); + + //subject 级别 有序 无序查询 + if (isReadingTaskViewInOrder == ReadingOrder.InOrder || isReadingTaskViewInOrder == ReadingOrder.SubjectRandom) + { + result = await GetSubjectReadingIQueryable(new GetReadingIQueryableInDto() + { + TrialId = trialId, + TrialReadingCriterionId = trialReadingCriterionId, + SubjectCode = inQuery.SubjectCode, + + PageIndex = inQuery.PageIndex, + PageSize = inQuery.PageSize, + Asc = inQuery.Asc, + SortField = inQuery.SortField, }); - - return await _visitTaskRepository.SaveChangesAsync(); + + } + //随机阅片 + else + { + var taskQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == trialReadingCriterionId) + .Where(x => !x.Subject.IsDeleted).Where(x => (x.IsNeedClinicalDataSign && x.IsClinicalDataSign) || !x.IsNeedClinicalDataSign); + + iRUnReadOut = new IRUnReadOutDto() + { + FinishJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(), + FinishTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(), + SuggesteFinishedTime = await taskQuery.Where(x => x.ReadingTaskState != ReadingTaskState.HaveSigned).MaxAsync(x => x.SuggesteFinishedTime), + UnReadJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(), + UnReadTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(), + }; } - public async Task> GetTrialCriterionList(Guid trialId, bool isHaveSigned = true, bool? isAutoCreate = null) + return ResponseOutput.Ok(result, new { - var list = await _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsConfirm) + IsReadingTaskViewInOrder = isReadingTaskViewInOrder, + RandomReadInfo = iRUnReadOut, + ReadingTool = readingTool, + IseCRFShowInDicomReading = criterionConfig.IseCRFShowInDicomReading, + IsReadingShowSubjectInfo = criterionConfig.IsReadingShowSubjectInfo, + IsReadingShowPreviousResults = criterionConfig.IsReadingShowPreviousResults, + DigitPlaces = criterionConfig.DigitPlaces, + CriterionType = criterionConfig.CriterionType, + }); - .OrderBy(t => t.ShowOrder) - .Select(t => new TrialReadingCriterionDto() + + } + + /// + /// 获取subject有序 或者无序阅片IQuery对象 + /// + /// + /// + public async Task> GetSubjectReadingIQueryable(GetReadingIQueryableInDto inQuery) + { + var trialReadingCriterionId = inQuery.TrialReadingCriterionId; + var subjectCode = inQuery.SubjectCode; + var trialId = inQuery.TrialId; + var subjectId = inQuery.SubjectId; + + var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId); + + if (critrion.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect) + + .WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId) + //前序 不存在 未生成任务的访视 + .WhereIf(critrion.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum)) + + // 前序 不存在 未一致性核查未通过的 + .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum >= sv.VisitNum)) + //.WhereIf(critrion.IsAutoCreate == false, t => t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(t => t.IsGeneratedTask == false) ? + //t.VisitTaskNum <= t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsGeneratedTask == false).Min(t => t.SubjectVisit.VisitNum) : true) + //.Where(t => t.Subject.SubjectVisitList.Any(t => t.CheckState != CheckStateEnum.CVPassed) ? t.VisitTaskNum <= t.Subject.SubjectVisitList.Where(t => t.CheckState != CheckStateEnum.CVPassed).Min(t => t.VisitNum) : true) + //满足前序访视不存在 需要签署但是未签署 sql 相当复杂 同时想查询所有未读的统计数字 就无法统计 byzhouhang + //但是加字段 IsFrontTaskNeedSignButNotSign 那么签名临床数据的时候,要对该subject 该标准的有效的任务 这个字段需要在签名的时候维护 采取这种方式 统计数字灵活 + //.Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate)); + + + var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }); + + var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView() + { + SubjectId = x.Key.SubjectId, + SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode, + + SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime), + + //未读任务量 + UnReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(), + + //未读 里可读任务量 + UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true) + //不能对包含聚合或子查询的表达式执行聚合函数 + //&& !x.Any(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.IsNeedClinicalDataSign == true && t.IsClinicalDataSign == false && t.VisitTaskNum y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned) + .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) + .OrderBy(x => x.VisitTaskNum) + .Select(u => new IRUnreadTaskView() { - TrialReadingCriterionId = t.Id, - IsAutoCreate = t.IsAutoCreate, - IsAdditionalAssessment = t.IsAdditionalAssessment, - TrialReadingCriterionName = t.CriterionName, - CriterionType = t.CriterionType, - ReadingType = t.ReadingType, - ReadingInfoSignTime = t.ReadingInfoSignTime, - IsReadingPeriod = t.IsReadingPeriod, - IsArbitrationReading = t.IsArbitrationReading, - IsGlobalReading = t.IsGlobalReading, - IsOncologyReading = t.IsOncologyReading, - ImageDownloadEnum = t.ImageDownloadEnum, - ImageUploadEnum = t.ImageUploadEnum, - IsReadingTaskViewInOrder = t.IsReadingTaskViewInOrder + Id = u.Id, + IsUrgent = u.IsUrgent, + VisitNum = u.VisitTaskNum, + TaskBlindName = u.TaskBlindName, + VisistId = u.SourceSubjectVisitId, + SuggesteFinishedTime = u.SuggesteFinishedTime, + ReadingCategory = u.ReadingCategory, + IsAnalysisCreate = u.IsAnalysisCreate, + ArmEnum = u.ArmEnum, + TrialReadingCriterionId = u.TrialReadingCriterionId, + IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, + IsClinicalDataSign = u.IsClinicalDataSign, + IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign }) - .ToListAsync(); - - //if (list.Count == 0) - //{ - // //---该项目还未确认任何一个阅片标准 - // throw new BusinessValidationFailedException(_localizer["VisitTask_VisitTask_TaskAlreadyApplied"]); - - //} + .ToList(), - return list.AsQueryable().WhereIf(isHaveSigned == true, t => t.ReadingInfoSignTime != null) - .WhereIf(isAutoCreate == false, t => t.IsAutoCreate == isAutoCreate).ToList(); - } + UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned) + .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) + .Where(x => x.IsUrgent).Count(), + //已读任务量 + HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(), + ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed), - - /// - /// Subject 任务类型 统计 +分配情况 - /// - /// - [HttpPost] - public async Task>> GetSubjectAssignAndTaskStatList(SubjectAssignStatQuery inQuery) - { - - var isAddtinoarlCriterion = await _trialReadingCriterionRepository.AnyAsync(t => t.Id == inQuery.TrialReadingCriterionId && t.IsAutoCreate == false); - - var subjectQuery = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId && t.SubjectVisitTaskList.Any()) - .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.Id == inQuery.SubjectId) - .WhereIf(inQuery.DoctorUserId != null, t => t.SubjectDoctorList.Any(t => t.DoctorUserId == inQuery.DoctorUserId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.Code.Contains(inQuery.SubjectCode)) - //未分配 - .WhereIf(inQuery.SubjectAllocateState == 0, t => !t.SubjectDoctorList.Any(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) - //已分配 - .WhereIf(inQuery.SubjectAllocateState == 1, t => t.SubjectDoctorList.Any(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) - - .WhereIf(inQuery.ArmList.Count > 0, t => !inQuery.ArmList.Except(t.SubjectDoctorList.Where(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).Select(c => c.ArmEnum)).Any()) - - - .WhereIf(isAddtinoarlCriterion, t => t.SubjectCriteriaEvaluationList.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).Any(t => t.IsJoinEvaluation)) - - - .ProjectTo(_mapper.ConfigurationProvider, new { trialReadingCriterionId = inQuery.TrialReadingCriterionId }); - - - var pageList = await subjectQuery.ToPagedListAsync(inQuery,nameof(SubjectAssignStat.SubjectId)); - - - - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading, x.IsGlobalReading }).FirstOrDefaultAsync()).IfNullThrowException(); - - return ResponseOutput.Ok(pageList, criterionConfig); - } - - /// - /// 一次性分配所有医生 批量分配(添加),后端现在没限制 - /// - /// - /// - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task BatchAssignDoctorToSubject(BatchAssignDoctorToSubjectCommand command) - { - //var inOrder = _trialRepository.Where(t => t.Id == command.TrialId).Select(t => t.IsReadingTaskViewInOrder).FirstOrDefault(); - - //var inOrder = _trialReadingCriterionRepository.Where(t => t.Id == command.TrialReadingCriterionId).Select(t => t.IsReadingTaskViewInOrder).FirstOrDefault(); - - - foreach (var subjectId in command.SubjectIdList) - { - foreach (var doctorArm in command.DoctorArmList) + //查出所有未读的 未读的可读的 在这个列表基础上 过滤下 y.IsFrontTaskNeedSignButNotSign==false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true) 这样容易排错 确认这三个字段是否维护有误 + UnReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).OrderBy(x => x.VisitTaskNum) + .Select(u => new IRUnreadTaskView() { - if (!await _subjectUserRepository.Where(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId).AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId == doctorArm.DoctorUserId && t.ArmEnum == doctorArm.ArmEnum && t.IsConfirmed && t.ReplacedSubjectUserId == null)) - { - await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = command.TrialId, TrialReadingCriterionId = command.TrialReadingCriterionId, ArmEnum = doctorArm.ArmEnum, DoctorUserId = doctorArm.DoctorUserId, SubjectId = subjectId, AssignTime = DateTime.Now }); + Id = u.Id, + IsUrgent = u.IsUrgent, + VisitNum = u.VisitTaskNum, + TaskBlindName = u.TaskBlindName, + VisistId = u.SourceSubjectVisitId, + SuggesteFinishedTime = u.SuggesteFinishedTime, + ReadingCategory = u.ReadingCategory, + IsAnalysisCreate = u.IsAnalysisCreate, + ArmEnum = u.ArmEnum, + TrialReadingCriterionId = u.TrialReadingCriterionId, + IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, + IsClinicalDataSign = u.IsClinicalDataSign, + IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign + }) + .ToList(), + }).Where(x => x.UnReadCanReadTaskCount > 0)/*.OrderBy(x => x.UnReadCanReadTaskCount)*/; + // 有序阅片需要找到最小需要 - //task.SuggesteFinishedTime = task.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7); - } + // 不这样写会有问题 + var count = visitQuery.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) + .GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }).Count(); + var result = new List(); - Expression> updateWhere = t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectId == subjectId && t.ArmEnum == doctorArm.ArmEnum && t.TrialId == command.TrialId && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false; + var propName = string.IsNullOrWhiteSpace(inQuery!.SortField) ? nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) : inQuery.SortField; - //if (inOrder) - //{ - // //针对有序阅片 只分配< 最小的 不是一致性核查通过状态 和不是失访 的访视 的任务 - // if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == subjectId && t.CheckState != CheckStateEnum.CVPassed && t.IsLostVisit == false)) - // { - // var notCheckPassedMinVisitNum = await _subjectVisitRepository.Where(t => t.SubjectId == subjectId && t.CheckState != CheckStateEnum.CVPassed).OrderBy(t => t.VisitNum).Select(t => t.VisitNum).FirstOrDefaultAsync(); + var visitTaskOrderQuery = inQuery.Asc ? visitTaskQuery.OrderBy(propName) : visitTaskQuery.OrderBy(propName + " desc"); - // updateWhere = updateWhere.And(t => t.VisitTaskNum < notCheckPassedMinVisitNum); - // } - //} + result = await visitTaskOrderQuery + .Skip((inQuery.PageIndex - 1) * inQuery.PageSize) + .Take(inQuery.PageSize).ToListAsync(); - await _visitTaskRepository - .UpdatePartialFromQueryAsync(updateWhere, - u => new VisitTask() - { - AllocateTime = DateTime.Now, - DoctorUserId = doctorArm.DoctorUserId, - TaskAllocationState = TaskAllocationState.Allocated, - - SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget), - }); - } - } - - await _subjectUserRepository.SaveChangesAsync(); - - - - - - return ResponseOutput.Ok(); - } - - - - /// - /// 阅片人维度 Subject统计表 - /// - /// - /// - /// - public async Task<(List, object)> GetDoctorSubjectStat(Guid trialId, Guid trialReadingCriterionId) - { - var list = await _taskAllocationRuleRepository.Where(t => t.TrialId == trialId) - .Where(t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == trialReadingCriterionId)) - .ProjectTo(_mapper.ConfigurationProvider, new { trialReadingCriterionId = trialReadingCriterionId }).ToListAsync(); - - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading }).FirstOrDefaultAsync()).IfNullThrowException(); - - return (list, criterionConfig); - } - - - /// - /// 获取Subject 分配医生情况 - /// - /// - /// - /// - public async Task<(List, object)> GetSubjectAssignedDoctorList(Guid subjectId, Guid trialReadingCriterionId) - { - var list = await _subjectUserRepository.Where(t => t.SubjectId == subjectId && t.ReplacedSubjectUserId == null && t.IsConfirmed && t.TrialReadingCriterionId == trialReadingCriterionId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsGlobalReading, x.IsOncologyReading, x.IsArbitrationReading }).FirstOrDefaultAsync()).IfNullThrowException(); - - return (list, criterionConfig); - } - - - /// - /// 取消Subject 分配的医生 - /// - /// - /// - /// - [HttpPost] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task CancelSubjectAssignedDoctor(CancelSubjectDoctorCommand cancelCommand) - { - foreach (var command in cancelCommand.CancelList.Where(t => t.IsCancelAssign)) - { - if (await _visitTaskRepository.AnyAsync(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState != ReadingTaskState.WaitReading)) - { - //---当前医生已开始做该Subject 该标准的任务,不允许取消分配 - throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorConfigNotFound"]); - } - - await _subjectUserRepository.DeleteFromQueryAsync(t => t.Id == command.Id); - - await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState == ReadingTaskState.WaitReading && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false, u => new VisitTask() - { - AllocateTime = null, - DoctorUserId = null, - TaskAllocationState = TaskAllocationState.NotAllocate, - SuggesteFinishedTime = null - }); - } - - var subjectId = cancelCommand.CancelList.First().SubjectId; - - await _subjectCanceDoctorRepository.AddAsync(new SubjectCanceDoctor() { SubjectId = subjectId, Note = cancelCommand.Note, TrialReadingCriterionId = cancelCommand.TrialReadingCriterionId }); - - await _visitTaskRepository.SaveChangesAsync(); - - return ResponseOutput.Ok(); - } - - - - - /// - /// 任务 手动分配 重新分配 确认 取消分配 - /// 分配 - /// - /// - [HttpPost] - [UnitOfWork] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task AssignSubjectTaskToDoctor(AssignSubjectTaskToDoctorCommand assignSubjectTaskToDoctorCommand) - { - var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(t => t.Id == assignSubjectTaskToDoctorCommand.Id); - - if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Assign || assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign) - { - //手动分配验证规则 - - if (visitTask.SourceSubjectVisitId != null) - { - - if (await _visitTaskRepository.AnyAsync(t => t.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && t.TaskAllocationState == TaskAllocationState.Allocated && t.DoctorUserId == assignSubjectTaskToDoctorCommand.DoctorUserId && t.Id != visitTask.Id)) - { - //---其中一个任务已分配给该医生,不允许分配 - return ResponseOutput.NotOk(_localizer["VisitTask_BackendDataError"]); - } - } - else if (visitTask.SouceReadModuleId != null) - { - if (await _visitTaskRepository.AnyAsync(t => t.SouceReadModuleId == visitTask.SouceReadModuleId && t.TaskAllocationState == TaskAllocationState.Allocated && t.DoctorUserId == assignSubjectTaskToDoctorCommand.DoctorUserId && t.Id != visitTask.Id)) - { - //---其中一个任务已分配给该医生,不允许分配 - return ResponseOutput.NotOk(_localizer["VisitTask_BackendDataError"]); - } - } - else - { - //---出现脏数据 任务来源字段没有值 - throw new BusinessValidationFailedException(_localizer["VisitTask_DirtyData"]); - } - - //PM 回退了 但是还没生成任务 当前任务编号前有访视进行了回退就不允许分配 - if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == visitTask.SubjectId && t.IsPMBackOrReReading && t.VisitNum <= visitTask.VisitTaskNum)) - { - //---该受试者有访视进入了退回流程,还未经过一致性核查通过,不允许分配 - return ResponseOutput.NotOk(_localizer["VisitTask_MissingTaskSource"]); - } - - - visitTask.AllocateTime = DateTime.Now; - visitTask.DoctorUserId = assignSubjectTaskToDoctorCommand.DoctorUserId; - visitTask.TaskAllocationState = TaskAllocationState.Allocated; - - visitTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); - - - - //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading }); - - //await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading }); - } - - else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign) - { - //验证 是不是两个任务都给了同一个医生 - - - - //是否删除配置规则表里的 Subject 医生绑定关系 重新添加绑定关系 - - //是否其该Subject 其他访视 绑定的医生 也同时变更? - - - } - - else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Confirm) - { - visitTask.TaskAllocationState = TaskAllocationState.Allocated; - } - else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.CancelAssign) - { - visitTask.AllocateTime = null; - visitTask.DoctorUserId = null; - visitTask.TaskAllocationState = TaskAllocationState.NotAllocate; - - //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.TaskAllocate }); - - //await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.TaskAllocate }); - } - await _visitTaskRepository.SaveChangesAsync(); - return ResponseOutput.Ok(); - } - - - - - /// - /// 获取手动分配 未分配的Subject列表(IsHaveAssigned 传递false) - /// - /// - [HttpPost] - public async Task> GetSubjectAssignList(SubjectAssignQuery inQuery) - { - var subjectQuery = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId) - .WhereIf(inQuery.IsJudgeDoctor == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) - .WhereIf(inQuery.IsJudgeDoctor, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) - - .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.Id == inQuery.SubjectId) - - .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == true && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) - .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == true && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) - .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == false && inQuery.IsJudgeDoctor == false, t => !t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) - .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == false && inQuery.IsJudgeDoctor, t => !t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) - - - .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == true && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).All(u => u.IsConfirmed)) - .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == true && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).All(u => u.IsConfirmed)) - - .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == false && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(u => u.IsConfirmed == false)) - .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == false && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(u => u.IsConfirmed == false)) - - .WhereIf(inQuery.DoctorUserId != null && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(t => t.DoctorUserId == inQuery.DoctorUserId)) - .WhereIf(inQuery.DoctorUserId != null && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(t => t.DoctorUserId == inQuery.DoctorUserId)) - .ProjectTo(_mapper.ConfigurationProvider, new { isJudgeDoctor = inQuery.IsJudgeDoctor }); - - var pageList = await subjectQuery.ToPagedListAsync(inQuery); - - return pageList; - } - - - /// - /// 批量为 多个Subject 分配医生 手动分配 IsReAssign 为true 批量删除 重新分配 - /// - /// - /// - [HttpPost] - [UnitOfWork] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task AssignSubjectDoctor(AssginSubjectDoctorCommand assginSubjectDoctorCommand) - { - var trialId = assginSubjectDoctorCommand.TrialId; - var doctorUserIdList = assginSubjectDoctorCommand.DoctorUserIdArmList.Select(t => t.DoctorUserId).ToList(); - - if (assginSubjectDoctorCommand.IsJudgeDoctor) - { - if (assginSubjectDoctorCommand.IsReAssign) - { - - //if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null && t.ArmEnum == Arm.JudgeArm)) - //{ - // throw new BusinessValidationFailedException("有Subject任务已应用,不允许重新分配"); - //} - - - await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.ArmEnum == Arm.JudgeArm); - } - - - } - else - { - if (assginSubjectDoctorCommand.IsReAssign) - { - - //if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm)) - //{ - // throw new BusinessValidationFailedException("有Subject任务已应用,不允许重新分配"); - //} - - - await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.ArmEnum != Arm.JudgeArm); - } - - - - } - foreach (var subjectId in assginSubjectDoctorCommand.SubjectIdList) - { - foreach (var doctorUserId in doctorUserIdList) - { - - var armEnum = assginSubjectDoctorCommand.DoctorUserIdArmList.Where(t => t.DoctorUserId == doctorUserId).First().ArmEnum; - - - if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum != armEnum && t.ReplacedSubjectUserId == null)) - { - //---有Subject 在其他Arm组已有该医生,不允许在新的组添加该医生 - throw new BusinessValidationFailedException(_localizer["VisitTask_InconsistentSubjectStatus"]); - } - - if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum == armEnum && t.ReplacedSubjectUserId == null)) - { - //---有Subject 已有该Arm组的医生,不允许继续分配,请刷新页面,确认页面数据是否过期 - throw new BusinessValidationFailedException(_localizer["VisitTask_DuplicateDoctorInArm"]); - } - else - { - await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subjectId, DoctorUserId = doctorUserId, ArmEnum = armEnum, AssignTime = DateTime.Now }); - - } - - } - - } - - - await _subjectUserRepository.SaveChangesAsync(); - - return ResponseOutput.Ok(); - } - - /// - /// 批量取消Subject 分配的医生 - /// - /// 数量 - [HttpPost] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task CancelSubjectAssignDoctor(CancelSubjectAssignCommand cancelSubjectAssignCommand) - { - if (cancelSubjectAssignCommand.IsJudgeDoctor) - { - foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList) - { - if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null && t.ArmEnum == Arm.JudgeArm)) - { - //---有Subject任务已应用,不允许取消分配 - throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorAlreadyInArm"]); - } - - await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId && t.ArmEnum == Arm.JudgeArm); - } - } - else - { - foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList) - { - if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm)) - { - //---有Subject任务已应用,不允许取消分配 - throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorAlreadyInArm"]); - } - - await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId && t.ArmEnum != Arm.JudgeArm); - } - } - - await _subjectUserRepository.SaveChangesAsync(); - - return ResponseOutput.Ok(); - } - - - /// - /// 手动分配确认 绑定该Subject的已存在的任务给医生 - /// - /// - /// - [HttpPost] - [UnitOfWork] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task ManualAssignDoctorApplyTask(AssignConfirmCommand assignConfirmCommand) - { - var trialId = assignConfirmCommand.TrialId; - - //获取项目配置 判断应该分配几个医生 - //var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.ReadingType, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync()).IfNullThrowException(); - - //需要确认的Subject - var subjectIdList = assignConfirmCommand.SubjectDoctorUserList.Select(t => t.SubjectId).ToList(); - - //将关系确认 - if (assignConfirmCommand.SubjectDoctorUserList.Count == 0) - { - await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.ReplacedSubjectUserId == null, u => new SubjectUser() { IsConfirmed = true }); - } - else - { - await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.ReplacedSubjectUserId == null - && subjectIdList.Contains(t.SubjectId), u => new SubjectUser() { IsConfirmed = true }); - } - - - var taskList = _visitTaskRepository.Where(t => t.TrialId == assignConfirmCommand.TrialId && t.DoctorUserId == null, true) - .WhereIf(subjectIdList.Count > 0 && assignConfirmCommand.IsJudgeDoctor == false, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) - .WhereIf(subjectIdList.Count > 0 && assignConfirmCommand.IsJudgeDoctor, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) - //过滤掉 那些回退的subject - .Where(t => !t.Subject.SubjectVisitList.Any(t => t.IsPMBackOrReReading)) - - .ToList(); - - - foreach (var subjectTaskGroup in taskList.GroupBy(t => t.SubjectId)) - { - var subjectId = subjectTaskGroup.Key; - - - - //如果数据为空 那么就是确认所有已分配的 - List subjectDoctorIdArmList = new List(); - - if (assignConfirmCommand.SubjectDoctorUserList.Count == 0) - { - subjectDoctorIdArmList = _subjectUserRepository.Where(t => t.SubjectId == subjectId && t.ReplacedSubjectUserId == null).Select(t => new DoctorArm() { DoctorUserId = t.DoctorUserId, ArmEnum = t.ArmEnum }).ToList(); - } - else - { - subjectDoctorIdArmList = assignConfirmCommand.SubjectDoctorUserList.Where(t => t.SubjectId == subjectId).First().DoctorUserIdArmList; - } - - - foreach (var task in subjectTaskGroup.OrderBy(t => t.ArmEnum).ToList()) - { - - var subjectDoctorArm = subjectDoctorIdArmList.Where(t => t.ArmEnum == task.ArmEnum).FirstOrDefault(); - - if (subjectDoctorArm != null) - { - task.DoctorUserId = subjectDoctorArm.DoctorUserId; - task.AllocateTime = DateTime.Now; - task.TaskAllocationState = TaskAllocationState.Allocated; - - task.SuggesteFinishedTime = /*task.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7)*/ GetSuggessFinishTime(true, UrgentType.NotUrget); - - await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading }); - - await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading }); - - - } - else - { - //---在配置表中未找到配置的医生,无法应用绑定,请核对数据 - throw new BusinessValidationFailedException(_localizer["VisitTask_TaskAlreadyApplied"]); - } - - } - } - - - - await _visitTaskRepository.SaveChangesAsync(); - - return ResponseOutput.Ok(); - } - - - - /// - /// 访视任务 - /// - /// - /// - /// - [HttpPost] - public async Task> GetVisitTaskList(VisitTaskQuery inQuery, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) - { - //以前访视未产生任务的,在查询这里要产生 - var svIdList = await _subjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId && t.CheckState == CheckStateEnum.CVPassed && t.IsVisitTaskGenerated == false).Select(t => t.Id).ToListAsync(); - - //之前没有生成任务的逻辑 但是现在加了,任务要自动生成 - await _visitTaskCommonService.GenerateVisitTaskAsync(inQuery.TrialId, svIdList); - - - var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) - .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge) - - .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) - .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) - .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) - - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - .ProjectTo(_mapper.ConfigurationProvider); - - var defalutSortArray = new string[] { nameof(VisitTaskView.IsUrgent) + " desc", nameof(VisitTaskView.SubjectCode), nameof(VisitTaskView.VisitTaskNum) }; - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); - - //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); - return pageList; - } - - - - /// - /// 裁判任务 - /// - /// - /// - [HttpPost] - public async Task/*, object)*/> GetJudgeVisitTaskList(VisitTaskQuery inQuery) - { - - var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) - .Where(t => t.ReadingCategory == ReadingCategory.Judge) - - .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) - .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) - .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - .ProjectTo(_mapper.ConfigurationProvider); - - var defalutSortArray = new string[] { nameof(JudgeVisitTaskView.IsUrgent) + " desc", nameof(JudgeVisitTaskView.SubjectCode), nameof(JudgeVisitTaskView.VisitTaskNum) }; - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); - - return pageList; - //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); - - //return (pageList, trialTaskConfig); - } - - - /// - /// PM阅片跟踪 - /// - /// - /// - [HttpPost] - public async Task>> GetReadingTaskList(VisitTaskQuery inQuery) - { - var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) - //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null) - - .WhereIf(inQuery.IsEffect == true, t => t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) - .WhereIf(inQuery.IsEffect == false, t => t.TaskState == TaskState.Adbandon || t.TaskState == TaskState.HaveReturned) - - .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) - .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) - .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState) - .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - .WhereIf(inQuery.ReReadingApplyState != null, t => t.ReReadingApplyState == inQuery.ReReadingApplyState) - - .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.Complete, t => t.IsClinicalDataSign && t.IsNeedClinicalDataSign == true) - .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NotComplete, t => t.IsClinicalDataSign == false && t.IsNeedClinicalDataSign == true) - .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NA, t => t.IsNeedClinicalDataSign == false) - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate) - .WhereIf(inQuery.BeginSignTime != null, t => t.SignTime > inQuery.BeginSignTime) - .WhereIf(inQuery.EndSignTime != null, t => t.SignTime < inQuery.EndSignTime) - .ProjectTo(_mapper.ConfigurationProvider); - - var defalutSortArray = new string[] { nameof(ReadingTaskView.IsUrgent) + " desc", nameof(ReadingTaskView.SubjectCode), nameof(ReadingTaskView.VisitTaskNum) }; - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); - - var trialTaskConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); - - return ResponseOutput.Ok(pageList, trialTaskConfig); - } - - - /// - /// PM 重阅追踪 - /// - /// - /// - [HttpPost] - public async Task> GetReReadingTaskList(VisitTaskQuery inQuery) - { - - - var visitTaskQueryable = _visitTaskReReadingRepository - .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/) - .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) - .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) - .WhereIf(inQuery.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == inQuery.ReReadingApplyState) - .WhereIf(inQuery.RequestReReadingType != null, t => t.RequestReReadingType == inQuery.RequestReReadingType) - .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) - .WhereIf(inQuery.ArmEnum != null, t => t.OriginalReReadingTask.ArmEnum == inQuery.ArmEnum) - .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) - .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - .WhereIf(inQuery.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == inQuery.ReadingCategory) - - .WhereIf(!string.IsNullOrEmpty(inQuery.RequestReReadingReason), t => t.RequestReReadingReason.Contains(inQuery.RequestReReadingReason)) - - .WhereIf(inQuery.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == inQuery.RequestReReadingResultEnum) - - - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => ((t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) || t.OriginalReReadingTask.Subject.MedicalNo.Contains(inQuery.SubjectCode)) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - - .WhereIf(inQuery.BeginRequestReReadingTime != null, t => t.RequestReReadingTime >= inQuery.BeginRequestReReadingTime) - .WhereIf(inQuery.EndRequestReReadingTime != null, t => t.RequestReReadingTime <= inQuery.EndRequestReReadingTime!.Value.AddDays(1)) - - .ProjectTo(_mapper.ConfigurationProvider); - - //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; - - var defalutSortArray = new string[] { - nameof(ReReadingTaskView.RequestReReadingResultEnum) , - nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", - nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.TaskState), - nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectCode),nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; - - - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); - - return pageList; - } - - - /// - /// 获取IR 重阅影像阅片列表 - /// - /// - /// - [HttpPost] - public async Task> GetIRReReadingTaskList(VisitTaskQuery inQuery) - { - - var visitTaskQueryable = _visitTaskReReadingRepository - .Where(t => t.RequestReReadingType == RequestReReadingType.DocotorApply) - .Where(t => t.OriginalReReadingTask.DoctorUserId == _userInfo.Id) - .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId) - .WhereIf(inQuery.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == inQuery.RequestReReadingResultEnum) - .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) - .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) - .WhereIf(inQuery.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == inQuery.ReReadingApplyState) - .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) - .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) - .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - - - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - .ProjectTo(_mapper.ConfigurationProvider); - - - - var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectCode), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); - - return pageList; - } - - - //SPM 能看到项目组申请记录 - [HttpPost] - public async Task> GetSPMReReadingTaskList(VisitTaskQuery inQuery) - { - var visitTaskQueryable = _visitTaskReReadingRepository.Where(t => t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.OriginalReReadingTask.IsAnalysisCreate == false) - .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId) - .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) - .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) - .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) - .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) - .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) - - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - .ProjectTo(_mapper.ConfigurationProvider); - - var defalutSortArray = new string[] { nameof(ReReadingTaskView.RequestReReadingTime) }; - - //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); - - return pageList; - } - - - - /// - /// IR 待阅片任务列表 - /// - /// - [HttpPost] - public async Task>> GetIRUnReadSubjectTaskList(IRUnReadSubjectQuery inQuery) - { - - var trialId = inQuery.TrialId; - var subjectCode = inQuery.SubjectCode; - - var trialReadingCriterionId = inQuery.TrialReadingCriterionId; - - var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).FirstNotNullAsync(); - - var readingTool = criterionConfig.ReadingTool; - var isReadingTaskViewInOrder = criterionConfig.IsReadingTaskViewInOrder; - - - var result = new PageOutput() + return new PageOutput() { PageSize = inQuery.PageSize, PageIndex = inQuery.PageIndex, - TotalCount = 0, - CurrentPageData = null, + TotalCount = count, + CurrentPageData = result, }; - - IRUnReadOutDto iRUnReadOut = new IRUnReadOutDto(); - - //subject 级别 有序 无序查询 - if (isReadingTaskViewInOrder == ReadingOrder.InOrder || isReadingTaskViewInOrder == ReadingOrder.SubjectRandom) - { - result = await GetSubjectReadingIQueryable(new GetReadingIQueryableInDto() - { - TrialId = trialId, - TrialReadingCriterionId = trialReadingCriterionId, - SubjectCode = inQuery.SubjectCode, - - PageIndex = inQuery.PageIndex, - PageSize = inQuery.PageSize, - Asc = inQuery.Asc, - SortField = inQuery.SortField, - }); - - } - //随机阅片 - else - { - var taskQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == trialReadingCriterionId) - .Where(x => !x.Subject.IsDeleted).Where(x => (x.IsNeedClinicalDataSign && x.IsClinicalDataSign) || !x.IsNeedClinicalDataSign); - - iRUnReadOut = new IRUnReadOutDto() - { - FinishJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(), - FinishTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(), - SuggesteFinishedTime = await taskQuery.Where(x => x.ReadingTaskState != ReadingTaskState.HaveSigned).MaxAsync(x => x.SuggesteFinishedTime), - UnReadJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(), - UnReadTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(), - }; - } - - return ResponseOutput.Ok(result, new - { - IsReadingTaskViewInOrder = isReadingTaskViewInOrder, - RandomReadInfo = iRUnReadOut, - ReadingTool = readingTool, - IseCRFShowInDicomReading = criterionConfig.IseCRFShowInDicomReading, - IsReadingShowSubjectInfo = criterionConfig.IsReadingShowSubjectInfo, - IsReadingShowPreviousResults = criterionConfig.IsReadingShowPreviousResults, - DigitPlaces = criterionConfig.DigitPlaces, - CriterionType = criterionConfig.CriterionType, - }); - - } - - /// - /// 获取subject有序 或者无序阅片IQuery对象 - /// - /// - /// - public async Task> GetSubjectReadingIQueryable(GetReadingIQueryableInDto inQuery) + else { - var trialReadingCriterionId = inQuery.TrialReadingCriterionId; - var subjectCode = inQuery.SubjectCode; - var trialId = inQuery.TrialId; - var subjectId = inQuery.SubjectId; - var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId); - - if (critrion.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + if (subjectId != null) { - var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect) + //找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务 + var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id + && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskBlindName == "Timepoint" && t.ReadingCategory == ReadingCategory.Visit + && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze), true).ToListAsync(); - .WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId) - //前序 不存在 未生成任务的访视 - .WhereIf(critrion.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum)) - - // 前序 不存在 未一致性核查未通过的 - .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum >= sv.VisitNum)) - //.WhereIf(critrion.IsAutoCreate == false, t => t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(t => t.IsGeneratedTask == false) ? - //t.VisitTaskNum <= t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsGeneratedTask == false).Min(t => t.SubjectVisit.VisitNum) : true) - //.Where(t => t.Subject.SubjectVisitList.Any(t => t.CheckState != CheckStateEnum.CVPassed) ? t.VisitTaskNum <= t.Subject.SubjectVisitList.Where(t => t.CheckState != CheckStateEnum.CVPassed).Min(t => t.VisitNum) : true) - //满足前序访视不存在 需要签署但是未签署 sql 相当复杂 同时想查询所有未读的统计数字 就无法统计 byzhouhang - //但是加字段 IsFrontTaskNeedSignButNotSign 那么签名临床数据的时候,要对该subject 该标准的有效的任务 这个字段需要在签名的时候维护 采取这种方式 统计数字灵活 - //.Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate)); - - - var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }); - - var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView() + if (needDealTaskList.Count > 0) { - SubjectId = x.Key.SubjectId, - SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode, + //已完成的访视任务数量(包含重阅的) + var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id + && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit); - SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime), + //已经处理过的任务名称的数量 - //未读任务量 - UnReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(), - - //未读 里可读任务量 - UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true) - //不能对包含聚合或子查询的表达式执行聚合函数 - //&& !x.Any(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.IsNeedClinicalDataSign == true && t.IsClinicalDataSign == false && t.VisitTaskNum t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id + && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint"); - UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned) - .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) - .OrderBy(x => x.VisitTaskNum) - .Select(u => new IRUnreadTaskView() + + //随机赋值编号 比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个 + List availableNumbers = Enumerable.Range(haveDealedTaskCount + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList(); + Random rng = new Random(); + foreach (var visitTask in needDealTaskList) { - Id = u.Id, - IsUrgent = u.IsUrgent, - VisitNum = u.VisitTaskNum, - TaskBlindName = u.TaskBlindName, - VisistId = u.SourceSubjectVisitId, - SuggesteFinishedTime = u.SuggesteFinishedTime, - ReadingCategory = u.ReadingCategory, - IsAnalysisCreate = u.IsAnalysisCreate, - ArmEnum = u.ArmEnum, - TrialReadingCriterionId = u.TrialReadingCriterionId, - IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, - IsClinicalDataSign = u.IsClinicalDataSign, - IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign - }) - .ToList(), + int randomIndex = rng.Next(availableNumbers.Count); + visitTask.TaskBlindName = $"Timepoint Ran {availableNumbers[randomIndex]}"; - UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned) - .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) - .Where(x => x.IsUrgent).Count(), - - //已读任务量 - HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(), - - ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed), - - //查出所有未读的 未读的可读的 在这个列表基础上 过滤下 y.IsFrontTaskNeedSignButNotSign==false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true) 这样容易排错 确认这三个字段是否维护有误 - UnReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).OrderBy(x => x.VisitTaskNum) - .Select(u => new IRUnreadTaskView() - { - Id = u.Id, - IsUrgent = u.IsUrgent, - VisitNum = u.VisitTaskNum, - TaskBlindName = u.TaskBlindName, - VisistId = u.SourceSubjectVisitId, - SuggesteFinishedTime = u.SuggesteFinishedTime, - ReadingCategory = u.ReadingCategory, - IsAnalysisCreate = u.IsAnalysisCreate, - ArmEnum = u.ArmEnum, - TrialReadingCriterionId = u.TrialReadingCriterionId, - IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, - IsClinicalDataSign = u.IsClinicalDataSign, - IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign - }) - .ToList(), - }).Where(x => x.UnReadCanReadTaskCount > 0)/*.OrderBy(x => x.UnReadCanReadTaskCount)*/; - // 有序阅片需要找到最小需要 - - - // 不这样写会有问题 - var count = visitQuery.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) - .GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }).Count(); - - var result = new List(); - - var propName = string.IsNullOrWhiteSpace(inQuery!.SortField) ? nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) : inQuery.SortField; - - var visitTaskOrderQuery = inQuery.Asc ? visitTaskQuery.OrderBy(propName) : visitTaskQuery.OrderBy(propName + " desc"); - - - - result = await visitTaskOrderQuery - .Skip((inQuery.PageIndex - 1) * inQuery.PageSize) - .Take(inQuery.PageSize).ToListAsync(); - - - return new PageOutput() - { - PageSize = inQuery.PageSize, - PageIndex = inQuery.PageIndex, - TotalCount = count, - CurrentPageData = result, - }; - } - else - { - - if (subjectId != null) - { - //找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务 - var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id - && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskBlindName == "Timepoint" && t.ReadingCategory == ReadingCategory.Visit - && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze), true).ToListAsync(); - - if (needDealTaskList.Count > 0) - { - //已完成的访视任务数量(包含重阅的) - var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id - && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit); - - //已经处理过的任务名称的数量 - - var haveDealedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id - && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint"); - - - - //随机赋值编号 比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个 - List availableNumbers = Enumerable.Range(haveDealedTaskCount + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList(); - Random rng = new Random(); - foreach (var visitTask in needDealTaskList) - { - int randomIndex = rng.Next(availableNumbers.Count); - - visitTask.TaskBlindName = $"Timepoint Ran {availableNumbers[randomIndex]}"; - - availableNumbers.RemoveAt(randomIndex); - } - await _visitTaskRepository.SaveChangesAsync(); + availableNumbers.RemoveAt(randomIndex); } + await _visitTaskRepository.SaveChangesAsync(); } - - var visitQuery = _visitTaskRepository.Where(x => x.TrialId == trialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect) - .WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId) - .WhereIf(!string.IsNullOrEmpty(subjectCode), t => (t.Subject.Code.Contains(subjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(subjectCode!) && t.IsAnalysisCreate)); - - var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }); - - var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView() - { - SubjectId = x.Key.SubjectId, - SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode, - - SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime), - - //未读任务量 - UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(), - - UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Where(x => x.IsUrgent).Count(), - - //已读任务量 - HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(), - - ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed), - - UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned) - .OrderBy(x => x.VisitTaskNum) - .Select(u => new IRUnreadTaskView() - { - Id = u.Id, - IsUrgent = u.IsUrgent, - VisitNum = u.VisitTaskNum, - TaskBlindName = u.TaskBlindName, - VisistId = u.SourceSubjectVisitId, - SuggesteFinishedTime = u.SuggesteFinishedTime, - ReadingCategory = u.ReadingCategory, - IsAnalysisCreate = u.IsAnalysisCreate, - ArmEnum = u.ArmEnum, - TrialReadingCriterionId = u.TrialReadingCriterionId, - IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, - IsClinicalDataSign = u.IsClinicalDataSign, - IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign - }) - .ToList() - }).Where(x => x.UnReadCanReadTaskCount > 0); - - var pageList = await visitTaskQuery.ToPagedListAsync(inQuery, nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) ); - - return pageList; } - } + var visitQuery = _visitTaskRepository.Where(x => x.TrialId == trialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect) + .WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId) + .WhereIf(!string.IsNullOrEmpty(subjectCode), t => (t.Subject.Code.Contains(subjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(subjectCode!) && t.IsAnalysisCreate)); + var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }); - /// - /// IR 已阅片任务 - /// - /// - /// - [HttpPost] - public async Task> GetIRHaveReadTaskList(VisitTaskQuery inQuery) - { + var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView() + { + SubjectId = x.Key.SubjectId, + SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode, + SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime), - var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId) - .Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState == ReadingTaskState.HaveSigned)//该医生 已经签名的数据 + //未读任务量 + UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(), + UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Where(x => x.IsUrgent).Count(), - .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + //已读任务量 + HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(), + ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed), - .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - .ProjectTo(_mapper.ConfigurationProvider); + UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned) + .OrderBy(x => x.VisitTaskNum) + .Select(u => new IRUnreadTaskView() + { + Id = u.Id, + IsUrgent = u.IsUrgent, + VisitNum = u.VisitTaskNum, + TaskBlindName = u.TaskBlindName, + VisistId = u.SourceSubjectVisitId, + SuggesteFinishedTime = u.SuggesteFinishedTime, + ReadingCategory = u.ReadingCategory, + IsAnalysisCreate = u.IsAnalysisCreate, + ArmEnum = u.ArmEnum, + TrialReadingCriterionId = u.TrialReadingCriterionId, + IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, + IsClinicalDataSign = u.IsClinicalDataSign, + IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign + }) + .ToList() + }).Where(x => x.UnReadCanReadTaskCount > 0); - var defalutSortArray = new string[] { nameof(IRHaveReadView.IsUrgent) + " desc", nameof(IRHaveReadView.SubjectCode), nameof(IRHaveReadView.VisitTaskNum) }; - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + var pageList = await visitTaskQuery.ToPagedListAsync(inQuery, nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) ); return pageList; } + } - [HttpPost] - [UnitOfWork] - public async Task AIRReReading(AIRReReadingCommand command, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) + /// + /// IR 已阅片任务 + /// + /// + /// + [HttpPost] + public async Task> GetIRHaveReadTaskList(VisitTaskQuery inQuery) + { + + + var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId) + .Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState == ReadingTaskState.HaveSigned)//该医生 已经签名的数据 + + + .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) + .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + + + .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + .ProjectTo(_mapper.ConfigurationProvider); + + var defalutSortArray = new string[] { nameof(IRHaveReadView.IsUrgent) + " desc", nameof(IRHaveReadView.SubjectCode), nameof(IRHaveReadView.VisitTaskNum) }; + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + return pageList; + } + + + + [HttpPost] + [UnitOfWork] + public async Task AIRReReading(AIRReReadingCommand command, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) + { + var baseLineTaskList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id + && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.SourceSubjectVisit.IsBaseLine == true).ToListAsync(); + + var judegeList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id + && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned).ToListAsync(); + + foreach (var item in judegeList) { - var baseLineTaskList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id - && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.SourceSubjectVisit.IsBaseLine == true).ToListAsync(); - - var judegeList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id - && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned).ToListAsync(); - - foreach (var item in judegeList) + if (!baseLineTaskList.Any(t => t.SubjectId == item.SubjectId)) { - if (!baseLineTaskList.Any(t => t.SubjectId == item.SubjectId)) - { - baseLineTaskList.Add(item); - } + baseLineTaskList.Add(item); } - - - var baseLineTaskIdList = baseLineTaskList.Select(t => t.Id).ToList(); - - if (baseLineTaskIdList.Count == 0) - { - return ResponseOutput.Ok(); - } - - //if (baseLineTaskList == null) - //{ - // return ResponseOutput.NotOk("基线任务未阅完,不允许重阅基线任务"); - //} - - await ApplyReReading(new ApplyReReadingCommand() { IsCopyFollowForms = false, IsCopyOrigenalForms = false, TaskIdList = baseLineTaskIdList, TrialId = command.TrialId, RequestReReadingReason = "AIR自动重阅基线", RequestReReadingType = RequestReReadingType.DocotorApply }); - - - - var requestRecordList = await _visitTaskReReadingRepository.Where(t => baseLineTaskIdList.Contains(t.OriginalReReadingTaskId) && t.RequestReReadingUserId == _userInfo.Id && t.RequestReReadingReason == "AIR自动重阅基线").ToListAsync(); - - if (requestRecordList.Count != baseLineTaskIdList.Count) - { - //---后台数据有错误 - return ResponseOutput.NotOk(_localizer["VisitTask_DoctorConfiguration"]); - } - - await ConfirmReReading(new ConfirmReReadingCommand() - { - TrialId = command.TrialId, - RequestReReadingResultEnum = RequestReReadingResult.Agree, - //ConfirmReReadingList = new List() { new ConfirmReReadingDTO() { Id = requestRecord.Id, OriginalReReadingTaskId = task.Id } } - ConfirmReReadingList = requestRecordList.Select(t => new ConfirmReReadingDTO() { Id = t.Id, OriginalReReadingTaskId = t.OriginalReReadingTaskId }).ToList() - }, _visitTaskCommonService); - - return ResponseOutput.Ok(); - } + var baseLineTaskIdList = baseLineTaskList.Select(t => t.Id).ToList(); - /// - /// 申请重阅 1:IR 2:PM - /// - /// - /// - [HttpPost] - [UnitOfWork] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - - public async Task ApplyReReading(ApplyReReadingCommand applyReReadingCommand) + if (baseLineTaskIdList.Count == 0) { - - - var taskList = await _visitTaskRepository.Where(t => applyReReadingCommand.TaskIdList.Contains(t.Id), true).ToListAsync(); - - var trialReadingCriterionId = taskList.First()!.TrialReadingCriterionId; - - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsAutoCreate, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); - - - foreach (var task in taskList) - { - - - if (task.ReadingTaskState != ReadingTaskState.HaveSigned || (task.TaskState != TaskState.Effect && task.TaskState != TaskState.Freeze)) - { - //---未阅片完成,或者未生效的任务不允许申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_BackendData"]); - } - - if (task.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.Agree) - { - //---重阅已申请,或者重阅已同意状态下不允许申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_UnreadTask"]); - } - - - - - if (IsPMOrAPm()) - { - if (criterionConfig.IsAutoCreate == false) - { - //---手动生成任务的不允许PM 申请影像重阅 - return ResponseOutput.NotOk(_localizer["VisitTask_NoPMRecheck"]); - } - - if (task.IsAnalysisCreate) - { - //---PM 不允许对一致性分析任务进行申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_Reapply"]); - } - - if (task.ReadingCategory != ReadingCategory.Visit) - { - //---PM 仅仅允许对访视类型的任务申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_ConsistencyAnalysis"]); - } - - - // 有序 一个受试者访视重阅未处理完,不能申请其他的 - if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) - { - if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect - && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId - && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default)) - { - //---当前为有序阅片,该受试者已有访视已申请重阅还未处理(项目组申请),暂不能继续申请重阅 - return ResponseOutput.NotOk(_localizer["VisitTask_VisitTypeRestriction"]); - } - } - - - task.ReReadingApplyState = ReReadingApplyState.TrialGroupHaveApplyed; - - - } - if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer) - { - task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; - - - //在PM 的申请重阅的影响列表里也不能申请重阅 - - var pmApply = await _visitTaskReReadingRepository.Where(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect && t.OriginalReReadingTask.ReadingCategory == ReadingCategory.Visit - && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default).Include(t => t.OriginalReReadingTask).FirstOrDefaultAsync(); - - - // 有序 - if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) - { - // 针对同一个subject 不同阅片人 针对同一个访视申请重阅,是允许的,所以同一阅片人,针对同一suject 有访视申请重阅还未处理,不允许申请重阅 - if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect - && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId && t.OriginalReReadingTask.DoctorUserId == task.DoctorUserId - && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default)) - { - //---当前为有序阅片,该受试者已有访视已申请重阅还未处理,暂不能继续申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_SequentialReading"]); - } - - - - if (pmApply != null) - { - var originalTask = pmApply.OriginalReReadingTask; - - //PM 有序影响列表 - if (await _visitTaskRepository.Where(t => t.TrialId == originalTask.TrialId && t.SubjectId == originalTask.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.TrialReadingCriterionId == originalTask.TrialReadingCriterionId && t.VisitTaskNum >= originalTask.VisitTaskNum) - .AnyAsync(t => t.VisitTaskNum == task.VisitTaskNum)) - { - //---当前为有序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_ImageProblem"]); - } - - } - - - - Expression> filterExpression = t => t.TrialId == task.TrialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == task.TrialReadingCriterionId - && t.DoctorUserId == task.DoctorUserId && t.IsAnalysisCreate == false && t.VisitTaskNum > task.VisitTaskNum; - - - - if (task.ReadingCategory == ReadingCategory.Global && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Global))) - { - //---有序阅片,只允许申请该受试者阅片人最后一次完成全局任务重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_LastReading"]); - } - - if (task.ReadingCategory == ReadingCategory.Oncology && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Oncology && t.ReadingTaskState == ReadingTaskState.HaveSigned))) - { - //---有序阅片,只允许申请该受试者阅片人最后一次完成肿瘤学任务重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_LastOncologistRecheck"]); - } - - if (task.ReadingCategory == ReadingCategory.Judge && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned))) - { - //---有序阅片,只允许申请该受试者阅片人最后一次完成裁判的任务重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_LastAdjudicatorRecheck"]); - } - - } - else - { - - if (pmApply != null) - { - var originalTask = pmApply.OriginalReReadingTask; - - //PM 无序影响列表 - if (await _visitTaskRepository.Where(t => t.TrialId == originalTask.TrialId && t.SubjectId == originalTask.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.TrialReadingCriterionId == originalTask.TrialReadingCriterionId) - .Where(t => t.Id == originalTask.Id || t.Id == originalTask.JudgeVisitTaskId) - .AnyAsync(t => t.VisitTaskNum == task.VisitTaskNum)) - { - //---当前为无序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_RandomInvalidRereading"]); - } - - } - - //也要支持裁判重阅240701 - - if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Judge) - { - //---无序阅片,仅仅允许IR 申请 访视、裁判类型类别的任务进行重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_IRGlobalRecheck"]); - } - } - - } - - //AIR 不加验证 - if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR) - { - task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; - } - - - - var rootReReadingTaskId = _visitTaskReReadingRepository.Where(t => t.NewReReadingTaskId == task.Id).Select(u => u.RootReReadingTaskId).FirstOrDefault(); - - //添加申请记录 - var visitTaskReReading = await _visitTaskReReadingRepository.AddAsync(new VisitTaskReReading() - { - TrialId = applyReReadingCommand.TrialId, - RootReReadingTaskId = rootReReadingTaskId == Guid.Empty ? task.Id : rootReReadingTaskId, - OriginalReReadingTaskId = task.Id, - RequestReReadingTime = DateTime.Now, - RequestReReadingUserId = _userInfo.Id, - IsCopyOrigenalForms = applyReReadingCommand.IsCopyOrigenalForms, - IsCopyFollowForms = applyReReadingCommand.IsCopyFollowForms, - RequestReReadingReason = applyReReadingCommand.RequestReReadingReason, - RequestReReadingType = applyReReadingCommand.RequestReReadingType, - - }); - } - - - await _visitTaskRepository.SaveChangesAsync(); - return ResponseOutput.Ok(); } + //if (baseLineTaskList == null) + //{ + // return ResponseOutput.NotOk("基线任务未阅完,不允许重阅基线任务"); + //} - /// - /// 重阅原任务跟踪处理 - /// - /// - /// - /// - private void ReReadingTaskTrackingDeal(VisitTask origenalTask, ConfirmReReadingCommand agreeReReadingCommand) + await ApplyReReading(new ApplyReReadingCommand() { IsCopyFollowForms = false, IsCopyOrigenalForms = false, TaskIdList = baseLineTaskIdList, TrialId = command.TrialId, RequestReReadingReason = "AIR自动重阅基线", RequestReReadingType = RequestReReadingType.DocotorApply }); + + + + var requestRecordList = await _visitTaskReReadingRepository.Where(t => baseLineTaskIdList.Contains(t.OriginalReReadingTaskId) && t.RequestReReadingUserId == _userInfo.Id && t.RequestReReadingReason == "AIR自动重阅基线").ToListAsync(); + + if (requestRecordList.Count != baseLineTaskIdList.Count) { - if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) - { - origenalTask.ReReadingApplyState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? ReReadingApplyState.Agree : ReReadingApplyState.Reject; - origenalTask.TaskState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? TaskState.HaveReturned : origenalTask.TaskState; - } - else - { - //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面 - throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]); - } - + //---后台数据有错误 + return ResponseOutput.NotOk(_localizer["VisitTask_DoctorConfiguration"]); } - private async Task SetMedicalReviewInvalidAsync(List influenceTaskList, bool isPMApply = true) + await ConfirmReReading(new ConfirmReReadingCommand() { - //将医学审核设置为失效 - var taskIdList = influenceTaskList.Select(t => t.Id).ToList(); + TrialId = command.TrialId, + RequestReReadingResultEnum = RequestReReadingResult.Agree, + //ConfirmReReadingList = new List() { new ConfirmReReadingDTO() { Id = requestRecord.Id, OriginalReReadingTaskId = task.Id } } + ConfirmReReadingList = requestRecordList.Select(t => new ConfirmReReadingDTO() { Id = t.Id, OriginalReReadingTaskId = t.OriginalReReadingTaskId }).ToList() + }, _visitTaskCommonService); - //PM 申请 医学审核任务状态为待审核、审核中的,设置为失效。 + return ResponseOutput.Ok(); - //IR 申请 当前任务进入医学审核,医学审核任务未签名且结论中是否有问题项,答案为否的,设置为失效 + } - if (isPMApply) - { - await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true }); - } - else - { - await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.IsHaveQuestion == false && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true }); - } - } + /// + /// 申请重阅 1:IR 2:PM + /// + /// + /// + [HttpPost] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - /// - /// PM 申请重阅 被同意 或者 PM 直接退回的时候影响 - /// - /// - /// - private async Task PMReReadingConfirmOrBackInfluenceAnalysisAsync(Guid subjectId) - { - if (await _visitTaskRepository.AnyAsync(t => t.IsAnalysisCreate && t.SubjectId == subjectId)) - { - await _subjectRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectId, u => new Subject() { IsReReadingOrBackInfluenceAnalysis = true }); + public async Task ApplyReReading(ApplyReReadingCommand applyReReadingCommand) + { - } - } + var taskList = await _visitTaskRepository.Where(t => applyReReadingCommand.TaskIdList.Contains(t.Id), true).ToListAsync(); - public DateTime GetSuggessFinishTime(bool isInOrder, UrgentType urgentType) + var trialReadingCriterionId = taskList.First()!.TrialReadingCriterionId; + + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsAutoCreate, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); + + + foreach (var task in taskList) { - var datetime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 22, 0, 0).AddDays(7); - return datetime; - } - - /// - /// 确认重阅与否 1同意 2 拒绝 - /// - /// - /// - /// - [HttpPost] - [UnitOfWork] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - - public async Task ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) - { - - var trialId = agreeReReadingCommand.TrialId; - - foreach (var item in agreeReReadingCommand.ConfirmReReadingList) + if (task.ReadingTaskState != ReadingTaskState.HaveSigned || (task.TaskState != TaskState.Effect && task.TaskState != TaskState.Freeze)) { - - var origenalTask = (await _visitTaskRepository.Where(t => item.OriginalReReadingTaskId == t.Id).FirstOrDefaultAsync()).IfNullThrowException(); - - - if ((origenalTask.TaskState != TaskState.Effect && origenalTask.TaskState != TaskState.Freeze)) - { - await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new VisitTaskReReading() { RequestReReadingConfirmUserId = _userInfo.Id, RequestReReadingResultEnum = RequestReReadingResult.Invalid }); - - //---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作 - return ResponseOutput.Ok(string.Empty, msg: _localizer["VisitTask_ReapplyStatusConflict"]); - } - - - var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == origenalTask.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync(); - - //更新申请信息 - var visitTaskReReadingAppply = await _visitTaskReReadingRepository.FirstOrDefaultAsync(t => t.Id == item.Id); - visitTaskReReadingAppply.RequestReReadingConfirmUserId = _userInfo.Id; - visitTaskReReadingAppply.RequestReReadingResultEnum = agreeReReadingCommand.RequestReReadingResultEnum; - visitTaskReReadingAppply.RequestReReadingRejectReason = agreeReReadingCommand.RequestReReadingRejectReason; - - - Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == origenalTask.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.TaskAllocationState == TaskAllocationState.Allocated; - - //是否是一致性分析任务 正常申请 会影响一致性分析任务 - filterExpression = filterExpression.And(t => t.IsAnalysisCreate == origenalTask.IsAnalysisCreate); - - //IR 申请1.1 基线重阅,影响附加评估两个IR所有的任务 - var isIR1Point1AdditionalAssessmentBaseline = false; - - //附加评估 IR 和PM 看到的影响列表不一样 - - //1.1 有附加评估,会影响其他标准的任务 - if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) - { - // PM申请 SPM / CPM审批 - if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (IsSpmOrCPM())) - { - filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); - } - //IR 申请 PM审批 - else - { - - // 1.1 基线任务影响BM任务 - if ((IsPMOrAPm()) && _subjectVisitRepository.Any(t => t.Id == origenalTask.SourceSubjectVisitId && t.IsBaseLine == true)) - { - - isIR1Point1AdditionalAssessmentBaseline = true; - - } - // 1.1 非基线任务不影响BM任务 - else - { - filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); - } - } - } - else - { - //默认影响的都是该标准的任务 - filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); - } - - - if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree) - { - //PM申请 SPM / CPM审批 回退访视,因此这里不生成访视任务 影响多个标准的任务 - if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (IsSpmOrCPM())) - { - - // 不管有序 无序 都会 回退访视 - if (origenalTask.ReadingCategory == ReadingCategory.Visit) - { - //执行类似一致性核查回退流程 - await VisitBackAsync(origenalTask.SourceSubjectVisitId); - - } - else - { - //---仅允许同意访视类型的任务重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskNotApplied"]); - } - - //有序阅片 - if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) - { - - - //访视影响当前以及当前之后的 两个阅片人的 - filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum); - - - #region 影响的任务 - - - - var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); - - var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); - - foreach (var influenceTask in influenceTaskList) - { - //处理申请的任务 - if (influenceTask.Id == origenalTask.Id) - { - ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); - - await InfluenceAddtioncalEvaluationCritrionAsync(origenalTask, influenceTaskList.Where(t => t.Id != origenalTask.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList()); - - await PMReReadingConfirmOrBackInfluenceAnalysisAsync(origenalTask.SubjectId); - - await SetMedicalReviewInvalidAsync(influenceTaskList); - - } - - - if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - influenceTask.TaskState = TaskState.HaveReturned; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - influenceTask.TaskState = TaskState.Adbandon; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); - } - - - } - #endregion - } - //无序阅片 没有 全局 肿瘤学 - else - { - - // 1.当前任务及裁判任务 - // 2.影响所有阅片人的任务 - - var judegTaskNum = origenalTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]; - - filterExpression = filterExpression.And(t => t.VisitTaskNum == origenalTask.VisitTaskNum || t.VisitTaskNum == judegTaskNum); - - - var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); - - //影像列表为空就为null - var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); - - foreach (var influenceTask in influenceTaskList) - { - //处理申请的任务 - if (influenceTask.Id == origenalTask.Id) - { - ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); - - - await PMReReadingConfirmOrBackInfluenceAnalysisAsync(origenalTask.SubjectId); - - await SetMedicalReviewInvalidAsync(influenceTaskList); - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - influenceTask.TaskState = TaskState.HaveReturned; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - influenceTask.TaskState = TaskState.Adbandon; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); - } - } - } - - } - - - - } - //IR申请 PM 审批 注意这里有一致性分析的申请同意 不会回退访视,在此要生成影响的访视任务 - else if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.DocotorApply && (IsPMOrAPm() || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR)) - { - - - - //有序阅片 - if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) - { - #region 有序 IR 申请 重阅 影响的其他访视查询 - - - - switch (origenalTask.ReadingCategory) - { - case ReadingCategory.Visit: - //影响后续访视已经读完的,正在读的,未读的不做处理 以及其他类型任务 - - //申请的是转化的,那么影响列表要排除转化之前的 - if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && origenalTask.BeforeConvertedTaskId != null) - { - - - filterExpression = filterExpression.And(t => (t.VisitTaskNum > origenalTask.VisitTaskNum && - ( - ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) - // 裁判 肿瘤学是另外的医生做 - || t.ReadingCategory == ReadingCategory.Judge - || t.ReadingCategory == ReadingCategory.Oncology - )) || t.Id == origenalTask.Id) - ; - } - else if (isIR1Point1AdditionalAssessmentBaseline) - { - filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum && - ((( - ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) - // 裁判 肿瘤学是另外的医生做 - || t.ReadingCategory == ReadingCategory.Judge - || t.ReadingCategory == ReadingCategory.Oncology - ) && t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId) || (t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB)) - ); - } - else - { - filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum && - ( - ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) - // 裁判 肿瘤学是另外的医生做 - || t.ReadingCategory == ReadingCategory.Judge - || t.ReadingCategory == ReadingCategory.Oncology - ) - ); - } - - - - - - - break; - - - //不影响后续访视: (t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.WaitReading) || - case ReadingCategory.Global: - - filterExpression = filterExpression.And(t => t.VisitTaskNum > origenalTask.VisitTaskNum && - ((t.DoctorUserId == origenalTask.DoctorUserId && t.ReadingCategory == ReadingCategory.Global) - || (t.ReadingCategory == ReadingCategory.Oncology) || (t.ReadingCategory == ReadingCategory.Judge)) || t.Id == origenalTask.Id); - break; - - case ReadingCategory.Oncology: - - //仅仅影响自己 后续任务如果是访视任务、全局任务或裁判任务,均不处理 - filterExpression = filterExpression.And(t => t.Id == origenalTask.Id); - break; - - case ReadingCategory.Judge: - - //裁判的影响自己 和后续肿瘤学阅片(不是自己做的) - filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.VisitTaskNum > origenalTask.VisitTaskNum && t.ReadingCategory == ReadingCategory.Oncology); - - break; - - - default: - //---不支持重阅的任务类型 - throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]); - - } - - #endregion - - - - var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).OrderBy(t => t.VisitTaskNum).ToListAsync(); - - var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); - - - - foreach (var influenceTask in influenceTaskList) - { - var beforeTaskState = influenceTask.TaskState; - - //已签名的任务 设置转变后的标志 - if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - var isConvertedTask = _visitTaskRepository.Where(t => t.Id == influenceTask.Id).Select(t => t.IsConvertedTask).FirstOrDefault(); - - if (isConvertedTask) - { - influenceTask.IsHistoryConvertedTask = true; - } - } - - - //处理申请的任务 - if (influenceTask.Id == origenalTask.Id) - { - ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); - - - await SetMedicalReviewInvalidAsync(influenceTaskList, false); - - await InfluenceAddtioncalEvaluationCritrionAsync(origenalTask, influenceTaskList.Where(t => t.Id != origenalTask.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList(), false); - - } - - - - if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - influenceTask.TaskState = TaskState.HaveReturned; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - influenceTask.TaskState = TaskState.Adbandon; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); - } - - - #region 受影响的任务生成 - - // 影响的任务 仅仅访视类别的才生成 或者就是IR 申请的任务 - if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id) - { - - - // 影响的其他标准的附加评估的任务不立即生成 比如1.1基线 重阅 PM 同意仅仅生成1.1任务,不生成BM任务 - if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment && influenceTask.TrialReadingCriterionId != origenalTask.TrialReadingCriterionId) - { - //BM标准的不生成任务 - continue; - } - - - // i1.1标准 当前任务是转变任务,并且影响列表里有转变之前的任务 那么该访视任务就不生成 - if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1) - { - //申请的任务是冻结的任务(该任务发生转变) 影响自己 以及转变后的 以及后续任务 但是生成的时候,仅仅生成转变之前的 - //申请的是转变之后的任务 (转变生成的任务) 影响自己以及后续任务 生成转变后的任务 - if (influenceTask.BeforeConvertedTaskId != null && influenceTaskList.Any(t => t.Id == influenceTask.BeforeConvertedTaskId)) - { - //有转化的任务 和转化之前的任务时,转化后的任务时不生成的 - continue; - - } - - - } - - - await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand() - { - TrialId = trialId, - - ReadingCategory = GenerateTaskCategory.ReReading, - - ReReadingTask = influenceTask, - - //同步才可以 - Action = (newTask) => - { - //申请表 设置新任务Id - visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id; - - //生成的任务分配给原始医生 - newTask.DoctorUserId = origenalTask.DoctorUserId; - newTask.TaskAllocationState = TaskAllocationState.Allocated; - newTask.AllocateTime = DateTime.Now; - newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); - - //拷贝原始表单 - if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id) - { - if (origenalTask.ReadingCategory == ReadingCategory.Visit) - { - CopyForms(newTask, origenalTask); - - } - - } - - //拷贝后续表单 - if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum) - { - if (origenalTask.ReadingCategory == ReadingCategory.Visit) - { - CopyForms(newTask, origenalTask); - } - - - } - - } - }); - - - - #endregion - - - } - - } - - - - } - //无序阅片 IR只会申请访视类型和裁判类型的任务 注意这里有一致性分析的申请同意 - else - { - - - //1.当前任务及裁判任务 - //2.影响当前阅片人的任务 - filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.Id == origenalTask.JudgeVisitTaskId); - - - var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); - - var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); - - foreach (var influenceTask in influenceTaskList) - { - //申请原任务处理 - if (influenceTask.Id == origenalTask.Id) - { - ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); - - await SetMedicalReviewInvalidAsync(influenceTaskList, false); - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - influenceTask.TaskState = TaskState.HaveReturned; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - influenceTask.TaskState = TaskState.Adbandon; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); - } - } - - #region 受影响任务的生成 - - if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id) - { - await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand() - { - TrialId = trialId, - - ReadingCategory = GenerateTaskCategory.ReReading, - - ReReadingTask = origenalTask, - - //同步才可以 - Action = (newTask) => - { - //申请表 设置新任务Id - visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id; - - ////生成的任务分配给原始医生 - newTask.DoctorUserId = origenalTask.DoctorUserId; - newTask.TaskAllocationState = TaskAllocationState.Allocated; - newTask.AllocateTime = DateTime.Now; - newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); - - - //裁判任务 需要进行特殊处理 在重阅逻辑里面处理 - - - if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id) - { - if (origenalTask.ReadingCategory == ReadingCategory.Visit) - { - CopyForms(newTask, origenalTask); - - } - - } - - //拷贝后续表单 - if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum) - { - if (origenalTask.ReadingCategory == ReadingCategory.Visit) - { - CopyForms(newTask, origenalTask); - - } - } - - - } - }); - - } - #endregion - - } - - } - - } - else - { - //---不符合 PM申请 SPM / CPM审批 | IR申请 PM 审批 - throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskAlreadyAffected"]); - } - - } - else if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Reject) - { - - if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) - { - await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == origenalTask.Id, u => new VisitTask() - { - ReReadingApplyState = ReReadingApplyState.Reject - }); - } - else - { - //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面 - throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]); - } - - } - - - - + //---未阅片完成,或者未生效的任务不允许申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_BackendData"]); + } + + if (task.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.Agree) + { + //---重阅已申请,或者重阅已同意状态下不允许申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_UnreadTask"]); } - - await _visitTaskRepository.SaveChangesAsync(); - - return ResponseOutput.Ok(); - } - - private void CopyForms(VisitTask newTask, VisitTask origenalTask) - { - - //自定义 - var readingCustomTagList = _readingCustomTagRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); - - foreach (var item in readingCustomTagList) - { - item.Id = Guid.Empty; - item.VisitTaskId = newTask.Id; - } - - _ = _readingCustomTagRepository.AddRangeAsync(readingCustomTagList).Result; - - - var readingTaskQuestionMarkList = _readingTaskQuestionMarkRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); - - foreach (var item in readingTaskQuestionMarkList) - { - item.Id = Guid.Empty; - item.VisitTaskId = newTask.Id; - } - - _ = _readingTaskQuestionMarkRepository.AddRangeAsync(readingTaskQuestionMarkList).Result; - - var readingTaskQuestionAnswerList = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); - - foreach (var item in readingTaskQuestionAnswerList) - { - item.Id = Guid.Empty; - item.VisitTaskId = newTask.Id; - } - _ = _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskQuestionAnswerList).Result; - - - - //ReadingTableAnswerRowInfo ReadingTableQuestionAnswer 一起加 - var readingTableAnswerRowInfoList = _readingTableAnswerRowInfoRepository.Where(t => t.VisitTaskId == origenalTask.Id).Include(t => t.LesionAnswerList).ToList(); - - foreach (var item in readingTableAnswerRowInfoList) - { - - var originalVisitTaskId = item.VisitTaskId; - var originalFristAddTaskId = item.FristAddTaskId; - - item.Id = NewId.NextSequentialGuid(); - item.VisitTaskId = newTask.Id; - - //默认值是当前任务添加的 - item.FristAddTaskId = originalVisitTaskId == originalFristAddTaskId ? newTask.Id : item.FristAddTaskId; - - - foreach (var item2 in item.LesionAnswerList) - { - item2.Id = Guid.Empty; - item2.RowId = item.Id; - item2.VisitTaskId = newTask.Id; - } - } - - _ = _readingTableAnswerRowInfoRepository.AddRangeAsync(readingTableAnswerRowInfoList).Result; - - - - - - } - - - /// - /// PM 设置任务 退回 - /// - /// - [HttpPut("{trialId:guid}/{taskId:guid}")] - [UnitOfWork] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - - public async Task PMSetTaskBack(Guid trialId, Guid taskId) - { - - //var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.IsReadingTaskViewInOrder, t.ReadingType }).FirstOrDefaultAsync()).IfNullThrowException(); - - - var task = (await _visitTaskRepository.Where(t => t.Id == taskId).FirstOrDefaultAsync()).IfNullThrowException(); - - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == task.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAutoCreate, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); - - if (criterionConfig.IsAutoCreate == false) - { - //---手动生成任务的不允许在此入口影像退回 - return ResponseOutput.NotOk(_localizer["VisitTask_NoImageReturn"]); - } - - if (task.TaskState != TaskState.Effect || task.ReadingCategory != ReadingCategory.Visit || task.ReadingTaskState == ReadingTaskState.HaveSigned) - { - //---仅仅允许针对生效、未完成的访视任务进行退回操作,请刷新页面数据 - return ResponseOutput.NotOk(_localizer["VisitTask_NonEffectiveTaskCannotBeReturned"]); - } - - - if (await _subjectVisitRepository.AnyAsync(t => t.Id == task.SourceSubjectVisitId && t.CheckState != CheckStateEnum.CVPassed)) - { - //---当前访视已回退到影像上传,不允许继续回退! - return ResponseOutput.NotOk(_localizer["VisitTask_NoFurtherReturn"]); - } - - - if (task.IsAnalysisCreate) - { - //---一致性分析的任务,不允许设置退回 - return ResponseOutput.NotOk(_localizer["VisitTask_ConsistencyTaskCannotBeReturned"]); - } - - Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.TaskAllocationState == TaskAllocationState.Allocated; - - - #region 退回到访视 不区分标准 - //if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) - //{ - // //影像退回,必定影响两个标准的任务 - // filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == task.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); - - - //} - //else - //{ - // //默认影响的都是该标准的任务 - // filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == task.TrialReadingCriterionId); - //} - #endregion - - - //PM 才允许操作 if (IsPMOrAPm()) { + if (criterionConfig.IsAutoCreate == false) + { + //---手动生成任务的不允许PM 申请影像重阅 + return ResponseOutput.NotOk(_localizer["VisitTask_NoPMRecheck"]); + } - #region 有序 无序公用流程 + if (task.IsAnalysisCreate) + { + //---PM 不允许对一致性分析任务进行申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_Reapply"]); + } + + if (task.ReadingCategory != ReadingCategory.Visit) + { + //---PM 仅仅允许对访视类型的任务申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_ConsistencyAnalysis"]); + } - //执行类似一致性核查回退流程 回退访视到影像上传流程 - await VisitBackAsync(task.SourceSubjectVisitId); - - #endregion - - - - //有序 + // 有序 一个受试者访视重阅未处理完,不能申请其他的 if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) { - - //Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated; - - filterExpression = filterExpression.And(t => t.IsAnalysisCreate == false); - - - - //另一个阅片人的任务根据任务进度自动进入PM退回或PM申请重阅 - filterExpression = filterExpression.And(t => t.VisitTaskNum >= task.VisitTaskNum); - - - var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); - - - - #region 方式二 - - - //pm退回的时候,影响的任务里不一定有该任务id 双重 分配了一个人,退回的时候,选择的是未分配的 - - //var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault(); - - var origenalTask = await _visitTaskRepository.FindAsync(task.Id); - - - foreach (var influenceTask in influenceTaskList) + if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect + && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId + && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default)) { - - //已签名的任务 设置转变后的标志 - if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - var isConvertedTask = _visitTaskRepository.Where(t => t.Id == influenceTask.Id).Select(t => t.IsConvertedTask).FirstOrDefault(); - - if (isConvertedTask) - { - influenceTask.IsHistoryConvertedTask = true; - } - } - - //同意的访视 因为要记录具体的操作,所以废弃 - if (influenceTask.Id == task.Id) - { - - await InfluenceAddtioncalEvaluationCritrionAsync(task, influenceTaskList.Where(t => t.Id != task.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList()); - - await PMReReadingConfirmOrBackInfluenceAnalysisAsync(influenceTask.SubjectId); - - await SetMedicalReviewInvalidAsync(influenceTaskList); - - - influenceTask.IsPMSetBack = true; - } - - if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - influenceTask.TaskState = TaskState.HaveReturned; - origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - influenceTask.TaskState = TaskState.Adbandon; - origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); - } - + //---当前为有序阅片,该受试者已有访视已申请重阅还未处理(项目组申请),暂不能继续申请重阅 + return ResponseOutput.NotOk(_localizer["VisitTask_VisitTypeRestriction"]); } - - #endregion - - - } - else - { - //无序 无序阅片没有 全局 肿瘤学 - // 申请该访视的任务 申请人失效 另外一个人重阅重置或者失效 + task.ReReadingApplyState = ReReadingApplyState.TrialGroupHaveApplyed; - var currentVisitList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == task.SourceSubjectVisitId && t.ReadingCategory == ReadingCategory.Visit && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.VisitTaskNum == task.VisitTaskNum, true).ToListAsync(); - - await SetMedicalReviewInvalidAsync(currentVisitList); - - //var origenalTask = currentVisitList.Where(t => t.Id == task.Id).First(); - - var origenalTask = await _visitTaskRepository.FindAsync(task.Id); - - foreach (var influenceTask in currentVisitList) - { - if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - //另外阅片人完成阅片了 就设置为重阅重置 - influenceTask.TaskState = TaskState.HaveReturned; - - origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - influenceTask.TaskState = TaskState.Adbandon; - - origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); - } - - } - - } } - else + if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer) { - //---仅PM 可以进行回退操作 - return ResponseOutput.NotOk(_localizer["VisitTask_PMOnlyAllowedForReturn"]); - } + task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; + //在PM 的申请重阅的影响列表里也不能申请重阅 + + var pmApply = await _visitTaskReReadingRepository.Where(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect && t.OriginalReReadingTask.ReadingCategory == ReadingCategory.Visit + && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default).Include(t => t.OriginalReReadingTask).FirstOrDefaultAsync(); - - - await _visitTaskRepository.SaveChangesAsync(); - - return ResponseOutput.Ok(); - } - - - /// - /// 基线退回 影响附加评估标准 是否参与评估 - /// - /// - private async Task InfluenceAddtioncalEvaluationCritrionAsync(VisitTask task, List otherVisitIdList, bool isImageBack = true) - { - - var criterion = await _trialReadingCriterionRepository.FindAsync(task.TrialReadingCriterionId); - - if (criterion.CriterionType == CriterionType.RECIST1Point1) - { - //影像回退了|| IR 申请及基线重阅 - if (_subjectVisitRepository.Any(t => t.Id == task.SourceSubjectVisitId && t.IsBaseLine)) + // 有序 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) { - await _subjectCriteriaEvaluationRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.IsAutoCreate == false && t.SubjectId == task.SubjectId, u => new SubjectCriteriaEvaluation() + // 针对同一个subject 不同阅片人 针对同一个访视申请重阅,是允许的,所以同一阅片人,针对同一suject 有访视申请重阅还未处理,不允许申请重阅 + if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect + && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId && t.OriginalReReadingTask.DoctorUserId == task.DoctorUserId + && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default)) { - IsJoinEvaluation = false - }); - - //删除筛选的访视数据 - await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectId == task.SubjectId); - - //删除筛选的序列数据 - await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId); - } - else if (isImageBack) - { - //当前访视筛选状态重置,任务生成状态重置 - if (task.SourceSubjectVisitId != null) - { - await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && t.SubjectVisitId == task.SourceSubjectVisitId, - t => new SubjectCriteriaEvaluationVisitFilter() - { - ImageFilterState = ImageFilterState.None, - ImageDeterminationResultState = ImageDeterminationResultState.None, - IsGeneratedTask = false - }); - - //删除序列数据 - await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && t.SubjectVisitId == task.SourceSubjectVisitId); + //---当前为有序阅片,该受试者已有访视已申请重阅还未处理,暂不能继续申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_SequentialReading"]); } - //BM后续访视 ,筛选状态不变,任务生成状态重置(实际该访视任务状态 可能是重阅重置了或者失效了,需要后续生成,或者取消分配了,需要后续重新分配) - await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && otherVisitIdList.Contains(t.SubjectVisitId), - t => new SubjectCriteriaEvaluationVisitFilter() + + if (pmApply != null) + { + var originalTask = pmApply.OriginalReReadingTask; + + //PM 有序影响列表 + if (await _visitTaskRepository.Where(t => t.TrialId == originalTask.TrialId && t.SubjectId == originalTask.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.TrialReadingCriterionId == originalTask.TrialReadingCriterionId && t.VisitTaskNum >= originalTask.VisitTaskNum) + .AnyAsync(t => t.VisitTaskNum == task.VisitTaskNum)) { - IsGeneratedTask = false - }); + //---当前为有序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_ImageProblem"]); + } + + } + + + + Expression> filterExpression = t => t.TrialId == task.TrialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == task.TrialReadingCriterionId + && t.DoctorUserId == task.DoctorUserId && t.IsAnalysisCreate == false && t.VisitTaskNum > task.VisitTaskNum; + + + + if (task.ReadingCategory == ReadingCategory.Global && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Global))) + { + //---有序阅片,只允许申请该受试者阅片人最后一次完成全局任务重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_LastReading"]); + } + + if (task.ReadingCategory == ReadingCategory.Oncology && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Oncology && t.ReadingTaskState == ReadingTaskState.HaveSigned))) + { + //---有序阅片,只允许申请该受试者阅片人最后一次完成肿瘤学任务重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_LastOncologistRecheck"]); + } + + if (task.ReadingCategory == ReadingCategory.Judge && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned))) + { + //---有序阅片,只允许申请该受试者阅片人最后一次完成裁判的任务重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_LastAdjudicatorRecheck"]); + } + } else { - //IR 端 非基线申请重阅 不影响 + + if (pmApply != null) + { + var originalTask = pmApply.OriginalReReadingTask; + + //PM 无序影响列表 + if (await _visitTaskRepository.Where(t => t.TrialId == originalTask.TrialId && t.SubjectId == originalTask.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.TrialReadingCriterionId == originalTask.TrialReadingCriterionId) + .Where(t => t.Id == originalTask.Id || t.Id == originalTask.JudgeVisitTaskId) + .AnyAsync(t => t.VisitTaskNum == task.VisitTaskNum)) + { + //---当前为无序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_RandomInvalidRereading"]); + } + + } + + //也要支持裁判重阅240701 + + if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Judge) + { + //---无序阅片,仅仅允许IR 申请 访视、裁判类型类别的任务进行重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_IRGlobalRecheck"]); + } } + } - - - } - - //包括临床数据签名状态 - private async Task VisitBackAsync(Guid? subjectVisitId) - { - var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException(); - - - //需要重新产生任务 - sv.IsVisitTaskGenerated = false; - sv.IsPMBackOrReReading = true; - - sv.AuditState = AuditStateEnum.None; - sv.SubmitState = SubmitStateEnum.ToSubmit; - sv.ReadingStatus = ReadingStatusEnum.ImageNotSubmit; - - //回退后,回退状态恢复 - sv.RequestBackState = RequestBackStateEnum.NotRequest; - sv.IsCheckBack = false; - sv.CheckBackTime = null; - sv.CheckState = CheckStateEnum.None; - sv.CheckChallengeState = CheckChanllengeTypeEnum.None; - - sv.SVENDTC = null; - sv.SVSTDTC = null; - - sv.PreliminaryAuditTime = null; - sv.SubmitTime = null; - sv.ReviewAuditTime = null; - sv.CurrentActionUserExpireTime = null; - - - sv.IsTake = false; - sv.CurrentActionUserId = null; - sv.PreliminaryAuditUserId = null; - sv.ReviewAuditUserId = null; - - - if (sv.IsBaseLine) + //AIR 不加验证 + if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR) { - await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && (t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit), c => new ReadingClinicalData() { IsSign = false, ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded }); - + task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; } - else + + + + var rootReReadingTaskId = _visitTaskReReadingRepository.Where(t => t.NewReReadingTaskId == task.Id).Select(u => u.RootReReadingTaskId).FirstOrDefault(); + + //添加申请记录 + var visitTaskReReading = await _visitTaskReReadingRepository.AddAsync(new VisitTaskReReading() { - await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit, c => new ReadingClinicalData() - { - IsSign = false, - ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded, - IsBlind = null, - IsComplete = null - }); + TrialId = applyReReadingCommand.TrialId, + RootReReadingTaskId = rootReReadingTaskId == Guid.Empty ? task.Id : rootReReadingTaskId, + OriginalReReadingTaskId = task.Id, + RequestReReadingTime = DateTime.Now, + RequestReReadingUserId = _userInfo.Id, + IsCopyOrigenalForms = applyReReadingCommand.IsCopyOrigenalForms, + IsCopyFollowForms = applyReReadingCommand.IsCopyFollowForms, + RequestReReadingReason = applyReReadingCommand.RequestReReadingReason, + RequestReReadingType = applyReReadingCommand.RequestReReadingType, + + }); + } + + + await _visitTaskRepository.SaveChangesAsync(); + + return ResponseOutput.Ok(); + } + + + /// + /// 重阅原任务跟踪处理 + /// + /// + /// + /// + private void ReReadingTaskTrackingDeal(VisitTask origenalTask, ConfirmReReadingCommand agreeReReadingCommand) + { + if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) + { + origenalTask.ReReadingApplyState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? ReReadingApplyState.Agree : ReReadingApplyState.Reject; + origenalTask.TaskState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? TaskState.HaveReturned : origenalTask.TaskState; + } + else + { + //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面 + throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]); + } + + } + + private async Task SetMedicalReviewInvalidAsync(List influenceTaskList, bool isPMApply = true) + { + //将医学审核设置为失效 + var taskIdList = influenceTaskList.Select(t => t.Id).ToList(); + + //PM 申请 医学审核任务状态为待审核、审核中的,设置为失效。 + + //IR 申请 当前任务进入医学审核,医学审核任务未签名且结论中是否有问题项,答案为否的,设置为失效 + + if (isPMApply) + { + await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true }); + + } + else + { + + await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.IsHaveQuestion == false && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true }); + } + } + + /// + /// PM 申请重阅 被同意 或者 PM 直接退回的时候影响 + /// + /// + /// + private async Task PMReReadingConfirmOrBackInfluenceAnalysisAsync(Guid subjectId) + { + if (await _visitTaskRepository.AnyAsync(t => t.IsAnalysisCreate && t.SubjectId == subjectId)) + { + await _subjectRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectId, u => new Subject() { IsReReadingOrBackInfluenceAnalysis = true }); + + } + + } + + public DateTime GetSuggessFinishTime(bool isInOrder, UrgentType urgentType) + { + + var datetime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 22, 0, 0).AddDays(7); + + return datetime; + } + + /// + /// 确认重阅与否 1同意 2 拒绝 + /// + /// + /// + /// + [HttpPost] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + + public async Task ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) + { + + var trialId = agreeReReadingCommand.TrialId; + + foreach (var item in agreeReReadingCommand.ConfirmReReadingList) + { + + var origenalTask = (await _visitTaskRepository.Where(t => item.OriginalReReadingTaskId == t.Id).FirstOrDefaultAsync()).IfNullThrowException(); + + + if ((origenalTask.TaskState != TaskState.Effect && origenalTask.TaskState != TaskState.Freeze)) + { + await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new VisitTaskReReading() { RequestReReadingConfirmUserId = _userInfo.Id, RequestReReadingResultEnum = RequestReReadingResult.Invalid }); + + //---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作 + return ResponseOutput.Ok(string.Empty, msg: _localizer["VisitTask_ReapplyStatusConflict"]); } + var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == origenalTask.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync(); - //await _repository.AddAsync(new CheckChallengeDialog() { SubjectVisitId = subjectVisitId, TalkContent = "PM/APM同意一致性核查回退。", UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt }); - - await _trialQCQuestionAnswerRepository.BatchDeleteNoTrackingAsync(t => t.SubjectVisitId == subjectVisitId); - await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => t.DicomSerie.IsDeleted); - await _dicomSeriesRepository.BatchDeleteNoTrackingAsync(t => t.IsDeleted); - - var success = await _subjectVisitRepository.SaveChangesAsync(); - - } + //更新申请信息 + var visitTaskReReadingAppply = await _visitTaskReReadingRepository.FirstOrDefaultAsync(t => t.Id == item.Id); + visitTaskReReadingAppply.RequestReReadingConfirmUserId = _userInfo.Id; + visitTaskReReadingAppply.RequestReReadingResultEnum = agreeReReadingCommand.RequestReReadingResultEnum; + visitTaskReReadingAppply.RequestReReadingRejectReason = agreeReReadingCommand.RequestReReadingRejectReason; - private bool IsPMOrAPm() - { - return _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM; - } + Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == origenalTask.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.TaskAllocationState == TaskAllocationState.Allocated; - private bool IsSpmOrCPM() - { - return _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM; - } + //是否是一致性分析任务 正常申请 会影响一致性分析任务 + filterExpression = filterExpression.And(t => t.IsAnalysisCreate == origenalTask.IsAnalysisCreate); - /// - /// 影响提示列表 重阅仅仅针对已完成的任务申请 退回针对的是未完成的(退回仅仅针对是访视类型的) - /// - /// - /// 重阅还是直接回退 - /// 申请记录的Id - /// - [HttpGet("{taskId:guid}/{isReReading:bool}")] - public async Task<(List, object)> GetReReadingOrBackInfluenceTaskList(Guid taskId, bool isReReading, Guid? applyId) - { - var isIRAppyTaskInfluenced = false; - - var filterObj = (await _visitTaskRepository.FirstOrDefaultNoTrackingAsync(t => t.Id == taskId)).IfNullThrowException(); - var trialId = filterObj.TrialId; - - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == filterObj.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); - - Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == filterObj.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.TaskAllocationState == TaskAllocationState.Allocated; - - //是否是一致性分析任务 (一致性分析的任务 不会产生裁判 肿瘤学 仅仅有生成的访视和全局) - - filterExpression = filterExpression.And(t => t.IsAnalysisCreate == filterObj.IsAnalysisCreate); - - //IR 申请1.1 基线重阅,影响附加评估所有的任务 + //IR 申请1.1 基线重阅,影响附加评估两个IR所有的任务 var isIR1Point1AdditionalAssessmentBaseline = false; //附加评估 IR 和PM 看到的影响列表不一样 + + //1.1 有附加评估,会影响其他标准的任务 if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) { - - // IR 申请 PM 同意 - if (((IsPMOrAPm() && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) - || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null))) + // PM申请 SPM / CPM审批 + if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (IsSpmOrCPM())) + { + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); + } + //IR 申请 PM审批 + else { // 1.1 基线任务影响BM任务 - if (IsPMOrAPm() && _subjectVisitRepository.Any(t => t.Id == filterObj.SourceSubjectVisitId && t.IsBaseLine == true)) + if ((IsPMOrAPm()) && _subjectVisitRepository.Any(t => t.Id == origenalTask.SourceSubjectVisitId && t.IsBaseLine == true)) { isIR1Point1AdditionalAssessmentBaseline = true; - //filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); - } // 1.1 非基线任务不影响BM任务 else { - filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId); + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); } - - } - //(1、PM回退,PM申请重阅,SPM同意回退) - else - { - filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); - } } else { //默认影响的都是该标准的任务 - filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId); + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); } - - //重阅影响 - if (isReReading) + if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree) { - - - - //IR 申请 PM 同意 仅仅影响自己 - - if ((IsPMOrAPm() && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) - || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null)) + //PM申请 SPM / CPM审批 回退访视,因此这里不生成访视任务 影响多个标准的任务 + if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (IsSpmOrCPM())) { - //当前任务及其之后的所有访视任务、全局任务、裁判任务、肿瘤学阅片任务 + // 不管有序 无序 都会 回退访视 + if (origenalTask.ReadingCategory == ReadingCategory.Visit) + { + //执行类似一致性核查回退流程 + await VisitBackAsync(origenalTask.SourceSubjectVisitId); - //有序 + } + else + { + //---仅允许同意访视类型的任务重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskNotApplied"]); + } + + //有序阅片 if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) { - switch (filterObj.ReadingCategory) + + //访视影响当前以及当前之后的 两个阅片人的 + filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum); + + + #region 影响的任务 + + + + var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); + + var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); + + foreach (var influenceTask in influenceTaskList) { - case ReadingCategory.Visit: - //影响当前医生 以及当前医生之后的 1、访视任务 已经读完的 - //2、后续任务如果是全局、肿瘤学阅片任务,状态为阅片完成标记为重阅重置;若在阅片中,则标记为失效;若为待阅片,则标记为失效; - //3、当前任务、后续访视任务或者全局任务触发了裁判任务,若裁判任务状态为阅片完成,则标记为重阅重置;若在阅片中或待阅片,则标记为失效 + //处理申请的任务 + if (influenceTask.Id == origenalTask.Id) + { + ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); - //申请的是转化的,那么影响列表要排除转化之前的 - if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && filterObj.BeforeConvertedTaskId != null) + await InfluenceAddtioncalEvaluationCritrionAsync(origenalTask, influenceTaskList.Where(t => t.Id != origenalTask.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList()); + + await PMReReadingConfirmOrBackInfluenceAnalysisAsync(origenalTask.SubjectId); + + await SetMedicalReviewInvalidAsync(influenceTaskList); + + } + + + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + influenceTask.TaskState = TaskState.HaveReturned; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + influenceTask.TaskState = TaskState.Adbandon; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); + } + + + } + #endregion + } + //无序阅片 没有 全局 肿瘤学 + else + { + + // 1.当前任务及裁判任务 + // 2.影响所有阅片人的任务 + + var judegTaskNum = origenalTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]; + + filterExpression = filterExpression.And(t => t.VisitTaskNum == origenalTask.VisitTaskNum || t.VisitTaskNum == judegTaskNum); + + + var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); + + //影像列表为空就为null + var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); + + foreach (var influenceTask in influenceTaskList) + { + //处理申请的任务 + if (influenceTask.Id == origenalTask.Id) + { + ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); + + + await PMReReadingConfirmOrBackInfluenceAnalysisAsync(origenalTask.SubjectId); + + await SetMedicalReviewInvalidAsync(influenceTaskList); + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { + influenceTask.TaskState = TaskState.HaveReturned; - - filterExpression = filterExpression.And(t => (t.VisitTaskNum > filterObj.VisitTaskNum && - ( - ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId) - // 裁判 肿瘤学是另外的医生做 - || t.ReadingCategory == ReadingCategory.Judge - || t.ReadingCategory == ReadingCategory.Oncology - )) || t.Id == filterObj.Id) - ; - } - // IR 申请1.1 基线重阅,影响附加评估所有的任务 - else if (isIR1Point1AdditionalAssessmentBaseline) - { - filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && - ((( - ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId) - // 裁判 肿瘤学是另外的医生做 - || t.ReadingCategory == ReadingCategory.Judge - || t.ReadingCategory == ReadingCategory.Oncology - ) && t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId) || (t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB)) - ); + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); } else { - filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && + influenceTask.TaskState = TaskState.Adbandon; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); + } + } + } + + } + + + + } + //IR申请 PM 审批 注意这里有一致性分析的申请同意 不会回退访视,在此要生成影响的访视任务 + else if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.DocotorApply && (IsPMOrAPm() || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR)) + { + + + + //有序阅片 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + #region 有序 IR 申请 重阅 影响的其他访视查询 + + + + switch (origenalTask.ReadingCategory) + { + case ReadingCategory.Visit: + //影响后续访视已经读完的,正在读的,未读的不做处理 以及其他类型任务 + + //申请的是转化的,那么影响列表要排除转化之前的 + if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && origenalTask.BeforeConvertedTaskId != null) + { + + + filterExpression = filterExpression.And(t => (t.VisitTaskNum > origenalTask.VisitTaskNum && + ( + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) + // 裁判 肿瘤学是另外的医生做 + || t.ReadingCategory == ReadingCategory.Judge + || t.ReadingCategory == ReadingCategory.Oncology + )) || t.Id == origenalTask.Id) + ; + } + else if (isIR1Point1AdditionalAssessmentBaseline) + { + filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum && + ((( + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) + // 裁判 肿瘤学是另外的医生做 + || t.ReadingCategory == ReadingCategory.Judge + || t.ReadingCategory == ReadingCategory.Oncology + ) && t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId) || (t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB)) + ); + } + else + { + filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum && ( - ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId) + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) // 裁判 肿瘤学是另外的医生做 || t.ReadingCategory == ReadingCategory.Judge || t.ReadingCategory == ReadingCategory.Oncology @@ -2696,43 +1841,28 @@ namespace IRaCIS.Core.Application.Service.Allocation + break; + + //不影响后续访视: (t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.WaitReading) || case ReadingCategory.Global: - // 1、后续任务如果是访视任务,均不处理; - //2、后续任务如果是全局、状态为阅片完成则标记为重阅重置,若阅片中或待阅片则不处理; - //3、当前任务或者全局任务触发了裁判任务,若裁判任务状态为阅片完成,则标记为重阅重置;若在阅片中或待阅片,则标记为失效 - //4、后续任务为肿瘤学阅片任务,状态为阅片完成标记为重阅重置;若在阅片中,则标记为失效;若为待阅片,则标记为失效; - - //filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && - //((t.DoctorUserId == filterObj.DoctorUserId && ((t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned) || t.ReadingCategory == ReadingCategory.Global)) || (t.ReadingCategory == ReadingCategory.Oncology) || (t.ReadingCategory == ReadingCategory.Judge))); - - - filterExpression = filterExpression.And(t => t.VisitTaskNum > filterObj.VisitTaskNum && - ( - (t.DoctorUserId == filterObj.DoctorUserId && t.ReadingCategory == ReadingCategory.Global) - || (t.ReadingCategory == ReadingCategory.Oncology) - || (t.ReadingCategory == ReadingCategory.Judge) - ) || t.Id == filterObj.Id); - + filterExpression = filterExpression.And(t => t.VisitTaskNum > origenalTask.VisitTaskNum && + ((t.DoctorUserId == origenalTask.DoctorUserId && t.ReadingCategory == ReadingCategory.Global) + || (t.ReadingCategory == ReadingCategory.Oncology) || (t.ReadingCategory == ReadingCategory.Judge)) || t.Id == origenalTask.Id); break; - //1、后续任务如果是访视任务、全局任务或裁判任务,均不处理; case ReadingCategory.Oncology: - //仅仅影响自己 - filterExpression = filterExpression.And(t => t.Id == filterObj.Id); + //仅仅影响自己 后续任务如果是访视任务、全局任务或裁判任务,均不处理 + filterExpression = filterExpression.And(t => t.Id == origenalTask.Id); break; - //(只允许申请该阅片人最后一次完成裁判的任务重阅)申请的时候做了限制 case ReadingCategory.Judge: - // 1、后续任务如果是访视任务、全局任务,均不处理; - //2、后续若有肿瘤学阅片,若肿瘤学阅片任务状态为阅片完成,则标记为重阅重置;若为阅片中则标记为失效,如为待阅片,则取消分配 - //裁判的影响自己 和后续肿瘤学阅片(不是自己做的) - filterExpression = filterExpression.And(t => t.Id == filterObj.Id || t.VisitTaskNum > filterObj.VisitTaskNum && t.ReadingCategory == ReadingCategory.Oncology); + filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.VisitTaskNum > origenalTask.VisitTaskNum && t.ReadingCategory == ReadingCategory.Oncology); break; @@ -2740,373 +1870,1242 @@ namespace IRaCIS.Core.Application.Service.Allocation default: //---不支持重阅的任务类型 throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]); + } + + #endregion + + + + var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).OrderBy(t => t.VisitTaskNum).ToListAsync(); + + var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); + + + + foreach (var influenceTask in influenceTaskList) + { + var beforeTaskState = influenceTask.TaskState; + + //已签名的任务 设置转变后的标志 + if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + var isConvertedTask = _visitTaskRepository.Where(t => t.Id == influenceTask.Id).Select(t => t.IsConvertedTask).FirstOrDefault(); + + if (isConvertedTask) + { + influenceTask.IsHistoryConvertedTask = true; + } + } + + + //处理申请的任务 + if (influenceTask.Id == origenalTask.Id) + { + ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); + + + await SetMedicalReviewInvalidAsync(influenceTaskList, false); + + await InfluenceAddtioncalEvaluationCritrionAsync(origenalTask, influenceTaskList.Where(t => t.Id != origenalTask.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList(), false); + + } + + + + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + influenceTask.TaskState = TaskState.HaveReturned; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + influenceTask.TaskState = TaskState.Adbandon; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); + } + + + #region 受影响的任务生成 + + // 影响的任务 仅仅访视类别的才生成 或者就是IR 申请的任务 + if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id) + { + + + // 影响的其他标准的附加评估的任务不立即生成 比如1.1基线 重阅 PM 同意仅仅生成1.1任务,不生成BM任务 + if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment && influenceTask.TrialReadingCriterionId != origenalTask.TrialReadingCriterionId) + { + //BM标准的不生成任务 + continue; + } + + + // i1.1标准 当前任务是转变任务,并且影响列表里有转变之前的任务 那么该访视任务就不生成 + if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1) + { + //申请的任务是冻结的任务(该任务发生转变) 影响自己 以及转变后的 以及后续任务 但是生成的时候,仅仅生成转变之前的 + //申请的是转变之后的任务 (转变生成的任务) 影响自己以及后续任务 生成转变后的任务 + if (influenceTask.BeforeConvertedTaskId != null && influenceTaskList.Any(t => t.Id == influenceTask.BeforeConvertedTaskId)) + { + //有转化的任务 和转化之前的任务时,转化后的任务时不生成的 + continue; + + } + + + } + + + await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand() + { + TrialId = trialId, + + ReadingCategory = GenerateTaskCategory.ReReading, + + ReReadingTask = influenceTask, + + //同步才可以 + Action = (newTask) => + { + //申请表 设置新任务Id + visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id; + + //生成的任务分配给原始医生 + newTask.DoctorUserId = origenalTask.DoctorUserId; + newTask.TaskAllocationState = TaskAllocationState.Allocated; + newTask.AllocateTime = DateTime.Now; + newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); + + //拷贝原始表单 + if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id) + { + if (origenalTask.ReadingCategory == ReadingCategory.Visit) + { + CopyForms(newTask, origenalTask); + + } + + } + + //拷贝后续表单 + if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum) + { + if (origenalTask.ReadingCategory == ReadingCategory.Visit) + { + CopyForms(newTask, origenalTask); + } + + + } + + } + }); + + + + #endregion + + + } + + } + + + } - //无序 + //无序阅片 IR只会申请访视类型和裁判类型的任务 注意这里有一致性分析的申请同意 else { + + //1.当前任务及裁判任务 //2.影响当前阅片人的任务 - filterExpression = filterExpression.And(t => t.Id == filterObj.Id || t.Id == filterObj.JudgeVisitTaskId); - } + filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.Id == origenalTask.JudgeVisitTaskId); - //throw new BusinessValidationFailedException("仅允许PM 同意 IR 申请的任务"); - } - //PM 影响所有阅片人 仅仅针对访视 SPM CPM 调用 + var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); - else if (((IsSpmOrCPM()) && applyId != null && - await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && (t.CreateUser.UserTypeEnum == UserTypeEnum.ProjectManager || t.CreateUser.UserTypeEnum == UserTypeEnum.APM)) && filterObj.IsAnalysisCreate == false && filterObj.ReadingCategory == ReadingCategory.Visit) - || (IsPMOrAPm() && applyId == null)) - { + var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); - - - - //有序 - if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) - { - switch (filterObj.ReadingCategory) + foreach (var influenceTask in influenceTaskList) { - case ReadingCategory.Visit: + //申请原任务处理 + if (influenceTask.Id == origenalTask.Id) + { + ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); - //访视影响当前以及当前之后的 两个阅片人的 - filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum); + await SetMedicalReviewInvalidAsync(influenceTaskList, false); - break; + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + influenceTask.TaskState = TaskState.HaveReturned; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + influenceTask.TaskState = TaskState.Adbandon; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); + } + } + + #region 受影响任务的生成 + + if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id) + { + await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand() + { + TrialId = trialId, + + ReadingCategory = GenerateTaskCategory.ReReading, + + ReReadingTask = origenalTask, + + //同步才可以 + Action = (newTask) => + { + //申请表 设置新任务Id + visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id; + + ////生成的任务分配给原始医生 + newTask.DoctorUserId = origenalTask.DoctorUserId; + newTask.TaskAllocationState = TaskAllocationState.Allocated; + newTask.AllocateTime = DateTime.Now; + newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); + + + //裁判任务 需要进行特殊处理 在重阅逻辑里面处理 + + + if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id) + { + if (origenalTask.ReadingCategory == ReadingCategory.Visit) + { + CopyForms(newTask, origenalTask); + + } + + } + + //拷贝后续表单 + if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum) + { + if (origenalTask.ReadingCategory == ReadingCategory.Visit) + { + CopyForms(newTask, origenalTask); + + } + } + + + } + }); + + } + #endregion - default: - //---不支持重阅的任务类型 - throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]); } - if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default && - t.OriginalReReadingTask.VisitTaskNum >= filterObj.VisitTaskNum && t.OriginalReReadingTask.SubjectId == filterObj.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == filterObj.TrialReadingCriterionId && t.OriginalReReadingTask.IsAnalysisCreate == filterObj.IsAnalysisCreate)) - { - isIRAppyTaskInfluenced = true; - } - } - //无序 - else - { - // 1.当前任务及裁判任务 - // 2.影响所有阅片人的任务 - - var judegTaskNum = filterObj.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]; - - filterExpression = filterExpression.And(t => t.VisitTaskNum == filterObj.VisitTaskNum || t.VisitTaskNum == judegTaskNum); } - //throw new BusinessValidationFailedException("仅允许SPM CPM 同意 PM 申请的非 一致性分析的访视任务"); } else { - //---当前用户查看列表未定义 - throw new BusinessValidationFailedException(_localizer["VisitTask_UndefinedList"]); + //---不符合 PM申请 SPM / CPM审批 | IR申请 PM 审批 + throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskAlreadyAffected"]); } - - } - - - //退回影响 仅仅针对是访视类型的 影响多个标准的任务 - else + else if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Reject) { - if (filterObj.IsAnalysisCreate) + if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) { - //---不允许退回一致性分析任务 - throw new BusinessValidationFailedException(_localizer["VisitTask_NoConsistencyReturn"]); - } - - if (filterObj.ReadingCategory == ReadingCategory.Visit && IsPMOrAPm()) - { - //有序 - if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == origenalTask.Id, u => new VisitTask() { - // 当前任务及其之后的所有访视任务 两个阅片人的 - - //2.当前任务未完成,不会产生全局任务。后续任务均为访视任务,且均为待阅片,取消分配; - filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum); - - - if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default && - t.OriginalReReadingTask.VisitTaskNum >= filterObj.VisitTaskNum && t.OriginalReReadingTask.SubjectId == filterObj.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == filterObj.TrialReadingCriterionId && t.OriginalReReadingTask.IsAnalysisCreate == filterObj.IsAnalysisCreate)) - { - isIRAppyTaskInfluenced = true; - } - } - //无序 - else - { - //自己和另一个人的当前任务 退回针对的是未完成的肯定不会有裁判 - filterExpression = filterExpression.And(t => t.VisitTaskNum == filterObj.VisitTaskNum); - } + ReReadingApplyState = ReReadingApplyState.Reject + }); } else { - //---仅仅访视类型的任务支持PM退回 - throw new BusinessValidationFailedException(_localizer["VisitTask_VisitTypeTaskAllowedForPMOnly"]); + //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面 + throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]); } } - var list = await _visitTaskRepository.Where(filterExpression) - //IR 申请的时候,仅仅看到影响自己的 - .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer, t => t.DoctorUserId == _userInfo.Id) - .OrderBy(t => t.VisitTaskNum).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - #region 影响后的操作 - foreach (var influenceTask in list) + + } + + + + + + await _visitTaskRepository.SaveChangesAsync(); + + return ResponseOutput.Ok(); + } + + private void CopyForms(VisitTask newTask, VisitTask origenalTask) + { + + //自定义 + var readingCustomTagList = _readingCustomTagRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); + + foreach (var item in readingCustomTagList) + { + item.Id = Guid.Empty; + item.VisitTaskId = newTask.Id; + } + + _ = _readingCustomTagRepository.AddRangeAsync(readingCustomTagList).Result; + + + var readingTaskQuestionMarkList = _readingTaskQuestionMarkRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); + + foreach (var item in readingTaskQuestionMarkList) + { + item.Id = Guid.Empty; + item.VisitTaskId = newTask.Id; + } + + _ = _readingTaskQuestionMarkRepository.AddRangeAsync(readingTaskQuestionMarkList).Result; + + var readingTaskQuestionAnswerList = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); + + foreach (var item in readingTaskQuestionAnswerList) + { + item.Id = Guid.Empty; + item.VisitTaskId = newTask.Id; + } + _ = _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskQuestionAnswerList).Result; + + + + //ReadingTableAnswerRowInfo ReadingTableQuestionAnswer 一起加 + var readingTableAnswerRowInfoList = _readingTableAnswerRowInfoRepository.Where(t => t.VisitTaskId == origenalTask.Id).Include(t => t.LesionAnswerList).ToList(); + + foreach (var item in readingTableAnswerRowInfoList) + { + + var originalVisitTaskId = item.VisitTaskId; + var originalFristAddTaskId = item.FristAddTaskId; + + item.Id = NewId.NextSequentialGuid(); + item.VisitTaskId = newTask.Id; + + //默认值是当前任务添加的 + item.FristAddTaskId = originalVisitTaskId == originalFristAddTaskId ? newTask.Id : item.FristAddTaskId; + + + foreach (var item2 in item.LesionAnswerList) { - influenceTask.OptType = influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned ? ReReadingOrBackOptType.Return : ReReadingOrBackOptType.Abandon; + item2.Id = Guid.Empty; + item2.RowId = item.Id; + item2.VisitTaskId = newTask.Id; } + } + + _ = _readingTableAnswerRowInfoRepository.AddRangeAsync(readingTableAnswerRowInfoList).Result; + + + + + + } + + + /// + /// PM 设置任务 退回 + /// + /// + [HttpPut("{trialId:guid}/{taskId:guid}")] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + + public async Task PMSetTaskBack(Guid trialId, Guid taskId) + { + + //var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.IsReadingTaskViewInOrder, t.ReadingType }).FirstOrDefaultAsync()).IfNullThrowException(); + + + var task = (await _visitTaskRepository.Where(t => t.Id == taskId).FirstOrDefaultAsync()).IfNullThrowException(); + + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == task.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAutoCreate, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); + + if (criterionConfig.IsAutoCreate == false) + { + //---手动生成任务的不允许在此入口影像退回 + return ResponseOutput.NotOk(_localizer["VisitTask_NoImageReturn"]); + } + + if (task.TaskState != TaskState.Effect || task.ReadingCategory != ReadingCategory.Visit || task.ReadingTaskState == ReadingTaskState.HaveSigned) + { + //---仅仅允许针对生效、未完成的访视任务进行退回操作,请刷新页面数据 + return ResponseOutput.NotOk(_localizer["VisitTask_NonEffectiveTaskCannotBeReturned"]); + } + + + if (await _subjectVisitRepository.AnyAsync(t => t.Id == task.SourceSubjectVisitId && t.CheckState != CheckStateEnum.CVPassed)) + { + //---当前访视已回退到影像上传,不允许继续回退! + return ResponseOutput.NotOk(_localizer["VisitTask_NoFurtherReturn"]); + } + + + if (task.IsAnalysisCreate) + { + //---一致性分析的任务,不允许设置退回 + return ResponseOutput.NotOk(_localizer["VisitTask_ConsistencyTaskCannotBeReturned"]); + } + + Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.TaskAllocationState == TaskAllocationState.Allocated; + + + #region 退回到访视 不区分标准 + //if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) + //{ + // //影像退回,必定影响两个标准的任务 + // filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == task.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); + + + //} + //else + //{ + // //默认影响的都是该标准的任务 + // filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == task.TrialReadingCriterionId); + //} + #endregion + + + //PM 才允许操作 + if (IsPMOrAPm()) + { + + #region 有序 无序公用流程 + + + //执行类似一致性核查回退流程 回退访视到影像上传流程 + await VisitBackAsync(task.SourceSubjectVisitId); + #endregion - return (list, new { IsIRAppyTaskInfluenced = isIRAppyTaskInfluenced }); + + //有序 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + + //Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated; + + filterExpression = filterExpression.And(t => t.IsAnalysisCreate == false); + + + + //另一个阅片人的任务根据任务进度自动进入PM退回或PM申请重阅 + filterExpression = filterExpression.And(t => t.VisitTaskNum >= task.VisitTaskNum); + + + var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); + + + + #region 方式二 + + + //pm退回的时候,影响的任务里不一定有该任务id 双重 分配了一个人,退回的时候,选择的是未分配的 + + //var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault(); + + var origenalTask = await _visitTaskRepository.FindAsync(task.Id); + + + foreach (var influenceTask in influenceTaskList) + { + + //已签名的任务 设置转变后的标志 + if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + var isConvertedTask = _visitTaskRepository.Where(t => t.Id == influenceTask.Id).Select(t => t.IsConvertedTask).FirstOrDefault(); + + if (isConvertedTask) + { + influenceTask.IsHistoryConvertedTask = true; + } + } + + //同意的访视 因为要记录具体的操作,所以废弃 + if (influenceTask.Id == task.Id) + { + + await InfluenceAddtioncalEvaluationCritrionAsync(task, influenceTaskList.Where(t => t.Id != task.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList()); + + await PMReReadingConfirmOrBackInfluenceAnalysisAsync(influenceTask.SubjectId); + + await SetMedicalReviewInvalidAsync(influenceTaskList); + + + influenceTask.IsPMSetBack = true; + } + + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + influenceTask.TaskState = TaskState.HaveReturned; + origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + influenceTask.TaskState = TaskState.Adbandon; + origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); + } + + } + + #endregion + + + + } + + else + { + //无序 无序阅片没有 全局 肿瘤学 + + // 申请该访视的任务 申请人失效 另外一个人重阅重置或者失效 + + var currentVisitList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == task.SourceSubjectVisitId && t.ReadingCategory == ReadingCategory.Visit && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.VisitTaskNum == task.VisitTaskNum, true).ToListAsync(); + + await SetMedicalReviewInvalidAsync(currentVisitList); + + //var origenalTask = currentVisitList.Where(t => t.Id == task.Id).First(); + + var origenalTask = await _visitTaskRepository.FindAsync(task.Id); + + foreach (var influenceTask in currentVisitList) + { + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + //另外阅片人完成阅片了 就设置为重阅重置 + influenceTask.TaskState = TaskState.HaveReturned; + + origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + influenceTask.TaskState = TaskState.Adbandon; + + origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); + } + + } + + } } - - - - - /// - /// 获取已影响的列表 - /// - /// - public async Task> GetInfluencedTaskList(Guid taskId) + else { - var list = await _taskInfluenceRepository.Where(t => t.OriginalTaskId == taskId)/*.Select(t => t.InfluenceTask)*/.ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - - return list; + //---仅PM 可以进行回退操作 + return ResponseOutput.NotOk(_localizer["VisitTask_PMOnlyAllowedForReturn"]); } - #region 暂时废弃 - - - ///// - ///// 自动一次性分配所有未分配的 Subject 给医生 暂时废弃 - ///// - ///// - ///// - //[HttpPost] - //[UnitOfWork] - //[Obsolete] - //public async Task AutoSubjectAssignDoctor(AutoSubjectAssignCommand autoSubjectAssignCommand) - //{ - // //自动分配的话,需要把手动分配的给删掉 - - - // var trialId = autoSubjectAssignCommand.TrialId; - // var isJudge = autoSubjectAssignCommand.IsJudgeDoctor; - - - // //获取项目配置 判断应该分配几个医生 - // var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id/*, t.ReadingType*/, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync()).IfNullThrowException(); - - - // //获取 已产生任务的Subject 目前分配情况 - // var subjectList = _subjectRepository.Where(t => t.TrialId == trialId) - // .WhereIf(isJudge == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) - // .WhereIf(isJudge, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) - // ////过滤掉 那些回退的subject - // //.Where(t => !t.SubjectVisitList.Any(t => t.IsPMBackOrReReading)) - // .Select(t => new - // { - // SubjectId = t.Id, - - // //给Subject分配医生的时候, 未确认绑定关系的 - // DoctorUserList = t.SubjectDoctorList.Where(t => isJudge ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.OrignalSubjectUserId == null).Select(t => new { t.DoctorUserId, t.ArmEnum }), - // //IsApplyed = t.SubjectDoctorList.Where(t => isJudge ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.OrignalSubjectUserId == null).SelectMany(t => t.SubjectArmVisitTaskList).Any(c => c.DoctorUserId != null) - // IsApplyed = false - // }).ToList(); - - // //已产生任务的Subject数量(裁判情况下,就是产生裁判任务Subject 的数量) - // var subjectCount = subjectList.Count; - - // //获取医生列表(裁判是裁判的医生列表) - // var waitAllocationDoctorList = _taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable) - // .Where(t => t.IsJudgeDoctor == isJudge) - // .Select(t => new AutoAssignResultDTO() { DoctorUserId = t.DoctorUserId, PlanReadingRatio = t.PlanReadingRatio, SubjectCount = subjectCount }) - // .ToList(); - - // if (waitAllocationDoctorList.Count == 0) - // { - // throw new BusinessValidationFailedException("启用的医生数量为0"); - // } - - - // //已分配的 医生的情况 - // var haveAssignedSubjectDoctorList = subjectList.Clone().SelectMany(t => t.DoctorUserList.Select(c => new { t.SubjectId, c.DoctorUserId, c.ArmEnum })).ToList(); - - // //将目前已分配的情况 换到医生的维度 - // foreach (var waitAllocationDoctor in waitAllocationDoctorList) - // { - // waitAllocationDoctor.SubjectArmList = haveAssignedSubjectDoctorList.Where(t => t.DoctorUserId == waitAllocationDoctor.DoctorUserId) - // .Select(g => new SubjectArm() - // { - // SubjectId = g.SubjectId, - // ArmEnum = g.ArmEnum - // }).ToList(); - // } - - - // #region 完全按照Subject 遍历去分 - - - // //仅仅分配未应用的 而且 没有分配医生的 - // foreach (var subject in subjectList.Where(t => t.IsApplyed == false && !t.DoctorUserList.Any())) - // { - // //该Subject 已经分配的医生数量 - // var hasAssignDoctorCount = subject.DoctorUserList.Count(); - - // if (isJudge) - // { - // if (hasAssignDoctorCount > 1) - // { - // throw new BusinessValidationFailedException("当前有Subject裁判绑定医生数量大于1"); - - // } - - // var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault(); - - // //将分配结果记录 - // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm() - // { - // SubjectId = subject.SubjectId, - // ArmEnum = Arm.JudgeArm - // }); - - // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.JudgeArm, AssignTime = DateTime.Now }); - - // } - // else - // { - - // //分配两个医生 - // if (trialConfig.ReadingType == ReadingMethod.Double) - // { - - - // if (hasAssignDoctorCount > 2) - // { - // throw new BusinessValidationFailedException("双重阅片当前有Subject绑定医生数量大于2"); - - // } - - // var allocateDoctorList = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).Take(2).ToList(); - - - // #region 看阅片人之前在Subject哪个组做的多 - - // var preferredDoctor1Arm = waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId) - // .SelectMany(t => t.SubjectArmList).GroupBy(t => t.ArmEnum) - // .Select(g => new { ArmEnum = g.Key, SubjectCount = g.Count() }) - // .OrderByDescending(t => t.SubjectCount).FirstOrDefault()?.ArmEnum; - - // var preferredDoctor2Arm = waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId) - // .SelectMany(t => t.SubjectArmList).GroupBy(t => t.ArmEnum) - // .Select(g => new { ArmEnum = g.Key, SubjectCount = g.Count() }) - // .OrderByDescending(t => t.SubjectCount).FirstOrDefault()?.ArmEnum; - - // //存放医生分配的Arm - // var doctor1Arm = Arm.DoubleReadingArm1; - // var doctor2Arm = Arm.DoubleReadingArm2; - - // if (preferredDoctor1Arm == null && preferredDoctor2Arm == null || - // preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm2 || - // preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == null || - // preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm2 - // ) - // { - // doctor1Arm = Arm.DoubleReadingArm1; - // doctor2Arm = Arm.DoubleReadingArm2; - // } - // else if (preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm1 || - // preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm1 || - // preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == null) - // { - // doctor1Arm = Arm.DoubleReadingArm2; - // doctor2Arm = Arm.DoubleReadingArm1; - // } - - // else if (preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm1) - // { - // doctor1Arm = Arm.DoubleReadingArm1; - // doctor2Arm = Arm.DoubleReadingArm2; - // } - // else if (preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm2) - // { - // doctor1Arm = Arm.DoubleReadingArm2; - // doctor2Arm = Arm.DoubleReadingArm1; - // } - - // #endregion - - - // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[0].DoctorUserId, ArmEnum = doctor1Arm, AssignTime = DateTime.Now }); - - - // //将分配结果记录 - // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId).SubjectArmList.Add(new SubjectArm() - // { - // SubjectId = subject.SubjectId, - // ArmEnum = doctor1Arm - // }); - - - // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[1].DoctorUserId, ArmEnum = doctor2Arm, AssignTime = DateTime.Now }); - - // //将分配结果记录 - // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId).SubjectArmList.Add(new SubjectArm() - // { - // SubjectId = subject.SubjectId, - // ArmEnum = doctor2Arm - // }); - // } - // else if (trialConfig.ReadingType == ReadingMethod.Single) - // { - // if (hasAssignDoctorCount > 1) - // { - // throw new BusinessValidationFailedException("单重阅片当前有Subject绑定医生数量大于1"); - // } - - // var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault(); - - // //将分配结果记录 - // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm() - // { - // SubjectId = subject.SubjectId, - // ArmEnum = Arm.SingleReadingArm - // }); - - // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.SingleReadingArm, AssignTime = DateTime.Now }); - - // } - - // } - - // } - - - // #endregion + await _visitTaskRepository.SaveChangesAsync(); - - - // await _subjectUserRepository.SaveChangesAsync(); - // return ResponseOutput.Ok(); - - //} - - - #endregion + return ResponseOutput.Ok(); } + + + /// + /// 基线退回 影响附加评估标准 是否参与评估 + /// + /// + private async Task InfluenceAddtioncalEvaluationCritrionAsync(VisitTask task, List otherVisitIdList, bool isImageBack = true) + { + + var criterion = await _trialReadingCriterionRepository.FindAsync(task.TrialReadingCriterionId); + + if (criterion.CriterionType == CriterionType.RECIST1Point1) + { + //影像回退了|| IR 申请及基线重阅 + if (_subjectVisitRepository.Any(t => t.Id == task.SourceSubjectVisitId && t.IsBaseLine)) + { + await _subjectCriteriaEvaluationRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.IsAutoCreate == false && t.SubjectId == task.SubjectId, u => new SubjectCriteriaEvaluation() + { + IsJoinEvaluation = false + }); + + //删除筛选的访视数据 + await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectId == task.SubjectId); + + //删除筛选的序列数据 + await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId); + } + else if (isImageBack) + { + //当前访视筛选状态重置,任务生成状态重置 + if (task.SourceSubjectVisitId != null) + { + await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && t.SubjectVisitId == task.SourceSubjectVisitId, + t => new SubjectCriteriaEvaluationVisitFilter() + { + ImageFilterState = ImageFilterState.None, + ImageDeterminationResultState = ImageDeterminationResultState.None, + IsGeneratedTask = false + }); + + //删除序列数据 + await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && t.SubjectVisitId == task.SourceSubjectVisitId); + } + + + //BM后续访视 ,筛选状态不变,任务生成状态重置(实际该访视任务状态 可能是重阅重置了或者失效了,需要后续生成,或者取消分配了,需要后续重新分配) + await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && otherVisitIdList.Contains(t.SubjectVisitId), + t => new SubjectCriteriaEvaluationVisitFilter() + { + IsGeneratedTask = false + }); + } + else + { + //IR 端 非基线申请重阅 不影响 + } + } + + + + } + + //包括临床数据签名状态 + private async Task VisitBackAsync(Guid? subjectVisitId) + { + var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException(); + + + //需要重新产生任务 + sv.IsVisitTaskGenerated = false; + sv.IsPMBackOrReReading = true; + + sv.AuditState = AuditStateEnum.None; + sv.SubmitState = SubmitStateEnum.ToSubmit; + sv.ReadingStatus = ReadingStatusEnum.ImageNotSubmit; + + //回退后,回退状态恢复 + sv.RequestBackState = RequestBackStateEnum.NotRequest; + sv.IsCheckBack = false; + sv.CheckBackTime = null; + sv.CheckState = CheckStateEnum.None; + sv.CheckChallengeState = CheckChanllengeTypeEnum.None; + + sv.SVENDTC = null; + sv.SVSTDTC = null; + + sv.PreliminaryAuditTime = null; + sv.SubmitTime = null; + sv.ReviewAuditTime = null; + sv.CurrentActionUserExpireTime = null; + + + sv.IsTake = false; + sv.CurrentActionUserId = null; + sv.PreliminaryAuditUserId = null; + sv.ReviewAuditUserId = null; + + + if (sv.IsBaseLine) + { + await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && (t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit), c => new ReadingClinicalData() { IsSign = false, ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded }); + + } + else + { + await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit, c => new ReadingClinicalData() + { + IsSign = false, + ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded, + IsBlind = null, + IsComplete = null + }); + } + + + + //await _repository.AddAsync(new CheckChallengeDialog() { SubjectVisitId = subjectVisitId, TalkContent = "PM/APM同意一致性核查回退。", UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt }); + + await _trialQCQuestionAnswerRepository.BatchDeleteNoTrackingAsync(t => t.SubjectVisitId == subjectVisitId); + await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => t.DicomSerie.IsDeleted); + await _dicomSeriesRepository.BatchDeleteNoTrackingAsync(t => t.IsDeleted); + + var success = await _subjectVisitRepository.SaveChangesAsync(); + + } + + + private bool IsPMOrAPm() + { + return _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM; + } + + private bool IsSpmOrCPM() + { + return _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM; + } + + /// + /// 影响提示列表 重阅仅仅针对已完成的任务申请 退回针对的是未完成的(退回仅仅针对是访视类型的) + /// + /// + /// 重阅还是直接回退 + /// 申请记录的Id + /// + [HttpGet("{taskId:guid}/{isReReading:bool}")] + public async Task<(List, object)> GetReReadingOrBackInfluenceTaskList(Guid taskId, bool isReReading, Guid? applyId) + { + var isIRAppyTaskInfluenced = false; + + var filterObj = (await _visitTaskRepository.FirstOrDefaultNoTrackingAsync(t => t.Id == taskId)).IfNullThrowException(); + var trialId = filterObj.TrialId; + + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == filterObj.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); + + Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == filterObj.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.TaskAllocationState == TaskAllocationState.Allocated; + + //是否是一致性分析任务 (一致性分析的任务 不会产生裁判 肿瘤学 仅仅有生成的访视和全局) + + filterExpression = filterExpression.And(t => t.IsAnalysisCreate == filterObj.IsAnalysisCreate); + + //IR 申请1.1 基线重阅,影响附加评估所有的任务 + var isIR1Point1AdditionalAssessmentBaseline = false; + + //附加评估 IR 和PM 看到的影响列表不一样 + if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) + { + + // IR 申请 PM 同意 + if (((IsPMOrAPm() && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) + || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null))) + { + + // 1.1 基线任务影响BM任务 + if (IsPMOrAPm() && _subjectVisitRepository.Any(t => t.Id == filterObj.SourceSubjectVisitId && t.IsBaseLine == true)) + { + + isIR1Point1AdditionalAssessmentBaseline = true; + //filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); + + + } + // 1.1 非基线任务不影响BM任务 + else + { + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId); + } + + } + //(1、PM回退,PM申请重阅,SPM同意回退) + else + { + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); + + } + } + else + { + //默认影响的都是该标准的任务 + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId); + } + + + + //重阅影响 + if (isReReading) + { + + + + //IR 申请 PM 同意 仅仅影响自己 + + if ((IsPMOrAPm() && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) + || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null)) + { + + //当前任务及其之后的所有访视任务、全局任务、裁判任务、肿瘤学阅片任务 + + //有序 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + + switch (filterObj.ReadingCategory) + { + case ReadingCategory.Visit: + //影响当前医生 以及当前医生之后的 1、访视任务 已经读完的 + //2、后续任务如果是全局、肿瘤学阅片任务,状态为阅片完成标记为重阅重置;若在阅片中,则标记为失效;若为待阅片,则标记为失效; + //3、当前任务、后续访视任务或者全局任务触发了裁判任务,若裁判任务状态为阅片完成,则标记为重阅重置;若在阅片中或待阅片,则标记为失效 + + //申请的是转化的,那么影响列表要排除转化之前的 + if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && filterObj.BeforeConvertedTaskId != null) + { + + + filterExpression = filterExpression.And(t => (t.VisitTaskNum > filterObj.VisitTaskNum && + ( + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId) + // 裁判 肿瘤学是另外的医生做 + || t.ReadingCategory == ReadingCategory.Judge + || t.ReadingCategory == ReadingCategory.Oncology + )) || t.Id == filterObj.Id) + ; + } + // IR 申请1.1 基线重阅,影响附加评估所有的任务 + else if (isIR1Point1AdditionalAssessmentBaseline) + { + filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && + ((( + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId) + // 裁判 肿瘤学是另外的医生做 + || t.ReadingCategory == ReadingCategory.Judge + || t.ReadingCategory == ReadingCategory.Oncology + ) && t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId) || (t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB)) + ); + } + else + { + filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && + ( + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId) + // 裁判 肿瘤学是另外的医生做 + || t.ReadingCategory == ReadingCategory.Judge + || t.ReadingCategory == ReadingCategory.Oncology + ) + ); + } + + + + + + break; + + case ReadingCategory.Global: + + // 1、后续任务如果是访视任务,均不处理; + //2、后续任务如果是全局、状态为阅片完成则标记为重阅重置,若阅片中或待阅片则不处理; + //3、当前任务或者全局任务触发了裁判任务,若裁判任务状态为阅片完成,则标记为重阅重置;若在阅片中或待阅片,则标记为失效 + //4、后续任务为肿瘤学阅片任务,状态为阅片完成标记为重阅重置;若在阅片中,则标记为失效;若为待阅片,则标记为失效; + + //filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && + //((t.DoctorUserId == filterObj.DoctorUserId && ((t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned) || t.ReadingCategory == ReadingCategory.Global)) || (t.ReadingCategory == ReadingCategory.Oncology) || (t.ReadingCategory == ReadingCategory.Judge))); + + + filterExpression = filterExpression.And(t => t.VisitTaskNum > filterObj.VisitTaskNum && + ( + (t.DoctorUserId == filterObj.DoctorUserId && t.ReadingCategory == ReadingCategory.Global) + || (t.ReadingCategory == ReadingCategory.Oncology) + || (t.ReadingCategory == ReadingCategory.Judge) + ) || t.Id == filterObj.Id); + + break; + + //1、后续任务如果是访视任务、全局任务或裁判任务,均不处理; + case ReadingCategory.Oncology: + + //仅仅影响自己 + filterExpression = filterExpression.And(t => t.Id == filterObj.Id); + break; + + //(只允许申请该阅片人最后一次完成裁判的任务重阅)申请的时候做了限制 + case ReadingCategory.Judge: + + // 1、后续任务如果是访视任务、全局任务,均不处理; + //2、后续若有肿瘤学阅片,若肿瘤学阅片任务状态为阅片完成,则标记为重阅重置;若为阅片中则标记为失效,如为待阅片,则取消分配 + + //裁判的影响自己 和后续肿瘤学阅片(不是自己做的) + filterExpression = filterExpression.And(t => t.Id == filterObj.Id || t.VisitTaskNum > filterObj.VisitTaskNum && t.ReadingCategory == ReadingCategory.Oncology); + + break; + + + default: + //---不支持重阅的任务类型 + throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]); + } + } + //无序 + else + { + //1.当前任务及裁判任务 + //2.影响当前阅片人的任务 + filterExpression = filterExpression.And(t => t.Id == filterObj.Id || t.Id == filterObj.JudgeVisitTaskId); + } + + + //throw new BusinessValidationFailedException("仅允许PM 同意 IR 申请的任务"); + } + //PM 影响所有阅片人 仅仅针对访视 SPM CPM 调用 + + else if (((IsSpmOrCPM()) && applyId != null && + await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && (t.CreateUser.UserTypeEnum == UserTypeEnum.ProjectManager || t.CreateUser.UserTypeEnum == UserTypeEnum.APM)) && filterObj.IsAnalysisCreate == false && filterObj.ReadingCategory == ReadingCategory.Visit) + || (IsPMOrAPm() && applyId == null)) + { + + + + + //有序 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + switch (filterObj.ReadingCategory) + { + case ReadingCategory.Visit: + + //访视影响当前以及当前之后的 两个阅片人的 + filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum); + + break; + + default: + //---不支持重阅的任务类型 + throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]); + } + + if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default && + t.OriginalReReadingTask.VisitTaskNum >= filterObj.VisitTaskNum && t.OriginalReReadingTask.SubjectId == filterObj.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == filterObj.TrialReadingCriterionId && t.OriginalReReadingTask.IsAnalysisCreate == filterObj.IsAnalysisCreate)) + { + isIRAppyTaskInfluenced = true; + } + } + //无序 + else + { + // 1.当前任务及裁判任务 + // 2.影响所有阅片人的任务 + + var judegTaskNum = filterObj.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]; + + filterExpression = filterExpression.And(t => t.VisitTaskNum == filterObj.VisitTaskNum || t.VisitTaskNum == judegTaskNum); + } + + //throw new BusinessValidationFailedException("仅允许SPM CPM 同意 PM 申请的非 一致性分析的访视任务"); + } + else + { + //---当前用户查看列表未定义 + throw new BusinessValidationFailedException(_localizer["VisitTask_UndefinedList"]); + } + + + + } + + + //退回影响 仅仅针对是访视类型的 影响多个标准的任务 + else + { + + if (filterObj.IsAnalysisCreate) + { + //---不允许退回一致性分析任务 + throw new BusinessValidationFailedException(_localizer["VisitTask_NoConsistencyReturn"]); + } + + if (filterObj.ReadingCategory == ReadingCategory.Visit && IsPMOrAPm()) + { + //有序 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + // 当前任务及其之后的所有访视任务 两个阅片人的 + + //2.当前任务未完成,不会产生全局任务。后续任务均为访视任务,且均为待阅片,取消分配; + filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum); + + + if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default && + t.OriginalReReadingTask.VisitTaskNum >= filterObj.VisitTaskNum && t.OriginalReReadingTask.SubjectId == filterObj.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == filterObj.TrialReadingCriterionId && t.OriginalReReadingTask.IsAnalysisCreate == filterObj.IsAnalysisCreate)) + { + isIRAppyTaskInfluenced = true; + } + } + //无序 + else + { + //自己和另一个人的当前任务 退回针对的是未完成的肯定不会有裁判 + filterExpression = filterExpression.And(t => t.VisitTaskNum == filterObj.VisitTaskNum); + } + } + else + { + //---仅仅访视类型的任务支持PM退回 + throw new BusinessValidationFailedException(_localizer["VisitTask_VisitTypeTaskAllowedForPMOnly"]); + } + + } + + var list = await _visitTaskRepository.Where(filterExpression) + //IR 申请的时候,仅仅看到影响自己的 + .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer, t => t.DoctorUserId == _userInfo.Id) + .OrderBy(t => t.VisitTaskNum).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + #region 影响后的操作 + + foreach (var influenceTask in list) + { + influenceTask.OptType = influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned ? ReReadingOrBackOptType.Return : ReReadingOrBackOptType.Abandon; + } + #endregion + + + return (list, new { IsIRAppyTaskInfluenced = isIRAppyTaskInfluenced }); + + } + + + + + /// + /// 获取已影响的列表 + /// + /// + public async Task> GetInfluencedTaskList(Guid taskId) + { + var list = await _taskInfluenceRepository.Where(t => t.OriginalTaskId == taskId)/*.Select(t => t.InfluenceTask)*/.ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + return list; + } + + + #region 暂时废弃 + + + ///// + ///// 自动一次性分配所有未分配的 Subject 给医生 暂时废弃 + ///// + ///// + ///// + //[HttpPost] + //[UnitOfWork] + //[Obsolete] + //public async Task AutoSubjectAssignDoctor(AutoSubjectAssignCommand autoSubjectAssignCommand) + //{ + // //自动分配的话,需要把手动分配的给删掉 + + + // var trialId = autoSubjectAssignCommand.TrialId; + // var isJudge = autoSubjectAssignCommand.IsJudgeDoctor; + + + // //获取项目配置 判断应该分配几个医生 + // var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id/*, t.ReadingType*/, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync()).IfNullThrowException(); + + + // //获取 已产生任务的Subject 目前分配情况 + // var subjectList = _subjectRepository.Where(t => t.TrialId == trialId) + // .WhereIf(isJudge == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) + // .WhereIf(isJudge, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) + // ////过滤掉 那些回退的subject + // //.Where(t => !t.SubjectVisitList.Any(t => t.IsPMBackOrReReading)) + // .Select(t => new + // { + // SubjectId = t.Id, + + // //给Subject分配医生的时候, 未确认绑定关系的 + // DoctorUserList = t.SubjectDoctorList.Where(t => isJudge ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.OrignalSubjectUserId == null).Select(t => new { t.DoctorUserId, t.ArmEnum }), + // //IsApplyed = t.SubjectDoctorList.Where(t => isJudge ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.OrignalSubjectUserId == null).SelectMany(t => t.SubjectArmVisitTaskList).Any(c => c.DoctorUserId != null) + // IsApplyed = false + // }).ToList(); + + // //已产生任务的Subject数量(裁判情况下,就是产生裁判任务Subject 的数量) + // var subjectCount = subjectList.Count; + + // //获取医生列表(裁判是裁判的医生列表) + // var waitAllocationDoctorList = _taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable) + // .Where(t => t.IsJudgeDoctor == isJudge) + // .Select(t => new AutoAssignResultDTO() { DoctorUserId = t.DoctorUserId, PlanReadingRatio = t.PlanReadingRatio, SubjectCount = subjectCount }) + // .ToList(); + + // if (waitAllocationDoctorList.Count == 0) + // { + // throw new BusinessValidationFailedException("启用的医生数量为0"); + // } + + + // //已分配的 医生的情况 + // var haveAssignedSubjectDoctorList = subjectList.Clone().SelectMany(t => t.DoctorUserList.Select(c => new { t.SubjectId, c.DoctorUserId, c.ArmEnum })).ToList(); + + // //将目前已分配的情况 换到医生的维度 + // foreach (var waitAllocationDoctor in waitAllocationDoctorList) + // { + // waitAllocationDoctor.SubjectArmList = haveAssignedSubjectDoctorList.Where(t => t.DoctorUserId == waitAllocationDoctor.DoctorUserId) + // .Select(g => new SubjectArm() + // { + // SubjectId = g.SubjectId, + // ArmEnum = g.ArmEnum + // }).ToList(); + // } + + + // #region 完全按照Subject 遍历去分 + + + // //仅仅分配未应用的 而且 没有分配医生的 + // foreach (var subject in subjectList.Where(t => t.IsApplyed == false && !t.DoctorUserList.Any())) + // { + // //该Subject 已经分配的医生数量 + // var hasAssignDoctorCount = subject.DoctorUserList.Count(); + + // if (isJudge) + // { + // if (hasAssignDoctorCount > 1) + // { + // throw new BusinessValidationFailedException("当前有Subject裁判绑定医生数量大于1"); + + // } + + // var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault(); + + // //将分配结果记录 + // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm() + // { + // SubjectId = subject.SubjectId, + // ArmEnum = Arm.JudgeArm + // }); + + // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.JudgeArm, AssignTime = DateTime.Now }); + + // } + // else + // { + + // //分配两个医生 + // if (trialConfig.ReadingType == ReadingMethod.Double) + // { + + + // if (hasAssignDoctorCount > 2) + // { + // throw new BusinessValidationFailedException("双重阅片当前有Subject绑定医生数量大于2"); + + // } + + // var allocateDoctorList = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).Take(2).ToList(); + + + // #region 看阅片人之前在Subject哪个组做的多 + + // var preferredDoctor1Arm = waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId) + // .SelectMany(t => t.SubjectArmList).GroupBy(t => t.ArmEnum) + // .Select(g => new { ArmEnum = g.Key, SubjectCount = g.Count() }) + // .OrderByDescending(t => t.SubjectCount).FirstOrDefault()?.ArmEnum; + + // var preferredDoctor2Arm = waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId) + // .SelectMany(t => t.SubjectArmList).GroupBy(t => t.ArmEnum) + // .Select(g => new { ArmEnum = g.Key, SubjectCount = g.Count() }) + // .OrderByDescending(t => t.SubjectCount).FirstOrDefault()?.ArmEnum; + + // //存放医生分配的Arm + // var doctor1Arm = Arm.DoubleReadingArm1; + // var doctor2Arm = Arm.DoubleReadingArm2; + + // if (preferredDoctor1Arm == null && preferredDoctor2Arm == null || + // preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm2 || + // preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == null || + // preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm2 + // ) + // { + // doctor1Arm = Arm.DoubleReadingArm1; + // doctor2Arm = Arm.DoubleReadingArm2; + // } + // else if (preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm1 || + // preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm1 || + // preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == null) + // { + // doctor1Arm = Arm.DoubleReadingArm2; + // doctor2Arm = Arm.DoubleReadingArm1; + // } + + // else if (preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm1) + // { + // doctor1Arm = Arm.DoubleReadingArm1; + // doctor2Arm = Arm.DoubleReadingArm2; + // } + // else if (preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm2) + // { + // doctor1Arm = Arm.DoubleReadingArm2; + // doctor2Arm = Arm.DoubleReadingArm1; + // } + + // #endregion + + + // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[0].DoctorUserId, ArmEnum = doctor1Arm, AssignTime = DateTime.Now }); + + + // //将分配结果记录 + // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId).SubjectArmList.Add(new SubjectArm() + // { + // SubjectId = subject.SubjectId, + // ArmEnum = doctor1Arm + // }); + + + // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[1].DoctorUserId, ArmEnum = doctor2Arm, AssignTime = DateTime.Now }); + + // //将分配结果记录 + // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId).SubjectArmList.Add(new SubjectArm() + // { + // SubjectId = subject.SubjectId, + // ArmEnum = doctor2Arm + // }); + // } + // else if (trialConfig.ReadingType == ReadingMethod.Single) + // { + // if (hasAssignDoctorCount > 1) + // { + // throw new BusinessValidationFailedException("单重阅片当前有Subject绑定医生数量大于1"); + // } + + // var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault(); + + // //将分配结果记录 + // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm() + // { + // SubjectId = subject.SubjectId, + // ArmEnum = Arm.SingleReadingArm + // }); + + // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.SingleReadingArm, AssignTime = DateTime.Now }); + + // } + + // } + + // } + + + // #endregion + + + + + + + + // await _subjectUserRepository.SaveChangesAsync(); + // return ResponseOutput.Ok(); + + //} + + + #endregion } diff --git a/IRaCIS.Core.Application/Service/Common/DTO/FrontAuditConfigViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/FrontAuditConfigViewModel.cs index 13a4d84e2..b2d76c285 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/FrontAuditConfigViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/FrontAuditConfigViewModel.cs @@ -7,7 +7,7 @@ using System; using IRaCIS.Core.Domain.Share; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using IRaCIS.Core.Infra.EFCore.Common.Dto; +using IRaCIS.Core.Infra.EFCore.Common; namespace IRaCIS.Core.Application.ViewModel { diff --git a/IRaCIS.Core.Application/Service/Inspection/DTO/InspectionViewModel.cs b/IRaCIS.Core.Application/Service/Inspection/DTO/InspectionViewModel.cs new file mode 100644 index 000000000..858d8bd08 --- /dev/null +++ b/IRaCIS.Core.Application/Service/Inspection/DTO/InspectionViewModel.cs @@ -0,0 +1,73 @@ +using IRaCIS.Core.Domain.Share; +using System.ComponentModel.DataAnnotations; +namespace IRaCIS.Core.Application.ViewModel; + +public class DateDto +{ + public string Code { get; set; } + + public string DateType { get; set; } + + public string Identification { get; set; } +} + +public class SetInspectionEnumValueDto +{ + [NotDefault] + public Guid TrialId { get; set; } + + [NotDefault] + public List AuditDataIds { get; set; } + + + +} + + +public class AccessToDialogueInDto +{ + public Guid Id { get; set; } + + public AccessToDialogueEnum Type { get; set; } + + public DateTime Createtime { get; set; } +} + + +public class AccessToDialogueOutDto +{ + public string CreateUserName { get; set; } + + public string TalkContent { get; set; } + + public DateTime CreateTime { get; set; } + + public bool IsTitle { get; set; } +} + +public enum AccessToDialogueEnum +{ + /// + /// + /// + Question = 0, + + /// + /// һԺ˲ + /// + Consistency = 1, +} + +/// +/// +/// +public class CopyFrontAuditConfigItemDto +{ + public Guid ParentId { get; set; } + + public Guid ChildId { get; set; } +} + + + + diff --git a/IRaCIS.Core.Application/Service/Inspection/FrontAuditConfigService.cs b/IRaCIS.Core.Application/Service/Inspection/FrontAuditConfigService.cs index e48d7d026..8f9b8b527 100644 --- a/IRaCIS.Core.Application/Service/Inspection/FrontAuditConfigService.cs +++ b/IRaCIS.Core.Application/Service/Inspection/FrontAuditConfigService.cs @@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.ViewModel; using MassTransit; -using IRaCIS.Core.Infra.EFCore.Common.Dto; using Microsoft.Data.SqlClient; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -19,6 +18,7 @@ using IRaCIS.Application.Contracts; using IRaCIS.Core.Infrastructure.Extention; using Microsoft.EntityFrameworkCore; using Npgsql; +using IRaCIS.Core.Infra.EFCore.Common; namespace IRaCIS.Core.Application.Service { diff --git a/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs b/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs index 446560df0..6a211b97c 100644 --- a/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs +++ b/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs @@ -1,6 +1,5 @@ using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Share; -using IRaCIS.Core.Infra.EFCore.Common.Dto; using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure.Extention; using MassTransit; diff --git a/IRaCIS.Core.Infra.EFCore/Common/Dto/SetDictionaryValueDto.cs b/IRaCIS.Core.Infra.EFCore/Common/AuditingDto.cs similarity index 65% rename from IRaCIS.Core.Infra.EFCore/Common/Dto/SetDictionaryValueDto.cs rename to IRaCIS.Core.Infra.EFCore/Common/AuditingDto.cs index 627e7e891..ced7f0951 100644 --- a/IRaCIS.Core.Infra.EFCore/Common/Dto/SetDictionaryValueDto.cs +++ b/IRaCIS.Core.Infra.EFCore/Common/AuditingDto.cs @@ -7,20 +7,8 @@ using System.ComponentModel.DataAnnotations; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Share; -namespace IRaCIS.Core.Infra.EFCore.Common.Dto +namespace IRaCIS.Core.Infra.EFCore.Common { - public class SetInspectionEnumValueDto - { - [NotDefault] - public Guid TrialId { get; set; } - - [NotDefault] - public List AuditDataIds { get; set; } - - - - } - public class SetInspectionEnumDataDto { public Guid Id { get; set; } @@ -34,8 +22,6 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto public Guid? ObjectRelationParentId2 { get; set; } public Guid? ObjectRelationParentId3 { get; set; } - - /// /// 批次Id /// @@ -46,69 +32,6 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto - - public class AddInterface - { - public Guid ParentId { get; set; } - - public List Names { get; set; } - } - - public class AccessToDialogueInDto - { - public Guid Id { get; set; } - - public AccessToDialogueEnum Type { get; set; } - - public DateTime Createtime { get; set; } - } - - - public class AccessToDialogueOutDto - { - public string CreateUserName { get; set; } - - public string TalkContent { get; set; } - - public DateTime CreateTime { get; set; } - - public bool IsTitle { get; set; } - } - - public enum AccessToDialogueEnum - { - /// - /// 质疑 - /// - Question = 0, - - /// - /// 一致性核查 - /// - Consistency = 1, - } - - /// - /// 复制 - /// - public class CopyFrontAuditConfigItemDto - { - public Guid ParentId { get; set; } - - public Guid ChildId { get; set; } - } - - - public class UnitData - { - /// - /// 单位 - /// - public ValueUnit? Unit { get; set; } - - public string UnitName { get; set; } - } - /// /// 稽查数据 /// @@ -120,20 +43,32 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto public object CommonData { get; set; } } + + public class UnitData + { + /// + /// 单位 + /// + public ValueUnit? Unit { get; set; } + + public string UnitName { get; set; } + } + + public class VisitTaskAuditingDto { - public string UserRealName { get; set; } + public string UserRealName { get; set; } - public string SubjectCode { get; set; } + public string SubjectCode { get; set; } - public string R1 { get; set; } + public string R1 { get; set; } - public string R2 { get; set; } + public string R2 { get; set; } - public string CutOffVisitName { get; set; } + public string CutOffVisitName { get; set; } - public string SelectResult { get; set; } - } + public string SelectResult { get; set; } + } public class InspectionConvertDTO : DataInspection { /// @@ -172,10 +107,10 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto public string BlindName { get; set; } = string.Empty; - /// - /// 标识操作 是否区分接口 - /// - public bool IsDistinctionInterface=true; + /// + /// 标识操作 是否区分接口 + /// + public bool IsDistinctionInterface = true; public bool IsSelfDefine = false; @@ -195,9 +130,7 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto /// public Guid? TrialId { get; set; } - public Guid? TrialSiteId { get;set; } - - + public Guid? TrialSiteId { get; set; } /// /// 受试者 @@ -238,20 +171,6 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto /// public string SubjectVisitName { get; set; } - - - // /// - ///// 创建人名称 - ///// - //public string CreateUserName { get; set; } - - - // /// - // /// 角色名称 - // /// - // public string RoleName { get; set; } - - } public class SetInspectionEnum @@ -268,9 +187,4 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto public string Remake { get; set; } } - - - - - } diff --git a/IRaCIS.Core.Infra.EFCore/Common/Dto/DateDto.cs b/IRaCIS.Core.Infra.EFCore/Common/Dto/DateDto.cs deleted file mode 100644 index b102f4bf1..000000000 --- a/IRaCIS.Core.Infra.EFCore/Common/Dto/DateDto.cs +++ /dev/null @@ -1,23 +0,0 @@ -using IRaCIS.Core.Domain.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; - -namespace IRaCIS.Core.Infra.EFCore.Common.Dto -{ - public class DateDto - { - public string Code { get; set; } - - public string DateType { get; set; } - - public string Identification { get; set; } - } - public class ForeignKey - { - public string Text { get; set; } - } -} diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index bdf501aa4..47b7795e9 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -16,7 +16,6 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.ValueGeneration; using UserTypeGroup = IRaCIS.Core.Domain.Models.UserTypeGroup; using IRaCIS.Core.Infra.EFCore.Common; -using IRaCIS.Core.Infra.EFCore.Common.Dto; using Microsoft.Identity.Client; using EntityFramework.Exceptions.Common; using System.Data; diff --git a/IRaCIS.Core.Test/LiquidTemplate/EntityService.liquid b/IRaCIS.Core.Test/LiquidTemplate/EntityService.liquid index 479a9dc62..420282f76 100644 --- a/IRaCIS.Core.Test/LiquidTemplate/EntityService.liquid +++ b/IRaCIS.Core.Test/LiquidTemplate/EntityService.liquid @@ -11,62 +11,61 @@ using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Infrastructure.Extention; using System.Threading.Tasks; using IRaCIS.Core.Infra.EFCore; -namespace IRaCIS.Core.Application.Service -{ +namespace IRaCIS.Core.Application.Service; + +[ ApiExplorerSettings(GroupName = "Test")] +public class {{TableName}}Service(IRepository<{{TableName}}> {{LowercaseRepositoryName}}): BaseService, I{{TableName}}Service +{ - [ ApiExplorerSettings(GroupName = "Test")] - public class {{TableName}}Service(IRepository<{{TableName}}> {{LowercaseRepositoryName}}): BaseService, I{{TableName}}Service - { - - {% if IsPaged %} - [HttpPost] - public async Task> Get{{TableName}}List({{TableNameQuery}} inQuery) - { + {% if IsPaged %} + [HttpPost] + public async Task> Get{{TableName}}List({{TableNameQuery}} inQuery) + { - var {{LowercaseQueryableName}} ={{LowercaseRepositoryName}} - .ProjectTo<{{TableNameView}}>(_mapper.ConfigurationProvider); + var {{LowercaseQueryableName}} ={{LowercaseRepositoryName}} + .ProjectTo<{{TableNameView}}>(_mapper.ConfigurationProvider); - var pageList= await {{LowercaseQueryableName}}.ToPagedListAsync(inQuery); + var pageList= await {{LowercaseQueryableName}}.ToPagedListAsync(inQuery); - return pageList; - } - {% else %} - [HttpPost] - public async Task> Get{{TableName}}List({{TableNameQuery}} inQuery) - { + return pageList; + } + {% else %} + [HttpPost] + public async Task> Get{{TableName}}List({{TableNameQuery}} inQuery) + { - var {{LowercaseQueryableName}} ={{LowercaseRepositoryName}} - .ProjectTo<{{TableNameView}}>(_mapper.ConfigurationProvider); + var {{LowercaseQueryableName}} ={{LowercaseRepositoryName}} + .ProjectTo<{{TableNameView}}>(_mapper.ConfigurationProvider); - return await {{LowercaseQueryableName}}.ToListAsync(); - } - {% endif %} + return await {{LowercaseQueryableName}}.ToListAsync(); + } + {% endif %} - public async Task AddOrUpdate{{TableName}}({{TableName}}AddOrEdit addOrEdit{{TableName}}) - { - // 在此处拷贝automapper 映射 + public async Task AddOrUpdate{{TableName}}({{TableName}}AddOrEdit addOrEdit{{TableName}}) + { + // 在此处拷贝automapper 映射 - CreateMap<{{TableName}}, {{TableNameView}}>(); - CreateMap<{{TableName}},{{TableNameAddOrEdit}}>().ReverseMap(); + CreateMap<{{TableName}}, {{TableNameView}}>(); + CreateMap<{{TableName}},{{TableNameAddOrEdit}}>().ReverseMap(); - var entity = await {{LowercaseRepositoryName}}.InsertOrUpdateAsync(addOrEdit{{TableName}}, true); + var entity = await {{LowercaseRepositoryName}}.InsertOrUpdateAsync(addOrEdit{{TableName}}, true); - return ResponseOutput.Ok(entity.Id.ToString()); + return ResponseOutput.Ok(entity.Id.ToString()); - } + } - [HttpDelete("{{ '{' }}{{LowercaseTableNameId}}:guid{{ '}' }}")] - public async Task Delete{{TableName}}(Guid {{LowercaseTableNameId}}) - { - var success = await _<#=char.ToLower(tableName[0]) + tableName.Substring(1)#>Repository.DeleteFromQueryAsync(t => t.Id == {{LowercaseTableNameId}},true); - return ResponseOutput.Ok(); - } + [HttpDelete("{{ '{' }}{{LowercaseTableNameId}}:guid{{ '}' }}")] + public async Task Delete{{TableName}}(Guid {{LowercaseTableNameId}}) + { + var success = await _<#=char.ToLower(tableName[0]) + tableName.Substring(1)#>Repository.DeleteFromQueryAsync(t => t.Id == {{LowercaseTableNameId}},true); + return ResponseOutput.Ok(); + } + +} + - - } -} diff --git a/IRaCIS.Core.Test/LiquidTemplate/EntityViewModel.liquid b/IRaCIS.Core.Test/LiquidTemplate/EntityViewModel.liquid index 0a5902e97..87f4d4f2d 100644 --- a/IRaCIS.Core.Test/LiquidTemplate/EntityViewModel.liquid +++ b/IRaCIS.Core.Test/LiquidTemplate/EntityViewModel.liquid @@ -7,38 +7,38 @@ using System; using IRaCIS.Core.Domain.Share; using System.Collections.Generic; -namespace IRaCIS.Core.Application.ViewModel +namespace IRaCIS.Core.Application.ViewModel; + +public class {{ TableNameView }} : {{ TableNameAddOrEdit }} { - public class {{ TableNameView }} : {{ TableNameAddOrEdit }} - { - {% for field in ViewListFieldList %} - public {{ field.CSharpType }} {{ field.FieldName }} { get; set; } - {% endfor %} - } + {% for field in ViewListFieldList %} + public {{ field.CSharpType }} {{ field.FieldName }} { get; set; } + {% endfor %} +} - public class {{ TableNameAddOrEdit }} - { - {%- for field in AddOrUpdateFieldList -%} - {% if field.IsPrimarykey %} - public {{ field.CSharpType }}? {{ field.FieldName }} { get; set; } - {% else %} - public {{ field.CSharpType }} {{ field.FieldName }} { get; set; } - {% endif %} - {%- endfor -%} - } +public class {{ TableNameAddOrEdit }} +{ + {%- for field in AddOrUpdateFieldList -%} + {% if field.IsPrimarykey %} + public {{ field.CSharpType }}? {{ field.FieldName }} { get; set; } + {% else %} + public {{ field.CSharpType }} {{ field.FieldName }} { get; set; } + {% endif %} + {%- endfor -%} +} - public class {{ TableNameQuery }} - { - {%- for field in QueryListFieldList -%} - {% if field.IsNullable and field.IsCSharpString == false %} - public {{ field.CSharpType }} {{ field.FieldName }} { get; set; } - {% else %} - public {{ field.CSharpType }}? {{ field.FieldName }} { get; set; } - {% endif %} - {%- endfor -%} - } +public class {{ TableNameQuery }} +{ + {%- for field in QueryListFieldList -%} + {% if field.IsNullable and field.IsCSharpString == false %} + public {{ field.CSharpType }} {{ field.FieldName }} { get; set; } + {% else %} + public {{ field.CSharpType }}? {{ field.FieldName }} { get; set; } + {% endif %} + {%- endfor -%} } + diff --git a/IRaCIS.Core.Test/LiquidTemplate/IEntityService.liquid b/IRaCIS.Core.Test/LiquidTemplate/IEntityService.liquid index 9b22f711c..cd38ad0fc 100644 --- a/IRaCIS.Core.Test/LiquidTemplate/IEntityService.liquid +++ b/IRaCIS.Core.Test/LiquidTemplate/IEntityService.liquid @@ -8,18 +8,18 @@ using System; using IRaCIS.Core.Infrastructure.Extention; using System.Threading.Tasks; using IRaCIS.Core.Application.ViewModel; -namespace IRaCIS.Core.Application.Interfaces -{ - public interface I{{TableName}}Service - { - {% if IsPaged %} - Task> Get{{TableName}}List({{TableNameQuery}} inQuery); - {% else %} - Task> Get{{TableName}}List({{TableNameQuery}} inQuery); - {% endif %} - Task AddOrUpdate{{TableName}}({{TableNameAddOrEdit}} addOrEdit{{TableName}}); +namespace IRaCIS.Core.Application.Interfaces; - Task Delete{{TableNameView}}(Guid {{LowercaseTableNameId}}); - } +public interface I{{TableName}}Service +{ + {% if IsPaged %} + Task> Get{{TableName}}List({{TableNameQuery}} inQuery); + {% else %} + Task> Get{{TableName}}List({{TableNameQuery}} inQuery); + {% endif %} + Task AddOrUpdate{{TableName}}({{TableNameAddOrEdit}} addOrEdit{{TableName}}); + + Task Delete{{TableNameView}}(Guid {{LowercaseTableNameId}}); } + From 961ca49f769f50971a61d5d9ffe102a55aa9472b Mon Sep 17 00:00:00 2001 From: hang <87227557@qq.com> Date: Tue, 17 Sep 2024 12:24:51 +0800 Subject: [PATCH 42/59] =?UTF-8?q?=E6=95=B4=E7=90=86=E4=BB=93=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repository/ICommandRepository.cs | 42 +++--- .../Repository/Repository.cs | 140 ++++++------------ 2 files changed, 62 insertions(+), 120 deletions(-) diff --git a/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs b/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs index aa3bfc347..68e05af17 100644 --- a/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs +++ b/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs @@ -22,19 +22,6 @@ namespace IRaCIS.Core.Infra.EFCore Task UpdateFromDTOAsync(TFrom from, bool autoSave = false, bool ignoreDtoNullProperty = true, params EntityVerifyExp[] verify); - /// - /// 空和Empty不更新 - /// - /// - /// - /// - /// - /// - /// - Task NotUpdateEmptyAsync(TFrom from, bool autoSave = false, bool ignoreDtoNullProperty = true, params EntityVerifyExp[] verify); - - - #region EF 跟踪方式删除 (先查询完整实体,再删除) /// 批量删除,EF跟踪方式(所有查询出来,再删除 浪费性能,但是稽查 或者触发某些操作时,需要知道数据库实体信息 不可避免用这种) @@ -65,15 +52,7 @@ namespace IRaCIS.Core.Infra.EFCore #endregion - #region EF跟踪方式 部分字段更新,不会去数据库查询完整实体 - /// EF跟踪方式 生成 部分字段立即更新,不会去数据库查询完整的实体 - - Task UpdatePartialNowNoQueryAsync(Guid id, Expression> updateFactory, params EntityVerifyExp[] verify); - - /// EF跟踪方式 生成 部分字段更新,不会去数据库查询完整的实体 - Task UpdatePartialNoQueryAsync(Guid id, Expression> updateFactory, bool autoSave = false, params EntityVerifyExp[] verify); - #endregion #region 不走EF 跟踪机制,直接生成sql 批量更新或者删除 @@ -88,10 +67,18 @@ namespace IRaCIS.Core.Infra.EFCore #endregion + #region 不常用 + //Task UpdatePartialFieldsAsync(TEntity entity, string[] propertyNames, bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify); + + /// EF跟踪方式 生成 部分字段立即更新,不会去数据库查询完整的实体,不符合我们稽查的需求 + + Task UpdatePartialNowNoQueryAsync(Guid id, Expression> updateFactory, params EntityVerifyExp[] verify); + + /// EF跟踪方式 生成 部分字段更新,不会去数据库查询完整的实体,不符合我们稽查的需求 + //Task UpdatePartialNoQueryAsync(Guid id, Expression> updateFactory, bool autoSave = false, params EntityVerifyExp[] verify); + #endregion - /// 不常用 暂时废弃 - Task UpdatePartialFieldsAsync(TEntity entity, string[] propertyNames, bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify); } @@ -111,13 +98,18 @@ namespace IRaCIS.Core.Infra.EFCore Task FirstAsync(Expression> exp = null, bool isTracking = false,bool ignoreQueryFilters = false); /// - ///跟踪 查询单个实体,会出现NUll + ///跟踪 查询单个实体,会出现NUll 可以直接在实体对属性进行修改,然后save /// /// /// /// Task FirstOrDefaultAsync(Expression> exp = null, bool ignoreQueryFilters = false); - + /// + /// 不跟踪,查询单个实体 会出现NUll 配合 UpdateAsync 可以生成部分字段更新到数据库 + /// + /// + /// + /// Task FirstOrDefaultNoTrackingAsync(Expression> exp = null, bool ignoreQueryFilters = false); Task AnyAsync(Expression> exp, bool ignoreQueryFilters = false); diff --git a/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs b/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs index af822f27b..9b7b7c487 100644 --- a/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs +++ b/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs @@ -90,8 +90,7 @@ namespace IRaCIS.Core.Infra.EFCore #endregion - #region 异步 EF 跟踪 部分字段更新 - + #region 异步 EF 跟踪 自动生成 更新 和删除语句 /// 用前端传递的视图模型字段,更新,同时返回数据库该条记录的原始信息,方便对比某些字段是否更改,进行相应的逻辑操作 @@ -108,7 +107,7 @@ namespace IRaCIS.Core.Infra.EFCore if (dbEntity == null) { - + throw new BusinessValidationFailedException(_localizer["Repository_UpdateError"]); } @@ -139,95 +138,6 @@ namespace IRaCIS.Core.Infra.EFCore } - public async Task NotUpdateEmptyAsync(TFrom from, bool autoSave = false, bool ignoreDtoNullProperty = true, params EntityVerifyExp[] verify) - { - - var entity = _mapper.Map(from); - - //await EntityVerifyAsync(false, verify, entity.Id); - - await _dbContext.EntityVerifyAsync(false, verify, entity.Id); - - var dbEntity = await _dbSet.IgnoreQueryFilters().FirstOrDefaultAsync(t => t.Id == entity.Id).ConfigureAwait(false); - - if (dbEntity == null) - { - - throw new BusinessValidationFailedException(_localizer["Repository_UpdateError"]); - } - - var dbBeforEntity = dbEntity.Clone(); - - - _mapper.Map(from, dbEntity); - - - //为null 或者 string.empty 不更新 - if (ignoreDtoNullProperty) - { - var dbEntityProp = typeof(TEntity).GetProperties(); - foreach (var propertyInfo in from.GetType().GetProperties()) - { - if ((propertyInfo.GetValue(from) == null|| propertyInfo.GetValue(from).ToString()==string.Empty) && dbEntityProp.Any(t => t.Name == propertyInfo.Name)) - { - _dbContext.Entry(dbEntity).Property(propertyInfo.Name).IsModified = false; - } - } - } - - await SaveChangesAsync(autoSave); - - - return dbBeforEntity; - } - - - /// EF跟踪方式 生成 部分字段更新, 跟踪的实体仅有修改的属性的值有具体意义,没有从数据库查询完整的实体 - - public async Task UpdatePartialNoQueryAsync(Guid id, Expression> updateFactory, bool autoSave = false, params EntityVerifyExp[] verify) - { - - await _dbContext.EntityVerifyAsync(false, verify, id); - - var entity = new TEntity() { Id = id }; - - _dbContext.EntityModifyPartialFiled(entity, updateFactory); - - - await SaveChangesAsync(autoSave); - - } - - - /// EF跟踪方式 生成 部分字段立即更新,默认会去处理更新更新人 更新时间 - public async Task UpdatePartialNowNoQueryAsync(Guid id, Expression> updateFactory, - params EntityVerifyExp[] verify) - { - await _dbContext.EntityVerifyAsync(false, verify, id); - - var entity = new TEntity() { Id = id }; - - _dbContext.EntityModifyPartialFiled(entity, updateFactory); - - return await SaveChangesAsync(true); - } - - - - - #endregion - - - #region 异步 EF 跟踪 自动生成 更新 和删除语句 - - - /// EF跟踪方式 更新,全字段更新 不好 - public async Task UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) - { - _dbSet.Update(entity); - - return await SaveChangesAsync(autoSave); - } /// EF跟踪方式 外层先有查询好的完成实体,再更新部分字段 稽查的时候需要完整的实体信息 @@ -349,7 +259,6 @@ namespace IRaCIS.Core.Infra.EFCore #endregion - #region 不走EF 跟踪机制的删除 更新 以及批量操作 /// 批量删除,相当于原生sql, 没用EF跟踪方式(所有查询出来,再删除 浪费性能) @@ -370,6 +279,8 @@ namespace IRaCIS.Core.Infra.EFCore } + /// EF core 7+ 原生批量更新方法 + public async Task ExecuteUpdateAsync(Expression> where, Expression, SetPropertyCalls>> setPropertyCalls) { return await _dbContext.ExecuteUpdateAsync(where, setPropertyCalls); @@ -378,8 +289,6 @@ namespace IRaCIS.Core.Infra.EFCore #endregion - - #region 保存 、忽略 、验证 public async Task InsertOrUpdateAsync(TFrom from, bool autoSave = false, params EntityVerifyExp[] verify) { @@ -458,6 +367,47 @@ namespace IRaCIS.Core.Infra.EFCore #endregion #region 不常用 + + + /// EF跟踪方式 更新,全字段更新 不好 + public async Task UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) + { + _dbSet.Update(entity); + + return await SaveChangesAsync(autoSave); + } + + + + /// EF跟踪方式 生成 部分字段立即更新,默认会去处理更新更新人 更新时间 + public async Task UpdatePartialNowNoQueryAsync(Guid id, Expression> updateFactory, + params EntityVerifyExp[] verify) + { + await _dbContext.EntityVerifyAsync(false, verify, id); + + var entity = new TEntity() { Id = id }; + + _dbContext.EntityModifyPartialFiled(entity, updateFactory); + + return await SaveChangesAsync(true); + } + + /// EF跟踪方式 生成 部分字段更新, 跟踪的实体仅有修改的属性的值有具体意义,没有从数据库查询完整的实体 + + public async Task UpdatePartialNoQueryAsync(Guid id, Expression> updateFactory, bool autoSave = false, params EntityVerifyExp[] verify) + { + + await _dbContext.EntityVerifyAsync(false, verify, id); + + var entity = new TEntity() { Id = id }; + + _dbContext.EntityModifyPartialFiled(entity, updateFactory); + + + await SaveChangesAsync(autoSave); + + } + /// EF跟踪方式 生成 部分字段更新 (只更新传递的字段名 new[] {nameof(User.Name), nameof(User.Age)) public async Task UpdatePartialFieldsAsync(TEntity entity, string[] propertyNames, bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify) From 5990477fdc6cb14a4c8b9bcf214ef49fdba04fc8 Mon Sep 17 00:00:00 2001 From: hang <87227557@qq.com> Date: Tue, 17 Sep 2024 12:26:18 +0800 Subject: [PATCH 43/59] =?UTF-8?q?guid=20=E7=94=9F=E6=88=90=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Context/ValueGenerator/MySequentialGuidValueGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Infra.EFCore/Context/ValueGenerator/MySequentialGuidValueGenerator.cs b/IRaCIS.Core.Infra.EFCore/Context/ValueGenerator/MySequentialGuidValueGenerator.cs index 782a28300..f7aa2956c 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/ValueGenerator/MySequentialGuidValueGenerator.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/ValueGenerator/MySequentialGuidValueGenerator.cs @@ -10,7 +10,7 @@ namespace IRaCIS.Core.Infra.EFCore { public override Guid Next(EntityEntry entry) { - return NewId.NextGuid(); + return NewId.NextSequentialGuid(); } public override bool GeneratesTemporaryValues => false; } From ab68a63bdd51d56ac729f23d456bacf25cb48da4 Mon Sep 17 00:00:00 2001 From: hang <87227557@qq.com> Date: Tue, 17 Sep 2024 14:26:12 +0800 Subject: [PATCH 44/59] =?UTF-8?q?=E5=A2=9E=E5=8A=A0codefirst=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS - Backup.Core.API.csproj | 107 -- IRaCIS.Core.API/IRaCIS.Core.API.csproj | 6 + IRaCIS.Core.API/IRaCIS.Core.API.xml | 5 - .../TimeZoneAdjustmentMiddleware.cs | 118 --- IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs | 5 +- IRaCIS.Core.API/appsettings.json | 35 - IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 | 19 + .../Convention/DecimalPrecisionConvention.cs | 40 + .../DefaultStringLengthConvention .cs | 56 + .../NoForeignKeyMigrationsSqlGenerator.cs | 23 + .../Context/DbContextExt.cs | 459 ++++---- .../Context/IRaCISDBContext.cs | 982 +++++++++--------- .../Context/IRaCISDBContextFactory.cs | 25 + .../MySequentialGuidValueGenerator.cs | 18 +- .../IRaCIS.Core.Infra.EFCore.csproj | 9 + .../CodeFirstTest/CodeFirst使用说明 | 2 +- .../Convention/MaxStringLengthConvention .cs | 14 +- .../CodeFirstTest/PGSQL/PGContext.cs | 2 +- IRaCIS.Core.Test/IRaCIS.Core.Test.csproj | 7 +- IRaCIS.Core.Test/模板使用说明 | 2 +- 20 files changed, 928 insertions(+), 1006 deletions(-) delete mode 100644 IRaCIS.Core.API/IRaCIS - Backup.Core.API.csproj delete mode 100644 IRaCIS.Core.API/Middleware/TimeZoneAdjustmentMiddleware.cs create mode 100644 IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 create mode 100644 IRaCIS.Core.Infra.EFCore/Context/Convention/DecimalPrecisionConvention.cs create mode 100644 IRaCIS.Core.Infra.EFCore/Context/Convention/DefaultStringLengthConvention .cs create mode 100644 IRaCIS.Core.Infra.EFCore/Context/Convention/NoForeignKeyMigrationsSqlGenerator.cs create mode 100644 IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContextFactory.cs diff --git a/IRaCIS.Core.API/IRaCIS - Backup.Core.API.csproj b/IRaCIS.Core.API/IRaCIS - Backup.Core.API.csproj deleted file mode 100644 index b14f8c9bf..000000000 --- a/IRaCIS.Core.API/IRaCIS - Backup.Core.API.csproj +++ /dev/null @@ -1,107 +0,0 @@ - - - - net6.0 - false - 354572d4-9e15-4099-807c-63a2d29ff9f2 - default - Linux - - - - .\IRaCIS.Core.API.xml - 1701;1702;1591; - ..\bin\ - - - - bin\Release\IRaCIS.Core.API.xml - bin\Release\ - 1701;1702;1591 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Client - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - - - - - - - - - - - - Always - - - - - - - diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj index d73c5fbc1..1a7f28ec4 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj +++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj @@ -96,6 +96,12 @@ + + + Always + + + diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.xml b/IRaCIS.Core.API/IRaCIS.Core.API.xml index 6573bf84a..4402bc0b9 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.xml +++ b/IRaCIS.Core.API/IRaCIS.Core.API.xml @@ -375,11 +375,6 @@ 序列化成员 - - - 废弃,没用 - - 对称可逆加密 diff --git a/IRaCIS.Core.API/Middleware/TimeZoneAdjustmentMiddleware.cs b/IRaCIS.Core.API/Middleware/TimeZoneAdjustmentMiddleware.cs deleted file mode 100644 index c3c71da2a..000000000 --- a/IRaCIS.Core.API/Middleware/TimeZoneAdjustmentMiddleware.cs +++ /dev/null @@ -1,118 +0,0 @@ -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Primitives; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading.Tasks; - -/// -/// 废弃,没用 -/// -public class TimeZoneAdjustmentMiddleware -{ - private readonly RequestDelegate _next; - - public TimeZoneAdjustmentMiddleware(RequestDelegate next) - { - _next = next; - } - - public async Task Invoke(HttpContext context) - { - if (string.IsNullOrEmpty(context.Request.ContentType)) - { - // 请求没有内容体,可能是一个没有请求体的请求,比如 GET 请求 - await _next(context); - return; - } - - - var timeZoneId = "Asia/Shanghai"; // 客户端默认时区 - - var timeZoneIdHeaderValue = context.Request.Headers["TimeZoneId"]; - - if (!string.IsNullOrEmpty(timeZoneIdHeaderValue)) - { - timeZoneId = timeZoneIdHeaderValue; - } - - var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); - - - - // 处理 JSON 请求体中的时间字段 - if (context.Request.ContentType.StartsWith("application/json")) - { - var requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync(); - - // 使用 JSON.NET 或 System.Text.Json 解析 JSON 请求体 - // 假设请求体中有一个名为 "dateTime" 的时间字段 - dynamic jsonData = JsonConvert.DeserializeObject(requestBody); - - if (jsonData.dateTime != null) - { - if (DateTime.TryParse((string)jsonData.dateTime, out DateTime dateTime)) - { - // 将 JSON 请求体中的时间字段转换为服务器时区的时间 - var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone); - jsonData.dateTime = serverTime; - } - } - - // 将修改后的 JSON 请求体重新写入请求流中 - var jsonBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jsonData)); - context.Request.Body = new MemoryStream(jsonBytes); - context.Request.ContentLength = jsonBytes.Length; - } - - - // 处理 URL 表单参数 - var modifiedQuery = new Dictionary(); - - foreach (var key in context.Request.Query.Keys) - { - if (DateTime.TryParse(context.Request.Query[key], out DateTime dateTime)) - { - // 将 URL 表单参数中的时间转换为服务器时区的时间 - var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone); - modifiedQuery[key] = new StringValues(serverTime.ToString()); - } - else - { - modifiedQuery[key] = context.Request.Query[key]; - } - } - - context.Request.Query = new QueryCollection(modifiedQuery); - - // 处理Form请求体中的参数 - if (context.Request.HasFormContentType) - { - var modifiedForm = new Dictionary(); - - foreach (var key in context.Request.Form.Keys) - { - if (DateTime.TryParse(context.Request.Form[key], out DateTime dateTime)) - { - // 将请求体中的时间转换为服务器时区的时间 - var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone); - modifiedForm[key] = new StringValues(serverTime.ToString()); - } - else - { - modifiedForm[key] = context.Request.Form[key]; - } - } - - var newFormCollection = new FormCollection(modifiedForm); - - // 将新的表单集合设置回请求对象 - context.Request.Form = newFormCollection; - } - - await _next(context); - } - -} diff --git a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs index a6e0352d5..176ea178c 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs @@ -8,9 +8,11 @@ using Medallion.Threading; using Medallion.Threading.SqlServer; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using StackExchange.Redis; namespace IRaCIS.Core.API @@ -46,10 +48,11 @@ namespace IRaCIS.Core.API else { options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure()); - } + //迁移的时候,不生成外键 + options.ReplaceService(); options.UseLoggerFactory(logFactory); diff --git a/IRaCIS.Core.API/appsettings.json b/IRaCIS.Core.API/appsettings.json index 75bc653af..dec14286d 100644 --- a/IRaCIS.Core.API/appsettings.json +++ b/IRaCIS.Core.API/appsettings.json @@ -43,40 +43,6 @@ } ] }, - "easycaching": { - "inmemory": { - "MaxRdSecond": 120, - "EnableLogging": false, - "LockMs": 5000, - "SleepMs": 300, - "DBConfig": { - "SizeLimit": 10000, - "ExpirationScanFrequency": 60, - "EnableReadDeepClone": true, - "EnableWriteDeepClone": false - } - }, - "redis": { - "MaxRdSecond": 120, - "EnableLogging": false, - "LockMs": 5000, - "SleepMs": 300, - "dbconfig": { - "Password": "xc@123456", - "IsSsl": false, - "SslHost": null, - "ConnectionTimeout": 5000, - "AllowAdmin": true, - "Endpoints": [ - { - "Host": "47.117.164.182", - "Port": 6379 - } - ], - "Database": 0 - } - } - }, "IRaCISImageStore": { "SwitchingMode": "RemainingDiskCapacity", "SwitchingRatio": 80, @@ -93,7 +59,6 @@ "DefaultPassword": "123456", "ImageShareExpireDays": 10 }, - "EncrypteResponseConfig": { "IsEnable": true, "ApiPathList": [ diff --git a/IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 b/IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 new file mode 100644 index 000000000..c5e75d12e --- /dev/null +++ b/IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 @@ -0,0 +1,19 @@ + + + +# ̨ʹ÷ʽ + +1Ǩļ +add-migration init -Context IRaCISDBContext + + + + + + +# ʹdotnet Ǩ + +# dotnet ef migrations add Ǩ -p Ŀ -c ݿ -o ǨļĿ¼ + +1Ǩļ +dotnet ef migrations add Initial -s IRaCIS.Core.API -p IRaCIS.Core.Infra.EFCore -c IRaCISDBContext -o CodeFirst_MSSQL/Migrations diff --git a/IRaCIS.Core.Infra.EFCore/Context/Convention/DecimalPrecisionConvention.cs b/IRaCIS.Core.Infra.EFCore/Context/Convention/DecimalPrecisionConvention.cs new file mode 100644 index 000000000..9b473d1cf --- /dev/null +++ b/IRaCIS.Core.Infra.EFCore/Context/Convention/DecimalPrecisionConvention.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Infra.EFCore; + + +public class DecimalPrecisionConvention : IModelFinalizingConvention +{ + private readonly int _precision; + private readonly int _scale; + + public DecimalPrecisionConvention(int precision, int scale) + { + _precision = precision; + _scale = scale; + } + + public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext context) + { + + foreach (var property in modelBuilder.Metadata.GetEntityTypes() + .SelectMany( + entityType => entityType.GetDeclaredProperties() + .Where( + property => property.ClrType == typeof(decimal) || property.ClrType == typeof(decimal?)))) + { + + + // 设置精度和小数位数 + property.SetPrecision(_precision); + property.SetScale(_scale); + } + } +} diff --git a/IRaCIS.Core.Infra.EFCore/Context/Convention/DefaultStringLengthConvention .cs b/IRaCIS.Core.Infra.EFCore/Context/Convention/DefaultStringLengthConvention .cs new file mode 100644 index 000000000..1e5845ef8 --- /dev/null +++ b/IRaCIS.Core.Infra.EFCore/Context/Convention/DefaultStringLengthConvention .cs @@ -0,0 +1,56 @@ +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using System; +using System.ComponentModel.DataAnnotations; +using System.Linq; + +namespace IRaCIS.Core.Infra.EFCore; + +/// +/// Efcore 最新支持批量配置字符串类型长度作为保底的 官网参考:https://learn.microsoft.com/zh-cn/ef/core/modeling/bulk-configuration#conventions +/// 设置不标注,默认长度,然后标注了与默认长度不一致,那么就是以标注的为准,同时如果标注了MaxLength ,对于mssql 那就是nvarcharMax,对于pgsql 就是text +/// +public class DefaultStringLengthConvention : IModelFinalizingConvention +{ + private readonly int _defaultLenth; + + public DefaultStringLengthConvention(int defaultLenth) + { + _defaultLenth = defaultLenth; + } + + public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext context) + { + foreach (var property in modelBuilder.Metadata.GetEntityTypes() + .SelectMany( + entityType => entityType.GetDeclaredProperties() + .Where( + property => property.ClrType == typeof(string)))) + { + + // 获取 MaxLength 特性 + var maxLengthAttribute = property.PropertyInfo?.GetCustomAttributes(typeof(MaxLengthAttribute), false) + .FirstOrDefault() as MaxLengthAttribute; + + // 获取 StringLength 特性 + var stringLengthAttribute = property.PropertyInfo?.GetCustomAttributes(typeof(StringLengthAttribute), false) + .FirstOrDefault() as StringLengthAttribute; + + // 输出调试信息,看看是哪种特性生效 + if (stringLengthAttribute != null) + { + //Console.WriteLine($"{property.Name}: StringLength({stringLengthAttribute.MaximumLength})"); + property.Builder.HasMaxLength(stringLengthAttribute.MaximumLength); + } + else if (maxLengthAttribute != null) + { + //Console.WriteLine($"{property.Name}: MaxLength (no specific length, allowing max)"); + } + else + { + //Console.WriteLine($"{property.Name}: Default length 200"); + property.Builder.HasMaxLength(_defaultLenth); + } + } + } +} diff --git a/IRaCIS.Core.Infra.EFCore/Context/Convention/NoForeignKeyMigrationsSqlGenerator.cs b/IRaCIS.Core.Infra.EFCore/Context/Convention/NoForeignKeyMigrationsSqlGenerator.cs new file mode 100644 index 000000000..7603b8e06 --- /dev/null +++ b/IRaCIS.Core.Infra.EFCore/Context/Convention/NoForeignKeyMigrationsSqlGenerator.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations.Operations; + +namespace IRaCIS.Core.Infra.EFCore; + + +/// +/// 迁移的时候,忽略显示外键的建立,增加灵活性,同时为了兼容之前dbfirst 一个字段关联多个表 +/// +public class NoForeignKeyMigrationsSqlGenerator : MigrationsSqlGenerator +{ + public NoForeignKeyMigrationsSqlGenerator( + MigrationsSqlGeneratorDependencies dependencies) : base(dependencies) + { + } + + protected override void Generate(Microsoft.EntityFrameworkCore.Migrations.Operations.CreateTableOperation operation, IModel? model, MigrationCommandListBuilder builder, bool terminate = true) + { + operation.ForeignKeys.Clear(); + base.Generate(operation, model, builder, terminate); + } +} diff --git a/IRaCIS.Core.Infra.EFCore/Context/DbContextExt.cs b/IRaCIS.Core.Infra.EFCore/Context/DbContextExt.cs index 0eb9ee82a..88d80e112 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/DbContextExt.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/DbContextExt.cs @@ -5,246 +5,245 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; -namespace IRaCIS.Core.Infra.EFCore +namespace IRaCIS.Core.Infra.EFCore; + +public static class DbContextExt { - public static class DbContextExt + + /// + /// 获取变化的实体信息 + /// + /// + /// + /// + public static IEnumerable GetChanges(this DbContext db) { - - /// - /// 获取变化的实体信息 - /// - /// - /// - /// - public static IEnumerable GetChanges(this DbContext db) + return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified && e.Entity is T).Select(e => { - return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified && e.Entity is T).Select(e => + var originalObject = e.OriginalValues.ToObject(); + var currentObject = e.CurrentValues.ToObject(); + return new ChangeEntry { - var originalObject = e.OriginalValues.ToObject(); - var currentObject = e.CurrentValues.ToObject(); - return new ChangeEntry + EntityState = e.State, + Entity = e.Entity, + EntityType = e.OriginalValues.EntityType.ClrType, + ChangeProperties = e.OriginalValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(originalObject))).Zip(e.CurrentValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(currentObject))), (t1, t2) => new ChangePropertyInfo() { - EntityState = e.State, - Entity = e.Entity, - EntityType = e.OriginalValues.EntityType.ClrType, - ChangeProperties = e.OriginalValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(originalObject))).Zip(e.CurrentValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(currentObject))), (t1, t2) => new ChangePropertyInfo() - { - PropertyInfo = t1.Property.PropertyInfo, - OriginalValue = t1.Value, - CurrentValue = t2.Value, - IsPrimaryKey = t1.Property.IsPrimaryKey(), - IsForeignKey = t1.Property.IsForeignKey() - }).Where(t => Comparer.Default.Compare(t.OriginalValue, t.CurrentValue) != 0).ToList() - }; - }); - } - - - - /// - /// 获取变化的实体信息 - /// - /// - /// - public static IEnumerable GetChanges(this DbContext db) - { - return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified).Select(e => - { - var originalObject = e.OriginalValues.ToObject(); - var currentObject = e.CurrentValues.ToObject(); - return new ChangeEntry() - { - EntityState = e.State, - Entity = e.Entity, - EntityType = e.OriginalValues.EntityType.ClrType, - ChangeProperties = e.OriginalValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(originalObject))).Zip(e.CurrentValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(currentObject))), (t1, t2) => new ChangePropertyInfo() - { - PropertyInfo = t1.Property.PropertyInfo, - OriginalValue = t1.Value, - CurrentValue = t2.Value, - IsPrimaryKey = t1.Property.IsPrimaryKey(), - IsForeignKey = t1.Property.IsForeignKey(), - }).Where(t => Comparer.Default.Compare(t.OriginalValue, t.CurrentValue) != 0).ToList() - }; - }); - } - - /// - /// 获取添加的实体信息 - /// - /// - /// - /// - public static IEnumerable GetAdded(this DbContext db) - { - return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Added && e.Entity is T).Select(e => - { - var currentObject = e.CurrentValues.ToObject(); - return new ChangeEntry - { - EntityState = e.State, - Entity = e.Entity, - EntityType = e.CurrentValues.EntityType.ClrType, - ChangeProperties = e.CurrentValues.Properties.Select(p => new ChangePropertyInfo() - { - PropertyInfo = p.PropertyInfo, - CurrentValue = p.PropertyInfo.GetValue(currentObject), - IsPrimaryKey = p.IsPrimaryKey(), - IsForeignKey = p.IsForeignKey(), - }).ToList() - }; - }); - } - - /// - /// 获取添加的实体信息 - /// - /// - /// - public static IEnumerable GetAdded(this DbContext db) - { - return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Added).Select(e => - { - var currentObject = e.CurrentValues.ToObject(); - return new ChangeEntry - { - EntityState = e.State, - Entity = e.Entity, - EntityType = e.CurrentValues.EntityType.ClrType, - ChangeProperties = e.CurrentValues.Properties.Select(p => new ChangePropertyInfo() - { - PropertyInfo = p.PropertyInfo, - CurrentValue = p.PropertyInfo.GetValue(currentObject), - IsPrimaryKey = p.IsPrimaryKey(), - IsForeignKey = p.IsForeignKey(), - }).ToList() - }; - }); - } - - /// - /// 获取移除的实体信息 - /// - /// - /// - /// - public static IEnumerable GetRemoved(this DbContext db) - { - return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted && e.Entity is T).Select(e => - { - var originalObject = e.OriginalValues.ToObject(); - return new ChangeEntry - { - EntityState = e.State, - Entity = e.Entity, - EntityType = e.OriginalValues.EntityType.ClrType, - ChangeProperties = e.OriginalValues.Properties.Select(p => new ChangePropertyInfo() - { - PropertyInfo = p.PropertyInfo, - OriginalValue = p.PropertyInfo.GetValue(originalObject), - IsPrimaryKey = p.IsPrimaryKey(), - IsForeignKey = p.IsForeignKey(), - }).ToList() - }; - }); - } - - /// - /// 获取移除的实体信息 - /// - /// - /// - public static IEnumerable GetRemoved(this DbContext db) - { - return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted).Select(e => - { - var originalObject = e.OriginalValues.ToObject(); - return new ChangeEntry - { - EntityState = e.State, - Entity = e.Entity, - EntityType = e.OriginalValues.EntityType.ClrType, - ChangeProperties = e.OriginalValues.Properties.Select(p => new ChangePropertyInfo() - { - PropertyInfo = p.PropertyInfo, - OriginalValue = p.PropertyInfo.GetValue(originalObject), - IsPrimaryKey = p.IsPrimaryKey(), - IsForeignKey = p.IsForeignKey(), - }).ToList() - }; - }); - } - - /// - /// 获取所有的变更信息 - /// - /// - /// - /// - public static IEnumerable GetAllChanges(this DbContext db) - { - return GetChanges(db).Union(GetAdded(db)).Union(GetRemoved(db)); - } - - /// - /// 获取所有的变更信息 - /// - /// - /// - public static IEnumerable GetAllChanges(this DbContext db) - { - return GetChanges(db).Union(GetAdded(db)).Union(GetRemoved(db)); - } + PropertyInfo = t1.Property.PropertyInfo, + OriginalValue = t1.Value, + CurrentValue = t2.Value, + IsPrimaryKey = t1.Property.IsPrimaryKey(), + IsForeignKey = t1.Property.IsForeignKey() + }).Where(t => Comparer.Default.Compare(t.OriginalValue, t.CurrentValue) != 0).ToList() + }; + }); } - public class ChangePropertyInfo + + + /// + /// 获取变化的实体信息 + /// + /// + /// + public static IEnumerable GetChanges(this DbContext db) { - /// - /// 属性 - /// - public PropertyInfo PropertyInfo { get; set; } - - /// - /// 原始值 - /// - public object OriginalValue { get; set; } - - /// - /// 新值 - /// - public object CurrentValue { get; set; } - - /// - /// 是否是主键 - /// - public bool IsPrimaryKey { get; set; } - - /// - /// 是否是外键 - /// - public bool IsForeignKey { get; set; } + return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified).Select(e => + { + var originalObject = e.OriginalValues.ToObject(); + var currentObject = e.CurrentValues.ToObject(); + return new ChangeEntry() + { + EntityState = e.State, + Entity = e.Entity, + EntityType = e.OriginalValues.EntityType.ClrType, + ChangeProperties = e.OriginalValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(originalObject))).Zip(e.CurrentValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(currentObject))), (t1, t2) => new ChangePropertyInfo() + { + PropertyInfo = t1.Property.PropertyInfo, + OriginalValue = t1.Value, + CurrentValue = t2.Value, + IsPrimaryKey = t1.Property.IsPrimaryKey(), + IsForeignKey = t1.Property.IsForeignKey(), + }).Where(t => Comparer.Default.Compare(t.OriginalValue, t.CurrentValue) != 0).ToList() + }; + }); } - public class ChangeEntry + /// + /// 获取添加的实体信息 + /// + /// + /// + /// + public static IEnumerable GetAdded(this DbContext db) { - /// - /// 所属实体 - /// - public object Entity { get; set; } - - /// - /// 实体类型 - /// - public Type EntityType { get; set; } - - /// - /// 变更类型 - /// - public EntityState EntityState { get; set; } - - /// - /// 字段变更信息 - /// - public List ChangeProperties { get; set; } + return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Added && e.Entity is T).Select(e => + { + var currentObject = e.CurrentValues.ToObject(); + return new ChangeEntry + { + EntityState = e.State, + Entity = e.Entity, + EntityType = e.CurrentValues.EntityType.ClrType, + ChangeProperties = e.CurrentValues.Properties.Select(p => new ChangePropertyInfo() + { + PropertyInfo = p.PropertyInfo, + CurrentValue = p.PropertyInfo.GetValue(currentObject), + IsPrimaryKey = p.IsPrimaryKey(), + IsForeignKey = p.IsForeignKey(), + }).ToList() + }; + }); } + + /// + /// 获取添加的实体信息 + /// + /// + /// + public static IEnumerable GetAdded(this DbContext db) + { + return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Added).Select(e => + { + var currentObject = e.CurrentValues.ToObject(); + return new ChangeEntry + { + EntityState = e.State, + Entity = e.Entity, + EntityType = e.CurrentValues.EntityType.ClrType, + ChangeProperties = e.CurrentValues.Properties.Select(p => new ChangePropertyInfo() + { + PropertyInfo = p.PropertyInfo, + CurrentValue = p.PropertyInfo.GetValue(currentObject), + IsPrimaryKey = p.IsPrimaryKey(), + IsForeignKey = p.IsForeignKey(), + }).ToList() + }; + }); + } + + /// + /// 获取移除的实体信息 + /// + /// + /// + /// + public static IEnumerable GetRemoved(this DbContext db) + { + return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted && e.Entity is T).Select(e => + { + var originalObject = e.OriginalValues.ToObject(); + return new ChangeEntry + { + EntityState = e.State, + Entity = e.Entity, + EntityType = e.OriginalValues.EntityType.ClrType, + ChangeProperties = e.OriginalValues.Properties.Select(p => new ChangePropertyInfo() + { + PropertyInfo = p.PropertyInfo, + OriginalValue = p.PropertyInfo.GetValue(originalObject), + IsPrimaryKey = p.IsPrimaryKey(), + IsForeignKey = p.IsForeignKey(), + }).ToList() + }; + }); + } + + /// + /// 获取移除的实体信息 + /// + /// + /// + public static IEnumerable GetRemoved(this DbContext db) + { + return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted).Select(e => + { + var originalObject = e.OriginalValues.ToObject(); + return new ChangeEntry + { + EntityState = e.State, + Entity = e.Entity, + EntityType = e.OriginalValues.EntityType.ClrType, + ChangeProperties = e.OriginalValues.Properties.Select(p => new ChangePropertyInfo() + { + PropertyInfo = p.PropertyInfo, + OriginalValue = p.PropertyInfo.GetValue(originalObject), + IsPrimaryKey = p.IsPrimaryKey(), + IsForeignKey = p.IsForeignKey(), + }).ToList() + }; + }); + } + + /// + /// 获取所有的变更信息 + /// + /// + /// + /// + public static IEnumerable GetAllChanges(this DbContext db) + { + return GetChanges(db).Union(GetAdded(db)).Union(GetRemoved(db)); + } + + /// + /// 获取所有的变更信息 + /// + /// + /// + public static IEnumerable GetAllChanges(this DbContext db) + { + return GetChanges(db).Union(GetAdded(db)).Union(GetRemoved(db)); + } +} + +public class ChangePropertyInfo +{ + /// + /// 属性 + /// + public PropertyInfo PropertyInfo { get; set; } + + /// + /// 原始值 + /// + public object OriginalValue { get; set; } + + /// + /// 新值 + /// + public object CurrentValue { get; set; } + + /// + /// 是否是主键 + /// + public bool IsPrimaryKey { get; set; } + + /// + /// 是否是外键 + /// + public bool IsForeignKey { get; set; } +} + +public class ChangeEntry +{ + /// + /// 所属实体 + /// + public object Entity { get; set; } + + /// + /// 实体类型 + /// + public Type EntityType { get; set; } + + /// + /// 变更类型 + /// + public EntityState EntityState { get; set; } + + /// + /// 字段变更信息 + /// + public List ChangeProperties { get; set; } } \ No newline at end of file diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index 47b7795e9..5eeb22984 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -25,512 +25,520 @@ using System.Collections.Generic; using System.ComponentModel; using Microsoft.VisualBasic; -namespace IRaCIS.Core.Infra.EFCore +namespace IRaCIS.Core.Infra.EFCore; + +#region 连接池废弃 +/// +/// 报错,添加subject 报错,重复添加访视 +/// +//public class IRaCISDBScopedFactory : IDbContextFactory +//{ + +// private readonly IDbContextFactory _pooledFactory; +// private readonly IUserInfo _userInfo; + +// public IRaCISDBScopedFactory(IDbContextFactory pooledFactory,IUserInfo userInfo) +// { +// _pooledFactory = pooledFactory; +// _userInfo = userInfo; +// } + +// public IRaCISDBContext CreateDbContext() +// { +// var context = _pooledFactory.CreateDbContext(); +// context._userInfo = _userInfo; +// return context; +// } +//} +#endregion + + +public class IRaCISDBContext : DbContext { - #region 连接池废弃 - /// - /// 报错,添加subject 报错,重复添加访视 - /// - //public class IRaCISDBScopedFactory : IDbContextFactory - //{ - - // private readonly IDbContextFactory _pooledFactory; - // private readonly IUserInfo _userInfo; - - // public IRaCISDBScopedFactory(IDbContextFactory pooledFactory,IUserInfo userInfo) - // { - // _pooledFactory = pooledFactory; - // _userInfo = userInfo; - // } - - // public IRaCISDBContext CreateDbContext() - // { - // var context = _pooledFactory.CreateDbContext(); - // context._userInfo = _userInfo; - // return context; - // } - //} - #endregion - public class IRaCISDBContext : DbContext + public IRaCISDBContext(DbContextOptions options) : base(options) { + } + /// + /// efcore codefirst 防止数据注解过多配置,全局统一配置 + /// + /// + protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) + { + //decimal 不配置,默认精度是18,2 + configurationBuilder.Conventions.Add(_ => new DecimalPrecisionConvention(18,2)); + //针对字符串使用默认的长度配置为200,如果标注了StringLength 其他长度,就是标注的长度,如果标注了MaxLength 那么就是nvarcharMax + configurationBuilder.Conventions.Add(_ => new DefaultStringLengthConvention(200)); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + #region pgsql codefirst 配置 暂时屏蔽 + //if (base.Database.IsNpgsql()) + //{ + // modelBuilder.HasPostgresExtension("uuid-ossp"); + + // //保证pgsql 生成的时间默认为timestamp 而不是 timestamp with time zone + // foreach (var entityType in modelBuilder.Model.GetEntityTypes()) + // { + // foreach (var property in entityType.GetProperties()) + // { + // if (property.ClrType == typeof(DateTime) || property.ClrType == typeof(DateTime?)) + // { + // property.SetColumnType("timestamp without time zone"); + // } + // } + // } + //} + #endregion - public IRaCISDBContext(DbContextOptions options) : base(options) + //遍历实体模型手动配置 + var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(q => q.GetInterface(typeof(IEntityTypeConfiguration<>).FullName) != null); + foreach (var type in typesToRegister) { + dynamic configurationInstance = Activator.CreateInstance(type); + modelBuilder.ApplyConfiguration(configurationInstance); } + base.OnModelCreating(modelBuilder); - protected override void OnModelCreating(ModelBuilder modelBuilder) + foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { - #region pgsql codefirst 配置 暂时屏蔽 - //if (base.Database.IsNpgsql()) - //{ - // modelBuilder.HasPostgresExtension("uuid-ossp"); - - // //保证pgsql 生成的时间默认为timestamp 而不是 timestamp with time zone - // foreach (var entityType in modelBuilder.Model.GetEntityTypes()) - // { - // foreach (var property in entityType.GetProperties()) - // { - // if (property.ClrType == typeof(DateTime) || property.ClrType == typeof(DateTime?)) - // { - // property.SetColumnType("timestamp without time zone"); - // } - // } - // } - //} - #endregion - - //遍历实体模型手动配置 - var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(q => q.GetInterface(typeof(IEntityTypeConfiguration<>).FullName) != null); - foreach (var type in typesToRegister) + // 软删除配置 + if (typeof(ISoftDelete).IsAssignableFrom(entityType.ClrType)) { - dynamic configurationInstance = Activator.CreateInstance(type); - modelBuilder.ApplyConfiguration(configurationInstance); + entityType.AddSoftDeleteQueryFilter(); + } - base.OnModelCreating(modelBuilder); - - foreach (var entityType in modelBuilder.Model.GetEntityTypes()) + if (typeof(Entity).IsAssignableFrom(entityType.ClrType)) { - // 软删除配置 - if (typeof(ISoftDelete).IsAssignableFrom(entityType.ClrType)) - { - entityType.AddSoftDeleteQueryFilter(); - - } - - if (typeof(Entity).IsAssignableFrom(entityType.ClrType)) - { - modelBuilder.Entity(entityType.ClrType).Property(nameof(Entity.Id)).HasValueGenerator(); - } - if (typeof(IEntitySeqId).IsAssignableFrom(entityType.ClrType)) - { - modelBuilder.Entity(entityType.ClrType).Property(nameof(IEntitySeqId.SeqId)).HasValueGenerator(); - } + modelBuilder.Entity(entityType.ClrType).Property(nameof(Entity.Id)).HasValueGenerator(); + } + if (typeof(IEntitySeqId).IsAssignableFrom(entityType.ClrType)) + { + modelBuilder.Entity(entityType.ClrType).Property(nameof(IEntitySeqId.SeqId)).HasValueGenerator(); } - } - #region 获取表名 和字段名 优化 - - /// - /// 直接获取代码定义的模型,以及表上定义的Description 获取表信息 以及备注 - /// - /// - public List GetContextTablesList() - { - var tableList = new List(); - - foreach (var entityType in this.Model.GetEntityTypes()) - { - var clrType = entityType.ClrType; - var tableName = entityType.GetTableName(); - - var tableDescription = clrType.GetCustomAttribute()?.Description ?? string.Empty; - - tableList.Add(new TableList - { - Name = tableName, - Remake = tableDescription, - }); - } - - return tableList; - } - - /// - /// 直接获取代码定义的某个表的属性,以及属性上定义的Description 获取备注 - /// - /// - public List GetContextTableColumnList(string tableName) - { - var tableColumList = new List(); - - var entityType = this.Model.GetEntityTypes().FirstOrDefault(t => t.GetTableName().ToLower() == tableName.ToLower()); - - if (entityType == null) - { - throw new ArgumentException($"Table '{tableName}' not found."); - } - - var clrType = entityType.ClrType; - - foreach (var property in entityType.GetProperties()) - { - var columnName = property.GetColumnName(); - var columnDescription = clrType.GetProperty(property.Name)?.GetCustomAttribute()?.Description ?? string.Empty; - - tableColumList.Add(new TableList - { - Name = columnName, - Remake = columnDescription, - }); - } - - return tableColumList.OrderBy(t => t.Name).ToList(); - } - #endregion - - - #region Doctor - public virtual DbSet Dictionary { get; set; } - public virtual DbSet Doctor { get; set; } - - public virtual DbSet DoctorCriterionFile { get; set; } - public virtual DbSet DoctorDictionary { get; set; } - public virtual DbSet Postgraduate { get; set; } - public virtual DbSet Education { get; set; } - public virtual DbSet ResearchPublications { get; set; } - public virtual DbSet TrialExperience { get; set; } - - public virtual DbSet UserDoctor { get; set; } - public virtual DbSet Vacation { get; set; } - - public virtual DbSet Attachment { get; set; } - public virtual DbSet TrialExperienceCriteria { get; set; } - - - - - #endregion - - #region Enroll - - public virtual DbSet DoctorWorkload { get; set; } - public virtual DbSet Enroll { get; set; } - - public virtual DbSet EnrollReadingCategory { get; set; } - - - public virtual DbSet EnrollDetails { get; set; } - - - - - #endregion - - - #region Reading - public virtual DbSet TrialCriterionDictionaryCode { get; set; } - - public virtual DbSet ReadingCustomTag { get; set; } - public virtual DbSet SystemCriterionDictionaryCode { get; set; } - public virtual DbSet ReadingTaskRelation { get; set; } - public virtual DbSet OrganInfo { get; set; } - - public virtual DbSet ReadingSystemCriterionDictionary { get; set; } - public virtual DbSet ReadingTableAnswerRowInfo { get; set; } - public virtual DbSet OrganTrialInfo { get; set; } - public virtual DbSet ReadingTableQuestionSystem { get; set; } - public virtual DbSet ReadingPeriodSet { get; set; } - - public virtual DbSet ReadingTaskQuestionAnswer { get; set; } - public virtual DbSet ReadingPeriodPlan { get; set; } - - public virtual DbSet ReadingClinicalData { get; set; } - - public virtual DbSet ReadingOncologyTaskInfo { get; set; } - public virtual DbSet ReadingGlobalTaskInfo { get; set; } - public virtual DbSet ReadingQuestionCriterionSystem { get; set; } - - public virtual DbSet ReadingQuestionCriterionTrial { get; set; } - - public virtual DbSet ReadingQuestionSystem { get; set; } - - public virtual DbSet ReadingQuestionTrial { get; set; } - - - public virtual DbSet ReadingClinicalDataPDF { get; set; } - public virtual DbSet ReadingConsistentClinicalData { get; set; } - public virtual DbSet ReadingConsistentClinicalDataPDF { get; set; } - - public virtual DbSet ReadingJudgeInfo { get; set; } - - public virtual DbSet ReadModule { get; set; } - - public virtual DbSet ReadModuleView { get; set; } - - public virtual DbSet ClinicalDataTrialSet { get; set; } - - public virtual DbSet ClinicalDataSystemSet { get; set; } - - public virtual DbSet ReadingMedicineSystemQuestion { get; set; } - - public virtual DbSet ReadingMedicineTrialQuestion { get; set; } - - public virtual DbSet ReadingMedicineQuestionAnswer { get; set; } - - public virtual DbSet ReadingMedicalReviewDialog { get; set; } - - public virtual DbSet CriterionNidusSystem { get; set; } - - public virtual DbSet CriterionNidusTrial { get; set; } - - public virtual DbSet ReadingTrialCriterionDictionary { get; set; } - - public virtual DbSet ReadingTableQuestionTrial { get; set; } - - - public virtual DbSet TumorAssessment_RECIST1Point1BM { get; set; } - public virtual DbSet TumorAssessment_RECIST1Point1 { get; set; } - - public virtual DbSet TumorAssessment_IRECIST1Point1 { get; set; } - - public virtual DbSet TrialClinicalDataSetCriterion { get; set; } - - public virtual DbSet TrialCriterionAdditionalAssessmentType { get; set; } - - public virtual DbSet SubjectCriteriaEvaluation { get; set; } - public virtual DbSet SubjectAdditionalEvaluationResult { get; set; } - public virtual DbSet SubjectCriteriaEvaluationVisitFilter { get; set; } - public virtual DbSet SubjectCriteriaEvaluationVisitStudyFilter { get; set; } - - public virtual DbSet ReadingTaskQuestionMark { get; set; } - - - //public virtual DbSet TrialClinicalDataCriterion { get; set; } - //public virtual DbSet SystemClinicalDataCriterion { get; set; } - - #endregion - - #region Subject and Visit and study - public virtual DbSet StudyMonitor { get; set; } - - public virtual DbSet Subject { get; set; } - public virtual DbSet VisitPlans { get; set; } - public virtual DbSet VisitPlanInfluenceStudy { get; set; } - - public virtual DbSet VisitPlanInfluenceStat { get; set; } - - public virtual DbSet NoneDicomStudyFile { get; set; } - public virtual DbSet NoneDicomStudy { get; set; } - public virtual DbSet PreviousPDF { get; set; } - public virtual DbSet PreviousSurgery { get; set; } - public virtual DbSet PreviousOther { get; set; } - public virtual DbSet PreviousHistory { get; set; } - - public virtual DbSet DicomStudys { get; set; } - public virtual DbSet DicomSeries { get; set; } - public virtual DbSet DicomInstances { get; set; } - public virtual DbSet ImageShare { get; set; } - - - #endregion - - #region Management - public virtual DbSet VerificationCodes { get; set; } - public virtual DbSet MenuFunctions { get; set; } - public virtual DbSet Roles { get; set; } - public virtual DbSet UserTypeMenuFunction { get; set; } - public virtual DbSet Users { get; set; } - public virtual DbSet TrialAudit { get; set; } - public virtual DbSet UserType { get; set; } - - - - - #endregion - - #region Institution - - - public virtual DbSet Hospitals { get; set; } - public virtual DbSet CROCompany { get; set; } - public virtual DbSet Sponsor { get; set; } - - #endregion - - #region Trial - public virtual DbSet Trial { get; set; } - - - public virtual DbSet TrialDictionary { get; set; } - public virtual DbSet TrialDetail { get; set; } - public virtual DbSet UserTrial { get; set; } - - public virtual DbSet ProjectDictionary { get; set; } - - public virtual DbSet UserTrialSite { get; set; } - public virtual DbSet TrialSite { get; set; } - - public virtual DbSet Site { get; set; } - - public virtual DbSet User { get; set; } - - public virtual DbSet UserPassWordLog { get; set; } - - public virtual DbSet TrialSiteUserSurvey { get; set; } - public virtual DbSet TrialSiteEquipmentSurvey { get; set; } - public virtual DbSet TrialSiteSurvey { get; set; } - - - - - #endregion - - #region Financial - public virtual DbSet ReviewerPayInformation { get; set; } - public virtual DbSet RankPrice { get; set; } - public virtual DbSet TrialPaymentPrice { get; set; } - public virtual DbSet AwardPrice { get; set; } - public virtual DbSet Payment { get; set; } - public virtual DbSet PaymentDetail { get; set; } - public virtual DbSet ExchangeRate { get; set; } - public virtual DbSet TrialRevenuesPrice { get; set; } - public virtual DbSet PaymentAdjustment { get; set; } - public virtual DbSet TrialRevenuesPriceVerification { get; set; } - - - #endregion - - #region QC - - public virtual DbSet TrialQCQuestionConfigure { get; set; } - public virtual DbSet QCQuestionConfigure { get; set; } - public virtual DbSet TrialQCQuestionAnswer { get; set; } - public virtual DbSet CheckChallengeDialog { get; set; } - #endregion - - - #region QA - - public virtual DbSet QCChallengeDialog { get; set; } - //public virtual DbSet QATemplateDictionary { get; set; } - public virtual DbSet QCChallenge { get; set; } - public virtual DbSet SubjectVisit { get; set; } - #endregion - - #region ClinicalQuestion - public virtual DbSet TrialClinicalQuestion { get; set; } - - public virtual DbSet SystemClinicalQuestion { get; set; } - - public virtual DbSet SystemClinicalTableQuestion { get; set; } - - public virtual DbSet TrialClinicalTableQuestion { get; set; } - - public virtual DbSet ClinicalQuestionAnswer { get; set; } - - public virtual DbSet ClinicalAnswerRowInfo { get; set; } - - public virtual DbSet ClinicalTableAnswer { get; set; } - - public virtual DbSet ReadModuleCriterionFrom { get; set; } - public virtual DbSet ClinicalForm { get; set; } - #endregion - - - #region Document - public virtual DbSet SystemDocument { get; set; } - public virtual DbSet TrialDocument { get; set; } - public virtual DbSet TrialDocUserTypeConfirm { get; set; } - public virtual DbSet SystemDocConfirmedUser { get; set; } - public virtual DbSet SystemDocNeedConfirmedUserType { get; set; } - - public virtual DbSet TrialDocNeedConfirmedUserType { get; set; } - - public virtual DbSet TrialDocConfirmedUser { get; set; } - #endregion - - #region 未分类 - - public virtual DbSet ShortcutKey { get; set; } - - public virtual DbSet UserWLTemplate { get; set; } - public virtual DbSet EmailNoticeConfig { get; set; } - public virtual DbSet SystemBasicData { get; set; } - - public virtual DbSet TrialSign { get; set; } - - public virtual DbSet TrialStateChange { get; set; } - - public virtual DbSet SystemAnonymization { get; set; } - - public virtual DbSet TrialExternalUser { get; set; } - - public virtual DbSet UserTypeGroup { get; set; } - - public virtual DbSet DataInspection { get; set; } - - - - public virtual DbSet FrontAuditConfig { get; set; } - - public virtual DbSet InspectionFile { get; set; } - - public virtual DbSet CommonDocument { get; set; } - - public virtual DbSet SystemNotice { get; set; } - - public virtual DbSet SystemNoticeUserRead { get; set; } - - public virtual DbSet SystemNoticeUserType { get; set; } - - public virtual DbSet ReadingTableQuestionAnswer { get; set; } - - public virtual DbSet PublishLog { get; set; } - public virtual DbSet UserLog { get; set; } - - - public virtual DbSet EmailNoticeUserType { get; set; } - public virtual DbSet TrialEmailBlackUser { get; set; } - - public virtual DbSet TrialBodyPart { get; set; } - - public virtual DbSet ExploreRecommend { get; set; } - - public virtual DbSet SCPPatient { get; set; } - public virtual DbSet SCPStudy { get; set; } - public virtual DbSet SCPSeries { get; set; } - public virtual DbSet SCPInstance { get; set; } - public virtual DbSet TrialDicomAE { get; set; } - - - public virtual DbSet TrialSiteDicomAE { get; set; } - - - public virtual DbSet SCPImageUpload { get; set; } - - public virtual DbSet UserFeedBack { get; set; } - - public virtual DbSet TaskAllocationRule { get; set; } - - public virtual DbSet VisitTask { get; set; } - - public virtual DbSet SubjectUser { get; set; } - - public virtual DbSet VisitTaskReReading { get; set; } - - public virtual DbSet TaskMedicalReview { get; set; } - - public virtual DbSet TaskMedicalReviewRule { get; set; } - - public virtual DbSet TaskConsistentRule { get; set; } - - - public virtual DbSet TaskInfluence { get; set; } - - public virtual DbSet SubjectCanceDoctor { get; set; } - - public virtual DbSet TrialEmailNoticeConfig { get; set; } - - public virtual DbSet TrialEmailNoticeUser { get; set; } - - - public virtual DbSet Internationalization { get; set; } - - public virtual DbSet TrialVirtualSiteCodeUpdate { get; set; } - public virtual DbSet EnrollReadingCriterion { get; set; } - #endregion - - public virtual DbSet TrialImageDownload { get; set; } - - - } + #region 获取表名 和字段名 优化 + + /// + /// 直接获取代码定义的模型,以及表上定义的Description 获取表信息 以及备注 + /// + /// + public List GetContextTablesList() + { + var tableList = new List(); + + foreach (var entityType in this.Model.GetEntityTypes()) + { + var clrType = entityType.ClrType; + var tableName = entityType.GetTableName(); + + var tableDescription = clrType.GetCustomAttribute()?.Description ?? string.Empty; + + tableList.Add(new TableList + { + Name = tableName, + Remake = tableDescription, + }); + } + + return tableList; + } + + /// + /// 直接获取代码定义的某个表的属性,以及属性上定义的Description 获取备注 + /// + /// + public List GetContextTableColumnList(string tableName) + { + var tableColumList = new List(); + + var entityType = this.Model.GetEntityTypes().FirstOrDefault(t => t.GetTableName().ToLower() == tableName.ToLower()); + + if (entityType == null) + { + throw new ArgumentException($"Table '{tableName}' not found."); + } + + var clrType = entityType.ClrType; + + foreach (var property in entityType.GetProperties()) + { + var columnName = property.GetColumnName(); + var columnDescription = clrType.GetProperty(property.Name)?.GetCustomAttribute()?.Description ?? string.Empty; + + tableColumList.Add(new TableList + { + Name = columnName, + Remake = columnDescription, + }); + } + + return tableColumList.OrderBy(t => t.Name).ToList(); + } + #endregion + + + #region Doctor + public virtual DbSet Dictionary { get; set; } + public virtual DbSet Doctor { get; set; } + + public virtual DbSet DoctorCriterionFile { get; set; } + public virtual DbSet DoctorDictionary { get; set; } + public virtual DbSet Postgraduate { get; set; } + public virtual DbSet Education { get; set; } + public virtual DbSet ResearchPublications { get; set; } + public virtual DbSet TrialExperience { get; set; } + + public virtual DbSet UserDoctor { get; set; } + public virtual DbSet Vacation { get; set; } + + public virtual DbSet Attachment { get; set; } + public virtual DbSet TrialExperienceCriteria { get; set; } + + + + + #endregion + + #region Enroll + + public virtual DbSet DoctorWorkload { get; set; } + public virtual DbSet Enroll { get; set; } + + public virtual DbSet EnrollReadingCategory { get; set; } + + + public virtual DbSet EnrollDetails { get; set; } + + + + + #endregion + + + #region Reading + public virtual DbSet TrialCriterionDictionaryCode { get; set; } + + public virtual DbSet ReadingCustomTag { get; set; } + public virtual DbSet SystemCriterionDictionaryCode { get; set; } + public virtual DbSet ReadingTaskRelation { get; set; } + public virtual DbSet OrganInfo { get; set; } + + public virtual DbSet ReadingSystemCriterionDictionary { get; set; } + public virtual DbSet ReadingTableAnswerRowInfo { get; set; } + public virtual DbSet OrganTrialInfo { get; set; } + public virtual DbSet ReadingTableQuestionSystem { get; set; } + public virtual DbSet ReadingPeriodSet { get; set; } + + public virtual DbSet ReadingTaskQuestionAnswer { get; set; } + public virtual DbSet ReadingPeriodPlan { get; set; } + + public virtual DbSet ReadingClinicalData { get; set; } + + public virtual DbSet ReadingOncologyTaskInfo { get; set; } + public virtual DbSet ReadingGlobalTaskInfo { get; set; } + public virtual DbSet ReadingQuestionCriterionSystem { get; set; } + + public virtual DbSet ReadingQuestionCriterionTrial { get; set; } + + public virtual DbSet ReadingQuestionSystem { get; set; } + + public virtual DbSet ReadingQuestionTrial { get; set; } + + + public virtual DbSet ReadingClinicalDataPDF { get; set; } + public virtual DbSet ReadingConsistentClinicalData { get; set; } + public virtual DbSet ReadingConsistentClinicalDataPDF { get; set; } + + public virtual DbSet ReadingJudgeInfo { get; set; } + + public virtual DbSet ReadModule { get; set; } + + public virtual DbSet ReadModuleView { get; set; } + + public virtual DbSet ClinicalDataTrialSet { get; set; } + + public virtual DbSet ClinicalDataSystemSet { get; set; } + + public virtual DbSet ReadingMedicineSystemQuestion { get; set; } + + public virtual DbSet ReadingMedicineTrialQuestion { get; set; } + + public virtual DbSet ReadingMedicineQuestionAnswer { get; set; } + + public virtual DbSet ReadingMedicalReviewDialog { get; set; } + + public virtual DbSet CriterionNidusSystem { get; set; } + + public virtual DbSet CriterionNidusTrial { get; set; } + + public virtual DbSet ReadingTrialCriterionDictionary { get; set; } + + public virtual DbSet ReadingTableQuestionTrial { get; set; } + + + public virtual DbSet TumorAssessment_RECIST1Point1BM { get; set; } + public virtual DbSet TumorAssessment_RECIST1Point1 { get; set; } + + public virtual DbSet TumorAssessment_IRECIST1Point1 { get; set; } + + public virtual DbSet TrialClinicalDataSetCriterion { get; set; } + + public virtual DbSet TrialCriterionAdditionalAssessmentType { get; set; } + + public virtual DbSet SubjectCriteriaEvaluation { get; set; } + public virtual DbSet SubjectAdditionalEvaluationResult { get; set; } + public virtual DbSet SubjectCriteriaEvaluationVisitFilter { get; set; } + public virtual DbSet SubjectCriteriaEvaluationVisitStudyFilter { get; set; } + + public virtual DbSet ReadingTaskQuestionMark { get; set; } + + + //public virtual DbSet TrialClinicalDataCriterion { get; set; } + //public virtual DbSet SystemClinicalDataCriterion { get; set; } + + #endregion + + #region Subject and Visit and study + public virtual DbSet StudyMonitor { get; set; } + + public virtual DbSet Subject { get; set; } + public virtual DbSet VisitPlans { get; set; } + public virtual DbSet VisitPlanInfluenceStudy { get; set; } + + public virtual DbSet VisitPlanInfluenceStat { get; set; } + + public virtual DbSet NoneDicomStudyFile { get; set; } + public virtual DbSet NoneDicomStudy { get; set; } + public virtual DbSet PreviousPDF { get; set; } + public virtual DbSet PreviousSurgery { get; set; } + public virtual DbSet PreviousOther { get; set; } + public virtual DbSet PreviousHistory { get; set; } + + public virtual DbSet DicomStudys { get; set; } + public virtual DbSet DicomSeries { get; set; } + public virtual DbSet DicomInstances { get; set; } + public virtual DbSet ImageShare { get; set; } + + + #endregion + + #region Management + public virtual DbSet VerificationCodes { get; set; } + public virtual DbSet MenuFunctions { get; set; } + public virtual DbSet Roles { get; set; } + public virtual DbSet UserTypeMenuFunction { get; set; } + public virtual DbSet Users { get; set; } + public virtual DbSet TrialAudit { get; set; } + public virtual DbSet UserType { get; set; } + + + + + #endregion + + #region Institution + + + public virtual DbSet Hospitals { get; set; } + public virtual DbSet CROCompany { get; set; } + public virtual DbSet Sponsor { get; set; } + + #endregion + + #region Trial + public virtual DbSet Trial { get; set; } + + + public virtual DbSet TrialDictionary { get; set; } + public virtual DbSet TrialDetail { get; set; } + public virtual DbSet UserTrial { get; set; } + + public virtual DbSet ProjectDictionary { get; set; } + + public virtual DbSet UserTrialSite { get; set; } + public virtual DbSet TrialSite { get; set; } + + public virtual DbSet Site { get; set; } + + public virtual DbSet User { get; set; } + + public virtual DbSet UserPassWordLog { get; set; } + + public virtual DbSet TrialSiteUserSurvey { get; set; } + public virtual DbSet TrialSiteEquipmentSurvey { get; set; } + public virtual DbSet TrialSiteSurvey { get; set; } + + + + + #endregion + + #region Financial + public virtual DbSet ReviewerPayInformation { get; set; } + public virtual DbSet RankPrice { get; set; } + public virtual DbSet TrialPaymentPrice { get; set; } + public virtual DbSet AwardPrice { get; set; } + public virtual DbSet Payment { get; set; } + public virtual DbSet PaymentDetail { get; set; } + public virtual DbSet ExchangeRate { get; set; } + public virtual DbSet TrialRevenuesPrice { get; set; } + public virtual DbSet PaymentAdjustment { get; set; } + public virtual DbSet TrialRevenuesPriceVerification { get; set; } + + + #endregion + + #region QC + + public virtual DbSet TrialQCQuestionConfigure { get; set; } + public virtual DbSet QCQuestionConfigure { get; set; } + public virtual DbSet TrialQCQuestionAnswer { get; set; } + public virtual DbSet CheckChallengeDialog { get; set; } + #endregion + + + #region QA + + public virtual DbSet QCChallengeDialog { get; set; } + //public virtual DbSet QATemplateDictionary { get; set; } + public virtual DbSet QCChallenge { get; set; } + public virtual DbSet SubjectVisit { get; set; } + #endregion + + #region ClinicalQuestion + public virtual DbSet TrialClinicalQuestion { get; set; } + + public virtual DbSet SystemClinicalQuestion { get; set; } + + public virtual DbSet SystemClinicalTableQuestion { get; set; } + + public virtual DbSet TrialClinicalTableQuestion { get; set; } + + public virtual DbSet ClinicalQuestionAnswer { get; set; } + + public virtual DbSet ClinicalAnswerRowInfo { get; set; } + + public virtual DbSet ClinicalTableAnswer { get; set; } + + public virtual DbSet ReadModuleCriterionFrom { get; set; } + public virtual DbSet ClinicalForm { get; set; } + #endregion + + + #region Document + public virtual DbSet SystemDocument { get; set; } + public virtual DbSet TrialDocument { get; set; } + public virtual DbSet TrialDocUserTypeConfirm { get; set; } + public virtual DbSet SystemDocConfirmedUser { get; set; } + public virtual DbSet SystemDocNeedConfirmedUserType { get; set; } + + public virtual DbSet TrialDocNeedConfirmedUserType { get; set; } + + public virtual DbSet TrialDocConfirmedUser { get; set; } + #endregion + + #region 未分类 + + public virtual DbSet ShortcutKey { get; set; } + + public virtual DbSet UserWLTemplate { get; set; } + public virtual DbSet EmailNoticeConfig { get; set; } + public virtual DbSet SystemBasicData { get; set; } + + public virtual DbSet TrialSign { get; set; } + + public virtual DbSet TrialStateChange { get; set; } + + public virtual DbSet SystemAnonymization { get; set; } + + public virtual DbSet TrialExternalUser { get; set; } + + public virtual DbSet UserTypeGroup { get; set; } + + public virtual DbSet DataInspection { get; set; } + + + + public virtual DbSet FrontAuditConfig { get; set; } + + public virtual DbSet InspectionFile { get; set; } + + public virtual DbSet CommonDocument { get; set; } + + public virtual DbSet SystemNotice { get; set; } + + public virtual DbSet SystemNoticeUserRead { get; set; } + + public virtual DbSet SystemNoticeUserType { get; set; } + + public virtual DbSet ReadingTableQuestionAnswer { get; set; } + + public virtual DbSet PublishLog { get; set; } + public virtual DbSet UserLog { get; set; } + + + public virtual DbSet EmailNoticeUserType { get; set; } + public virtual DbSet TrialEmailBlackUser { get; set; } + + public virtual DbSet TrialBodyPart { get; set; } + + public virtual DbSet ExploreRecommend { get; set; } + + public virtual DbSet SCPPatient { get; set; } + public virtual DbSet SCPStudy { get; set; } + public virtual DbSet SCPSeries { get; set; } + public virtual DbSet SCPInstance { get; set; } + public virtual DbSet TrialDicomAE { get; set; } + + + public virtual DbSet TrialSiteDicomAE { get; set; } + + + public virtual DbSet SCPImageUpload { get; set; } + + public virtual DbSet UserFeedBack { get; set; } + + public virtual DbSet TaskAllocationRule { get; set; } + + public virtual DbSet VisitTask { get; set; } + + public virtual DbSet SubjectUser { get; set; } + + public virtual DbSet VisitTaskReReading { get; set; } + + public virtual DbSet TaskMedicalReview { get; set; } + + public virtual DbSet TaskMedicalReviewRule { get; set; } + + public virtual DbSet TaskConsistentRule { get; set; } + + + public virtual DbSet TaskInfluence { get; set; } + + public virtual DbSet SubjectCanceDoctor { get; set; } + + public virtual DbSet TrialEmailNoticeConfig { get; set; } + + public virtual DbSet TrialEmailNoticeUser { get; set; } + + + public virtual DbSet Internationalization { get; set; } + + public virtual DbSet TrialVirtualSiteCodeUpdate { get; set; } + public virtual DbSet EnrollReadingCriterion { get; set; } + #endregion + + public virtual DbSet TrialImageDownload { get; set; } + + } \ No newline at end of file diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContextFactory.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContextFactory.cs new file mode 100644 index 000000000..55d07f2f7 --- /dev/null +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContextFactory.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Infra.EFCore.Context; + + +/// +/// Design-time DbContext Creation 用于迁移时指定使用哪个数据库 +/// +public class IRaCISDBContextFactory : IDesignTimeDbContextFactory +{ + public IRaCISDBContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlServer("Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure()); + + return new IRaCISDBContext(optionsBuilder.Options); + } +} + diff --git a/IRaCIS.Core.Infra.EFCore/Context/ValueGenerator/MySequentialGuidValueGenerator.cs b/IRaCIS.Core.Infra.EFCore/Context/ValueGenerator/MySequentialGuidValueGenerator.cs index f7aa2956c..7534f6b57 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/ValueGenerator/MySequentialGuidValueGenerator.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/ValueGenerator/MySequentialGuidValueGenerator.cs @@ -4,15 +4,13 @@ using MassTransit; using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.ValueGeneration; -namespace IRaCIS.Core.Infra.EFCore -{ - public class MySequentialGuidValueGenerator : ValueGenerator - { - public override Guid Next(EntityEntry entry) - { - return NewId.NextSequentialGuid(); - } - public override bool GeneratesTemporaryValues => false; - } +namespace IRaCIS.Core.Infra.EFCore; +public class MySequentialGuidValueGenerator : ValueGenerator +{ + public override Guid Next(EntityEntry entry) + { + return NewId.NextSequentialGuid(); + } + public override bool GeneratesTemporaryValues => false; } \ No newline at end of file diff --git a/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj b/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj index 3d99c723f..60a1b70d4 100644 --- a/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj +++ b/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj @@ -25,6 +25,15 @@ + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 b/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 index 0693d6509..8f755d360 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 +++ b/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 @@ -20,7 +20,7 @@ https://www.cnblogs.com/cqpanda/p/16815263.html 5ijθµݿǨƣԶִdown dotnet ef database update ijǨƵǰһǨ -p IRaCIS.Core.Test -c IRCContext - dotnet ef migrations add RemoveForeignKey -p IRaCIS.Core.Test -c IRCContext -o CodeFirstTest/MSSQL/Migrations + dotnet ef migrations add RemoveForeignKey -p IRaCIS.Core.Test -c IRCContext -o CodeFirstTest/MSSQL/Migrations diff --git a/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Convention/MaxStringLengthConvention .cs b/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Convention/MaxStringLengthConvention .cs index e59564802..efcbda828 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Convention/MaxStringLengthConvention .cs +++ b/IRaCIS.Core.Test/CodeFirstTest/PGSQL/Convention/MaxStringLengthConvention .cs @@ -11,6 +11,12 @@ namespace IRaCIS.Core.Test.CodeFirstTest.PGSQL.Migrations /// public class MaxStringLengthConvention : IModelFinalizingConvention { + private readonly int _defaultLenth; + + public MaxStringLengthConvention(int defaultLenth) + { + _defaultLenth = defaultLenth; + } public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext context) { foreach (var property in modelBuilder.Metadata.GetEntityTypes() @@ -31,17 +37,17 @@ namespace IRaCIS.Core.Test.CodeFirstTest.PGSQL.Migrations // 输出调试信息,看看是哪种特性生效 if (stringLengthAttribute != null) { - Console.WriteLine($"{property.Name}: StringLength({stringLengthAttribute.MaximumLength})"); + //Console.WriteLine($"{property.Name}: StringLength({stringLengthAttribute.MaximumLength})"); property.Builder.HasMaxLength(stringLengthAttribute.MaximumLength); } else if (maxLengthAttribute != null) { - Console.WriteLine($"{property.Name}: MaxLength (no specific length, allowing max)"); + //Console.WriteLine($"{property.Name}: MaxLength (no specific length, allowing max)"); } else { - Console.WriteLine($"{property.Name}: Default length 200"); - property.Builder.HasMaxLength(200); + //Console.WriteLine($"{property.Name}: Default length {_defaultLenth}"); + property.Builder.HasMaxLength(_defaultLenth); } } } diff --git a/IRaCIS.Core.Test/CodeFirstTest/PGSQL/PGContext.cs b/IRaCIS.Core.Test/CodeFirstTest/PGSQL/PGContext.cs index 0437fa656..bdd5f6db4 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/PGSQL/PGContext.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/PGSQL/PGContext.cs @@ -70,7 +70,7 @@ public partial class PGContext : DbContext //configurationBuilder.Conventions.Add(_ => new NoForeignKeyConvention()); //针对字符串使用默认的长度配置 - configurationBuilder.Conventions.Add(_ => new MaxStringLengthConvention()); + configurationBuilder.Conventions.Add(_ => new MaxStringLengthConvention(200)); } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); diff --git a/IRaCIS.Core.Test/IRaCIS.Core.Test.csproj b/IRaCIS.Core.Test/IRaCIS.Core.Test.csproj index 9d1a28e03..2bb08de11 100644 --- a/IRaCIS.Core.Test/IRaCIS.Core.Test.csproj +++ b/IRaCIS.Core.Test/IRaCIS.Core.Test.csproj @@ -52,16 +52,11 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - diff --git a/IRaCIS.Core.Test/模板使用说明 b/IRaCIS.Core.Test/模板使用说明 index d8aee69ec..f74d40bb9 100644 --- a/IRaCIS.Core.Test/模板使用说明 +++ b/IRaCIS.Core.Test/模板使用说明 @@ -17,7 +17,7 @@ -c 指定数据库上下文名字 -d 使用数据注解 不指定,默认是fluentAPI -t 指定要生成的表名 --p 指定项目名字 +-p 指定项目名字 (包含上下文,并且产生迁移文件的项目) 备注: 因为是从数据库反向生成实体,所以会默认生成dbcontext ,每次生成想要的实体后,删除指定的名称context即可 针对字符串类型,我们避免string字段 数据库存储null string? 数据库才存储null(除非有合理的理由),这样可以避免代码里面用string 变量,总是要判断是否为null From 65e47d991864bdb6277d720825ef7fc82c86bd38 Mon Sep 17 00:00:00 2001 From: hang <87227557@qq.com> Date: Tue, 17 Sep 2024 18:53:56 +0800 Subject: [PATCH 45/59] =?UTF-8?q?decimal=20=20=E7=B2=BE=E5=BA=A6=E8=A7=A3?= =?UTF-8?q?=E5=86=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Domain/Common/NotDefault.cs | 145 ++++++++++-------- .../Convention/DecimalPrecisionConvention.cs | 4 +- .../Context/IRaCISDBContext.cs | 32 +++- .../CodeTemplates/EFCore/EntityType.t4 | 32 +++- IRaCIS.Core.Test/模板使用说明 | 2 + 5 files changed, 145 insertions(+), 70 deletions(-) diff --git a/IRaCIS.Core.Domain/Common/NotDefault.cs b/IRaCIS.Core.Domain/Common/NotDefault.cs index b38738133..d6585ac01 100644 --- a/IRaCIS.Core.Domain/Common/NotDefault.cs +++ b/IRaCIS.Core.Domain/Common/NotDefault.cs @@ -1,78 +1,89 @@ -namespace System.ComponentModel.DataAnnotations +namespace System.ComponentModel.DataAnnotations; + +[AttributeUsage( + AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, + AllowMultiple = false)] +public class GuidNotEmptyAttribute : ValidationAttribute { - [AttributeUsage( - AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, - AllowMultiple = false)] - public class GuidNotEmptyAttribute : ValidationAttribute + public const string DefaultErrorMessage = "The {0} field must not be empty"; + public GuidNotEmptyAttribute() : base(DefaultErrorMessage) { } + + public override bool IsValid(object value) { - public const string DefaultErrorMessage = "The {0} field must not be empty"; - public GuidNotEmptyAttribute() : base(DefaultErrorMessage) { } - - public override bool IsValid(object value) + //NotEmpty doesn't necessarily mean required + if (value is null) { - //NotEmpty doesn't necessarily mean required - if (value is null) - { - return true; - } - - switch (value) - { - case Guid guid: - return guid != Guid.Empty; - default: - return true; - } - } - } - - public class NotDefaultAttribute : ValidationAttribute - { - public const string DefaultErrorMessage = "The {0} field is is not passed or not set a valid value"; - public NotDefaultAttribute() : base(DefaultErrorMessage) { } - - public override bool IsValid(object value) - { - //NotDefault doesn't necessarily mean required - if (value is null) - { - return true; - } - - var type = value.GetType(); - if (type.IsValueType) - { - var defaultValue = Activator.CreateInstance(type); - return !value.Equals(defaultValue); - } - - // non-null ref type return true; } - } - - public class CanConvertToTimeAttribute : ValidationAttribute - { - public const string DefaultErrorMessage = "The {0} field is is not a valid DateTime value"; - public CanConvertToTimeAttribute() : base(DefaultErrorMessage) { } - - public override bool IsValid(object value) + switch (value) { - if (value is null) - { - return false; - } - - if (DateTime.TryParse(value.ToString(), out _) == true) - { + case Guid guid: + return guid != Guid.Empty; + default: return true; - } - else - { - return false; - } } } - +} + +public class NotDefaultAttribute : ValidationAttribute +{ + public const string DefaultErrorMessage = "The {0} field is is not passed or not set a valid value"; + public NotDefaultAttribute() : base(DefaultErrorMessage) { } + + public override bool IsValid(object value) + { + //NotDefault doesn't necessarily mean required + if (value is null) + { + return true; + } + + var type = value.GetType(); + if (type.IsValueType) + { + var defaultValue = Activator.CreateInstance(type); + return !value.Equals(defaultValue); + } + + // non-null ref type + return true; + } +} + + +public class CanConvertToTimeAttribute : ValidationAttribute +{ + public const string DefaultErrorMessage = "The {0} field is is not a valid DateTime value"; + public CanConvertToTimeAttribute() : base(DefaultErrorMessage) { } + + public override bool IsValid(object value) + { + if (value is null) + { + return false; + } + + if (DateTime.TryParse(value.ToString(), out _) == true) + { + return true; + } + else + { + return false; + } + } +} + +[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] +public class DecimalPrecisionAttribute : Attribute +{ + public int Precision { get; } + public int Scale { get; } + + public DecimalPrecisionAttribute(int precision, int scale) + { + Precision = precision; + Scale = scale; + } } diff --git a/IRaCIS.Core.Infra.EFCore/Context/Convention/DecimalPrecisionConvention.cs b/IRaCIS.Core.Infra.EFCore/Context/Convention/DecimalPrecisionConvention.cs index 9b473d1cf..caf8ebd9f 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/Convention/DecimalPrecisionConvention.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/Convention/DecimalPrecisionConvention.cs @@ -9,7 +9,9 @@ using System.Threading.Tasks; namespace IRaCIS.Core.Infra.EFCore; - +/// +/// 设置decimal 默认精度问题 (但是用ef迁移工具的时候,还是会提示No store type was specified for the decimal property,但是迁移文件里面体现了该配置,在dbcontext里写,那么就会没该警告) +/// public class DecimalPrecisionConvention : IModelFinalizingConvention { private readonly int _precision; diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index 5eeb22984..3a666c46a 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -24,6 +24,7 @@ using System.Reflection.Metadata; using System.Collections.Generic; using System.ComponentModel; using Microsoft.VisualBasic; +using System.ComponentModel.DataAnnotations; namespace IRaCIS.Core.Infra.EFCore; @@ -67,7 +68,7 @@ public class IRaCISDBContext : DbContext protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) { //decimal 不配置,默认精度是18,2 - configurationBuilder.Conventions.Add(_ => new DecimalPrecisionConvention(18,2)); + //configurationBuilder.Conventions.Add(_ => new DecimalPrecisionConvention(18,2)); //针对字符串使用默认的长度配置为200,如果标注了StringLength 其他长度,就是标注的长度,如果标注了MaxLength 那么就是nvarcharMax configurationBuilder.Conventions.Add(_ => new DefaultStringLengthConvention(200)); } @@ -94,6 +95,35 @@ public class IRaCISDBContext : DbContext #endregion + #region decimal 自定义精度,适配多种数据库 + //foreach (var entityType in modelBuilder.Model.GetEntityTypes()) + //{ + // foreach (var property in entityType.GetProperties()) + // { + // // 如果属性类型是 decimal 或 nullable decimal + // if (property.ClrType == typeof(decimal) || property.ClrType == typeof(decimal?)) + // { + // // 获取自定义的 DecimalPrecisionAttribute + // var precisionAttr = property.PropertyInfo?.GetCustomAttributes(typeof(DecimalPrecisionAttribute), false) + // .FirstOrDefault() as DecimalPrecisionAttribute; + + // if (precisionAttr != null) + // { + // property.SetPrecision(precisionAttr.Precision); + // property.SetScale(precisionAttr.Scale); + // } + // else + // { + // // 默认的精度设置 + // property.SetPrecision(18); + // property.SetScale(2); + // } + // } + // } + //} + + #endregion + //遍历实体模型手动配置 var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(q => q.GetInterface(typeof(IEntityTypeConfiguration<>).FullName) != null); foreach (var type in typesToRegister) diff --git a/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 b/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 index 6246b3f15..25249cb1d 100644 --- a/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 +++ b/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 @@ -109,11 +109,41 @@ public partial class <#= EntityType.Name #>: BaseFullAuditEntity <# } } + if (property.ClrType == typeof(decimal) || property.ClrType == typeof(decimal?)) + { + var typeName = property.GetColumnType()??""; // ȡݿ + // ƥ decimal, numeric, number ʽ + var match = System.Text.RegularExpressions.Regex.Match(typeName, @"(decimal|numeric|number)\((\d+),(\d+)\)", System.Text.RegularExpressions.RegexOptions.IgnoreCase); + if (match.Success) + { + var precision = match.Groups[2].Value; + var scale = match.Groups[3].Value; +#> + [DecimalPrecision(<#= precision #>, <#= scale #>)] +<# + } + + else + { +#> + [DecimalPrecision(18, 2)] // Ĭֵ +<# + } + } + var dataAnnotations = property.GetDataAnnotations(annotationCodeGenerator) .Where(a => !(a.Type == typeof(RequiredAttribute) && Options.UseNullableReferenceTypes && !property.ClrType.IsValueType) - && a.Type != typeof(StringLengthAttribute)); // ų StringLengthAttribute + && a.Type != typeof(StringLengthAttribute) // ų StringLengthAttribute + ); + foreach (var dataAnnotation in dataAnnotations) { + // [Column(TypeName = "decimal(18,1)")] TypeName ֱӹ&& a.Type != typeof(ColumnAttribute) ᱨ + if(dataAnnotation.Arguments?.Count==0) + { + continue; + } + #> <#= code.Fragment(dataAnnotation) #> <# diff --git a/IRaCIS.Core.Test/模板使用说明 b/IRaCIS.Core.Test/模板使用说明 index f74d40bb9..81f681f8b 100644 --- a/IRaCIS.Core.Test/模板使用说明 +++ b/IRaCIS.Core.Test/模板使用说明 @@ -9,6 +9,8 @@ 4、微软官方针对这些不同的库,生成实体的T4模板是一样的,而且也提供了自定义模板的功能,我们可以在官方模板的基础上进行自定义,以适配属于我们项目的实体生成 1)继承我们自己的审计基类 2)生成的时候过滤Id 以及我们自己的审计字段 + 3)为适配多种数据库,自定义指定字符串长度(默认长度不用标注,特殊长度才标注) + 4)为适配多种数据库,自定义精度特性,统一处理 程序包管理控制台命令行工具使用: From 19b647fb4aa7308eee1c467da05f61682ac8beb0 Mon Sep 17 00:00:00 2001 From: hang <87227557@qq.com> Date: Tue, 17 Sep 2024 23:16:11 +0800 Subject: [PATCH 46/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BB=A5=E5=8F=8A=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/1Test.cs | 99 ----------------- IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 | 18 +++- .../UnitOfWork/EFUnitOfWork.cs | 100 +++++++++--------- .../UnitOfWork/IEFUnitOfWork.cs | 32 +++--- .../CodeFirstTest/CodeFirst使用说明 | 3 +- .../NoForeignKeyMigrationsSqlGenerator.cs | 5 + .../CodeFirstTest/MSSQL/IRCContext.cs | 3 +- ...cs => 20240917144649_TestName.Designer.cs} | 86 +++++++++++++-- ..._testSTR.cs => 20240917144649_TestName.cs} | 23 +++- ...20240917145100_TestNameChange.Designer.cs} | 47 ++++++-- ...st.cs => 20240917145100_TestNameChange.cs} | 18 +--- .../Migrations/IRCContextModelSnapshot.cs | 43 +++++++- .../CodeFirstTest/MSSQL/TrialImageDownload.cs | 18 +++- .../CodeTemplates/EFCore/DbContext.t4 | 2 +- .../CodeTemplates/EFCore/EntityType.t4 | 21 ++-- 15 files changed, 296 insertions(+), 222 deletions(-) delete mode 100644 IRaCIS.Core.API/1Test.cs rename IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/{20240912145208_test.Designer.cs => 20240917144649_TestName.Designer.cs} (64%) rename IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/{20240912152420_testSTR.cs => 20240917144649_TestName.cs} (56%) rename IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/{20240912152420_testSTR.Designer.cs => 20240917145100_TestNameChange.Designer.cs} (82%) rename IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/{20240912145208_test.cs => 20240917145100_TestNameChange.cs} (59%) diff --git a/IRaCIS.Core.API/1Test.cs b/IRaCIS.Core.API/1Test.cs deleted file mode 100644 index f7567c3ca..000000000 --- a/IRaCIS.Core.API/1Test.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using Microsoft.EntityFrameworkCore; - -namespace EFSaving.Concurrency -{ - public class Sample - { - public static void Run() - { - // Ensure database is created and has a person in it - using (var setupContext = new PersonContext()) - { - setupContext.Database.EnsureDeleted(); - setupContext.Database.EnsureCreated(); - - setupContext.People.Add(new Person { FirstName = "John", LastName = "Doe" }); - setupContext.SaveChanges(); - } - - #region ConcurrencyHandlingCode - using var context = new PersonContext(); - // Fetch a person from database and change phone number - var person = context.People.Single(p => p.PersonId == 1); - person.PhoneNumber = "555-555-5555"; - - // Change the person's name in the database to simulate a concurrency conflict - context.Database.ExecuteSqlRaw( - "UPDATE dbo.People SET FirstName = 'Jane' WHERE PersonId = 1"); - - var saved = false; - while (!saved) - { - try - { - // Attempt to save changes to the database - context.SaveChanges(); - saved = true; - } - catch (DbUpdateConcurrencyException ex) - { - foreach (var entry in ex.Entries) - { - if (entry.Entity is Person) - { - var proposedValues = entry.CurrentValues; - var databaseValues = entry.GetDatabaseValues(); - - foreach (var property in proposedValues.Properties) - { - var proposedValue = proposedValues[property]; - var databaseValue = databaseValues[property]; - - // TODO: decide which value should be written to database - // proposedValues[property] = ; - } - - // Refresh original values to bypass next concurrency check - entry.OriginalValues.SetValues(databaseValues); - } - else - { - throw new NotSupportedException( - "Don't know how to handle concurrency conflicts for " - + entry.Metadata.Name); - } - } - } - } - #endregion - } - - public class PersonContext : DbContext - { - public DbSet People { get; set; } - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - // Requires NuGet package Microsoft.EntityFrameworkCore.SqlServer - optionsBuilder.UseSqlServer( - @"Server=(localdb)\mssqllocaldb;Database=EFSaving.Concurrency;Trusted_Connection=True"); - } - } - - public class Person - { - public int PersonId { get; set; } - - [ConcurrencyCheck] - public string FirstName { get; set; } - - [ConcurrencyCheck] - public string LastName { get; set; } - - public string PhoneNumber { get; set; } - } - } -} \ No newline at end of file diff --git a/IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 b/IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 index c5e75d12e..6a24debc8 100644 --- a/IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 +++ b/IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 @@ -3,17 +3,25 @@ # ̨ʹ÷ʽ -1Ǩļ -add-migration init -Context IRaCISDBContext +1Ǩļ(add-migration init -Project IRaCIS.Core.Infra.EFCore ) + +add-migration init + +Remove-Migration -# ʹdotnet Ǩ +# ʹdotnet Ǩ(dotnet ef dbcontext list -p IRaCIS.Core.Infra.EFCore ) # dotnet ef migrations add Ǩ -p Ŀ -c ݿ -o ǨļĿ¼ -1Ǩļ -dotnet ef migrations add Initial -s IRaCIS.Core.API -p IRaCIS.Core.Infra.EFCore -c IRaCISDBContext -o CodeFirst_MSSQL/Migrations +1Ǩļ dotnet ef migrations add Initial -s IRaCIS.Core.API -p IRaCIS.Core.Infra.EFCore -c IRaCISDBContext -o CodeFirst_MSSQL/Migrations + +dotnet ef migrations add Initial -p IRaCIS.Core.Infra.EFCore + +2ɵǨļ + + dotnet ef migrations remove -p IRaCIS.Core.Infra.EFCore \ No newline at end of file diff --git a/IRaCIS.Core.Infra.EFCore/UnitOfWork/EFUnitOfWork.cs b/IRaCIS.Core.Infra.EFCore/UnitOfWork/EFUnitOfWork.cs index d12af4b4b..2b80fab4e 100644 --- a/IRaCIS.Core.Infra.EFCore/UnitOfWork/EFUnitOfWork.cs +++ b/IRaCIS.Core.Infra.EFCore/UnitOfWork/EFUnitOfWork.cs @@ -1,62 +1,62 @@ -using System; -using System.Data; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Storage; +//using System; +//using System.Data; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.EntityFrameworkCore; +//using Microsoft.EntityFrameworkCore.Storage; -namespace IRaCIS.Core.Infra.EFCore -{ - public class EFUnitOfWork : - IEFUnitOfWork where TDbContext : DbContext - , IDisposable - { - public DbContext DbContext { get; } - // https://docs.microsoft.com/en-us/ef/core/saving/transactions - private IDbContextTransaction _transaction; +//namespace IRaCIS.Core.Infra.EFCore +//{ +// public class EFUnitOfWork : +// IEFUnitOfWork where TDbContext : DbContext +// , IDisposable +// { +// public DbContext DbContext { get; } +// // https://docs.microsoft.com/en-us/ef/core/saving/transactions +// private IDbContextTransaction _transaction; - public EFUnitOfWork(TDbContext dbContext) - { - DbContext = dbContext; - } +// public EFUnitOfWork(TDbContext dbContext) +// { +// DbContext = dbContext; +// } - public void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted) - { - if (DbContext.Database.IsRelational()) - { - _transaction = DbContext.Database.BeginTransaction(isolationLevel); - } - } +// public void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted) +// { +// if (DbContext.Database.IsRelational()) +// { +// _transaction = DbContext.Database.BeginTransaction(isolationLevel); +// } +// } - public async Task BeginTransactionAsync(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted) - { - if (DbContext.Database.IsRelational()) - { - _transaction = await DbContext.Database.BeginTransactionAsync(isolationLevel); - } - } +// public async Task BeginTransactionAsync(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted) +// { +// if (DbContext.Database.IsRelational()) +// { +// _transaction = await DbContext.Database.BeginTransactionAsync(isolationLevel); +// } +// } - //失败 自动回退 - public virtual void Commit() - { - DbContext.SaveChanges(); - _transaction?.Commit(); - } +// //失败 自动回退 +// public virtual void Commit() +// { +// DbContext.SaveChanges(); +// _transaction?.Commit(); +// } - public virtual async Task CommitAsync(CancellationToken cancellationToken) - { - await DbContext.SaveChangesAsync(cancellationToken); +// public virtual async Task CommitAsync(CancellationToken cancellationToken) +// { +// await DbContext.SaveChangesAsync(cancellationToken); - await _transaction?.CommitAsync(cancellationToken); +// await _transaction?.CommitAsync(cancellationToken); - } +// } - public virtual void Dispose() - { - _transaction?.Dispose(); - } +// public virtual void Dispose() +// { +// _transaction?.Dispose(); +// } - } -} +// } +//} diff --git a/IRaCIS.Core.Infra.EFCore/UnitOfWork/IEFUnitOfWork.cs b/IRaCIS.Core.Infra.EFCore/UnitOfWork/IEFUnitOfWork.cs index 6d04c783c..9fb045614 100644 --- a/IRaCIS.Core.Infra.EFCore/UnitOfWork/IEFUnitOfWork.cs +++ b/IRaCIS.Core.Infra.EFCore/UnitOfWork/IEFUnitOfWork.cs @@ -1,22 +1,22 @@ -using System; -using System.Data; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; +//using System; +//using System.Data; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.EntityFrameworkCore; -namespace IRaCIS.Core.Infra.EFCore -{ - public interface IEFUnitOfWork :IDisposable where TDbContext : DbContext - { - DbContext DbContext { get; } +//namespace IRaCIS.Core.Infra.EFCore +//{ +// public interface IEFUnitOfWork :IDisposable where TDbContext : DbContext +// { +// DbContext DbContext { get; } - void BeginTransaction(IsolationLevel isolationLevel= IsolationLevel.ReadCommitted); +// void BeginTransaction(IsolationLevel isolationLevel= IsolationLevel.ReadCommitted); - Task BeginTransactionAsync(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted); +// Task BeginTransactionAsync(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted); - void Commit(); - Task CommitAsync(CancellationToken cancellationToken); +// void Commit(); +// Task CommitAsync(CancellationToken cancellationToken); - } -} +// } +//} diff --git a/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 b/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 index 8f755d360..900b5b978 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 +++ b/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 @@ -20,7 +20,8 @@ https://www.cnblogs.com/cqpanda/p/16815263.html 5ijθµݿǨƣԶִdown dotnet ef database update ijǨƵǰһǨ -p IRaCIS.Core.Test -c IRCContext - dotnet ef migrations add RemoveForeignKey -p IRaCIS.Core.Test -c IRCContext -o CodeFirstTest/MSSQL/Migrations + dotnet ef database update TestName -p IRaCIS.Core.Test -c IRCContext + diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/NoForeignKeyMigrationsSqlGenerator.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/NoForeignKeyMigrationsSqlGenerator.cs index 934413c0a..3cc41766f 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/NoForeignKeyMigrationsSqlGenerator.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/NoForeignKeyMigrationsSqlGenerator.cs @@ -16,5 +16,10 @@ namespace IRaCIS.Core.Test operation.ForeignKeys.Clear(); base.Generate(operation, model, builder, terminate); } + protected override void Generate(AddForeignKeyOperation operation, IModel? model, MigrationCommandListBuilder builder, bool terminate = true) + { + return; + } + } } diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs index d89991305..5780659dd 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs @@ -34,7 +34,8 @@ public partial class IRCContext : DbContext public virtual DbSet ProjectUser { get; set; } public virtual DbSet ProjectUser2 { get; set; } - + public virtual DbSet TestFieldName { get; set; } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.Designer.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917144649_TestName.Designer.cs similarity index 64% rename from IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.Designer.cs rename to IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917144649_TestName.Designer.cs index d0f7385ae..3ebd0d69f 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.Designer.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917144649_TestName.Designer.cs @@ -12,8 +12,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations { [DbContext(typeof(IRCContext))] - [Migration("20240912145208_test")] - partial class test + [Migration("20240917144649_TestName")] + partial class TestName { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -65,12 +65,7 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.Property("CreateUserId") .HasColumnType("uniqueidentifier"); - b.Property("Name2") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("OtherName") + b.Property("Name") .IsRequired() .HasMaxLength(200) .HasColumnType("nvarchar(200)"); @@ -119,6 +114,81 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.ToTable("ProjectUser2"); }); + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestFieldName", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("NAME1") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("NAme2") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("naMe3") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("TestFieldName"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DefineLength") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("DefualtLength") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("MaxLength") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("TestStr"); + }); + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => { b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917144649_TestName.cs similarity index 56% rename from IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.cs rename to IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917144649_TestName.cs index 6b04291ac..f504d5115 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917144649_TestName.cs @@ -6,11 +6,29 @@ using Microsoft.EntityFrameworkCore.Migrations; namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations { /// - public partial class testSTR : Migration + public partial class TestName : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) { + migrationBuilder.CreateTable( + name: "TestFieldName", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + NAME1 = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + NAme2 = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + naMe3 = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + CreateUserId = table.Column(type: "uniqueidentifier", nullable: false), + CreateTime = table.Column(type: "datetime2", nullable: false), + UpdateUserId = table.Column(type: "uniqueidentifier", nullable: false), + UpdateTime = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TestFieldName", x => x.Id); + }); + migrationBuilder.CreateTable( name: "TestStr", columns: table => new @@ -33,6 +51,9 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations /// protected override void Down(MigrationBuilder migrationBuilder) { + migrationBuilder.DropTable( + name: "TestFieldName"); + migrationBuilder.DropTable( name: "TestStr"); } diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.Designer.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.Designer.cs similarity index 82% rename from IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.Designer.cs rename to IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.Designer.cs index 9c516cb77..108267f5a 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912152420_testSTR.Designer.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.Designer.cs @@ -12,8 +12,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations { [DbContext(typeof(IRCContext))] - [Migration("20240912152420_testSTR")] - partial class testSTR + [Migration("20240917145100_TestNameChange")] + partial class TestNameChange { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -70,11 +70,6 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations .HasMaxLength(200) .HasColumnType("nvarchar(200)"); - b.Property("OtherName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - b.Property("ProjectId") .HasColumnType("uniqueidentifier"); @@ -119,6 +114,44 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.ToTable("ProjectUser2"); }); + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestFieldName", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("NAME1") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("NAme2") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("naMe3") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("TestFieldName"); + }); + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => { b.Property("Id") diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.cs similarity index 59% rename from IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.cs rename to IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.cs index f4e031f05..7086e78b2 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912145208_test.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.cs @@ -5,7 +5,7 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations { /// - public partial class test : Migration + public partial class TestNameChange : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) @@ -13,26 +13,14 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations migrationBuilder.RenameColumn( name: "Name", table: "ProjectUser", - newName: "OtherName"); - - migrationBuilder.AddColumn( - name: "Name2", - table: "ProjectUser", - type: "nvarchar(200)", - maxLength: 200, - nullable: false, - defaultValue: ""); + newName: "Name2"); } /// protected override void Down(MigrationBuilder migrationBuilder) { - migrationBuilder.DropColumn( - name: "Name2", - table: "ProjectUser"); - migrationBuilder.RenameColumn( - name: "OtherName", + name: "Name2", table: "ProjectUser", newName: "Name"); } diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs index 58210d549..ddacb9d81 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs @@ -67,11 +67,6 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations .HasMaxLength(200) .HasColumnType("nvarchar(200)"); - b.Property("OtherName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - b.Property("ProjectId") .HasColumnType("uniqueidentifier"); @@ -116,6 +111,44 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.ToTable("ProjectUser2"); }); + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestFieldName", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("NAME1") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("NAme2") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("naMe3") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("TestFieldName"); + }); + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => { b.Property("Id") diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs index 1a9805d06..111fea871 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs @@ -157,13 +157,13 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL public class ProjectUser : BaseFullAuditEntity { - public string Name2 { get; set; } + //public string Name2 { get; set; } - public string OtherName { get; set; } + //public string OtherName { get; set; } public string Code { get; set; } - + public string Name2 { get; set; } //外键 public Guid ProjectId { get; set; } @@ -195,4 +195,16 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL #endregion + + #region 测试命名不符合规则 + + public class TestFieldName : BaseFullAuditEntity + { + public string NAME1 { get; set; } + + public string NAme2 { get; set; } + + public string naMe3 { get; set; } + } + #endregion } diff --git a/IRaCIS.Core.Test/CodeTemplates/EFCore/DbContext.t4 b/IRaCIS.Core.Test/CodeTemplates/EFCore/DbContext.t4 index 1351902b0..c45f19507 100644 --- a/IRaCIS.Core.Test/CodeTemplates/EFCore/DbContext.t4 +++ b/IRaCIS.Core.Test/CodeTemplates/EFCore/DbContext.t4 @@ -197,7 +197,7 @@ public partial class <#= Options.ContextName #> : DbContext WriteLine(""); } #> - entity.Property(e => e.<#= property.Name #>)<#= code.Fragment(propertyFluentApiCalls, indent: 4) #>; + entity.Property(e => e.<#= property.GetColumnName() #>)<#= code.Fragment(propertyFluentApiCalls, indent: 4) #>; <# anyEntityTypeConfiguration = true; firstProperty = false; diff --git a/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 b/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 index 25249cb1d..db80a2a87 100644 --- a/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 +++ b/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 @@ -49,7 +49,7 @@ namespace <#= NamespaceHint #>; if (!string.IsNullOrEmpty(EntityType.GetComment())) { #> -[Comment("<#= code.XmlComment(EntityType.GetComment()) #>")] +[Comment("<#= code.XmlComment(EntityType.GetComment().Replace("\\", "|").Trim()) #>")] <# } @@ -80,9 +80,10 @@ public partial class <#= EntityType.Name #>: BaseFullAuditEntity if (!string.IsNullOrEmpty(property.GetComment())) { #> - [Comment(" <#= code.XmlComment(property.GetComment()) #>")] + [Comment(" <#= code.XmlComment(property.GetComment().Replace("\\", "|").Trim()) #>")] <# } + if (Options.UseDataAnnotations) { @@ -93,14 +94,9 @@ public partial class <#= EntityType.Name #>: BaseFullAuditEntity if (maxLength.HasValue && maxLength != 200) // ȲΪ200ʱ[StringLength] { - - #> [StringLength(<#= maxLength.Value #>)] -<# - - - +<# } else { @@ -134,7 +130,7 @@ public partial class <#= EntityType.Name #>: BaseFullAuditEntity var dataAnnotations = property.GetDataAnnotations(annotationCodeGenerator) .Where(a => !(a.Type == typeof(RequiredAttribute) && Options.UseNullableReferenceTypes && !property.ClrType.IsValueType) && a.Type != typeof(StringLengthAttribute) // ų StringLengthAttribute - ); + ); foreach (var dataAnnotation in dataAnnotations) { @@ -143,6 +139,11 @@ public partial class <#= EntityType.Name #>: BaseFullAuditEntity { continue; } + + if(dataAnnotation.Arguments?[0]== property.GetColumnName() && property.GetColumnName() !=property.Name ) + { + continue; + } #> <#= code.Fragment(dataAnnotation) #> @@ -155,7 +156,7 @@ public partial class <#= EntityType.Name #>: BaseFullAuditEntity var needsNullable = Options.UseNullableReferenceTypes && property.IsNullable && !property.ClrType.IsValueType; var needsInitializer = Options.UseNullableReferenceTypes && !property.IsNullable && !property.ClrType.IsValueType; #> - public <#= code.Reference(property.ClrType) #><#= needsNullable ? "?" : "" #> <#= property.Name #> { get; set; }<#= needsInitializer ? " = null!;" : "" #> + public <#= code.Reference(property.ClrType) #><#= needsNullable ? "?" : "" #> <#= property.GetColumnName() #> { get; set; }<#= needsInitializer ? " = null!;" : "" #> <# firstProperty = false; } From f1fadebfbab8411bb3efa4515bdf263d59bf72ee Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 18 Sep 2024 10:23:40 +0800 Subject: [PATCH 47/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=98=85=E7=89=87?= =?UTF-8?q?=E6=9C=9F=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingPeriod/ReadModuleService.cs | 2 +- .../CodeFirstTest/MSSQL/IRCContext.cs | 3 +- .../20240918010002_Comment.Designer.cs | 254 ++++++++++++++++++ .../Migrations/20240918010002_Comment.cs | 40 +++ .../20240918010449_CommentModify.Designer.cs | 253 +++++++++++++++++ .../20240918010449_CommentModify.cs | 74 +++++ .../Migrations/IRCContextModelSnapshot.cs | 37 +++ .../CodeFirstTest/MSSQL/TrialImageDownload.cs | 15 +- 8 files changed, 675 insertions(+), 3 deletions(-) create mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.Designer.cs create mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.cs create mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.Designer.cs create mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.cs diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingPeriod/ReadModuleService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingPeriod/ReadModuleService.cs index a37441d60..6c5ec1635 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingPeriod/ReadModuleService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingPeriod/ReadModuleService.cs @@ -605,7 +605,7 @@ namespace IRaCIS.Application.Services //只有阅片期有 CutOffVisitId = rm.SubjectVisit.Id, CutOffVisitName = rm.SubjectVisit.VisitName, - ReadingSetType = null, + ReadingSetType = rm.ReadingSetType, //之前视图返回的null 应该是没用的? ReadModuleId = rm.Id, diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs index 5780659dd..9c8af85c6 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs @@ -35,8 +35,9 @@ public partial class IRCContext : DbContext public virtual DbSet ProjectUser2 { get; set; } public virtual DbSet TestFieldName { get; set; } - + public virtual DbSet TestComment { get; set; } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // 替换默认的 MigrationsSqlGenerator diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.Designer.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.Designer.cs new file mode 100644 index 000000000..ea56ce6dd --- /dev/null +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.Designer.cs @@ -0,0 +1,254 @@ +// +using System; +using IRaCIS.Core.Test.CodeFirstTest.MSSQL; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations +{ + [DbContext(typeof(IRCContext))] + [Migration("20240918010002_Comment")] + partial class Comment + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("Project"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name2") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectUser"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectUser2"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestComment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)") + .HasComment("这是字段备注Code"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)") + .HasComment("这是字段备注Name"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("TestComment", t => + { + t.HasComment("这是类备注"); + }); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestFieldName", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("NAME1") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("NAme2") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("naMe3") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("TestFieldName"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DefineLength") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("DefualtLength") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("MaxLength") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("TestStr"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => + { + b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => + { + b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.cs new file mode 100644 index 000000000..ce24674e1 --- /dev/null +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.cs @@ -0,0 +1,40 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations +{ + /// + public partial class Comment : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "TestComment", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Code = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false, comment: "这是字段备注Code"), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false, comment: "这是字段备注Name"), + CreateUserId = table.Column(type: "uniqueidentifier", nullable: false), + CreateTime = table.Column(type: "datetime2", nullable: false), + UpdateUserId = table.Column(type: "uniqueidentifier", nullable: false), + UpdateTime = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TestComment", x => x.Id); + }, + comment: "这是类备注"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "TestComment"); + } + } +} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.Designer.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.Designer.cs new file mode 100644 index 000000000..6fc40cb71 --- /dev/null +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.Designer.cs @@ -0,0 +1,253 @@ +// +using System; +using IRaCIS.Core.Test.CodeFirstTest.MSSQL; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations +{ + [DbContext(typeof(IRCContext))] + [Migration("20240918010449_CommentModify")] + partial class CommentModify + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("Project"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name2") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectUser"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectUser2"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestComment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)") + .HasComment("这是字段备注Name的修改"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("TestComment", t => + { + t.HasComment("这是类备注的修改"); + }); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestFieldName", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("NAME1") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("NAme2") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("naMe3") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("TestFieldName"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DefineLength") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("DefualtLength") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("MaxLength") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("TestStr"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => + { + b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => + { + b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.cs new file mode 100644 index 000000000..96d191beb --- /dev/null +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.cs @@ -0,0 +1,74 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations +{ + /// + public partial class CommentModify : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterTable( + name: "TestComment", + comment: "这是类备注的修改", + oldComment: "这是类备注"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "TestComment", + type: "nvarchar(200)", + maxLength: 200, + nullable: false, + comment: "这是字段备注Name的修改", + oldClrType: typeof(string), + oldType: "nvarchar(200)", + oldMaxLength: 200, + oldComment: "这是字段备注Name"); + + migrationBuilder.AlterColumn( + name: "Code", + table: "TestComment", + type: "nvarchar(200)", + maxLength: 200, + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(200)", + oldMaxLength: 200, + oldComment: "这是字段备注Code"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterTable( + name: "TestComment", + comment: "这是类备注", + oldComment: "这是类备注的修改"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "TestComment", + type: "nvarchar(200)", + maxLength: 200, + nullable: false, + comment: "这是字段备注Name", + oldClrType: typeof(string), + oldType: "nvarchar(200)", + oldMaxLength: 200, + oldComment: "这是字段备注Name的修改"); + + migrationBuilder.AlterColumn( + name: "Code", + table: "TestComment", + type: "nvarchar(200)", + maxLength: 200, + nullable: false, + comment: "这是字段备注Code", + oldClrType: typeof(string), + oldType: "nvarchar(200)", + oldMaxLength: 200); + } + } +} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs index ddacb9d81..558de01a7 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs @@ -111,6 +111,43 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.ToTable("ProjectUser2"); }); + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestComment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)") + .HasComment("这是字段备注Name的修改"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("TestComment", t => + { + t.HasComment("这是类备注的修改"); + }); + }); + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestFieldName", b => { b.Property("Id") diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs index 111fea871..c36ea74ca 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.EntityFrameworkCore; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -207,4 +208,16 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL public string naMe3 { get; set; } } #endregion + + #region 测试备注迁移 以及修改备注迁移 + + [Comment("这是类备注的修改")] + public class TestComment: BaseFullAuditEntity + { + public string Code { get; set; } + + [Comment("这是字段备注Name的修改")] + public string Name { get; set; } + } + #endregion } From 0216665d5b925a2b0ee8bd98106becefd628a03e Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 18 Sep 2024 10:30:01 +0800 Subject: [PATCH 48/59] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E6=A8=A1=E5=9E=8B=EF=BC=8C=E5=90=8C=E6=97=B6=E6=B8=85?= =?UTF-8?q?=E7=90=86=E8=A7=86=E5=9B=BE=E6=A8=A1=E5=9E=8Bbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Doctor/DTO/DoctorModel.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Doctor/DTO/DoctorModel.cs b/IRaCIS.Core.Application/Service/Doctor/DTO/DoctorModel.cs index 62e84fc93..c9c49cfde 100644 --- a/IRaCIS.Core.Application/Service/Doctor/DTO/DoctorModel.cs +++ b/IRaCIS.Core.Application/Service/Doctor/DTO/DoctorModel.cs @@ -617,7 +617,6 @@ namespace IRaCIS.Application.Contracts public List SubspecialityIds { get; set; } = new List(); public Guid Id { get; set; } - public string OtherSkills { get; set; } = string.Empty; public string ReadingTypeOther { get; set; } = string.Empty; public string ReadingTypeOtherCN { get; set; } = string.Empty; From 5b2b5fead9a0272e203d10179d50f337f5908623 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 18 Sep 2024 10:43:11 +0800 Subject: [PATCH 49/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Test_IRC.json | 2 +- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 2 +- IRaCIS.Core.API/appsettings.US_Test_IRC.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index b42343431..1ccc9c7f2 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -44,7 +44,7 @@ "AccessKeyId": "AKIAW3MEAFJX7IPXISP4", "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", - "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com", "DurationSeconds": 7200 } }, diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index a2fa640b5..2943de824 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -33,7 +33,7 @@ "AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM", "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", - "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com", "DurationSeconds": 7200 } }, diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json index 8625d51d0..e12bcd647 100644 --- a/IRaCIS.Core.API/appsettings.US_Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -39,7 +39,7 @@ "AccessKeyId": "AKIAW3MEAFJX7IPXISP4", "SecretAccessKey": "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", "BucketName": "ei-med-s3-lili-uat-store", - "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/", + "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com", "DurationSeconds": 7200 } }, From a64cec987d92984effafba224704203020b1d3fd Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 18 Sep 2024 14:51:20 +0800 Subject: [PATCH 50/59] =?UTF-8?q?codefirst=20=E6=B5=8B=E8=AF=95=E5=AE=8C?= =?UTF-8?q?=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 | 33 ++- .../NoForeignKeyMigrationsSqlGenerator.cs | 14 +- .../IRaCIS.Core.Infra.EFCore.csproj | 4 +- .../CodeFirstTest/CodeFirst使用说明 | 40 +-- .../Convention/DecimalPrecisionConvention.cs | 42 +++ .../NoForeignKeyMigrationsSqlGenerator.cs | 11 +- .../CodeFirstTest/MSSQL/IRCContext.cs | 7 +- .../20240917145100_TestNameChange.cs | 28 -- .../20240918010002_Comment.Designer.cs | 254 ------------------ .../Migrations/20240918010002_Comment.cs | 40 --- .../20240918010449_CommentModify.Designer.cs | 253 ----------------- .../20240918010449_CommentModify.cs | 74 ----- ...cs => 20240918042003_addField.Designer.cs} | 47 +--- ...TestName.cs => 20240918042003_addField.cs} | 57 ++-- ... => 20240918042206_addComment.Designer.cs} | 50 +++- .../Migrations/20240918042206_addComment.cs | 58 ++++ ...s => 20240918042443_addField2.Designer.cs} | 58 ++-- ...ddField.cs => 20240918042443_addField2.cs} | 22 +- .../Migrations/IRCContextModelSnapshot.cs | 93 ++----- .../CodeFirstTest/MSSQL/TrialImageDownload.cs | 55 +++- 20 files changed, 354 insertions(+), 886 deletions(-) create mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/DecimalPrecisionConvention.cs delete mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.cs delete mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.Designer.cs delete mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.cs delete mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.Designer.cs delete mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.cs rename IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/{20240917145100_TestNameChange.Designer.cs => 20240918042003_addField.Designer.cs} (82%) rename IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/{20240917144649_TestName.cs => 20240918042003_addField.cs} (56%) rename IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/{20240912072724_addField.Designer.cs => 20240918042206_addComment.Designer.cs} (73%) create mode 100644 IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042206_addComment.cs rename IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/{20240917144649_TestName.Designer.cs => 20240918042443_addField2.Designer.cs} (83%) rename IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/{20240912072724_addField.cs => 20240918042443_addField2.cs} (53%) diff --git a/IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 b/IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 index 6a24debc8..f00ddbdc4 100644 --- a/IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 +++ b/IRaCIS.Core.Infra.EFCore/CodeFirst使用说明 @@ -1,16 +1,25 @@ - - # ̨ʹ÷ʽ 1Ǩļ(add-migration init -Project IRaCIS.Core.Infra.EFCore ) -add-migration init + add-migration init -Remove-Migration +2ƳɵǨļ + Remove-Migration +3ݿΪǨ + Update-Database + +4ݿΪǨƣ + + Update-Database xxxName + +5һָ from ǨƵָ to ǨƵ SQL ű + + Script-Migration from to @@ -20,8 +29,20 @@ Remove-Migration 1Ǩļ dotnet ef migrations add Initial -s IRaCIS.Core.API -p IRaCIS.Core.Infra.EFCore -c IRaCISDBContext -o CodeFirst_MSSQL/Migrations -dotnet ef migrations add Initial -p IRaCIS.Core.Infra.EFCore + dotnet ef migrations add Initial -p IRaCIS.Core.Infra.EFCore 2ɵǨļ - dotnet ef migrations remove -p IRaCIS.Core.Infra.EFCore \ No newline at end of file + dotnet ef migrations remove -p IRaCIS.Core.Infra.EFCore + +3Ǩļµݿ + + dotnet ef database update -p IRaCIS.Core.Infra.EFCore + +4ݿΪǨ + + dotnet ef database update xxxName -p IRaCIS.Core.Infra.EFCore + +5һָ from ǨƵָ to ǨƵ SQL ű + + dotnet ef migrations script from to -p IRaCIS.Core.Infra.EFCore \ No newline at end of file diff --git a/IRaCIS.Core.Infra.EFCore/Context/Convention/NoForeignKeyMigrationsSqlGenerator.cs b/IRaCIS.Core.Infra.EFCore/Context/Convention/NoForeignKeyMigrationsSqlGenerator.cs index 7603b8e06..148fd12ea 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/Convention/NoForeignKeyMigrationsSqlGenerator.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/Convention/NoForeignKeyMigrationsSqlGenerator.cs @@ -1,6 +1,7 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations.Operations; +using Microsoft.EntityFrameworkCore.Update; namespace IRaCIS.Core.Infra.EFCore; @@ -8,10 +9,12 @@ namespace IRaCIS.Core.Infra.EFCore; /// /// 迁移的时候,忽略显示外键的建立,增加灵活性,同时为了兼容之前dbfirst 一个字段关联多个表 /// -public class NoForeignKeyMigrationsSqlGenerator : MigrationsSqlGenerator +public class NoForeignKeyMigrationsSqlGenerator : SqlServerMigrationsSqlGenerator { - public NoForeignKeyMigrationsSqlGenerator( - MigrationsSqlGeneratorDependencies dependencies) : base(dependencies) + + + public NoForeignKeyMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, ICommandBatchPreparer commandBatchPreparer) + : base(dependencies, commandBatchPreparer) { } @@ -20,4 +23,9 @@ public class NoForeignKeyMigrationsSqlGenerator : MigrationsSqlGenerator operation.ForeignKeys.Clear(); base.Generate(operation, model, builder, terminate); } + protected override void Generate(AddForeignKeyOperation operation, IModel? model, MigrationCommandListBuilder builder, bool terminate = true) + { + + } + } diff --git a/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj b/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj index 60a1b70d4..b68ba65dc 100644 --- a/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj +++ b/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj @@ -1,5 +1,7 @@  - + + enable + net8.0 diff --git a/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 b/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 index 900b5b978..e126a2272 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 +++ b/IRaCIS.Core.Test/CodeFirstTest/CodeFirst使用说明 @@ -3,31 +3,33 @@ https://www.cnblogs.com/cqpanda/p/16815263.html - # dotnet ef migrations add Ǩ -p Ŀ -c ݿ -o ǨļĿ¼ +# ʹdotnet Ǩ(dotnet ef dbcontext list -p IRaCIS.Core.Infra.EFCore ) - 1Ǩļ - dotnet ef migrations add Initial -p IRaCIS.Core.Test -c IRCContext -o CodeFirstTest/MSSQL/Migrations +# dotnet ef migrations add Ǩ -p Ŀ -c ݿ -o ǨļĿ¼ - 2ղɵǨļδµݿģ - dotnet ef migrations remove -p IRaCIS.Core.Test -c IRCContext +1Ǩļ dotnet ef migrations add xxx -s IRaCIS.Core.API -p IRaCIS.Core.Infra.EFCore -c IRaCISDBContext -o CodeFirst_MSSQL/Migrations - 3Ǩļµݿ - dotnet ef database update -p IRaCIS.Core.Test -c IRCContext + dotnet ef migrations add xxx -p IRaCIS.Core.Test -c IRCContext - 4鿴Ǩ - dotnet ef migrations list -p IRaCIS.Core.Test -c IRCContext +2ɵǨļ - 5ijθµݿǨƣԶִdown - dotnet ef database update ijǨƵǰһǨ -p IRaCIS.Core.Test -c IRCContext + dotnet ef migrations remove -p IRaCIS.Core.Test -c IRCContext - dotnet ef database update TestName -p IRaCIS.Core.Test -c IRCContext +3Ǩļµݿ + + dotnet ef database update -p IRaCIS.Core.Test -c IRCContext + +4ݿΪǨ + + dotnet ef database update xxxName -p IRaCIS.Core.Test -c IRCContext + +5һָ from ǨƵָ to ǨƵ SQL ű + + dotnet ef migrations script from to -p IRaCIS.Core.Test -c IRCContext +PGSQL : + + dotnet ef migrations add testSTR -p IRaCIS.Core.Test -c PGContext -o CodeFirstTest/PGSQL/Migrations - - - - PGSQL ָ - dotnet ef migrations add testSTR -p IRaCIS.Core.Test -c PGContext -o CodeFirstTest/PGSQL/Migrations - - dotnet ef migrations remove -p IRaCIS.Core.Test -c PGContext \ No newline at end of file + dotnet ef migrations remove -p IRaCIS.Core.Test -c PGContext \ No newline at end of file diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/DecimalPrecisionConvention.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/DecimalPrecisionConvention.cs new file mode 100644 index 000000000..fa40d704e --- /dev/null +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/DecimalPrecisionConvention.cs @@ -0,0 +1,42 @@ +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Test; + +/// +/// 设置decimal 默认精度问题 (但是用ef迁移工具的时候,还是会提示No store type was specified for the decimal property,但是迁移文件里面体现了该配置,在dbcontext里写,那么就会没该警告) +/// +public class DecimalPrecisionConvention : IModelFinalizingConvention +{ + private readonly int _precision; + private readonly int _scale; + + public DecimalPrecisionConvention(int precision, int scale) + { + _precision = precision; + _scale = scale; + } + + public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext context) + { + + foreach (var property in modelBuilder.Metadata.GetEntityTypes() + .SelectMany( + entityType => entityType.GetDeclaredProperties() + .Where( + property => property.ClrType == typeof(decimal) || property.ClrType == typeof(decimal?)))) + { + + + // 设置精度和小数位数 + property.SetPrecision(_precision); + property.SetScale(_scale); + } + } +} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/NoForeignKeyMigrationsSqlGenerator.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/NoForeignKeyMigrationsSqlGenerator.cs index 3cc41766f..bb5cbb026 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/NoForeignKeyMigrationsSqlGenerator.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Convention/NoForeignKeyMigrationsSqlGenerator.cs @@ -1,13 +1,16 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations.Operations; +using Microsoft.EntityFrameworkCore.Update; namespace IRaCIS.Core.Test { - public class NoForeignKeyMigrationsSqlGenerator : MigrationsSqlGenerator + public class NoForeignKeyMigrationsSqlGenerator : SqlServerMigrationsSqlGenerator { - public NoForeignKeyMigrationsSqlGenerator( - MigrationsSqlGeneratorDependencies dependencies) : base(dependencies) + + + public NoForeignKeyMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, ICommandBatchPreparer commandBatchPreparer) + : base(dependencies, commandBatchPreparer) { } @@ -18,7 +21,7 @@ namespace IRaCIS.Core.Test } protected override void Generate(AddForeignKeyOperation operation, IModel? model, MigrationCommandListBuilder builder, bool terminate = true) { - return; + } } diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs index 9c8af85c6..26b6839f3 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/IRCContext.cs @@ -34,10 +34,13 @@ public partial class IRCContext : DbContext public virtual DbSet ProjectUser { get; set; } public virtual DbSet ProjectUser2 { get; set; } - public virtual DbSet TestFieldName { get; set; } + //public virtual DbSet TestFieldName { get; set; } - public virtual DbSet TestComment { get; set; } + //public virtual DbSet TestComment { get; set; } + + //public virtual DbSet TestStrDefaultValue { get; set; } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // 替换默认的 MigrationsSqlGenerator diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.cs deleted file mode 100644 index 7086e78b2..000000000 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations -{ - /// - public partial class TestNameChange : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.RenameColumn( - name: "Name", - table: "ProjectUser", - newName: "Name2"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.RenameColumn( - name: "Name2", - table: "ProjectUser", - newName: "Name"); - } - } -} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.Designer.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.Designer.cs deleted file mode 100644 index ea56ce6dd..000000000 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.Designer.cs +++ /dev/null @@ -1,254 +0,0 @@ -// -using System; -using IRaCIS.Core.Test.CodeFirstTest.MSSQL; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations -{ - [DbContext(typeof(IRCContext))] - [Migration("20240918010002_Comment")] - partial class Comment - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.8") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.ToTable("Project"); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("Name2") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("ProjectId") - .HasColumnType("uniqueidentifier"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("ProjectId"); - - b.ToTable("ProjectUser"); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("ProjectId") - .HasColumnType("uniqueidentifier"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("ProjectId"); - - b.ToTable("ProjectUser2"); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestComment", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)") - .HasComment("这是字段备注Code"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)") - .HasComment("这是字段备注Name"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.ToTable("TestComment", t => - { - t.HasComment("这是类备注"); - }); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestFieldName", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("NAME1") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("NAme2") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("naMe3") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id"); - - b.ToTable("TestFieldName"); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("DefineLength") - .IsRequired() - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.Property("DefualtLength") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("MaxLength") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.ToTable("TestStr"); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => - { - b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") - .WithMany() - .HasForeignKey("ProjectId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Project"); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => - { - b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") - .WithMany() - .HasForeignKey("ProjectId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Project"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.cs deleted file mode 100644 index ce24674e1..000000000 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010002_Comment.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations -{ - /// - public partial class Comment : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "TestComment", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - Code = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false, comment: "这是字段备注Code"), - Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false, comment: "这是字段备注Name"), - CreateUserId = table.Column(type: "uniqueidentifier", nullable: false), - CreateTime = table.Column(type: "datetime2", nullable: false), - UpdateUserId = table.Column(type: "uniqueidentifier", nullable: false), - UpdateTime = table.Column(type: "datetime2", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_TestComment", x => x.Id); - }, - comment: "这是类备注"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "TestComment"); - } - } -} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.Designer.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.Designer.cs deleted file mode 100644 index 6fc40cb71..000000000 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.Designer.cs +++ /dev/null @@ -1,253 +0,0 @@ -// -using System; -using IRaCIS.Core.Test.CodeFirstTest.MSSQL; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations -{ - [DbContext(typeof(IRCContext))] - [Migration("20240918010449_CommentModify")] - partial class CommentModify - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.8") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.ToTable("Project"); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("Name2") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("ProjectId") - .HasColumnType("uniqueidentifier"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("ProjectId"); - - b.ToTable("ProjectUser"); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("ProjectId") - .HasColumnType("uniqueidentifier"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("ProjectId"); - - b.ToTable("ProjectUser2"); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestComment", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)") - .HasComment("这是字段备注Name的修改"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.ToTable("TestComment", t => - { - t.HasComment("这是类备注的修改"); - }); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestFieldName", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("NAME1") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("NAme2") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("naMe3") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id"); - - b.ToTable("TestFieldName"); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("DefineLength") - .IsRequired() - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.Property("DefualtLength") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("MaxLength") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.ToTable("TestStr"); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => - { - b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") - .WithMany() - .HasForeignKey("ProjectId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Project"); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser2", b => - { - b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") - .WithMany() - .HasForeignKey("ProjectId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Project"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.cs deleted file mode 100644 index 96d191beb..000000000 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918010449_CommentModify.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations -{ - /// - public partial class CommentModify : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterTable( - name: "TestComment", - comment: "这是类备注的修改", - oldComment: "这是类备注"); - - migrationBuilder.AlterColumn( - name: "Name", - table: "TestComment", - type: "nvarchar(200)", - maxLength: 200, - nullable: false, - comment: "这是字段备注Name的修改", - oldClrType: typeof(string), - oldType: "nvarchar(200)", - oldMaxLength: 200, - oldComment: "这是字段备注Name"); - - migrationBuilder.AlterColumn( - name: "Code", - table: "TestComment", - type: "nvarchar(200)", - maxLength: 200, - nullable: false, - oldClrType: typeof(string), - oldType: "nvarchar(200)", - oldMaxLength: 200, - oldComment: "这是字段备注Code"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterTable( - name: "TestComment", - comment: "这是类备注", - oldComment: "这是类备注的修改"); - - migrationBuilder.AlterColumn( - name: "Name", - table: "TestComment", - type: "nvarchar(200)", - maxLength: 200, - nullable: false, - comment: "这是字段备注Name", - oldClrType: typeof(string), - oldType: "nvarchar(200)", - oldMaxLength: 200, - oldComment: "这是字段备注Name的修改"); - - migrationBuilder.AlterColumn( - name: "Code", - table: "TestComment", - type: "nvarchar(200)", - maxLength: 200, - nullable: false, - comment: "这是字段备注Code", - oldClrType: typeof(string), - oldType: "nvarchar(200)", - oldMaxLength: 200); - } - } -} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.Designer.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042003_addField.Designer.cs similarity index 82% rename from IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.Designer.cs rename to IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042003_addField.Designer.cs index 108267f5a..2493fc036 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917145100_TestNameChange.Designer.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042003_addField.Designer.cs @@ -12,8 +12,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations { [DbContext(typeof(IRCContext))] - [Migration("20240917145100_TestNameChange")] - partial class TestNameChange + [Migration("20240918042003_addField")] + partial class addField { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -98,6 +98,11 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.Property("CreateUserId") .HasColumnType("uniqueidentifier"); + b.Property("NewCreateName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + b.Property("ProjectId") .HasColumnType("uniqueidentifier"); @@ -114,44 +119,6 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.ToTable("ProjectUser2"); }); - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestFieldName", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("NAME1") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("NAme2") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("naMe3") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id"); - - b.ToTable("TestFieldName"); - }); - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => { b.Property("Id") diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917144649_TestName.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042003_addField.cs similarity index 56% rename from IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917144649_TestName.cs rename to IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042003_addField.cs index f504d5115..b217b2306 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917144649_TestName.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042003_addField.cs @@ -6,28 +6,34 @@ using Microsoft.EntityFrameworkCore.Migrations; namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations { /// - public partial class TestName : Migration + public partial class addField : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) { - migrationBuilder.CreateTable( - name: "TestFieldName", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - NAME1 = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), - NAme2 = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), - naMe3 = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), - CreateUserId = table.Column(type: "uniqueidentifier", nullable: false), - CreateTime = table.Column(type: "datetime2", nullable: false), - UpdateUserId = table.Column(type: "uniqueidentifier", nullable: false), - UpdateTime = table.Column(type: "datetime2", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_TestFieldName", x => x.Id); - }); + migrationBuilder.AddColumn( + name: "NewCreateName", + table: "ProjectUser2", + type: "nvarchar(200)", + maxLength: 200, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Code", + table: "ProjectUser", + type: "nvarchar(200)", + maxLength: 200, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Name2", + table: "ProjectUser", + type: "nvarchar(200)", + maxLength: 200, + nullable: false, + defaultValue: ""); migrationBuilder.CreateTable( name: "TestStr", @@ -51,11 +57,20 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations /// protected override void Down(MigrationBuilder migrationBuilder) { - migrationBuilder.DropTable( - name: "TestFieldName"); - migrationBuilder.DropTable( name: "TestStr"); + + migrationBuilder.DropColumn( + name: "NewCreateName", + table: "ProjectUser2"); + + migrationBuilder.DropColumn( + name: "Code", + table: "ProjectUser"); + + migrationBuilder.DropColumn( + name: "Name2", + table: "ProjectUser"); } } } diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912072724_addField.Designer.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042206_addComment.Designer.cs similarity index 73% rename from IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912072724_addField.Designer.cs rename to IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042206_addComment.Designer.cs index ca271c8d5..138e34153 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912072724_addField.Designer.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042206_addComment.Designer.cs @@ -12,8 +12,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations { [DbContext(typeof(IRCContext))] - [Migration("20240912072724_addField")] - partial class addField + [Migration("20240918042206_addComment")] + partial class addComment { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -98,6 +98,12 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.Property("CreateUserId") .HasColumnType("uniqueidentifier"); + b.Property("NewCreateName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)") + .HasComment("NewCreateName"); + b.Property("ProjectId") .HasColumnType("uniqueidentifier"); @@ -114,6 +120,46 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.ToTable("ProjectUser2"); }); + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("CreateUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DefineLength") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("DefualtLength") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("MaxLength") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("TestStr", t => + { + t.HasComment("test commment"); + }); + }); + modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => { b.HasOne("IRaCIS.Core.Test.CodeFirstTest.MSSQL.Project", "Project") diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042206_addComment.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042206_addComment.cs new file mode 100644 index 000000000..3ddb20667 --- /dev/null +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042206_addComment.cs @@ -0,0 +1,58 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations +{ + /// + public partial class addComment : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "Name2", + table: "ProjectUser", + newName: "Name"); + + migrationBuilder.AlterTable( + name: "TestStr", + comment: "test commment"); + + migrationBuilder.AlterColumn( + name: "NewCreateName", + table: "ProjectUser2", + type: "nvarchar(200)", + maxLength: 200, + nullable: false, + comment: "NewCreateName", + oldClrType: typeof(string), + oldType: "nvarchar(200)", + oldMaxLength: 200); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "Name", + table: "ProjectUser", + newName: "Name2"); + + migrationBuilder.AlterTable( + name: "TestStr", + oldComment: "test commment"); + + migrationBuilder.AlterColumn( + name: "NewCreateName", + table: "ProjectUser2", + type: "nvarchar(200)", + maxLength: 200, + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(200)", + oldMaxLength: 200, + oldComment: "NewCreateName"); + } + } +} diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917144649_TestName.Designer.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042443_addField2.Designer.cs similarity index 83% rename from IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917144649_TestName.Designer.cs rename to IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042443_addField2.Designer.cs index 3ebd0d69f..a4082ff88 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240917144649_TestName.Designer.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042443_addField2.Designer.cs @@ -12,8 +12,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations { [DbContext(typeof(IRCContext))] - [Migration("20240917144649_TestName")] - partial class TestName + [Migration("20240918042443_addField2")] + partial class addField2 { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -98,6 +98,12 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.Property("CreateUserId") .HasColumnType("uniqueidentifier"); + b.Property("NewCreateName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)") + .HasComment("NewCreateName"); + b.Property("ProjectId") .HasColumnType("uniqueidentifier"); @@ -114,44 +120,6 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.ToTable("ProjectUser2"); }); - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestFieldName", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("NAME1") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("NAme2") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("naMe3") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id"); - - b.ToTable("TestFieldName"); - }); - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => { b.Property("Id") @@ -184,9 +152,17 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.Property("UpdateUserId") .HasColumnType("uniqueidentifier"); + b.Property("UserAddField") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + b.HasKey("Id"); - b.ToTable("TestStr"); + b.ToTable("TestStr", t => + { + t.HasComment("test commment"); + }); }); modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912072724_addField.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042443_addField2.cs similarity index 53% rename from IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912072724_addField.cs rename to IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042443_addField2.cs index d9b40bfb5..a96236956 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240912072724_addField.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/20240918042443_addField2.cs @@ -5,22 +5,14 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations { /// - public partial class addField : Migration + public partial class addField2 : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.AddColumn( - name: "Code", - table: "ProjectUser", - type: "nvarchar(200)", - maxLength: 200, - nullable: false, - defaultValue: ""); - - migrationBuilder.AddColumn( - name: "Name", - table: "ProjectUser", + name: "UserAddField", + table: "TestStr", type: "nvarchar(200)", maxLength: 200, nullable: false, @@ -31,12 +23,8 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropColumn( - name: "Code", - table: "ProjectUser"); - - migrationBuilder.DropColumn( - name: "Name", - table: "ProjectUser"); + name: "UserAddField", + table: "TestStr"); } } } diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs index 558de01a7..93171abac 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/Migrations/IRCContextModelSnapshot.cs @@ -62,7 +62,7 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.Property("CreateUserId") .HasColumnType("uniqueidentifier"); - b.Property("Name2") + b.Property("Name") .IsRequired() .HasMaxLength(200) .HasColumnType("nvarchar(200)"); @@ -95,6 +95,12 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.Property("CreateUserId") .HasColumnType("uniqueidentifier"); + b.Property("NewCreateName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)") + .HasComment("NewCreateName"); + b.Property("ProjectId") .HasColumnType("uniqueidentifier"); @@ -111,81 +117,6 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.ToTable("ProjectUser2"); }); - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestComment", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)") - .HasComment("这是字段备注Name的修改"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.ToTable("TestComment", t => - { - t.HasComment("这是类备注的修改"); - }); - }); - - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestFieldName", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreateTime") - .HasColumnType("datetime2"); - - b.Property("CreateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("NAME1") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("NAme2") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("UpdateTime") - .HasColumnType("datetime2"); - - b.Property("UpdateUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("naMe3") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id"); - - b.ToTable("TestFieldName"); - }); - modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.TestStr", b => { b.Property("Id") @@ -218,9 +149,17 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL.Migrations b.Property("UpdateUserId") .HasColumnType("uniqueidentifier"); + b.Property("UserAddField") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + b.HasKey("Id"); - b.ToTable("TestStr"); + b.ToTable("TestStr", t => + { + t.HasComment("test commment"); + }); }); modelBuilder.Entity("IRaCIS.Core.Test.CodeFirstTest.MSSQL.ProjectUser", b => diff --git a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs index c36ea74ca..ec37ab23b 100644 --- a/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs +++ b/IRaCIS.Core.Test/CodeFirstTest/MSSQL/TrialImageDownload.cs @@ -158,13 +158,10 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL public class ProjectUser : BaseFullAuditEntity { - //public string Name2 { get; set; } - - //public string OtherName { get; set; } public string Code { get; set; } - public string Name2 { get; set; } + public string Name { get; set; } //外键 public Guid ProjectId { get; set; } @@ -178,20 +175,53 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL public Guid ProjectId { get; set; } public Project Project { get; set; } + + [Comment("NewCreateName")] + public string NewCreateName { get; set; } + } #endregion #region 测试字符串长度 + [Comment("test commment4")] public class TestStr: BaseFullAuditEntity { + [Comment("test commment3")] public string DefualtLength { get; set; } + [Comment("test commment1")] [MaxLength] public string MaxLength { get; set; } + [Comment("test commment2")] [StringLength(400)] public string DefineLength { get; set;} + + } + + /// + /// 备注 + /// + public class TestStr2 + { + /// + /// 备注1 + /// + [StringLength(200)] + public string DefualtLength { get; set; } + + /// + /// 备注1 + /// + [MaxLength] + public string MaxLength { get; set; } + + /// + /// 备注3 + /// + [StringLength(400)] + public string DefineLength { get; set; } } #endregion @@ -220,4 +250,21 @@ namespace IRaCIS.Core.Test.CodeFirstTest.MSSQL public string Name { get; set; } } #endregion + + + #region 测试默认值约束 + + + public class TestStrDefaultValue : BaseFullAuditEntity + { + //手动不给默认值 + public string Value1 { get; set; } + + //手动给默认值 + public string Value2 { get; set; } = string.Empty; + + //dbfirst 默认生成方式 项目开启了enable + public string Value3 { get; set; } = null!; + } + #endregion } From bf3961378945556a8d5537490a8d011b62e73322 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 18 Sep 2024 16:05:29 +0800 Subject: [PATCH 51/59] =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=85=AC=E5=8F=B8=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Controllers/ExtraController.cs | 8 ++++++++ IRaCIS.Core.API/IRaCIS.Core.API.xml | 2 +- .../Service/Management/DTO/UserModel.cs | 2 ++ IRaCIS.Core.Domain/_Config/_AppSettings.cs | 11 +++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs index 9152ace33..73cc21a20 100644 --- a/IRaCIS.Core.API/Controllers/ExtraController.cs +++ b/IRaCIS.Core.API/Controllers/ExtraController.cs @@ -37,6 +37,7 @@ using Amazon.SecurityToken.Model; using Amazon.SecurityToken; using Amazon; using AssumeRoleRequest = Amazon.SecurityToken.Model.AssumeRoleRequest; +using AutoMapper; namespace IRaCIS.Api.Controllers { @@ -109,8 +110,12 @@ namespace IRaCIS.Api.Controllers [FromServices] ITokenService _tokenService, [FromServices] IReadingImageTaskService readingImageTaskService, [FromServices] IOptionsMonitor _verifyConfig, + [FromServices] IOptionsMonitor _emailConfig, + [FromServices] IMailVerificationService _mailVerificationService) { + var emailConfig= _emailConfig.CurrentValue; + var companyInfo = new SystemEmailSendConfigView() { CompanyName = emailConfig.CompanyName, CompanyNameCN = emailConfig.CompanyNameCN, CompanyShortName = emailConfig.CompanyShortName, CompanyShortNameCN = emailConfig.CompanyShortNameCN }; //MFA 邮箱验证 前端传递用户Id 和MFACode if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA) @@ -147,6 +152,7 @@ namespace IRaCIS.Api.Controllers await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(userId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes)); + loginReturn.CompanyInfo = companyInfo; return ResponseOutput.Ok(loginReturn); } @@ -274,6 +280,8 @@ namespace IRaCIS.Api.Controllers } } + + returnModel.Data.CompanyInfo = companyInfo; return returnModel; } diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.xml b/IRaCIS.Core.API/IRaCIS.Core.API.xml index 4402bc0b9..068efa5a9 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.xml +++ b/IRaCIS.Core.API/IRaCIS.Core.API.xml @@ -29,7 +29,7 @@ - + 系统用户登录接口[New] diff --git a/IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs b/IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs index 7c2b014d7..6b63943e2 100644 --- a/IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs +++ b/IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs @@ -32,6 +32,8 @@ namespace IRaCIS.Application.Contracts public bool IsMFA { get; set; } = false; + public SystemEmailSendConfigView CompanyInfo { get; set; } + } public class UserBasicInfo diff --git a/IRaCIS.Core.Domain/_Config/_AppSettings.cs b/IRaCIS.Core.Domain/_Config/_AppSettings.cs index 2bca1cdfe..8afe0386d 100644 --- a/IRaCIS.Core.Domain/_Config/_AppSettings.cs +++ b/IRaCIS.Core.Domain/_Config/_AppSettings.cs @@ -78,6 +78,17 @@ namespace IRaCIS.Core.Domain.Share } + public class SystemEmailSendConfigView + { + public string CompanyName { get; set; } = string.Empty; + + public string CompanyNameCN { get; set; } = string.Empty; + + public string CompanyShortName { get; set; } = string.Empty; + + public string CompanyShortNameCN { get; set; } = string.Empty; + } + public class SystemPacsConfig { public int Port { get; set; } From 2dd86652f3f44ee563754d5a8a6e277209e1bf22 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 18 Sep 2024 16:36:59 +0800 Subject: [PATCH 52/59] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E5=88=97=E8=A1=A8=EF=BC=8C=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E6=A0=87=E5=87=86=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ImageAndDoc/DownloadAndUploadService.cs | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 1bf154b8a..8baae9c30 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -65,8 +65,10 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc /// public async Task SubejctRandomReadingTaskNameDeal(Guid subjectId, Guid trialReadingCriterionId) { - //subject 随机阅片 才处理任务编号 - if (_visitTaskRepository.Any(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom)) + //subject 随机阅片 或者无序 有上传 才处理任务编号 + if (_visitTaskRepository.Any(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && + (t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom || + (t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.Random && t.TrialReadingCriterion.ImageUploadEnum != ReadingImageUpload.None)))) { //找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务 var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id @@ -754,12 +756,18 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc [HttpPost] public async Task> GetSubjectImageDownloadSelectList(IRReadingDownloadQuery inQuery) { + //要根据标准阅片顺序,确定是否查询单个任务的,还是查询所有的 + + var criterionInfo= await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId) + .Select(t => new { t.IsReadingTaskViewInOrder }).FirstNotNullAsync(); + + var doctorUserId = _userInfo.Id; var isAnalysisCreate = false; //医学审核查看下载按钮,这个时候需要知道医生 - if (inQuery.VisitTaskId != null && inQuery.VisitTaskId != Guid.Empty) + if (inQuery.VisitTaskId != null ) { var info = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId).Select(t => new { t.DoctorUserId, t.IsAnalysisCreate }).FirstNotNullAsync(); @@ -769,6 +777,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var query = _visitTaskRepository.Where(t => t.SubjectId == inQuery.SubjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SourceSubjectVisitId != null && t.DoctorUserId == doctorUserId && t.TaskState == TaskState.Effect) + //满足 有序,或者随机只看到当前任务的dicom 非dicom检查 + .WhereIf(criterionInfo.IsReadingTaskViewInOrder!=ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null,t=>t.Id==inQuery.VisitTaskId) .ProjectTo(_mapper.ConfigurationProvider); //这里过滤是否是一致性分析的 @@ -838,7 +848,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc public async Task GetIRReadingDownloadStudyInfo(IRDownloadQuery inQuery) { var info = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId) - .Select(t => new { t.IsImageFilter, t.CriterionModalitys, t.TrialId }).FirstNotNullAsync(); + .Select(t => new { t.IsImageFilter, t.CriterionModalitys, t.TrialId,t.IsReadingTaskViewInOrder }).FirstNotNullAsync(); var isQueryDicom = inQuery.DicomStudyIdList.Count > 0; var isQueryNoneDicom = inQuery.NoneDicomStudyIdList.Count > 0; @@ -909,7 +919,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc Id = NewId.NextSequentialGuid(), TrialId = info.TrialId, SubjectCode = inQuery.SubjectCode, - IP=_userInfo.IP, + IP = _userInfo.IP, DownloadStartTime = DateTime.Now, IsSuccess = false, ImageType = imageType, @@ -921,8 +931,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc ) ?? 0 }; - await _trialImageDownloadRepository.AddAsync(preDownloadInfo,true); - return ResponseOutput.Ok(result, preDownloadInfo.Id); + await _trialImageDownloadRepository.AddAsync(preDownloadInfo, true); + + return ResponseOutput.Ok(result, new { PreDownloadId= preDownloadInfo.Id,info.IsReadingTaskViewInOrder } ); } /// From 3501f2acdfbcf77767fa1129b45327d2365ad9a4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 18 Sep 2024 18:03:23 +0800 Subject: [PATCH 53/59] =?UTF-8?q?=E5=8A=A0=E8=A7=A3=E5=AF=86=E9=A2=84?= =?UTF-8?q?=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Encryption/EncryptionRequestMiddleware.cs | 67 +++++++++++++ .../BusinessFilter/Encryption/RSAHelper.cs | 96 ++++++++++++++++++ IRaCIS.Core.Application/Helper/RSAHelper.cs | 97 ------------------- .../IRaCIS.Core.Application.xml | 28 +++--- IRaCIS.Core.Application/TestService.cs | 1 + 5 files changed, 178 insertions(+), 111 deletions(-) create mode 100644 IRaCIS.Core.Application/BusinessFilter/Encryption/EncryptionRequestMiddleware.cs create mode 100644 IRaCIS.Core.Application/BusinessFilter/Encryption/RSAHelper.cs delete mode 100644 IRaCIS.Core.Application/Helper/RSAHelper.cs diff --git a/IRaCIS.Core.Application/BusinessFilter/Encryption/EncryptionRequestMiddleware.cs b/IRaCIS.Core.Application/BusinessFilter/Encryption/EncryptionRequestMiddleware.cs new file mode 100644 index 000000000..055e306f9 --- /dev/null +++ b/IRaCIS.Core.Application/BusinessFilter/Encryption/EncryptionRequestMiddleware.cs @@ -0,0 +1,67 @@ +using DocumentFormat.OpenXml.InkML; +using Microsoft.AspNetCore.Http; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Application.BusinessFilter; + +public class EncryptionRequestMiddleware +{ + private readonly RequestDelegate _next; + + public EncryptionRequestMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task InvokeAsync(HttpContext context) + { + // 检查请求头中是否包含加密的对称密钥 + if (context.Request.Headers.ContainsKey("X-Encrypted-Key")) + { + var encryptedSymmetricKey = Convert.FromBase64String(context.Request.Headers["X-Encrypted-Key"]); + + //// 使用私钥解密对称密钥 + //var decryptedSymmetricKey = RsaEncryptionHelper.DecryptRsa(encryptedSymmetricKey, _rsaPrivateKey); + //var aesKey = decryptedSymmetricKey[..32]; // 前32字节作为AES密钥 + //var aesIv = decryptedSymmetricKey[32..]; // 后面16字节作为IV + + //// 读取并解密请求体中的JSON数据 + //context.Request.EnableBuffering(); + //using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, leaveOpen: true)) + //{ + // var encryptedBody = await reader.ReadToEndAsync(); + // context.Request.Body.Position = 0; + + // // 尝试解析为JObject + // var encryptedJson = JObject.Parse(encryptedBody); + // var decryptedJson = new JObject(); + + // // 解密每个字段的值 + // foreach (var property in encryptedJson.Properties()) + // { + // var encryptedValue = property.Value.ToString(); + // var decryptedValue = AesEncryptionHelper.DecryptString(encryptedValue, aesKey, aesIv); + // decryptedJson[property.Name] = decryptedValue; + // } + + // // 将解密后的JSON对象转换回字符串,并替换原始请求体 + // var decryptedBody = decryptedJson.ToString(); + // var bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(decryptedBody)); + // context.Request.Body = bodyStream; + // context.Request.ContentLength = bodyStream.Length; + // bodyStream.Seek(0, SeekOrigin.Begin); + } + + + // 调用下一个中间件 + await _next(context); + } + + + +} diff --git a/IRaCIS.Core.Application/BusinessFilter/Encryption/RSAHelper.cs b/IRaCIS.Core.Application/BusinessFilter/Encryption/RSAHelper.cs new file mode 100644 index 000000000..a89e57cbf --- /dev/null +++ b/IRaCIS.Core.Application/BusinessFilter/Encryption/RSAHelper.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.OpenSsl; +using Org.BouncyCastle.Security; + +namespace IRaCIS.Core.Application.BusinessFilter; + +/// +/// https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html +/// +public class RSAHelper +{ + + public static AsymmetricCipherKeyPair GenerateRSAKeyPair(int keySize) + { + var keyGenerationParameters = new KeyGenerationParameters(new SecureRandom(), keySize); + var keyPairGenerator = new RsaKeyPairGenerator(); + keyPairGenerator.Init(keyGenerationParameters); + return keyPairGenerator.GenerateKeyPair(); + } + + public static string ExportPublicKey(AsymmetricKeyParameter publicKey) + { + using (StringWriter sw = new StringWriter()) + { + PemWriter pw = new PemWriter(sw); + pw.WriteObject(publicKey); + pw.Writer.Flush(); + return sw.ToString(); + } + } + + public static string ExportPrivateKey(AsymmetricKeyParameter privateKey) + { + using (StringWriter sw = new StringWriter()) + { + PemWriter pw = new PemWriter(sw); + pw.WriteObject(privateKey); + pw.Writer.Flush(); + return sw.ToString(); + } + } + + /// + /// RSA解密 + /// + /// 私钥 + /// 待解密的字符串(Base64) + /// 解密后的字符串 + public static string Decrypt(string privateKey, string decryptstring) + { + using (TextReader reader = new StringReader(privateKey)) + { + dynamic key = new PemReader(reader).ReadObject(); + var rsaDecrypt = new Pkcs1Encoding(new RsaEngine()); + if (key is AsymmetricKeyParameter) + { + key = (AsymmetricKeyParameter)key; + } + else if (key is AsymmetricCipherKeyPair) + { + key = ((AsymmetricCipherKeyPair)key).Private; + } + rsaDecrypt.Init(false, key); //这里加密是true;解密是false + + byte[] entData = Convert.FromBase64String(decryptstring); + entData = rsaDecrypt.ProcessBlock(entData, 0, entData.Length); + return Encoding.UTF8.GetString(entData); + } + }/// + + /// 加密 + /// + /// 公钥 + /// 待加密的字符串 + /// 加密后的Base64 + public static string Encrypt(string publicKey, string encryptstring) + { + using (TextReader reader = new StringReader(publicKey)) + { + AsymmetricKeyParameter key = new PemReader(reader).ReadObject() as AsymmetricKeyParameter; + Pkcs1Encoding pkcs1 = new Pkcs1Encoding(new RsaEngine()); + pkcs1.Init(true, key);//加密是true;解密是false; + byte[] entData = Encoding.UTF8.GetBytes(encryptstring); + entData = pkcs1.ProcessBlock(entData, 0, entData.Length); + return Convert.ToBase64String(entData); + } + } +} diff --git a/IRaCIS.Core.Application/Helper/RSAHelper.cs b/IRaCIS.Core.Application/Helper/RSAHelper.cs deleted file mode 100644 index fb5309691..000000000 --- a/IRaCIS.Core.Application/Helper/RSAHelper.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Crypto.Encodings; -using Org.BouncyCastle.Crypto.Engines; -using Org.BouncyCastle.Crypto.Generators; -using Org.BouncyCastle.OpenSsl; -using Org.BouncyCastle.Security; - -namespace IRaCIS.Core.Application.Helper -{ - /// - /// https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html - /// - public class RSAHelper - { - - public static AsymmetricCipherKeyPair GenerateRSAKeyPair(int keySize) - { - var keyGenerationParameters = new KeyGenerationParameters(new SecureRandom(), keySize); - var keyPairGenerator = new RsaKeyPairGenerator(); - keyPairGenerator.Init(keyGenerationParameters); - return keyPairGenerator.GenerateKeyPair(); - } - - public static string ExportPublicKey(AsymmetricKeyParameter publicKey) - { - using (StringWriter sw = new StringWriter()) - { - PemWriter pw = new PemWriter(sw); - pw.WriteObject(publicKey); - pw.Writer.Flush(); - return sw.ToString(); - } - } - - public static string ExportPrivateKey(AsymmetricKeyParameter privateKey) - { - using (StringWriter sw = new StringWriter()) - { - PemWriter pw = new PemWriter(sw); - pw.WriteObject(privateKey); - pw.Writer.Flush(); - return sw.ToString(); - } - } - - /// - /// RSA解密 - /// - /// 私钥 - /// 待解密的字符串(Base64) - /// 解密后的字符串 - public static string Decrypt(string privateKey, string decryptstring) - { - using (TextReader reader = new StringReader(privateKey)) - { - dynamic key = new PemReader(reader).ReadObject(); - var rsaDecrypt = new Pkcs1Encoding(new RsaEngine()); - if (key is AsymmetricKeyParameter) - { - key = (AsymmetricKeyParameter)key; - } - else if (key is AsymmetricCipherKeyPair) - { - key = ((AsymmetricCipherKeyPair)key).Private; - } - rsaDecrypt.Init(false, key); //这里加密是true;解密是false - - byte[] entData = Convert.FromBase64String(decryptstring); - entData = rsaDecrypt.ProcessBlock(entData, 0, entData.Length); - return Encoding.UTF8.GetString(entData); - } - }/// - - /// 加密 - /// - /// 公钥 - /// 待加密的字符串 - /// 加密后的Base64 - public static string Encrypt(string publicKey, string encryptstring) - { - using (TextReader reader = new StringReader(publicKey)) - { - AsymmetricKeyParameter key = new PemReader(reader).ReadObject() as AsymmetricKeyParameter; - Pkcs1Encoding pkcs1 = new Pkcs1Encoding(new RsaEngine()); - pkcs1.Init(true, key);//加密是true;解密是false; - byte[] entData = Encoding.UTF8.GetBytes(encryptstring); - entData = pkcs1.ProcessBlock(entData, 0, entData.Length); - return Convert.ToBase64String(entData); - } - } - } -} diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 063780b32..db99c7473 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -29,6 +29,20 @@ 签名 + + + https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html + + + + + RSA解密 + + 私钥 + 待解密的字符串(Base64) + 解密后的字符串 + + 不生效,不知道为啥 @@ -102,20 +116,6 @@ - - - https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html - - - - - RSA解密 - - 私钥 - 待解密的字符串(Base64) - 解密后的字符串 - - 利用DocX 库 处理word国际化模板 diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index c36a7c6b5..f6cf88f9e 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -3,6 +3,7 @@ using DocumentFormat.OpenXml.Drawing.Charts; using DocumentFormat.OpenXml.Wordprocessing; using IP2Region.Net.XDB; using IRaCIS.Application.Contracts; +using IRaCIS.Core.Application.BusinessFilter; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Service; From de274e00d6f3756ea558497a019e4c230fe5c1ed Mon Sep 17 00:00:00 2001 From: hang <87227557@qq.com> Date: Wed, 18 Sep 2024 21:18:33 +0800 Subject: [PATCH 54/59] =?UTF-8?q?=E5=8A=A0=E5=AF=86=E8=A7=A3=E5=AF=86?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=87=86=E5=A4=87=E5=AE=8C=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessFilter/EncreptApiResultFilter.cs | 71 --------------- .../Encryption/AesEncryption.cs | 91 +++++++++++++++++++ .../Encryption/EncreptApiResultFilter.cs | 64 +++++++++++++ .../{RSAHelper.cs => RSAEncryption.cs} | 2 +- .../IRaCIS.Core.Application.csproj | 1 + .../IRaCIS.Core.Application.xml | 11 ++- IRaCIS.Core.Application/TestService.cs | 36 +++++++- 7 files changed, 196 insertions(+), 80 deletions(-) delete mode 100644 IRaCIS.Core.Application/BusinessFilter/EncreptApiResultFilter.cs create mode 100644 IRaCIS.Core.Application/BusinessFilter/Encryption/AesEncryption.cs create mode 100644 IRaCIS.Core.Application/BusinessFilter/Encryption/EncreptApiResultFilter.cs rename IRaCIS.Core.Application/BusinessFilter/Encryption/{RSAHelper.cs => RSAEncryption.cs} (99%) diff --git a/IRaCIS.Core.Application/BusinessFilter/EncreptApiResultFilter.cs b/IRaCIS.Core.Application/BusinessFilter/EncreptApiResultFilter.cs deleted file mode 100644 index fd58ae885..000000000 --- a/IRaCIS.Core.Application/BusinessFilter/EncreptApiResultFilter.cs +++ /dev/null @@ -1,71 +0,0 @@ -using IRaCIS.Core.Domain.Share; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Filters; -using Microsoft.Extensions.Options; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace IRaCIS.Core.Application.BusinessFilter -{ - public class EncreptApiResultFilter : IAsyncResultFilter - { - - private readonly IOptionsMonitor _encreptResponseMonitor; - - public EncreptApiResultFilter(IOptionsMonitor encreptResponseMonitor) - { - _encreptResponseMonitor = encreptResponseMonitor; - } - - public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) - { - - if(_encreptResponseMonitor.CurrentValue.IsEnable) - { - - if (context.Result is ObjectResult objectResult) - { - var statusCode = objectResult.StatusCode ?? context.HttpContext.Response.StatusCode; - - var objectValue = objectResult.Value; - - - if (objectValue is IResponseOutput) - { - var responseOutput = objectValue as IResponseOutput; - - var path = context.HttpContext?.Request.Path.Value?.ToLower(); - - - if(!string.IsNullOrEmpty(path) && path.Length>5 && _encreptResponseMonitor.CurrentValue.ApiPathList.Contains(path.ToLower())) - { - - if(responseOutput.IsSuccess) - { - responseOutput.Code = ApiResponseCodeEnum.ResultEncrepted; - responseOutput.Data = JsonConvert.SerializeObject(Convert.ToBase64String(Encoding.UTF8.GetBytes(responseOutput.Data.ToString()))); - - objectResult.Value = responseOutput; - } - - } - - } - - - - } - } - - - - - await next.Invoke(); - - } - } -} diff --git a/IRaCIS.Core.Application/BusinessFilter/Encryption/AesEncryption.cs b/IRaCIS.Core.Application/BusinessFilter/Encryption/AesEncryption.cs new file mode 100644 index 000000000..8c17165c8 --- /dev/null +++ b/IRaCIS.Core.Application/BusinessFilter/Encryption/AesEncryption.cs @@ -0,0 +1,91 @@ +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Org.BouncyCastle.Crypto.Modes; + +namespace IRaCIS.Core.Application.BusinessFilter; + +public class AesEncryption +{ + // AES 加密(不带 IV) + public static string Encrypt(string plainText, string key) + { + var keyBytes = Encoding.UTF8.GetBytes(key); + + // 使用 AES 引擎 + PKCS7 填充 + var engine = new AesEngine(); + var blockCipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding()); + blockCipher.Init(true, new KeyParameter(keyBytes)); // true 表示加密 + + var inputBytes = Encoding.UTF8.GetBytes(plainText); + var encryptedBytes = ProcessCipher(blockCipher, inputBytes); + + // 返回 Base64 编码的加密字符串 + return Convert.ToBase64String(encryptedBytes); + } + + // AES 解密(不带 IV) + public static string Decrypt(string encryptedText, string key) + { + var keyBytes = Encoding.UTF8.GetBytes(key); + var cipherBytes = Convert.FromBase64String(encryptedText); + + // 使用 AES 引擎 + PKCS7 填充 + var engine = new AesEngine(); + var blockCipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding()); + blockCipher.Init(false, new KeyParameter(keyBytes)); // false 表示解密 + + var decryptedBytes = ProcessCipher(blockCipher, cipherBytes); + return Encoding.UTF8.GetString(decryptedBytes); + } + + // AES 加密(带 IV) + public static string Encrypt(string plainText, string key, string iv) + { + var keyBytes = Encoding.UTF8.GetBytes(key); + var ivBytes = Encoding.UTF8.GetBytes(iv); + + // 使用 AES 引擎 + PKCS7 填充 + CBC 模式 + var engine = new AesEngine(); + var blockCipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding()); + blockCipher.Init(true, new ParametersWithIV(new KeyParameter(keyBytes), ivBytes)); // true 表示加密 + + var inputBytes = Encoding.UTF8.GetBytes(plainText); + var encryptedBytes = ProcessCipher(blockCipher, inputBytes); + + // 返回 Base64 编码的加密字符串 + return Convert.ToBase64String(encryptedBytes); + } + + // AES 解密(带 IV) + public static string Decrypt(string encryptedText, string key, string iv) + { + var keyBytes = Encoding.UTF8.GetBytes(key); + var ivBytes = Encoding.UTF8.GetBytes(iv); + var cipherBytes = Convert.FromBase64String(encryptedText); + + // 使用 AES 引擎 + PKCS7 填充 + CBC 模式 + var engine = new AesEngine(); + var blockCipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding()); + blockCipher.Init(false, new ParametersWithIV(new KeyParameter(keyBytes), ivBytes)); // false 表示解密 + + var decryptedBytes = ProcessCipher(blockCipher, cipherBytes); + return Encoding.UTF8.GetString(decryptedBytes); + } + + // 处理加密/解密数据 + private static byte[] ProcessCipher(IBufferedCipher cipher, byte[] input) + { + var output = new byte[cipher.GetOutputSize(input.Length)]; + int length = cipher.ProcessBytes(input, 0, input.Length, output, 0); + length += cipher.DoFinal(output, length); + Array.Resize(ref output, length); // 调整输出数组大小以适应实际数据长度 + return output; + } +} diff --git a/IRaCIS.Core.Application/BusinessFilter/Encryption/EncreptApiResultFilter.cs b/IRaCIS.Core.Application/BusinessFilter/Encryption/EncreptApiResultFilter.cs new file mode 100644 index 000000000..bae8e48ad --- /dev/null +++ b/IRaCIS.Core.Application/BusinessFilter/Encryption/EncreptApiResultFilter.cs @@ -0,0 +1,64 @@ +using IRaCIS.Core.Domain.Share; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Options; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Application.BusinessFilter; + +/// +/// 测试加密API 返回的结果 +/// +public class EncreptApiResultFilter : IAsyncResultFilter +{ + private readonly IOptionsMonitor _encreptResponseMonitor; + + public EncreptApiResultFilter(IOptionsMonitor encreptResponseMonitor) + { + _encreptResponseMonitor = encreptResponseMonitor; + } + + public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) + { + + if (_encreptResponseMonitor.CurrentValue.IsEnable) + { + + if (context.Result is ObjectResult objectResult) + { + var statusCode = objectResult.StatusCode ?? context.HttpContext.Response.StatusCode; + + var objectValue = objectResult.Value; + + + if (objectValue is IResponseOutput) + { + var responseOutput = objectValue as IResponseOutput; + + var path = context.HttpContext?.Request.Path.Value?.ToLower(); + + + if (!string.IsNullOrEmpty(path) && path.Length > 5 && _encreptResponseMonitor.CurrentValue.ApiPathList.Contains(path.ToLower())) + { + + if (responseOutput.IsSuccess) + { + responseOutput.Code = ApiResponseCodeEnum.ResultEncrepted; + responseOutput.Data = JsonConvert.SerializeObject(Convert.ToBase64String(Encoding.UTF8.GetBytes(responseOutput.Data.ToString()))); + + objectResult.Value = responseOutput; + } + + } + + } + } + } + await next.Invoke(); + } +} diff --git a/IRaCIS.Core.Application/BusinessFilter/Encryption/RSAHelper.cs b/IRaCIS.Core.Application/BusinessFilter/Encryption/RSAEncryption.cs similarity index 99% rename from IRaCIS.Core.Application/BusinessFilter/Encryption/RSAHelper.cs rename to IRaCIS.Core.Application/BusinessFilter/Encryption/RSAEncryption.cs index a89e57cbf..c4bd92d6e 100644 --- a/IRaCIS.Core.Application/BusinessFilter/Encryption/RSAHelper.cs +++ b/IRaCIS.Core.Application/BusinessFilter/Encryption/RSAEncryption.cs @@ -15,7 +15,7 @@ namespace IRaCIS.Core.Application.BusinessFilter; /// /// https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html /// -public class RSAHelper +public class RSAEncryption { public static AsymmetricCipherKeyPair GenerateRSAKeyPair(int keySize) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index 0f1672ecf..9faf0ffec 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -62,6 +62,7 @@ + diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index db99c7473..1ce5ba12e 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -29,12 +29,17 @@ 签名 - + + + 测试加密API 返回的结果 + + + https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html - + RSA解密 @@ -42,7 +47,7 @@ 待解密的字符串(Base64) 解密后的字符串 - + 不生效,不知道为啥 diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index f6cf88f9e..2c12fa561 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -248,14 +248,40 @@ namespace IRaCIS.Application.Services [UnitOfWork] public async Task Get() { + string plainText = "Hello, BouncyCastle!"; + string key = "12345678901234567890123456789012"; // AES 密钥长度应为 16 字节(128 位) + string iv = "your-iv-12345678"; // IV 长度为 16 字节 + + Console.WriteLine($"原始文本: {plainText}"); + + // 加密 + string encrypted = AesEncryption.Encrypt(plainText, key, iv); + Console.WriteLine($"加密后的数据: {encrypted}"); + + // 解密 + string decrypted = AesEncryption.Decrypt(encrypted, key, iv); + Console.WriteLine($"解密后的数据: {decrypted}"); + + + + + Console.WriteLine($"原始文本: {plainText}"); + + // 加密 + string encrypte = AesEncryption.Encrypt(plainText, key); + Console.WriteLine($"加密后的数据: {encrypte}"); + + // 解密 + string decrypte = AesEncryption.Decrypt(encrypte, key); + Console.WriteLine($"解密后的数据: {decrypte}"); // Generate RSA keys - var keyPair = RSAHelper.GenerateRSAKeyPair(2048); + var keyPair = RSAEncryption.GenerateRSAKeyPair(2048); // Export the public and private keys to PEM format - string publicKey = RSAHelper.ExportPublicKey(keyPair.Public); - string privateKey = RSAHelper.ExportPrivateKey(keyPair.Private); + string publicKey = RSAEncryption.ExportPublicKey(keyPair.Public); + string privateKey = RSAEncryption.ExportPrivateKey(keyPair.Private); Console.WriteLine("Public Key:"); Console.WriteLine(publicKey); @@ -267,11 +293,11 @@ namespace IRaCIS.Application.Services Console.WriteLine("\nOriginal Data: " + dataToEncrypt); // Encrypt the data - var encryptedData = RSAHelper.Encrypt(publicKey, dataToEncrypt); + var encryptedData = RSAEncryption.Encrypt(publicKey, dataToEncrypt); Console.WriteLine("\nEncrypted Data: " + encryptedData); // Decrypt the data - string decryptedData = RSAHelper.Decrypt(privateKey, encryptedData); + string decryptedData = RSAEncryption.Decrypt(privateKey, encryptedData); Console.WriteLine("\nDecrypted Data: " + decryptedData); From fb067534e73eebd08b7b3d9488f2aa68a39552e9 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 19 Sep 2024 11:45:23 +0800 Subject: [PATCH 55/59] =?UTF-8?q?=E5=8A=A0=E5=AF=86=E8=A7=A3=E5=AF=86?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ExtraController.cs | 14 +- IRaCIS.Core.API/Progranm.cs | 5 +- IRaCIS.Core.API/appsettings.json | 4 +- .../Encryption/EncreptApiResultFilter.cs | 6 +- .../Encryption/EncryptionRequestMiddleware.cs | 129 +++++++++++++----- IRaCIS.Core.Application/TestService.cs | 63 +++++++-- IRaCIS.Core.Domain/_Config/_AppSettings.cs | 10 +- 7 files changed, 178 insertions(+), 53 deletions(-) diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs index 73cc21a20..e20a5051e 100644 --- a/IRaCIS.Core.API/Controllers/ExtraController.cs +++ b/IRaCIS.Core.API/Controllers/ExtraController.cs @@ -110,11 +110,11 @@ namespace IRaCIS.Api.Controllers [FromServices] ITokenService _tokenService, [FromServices] IReadingImageTaskService readingImageTaskService, [FromServices] IOptionsMonitor _verifyConfig, - [FromServices] IOptionsMonitor _emailConfig, - + [FromServices] IOptionsMonitor _emailConfig, + [FromServices] IMailVerificationService _mailVerificationService) { - var emailConfig= _emailConfig.CurrentValue; + var emailConfig = _emailConfig.CurrentValue; var companyInfo = new SystemEmailSendConfigView() { CompanyName = emailConfig.CompanyName, CompanyNameCN = emailConfig.CompanyNameCN, CompanyShortName = emailConfig.CompanyShortName, CompanyShortNameCN = emailConfig.CompanyShortNameCN }; //MFA 邮箱验证 前端传递用户Id 和MFACode @@ -291,8 +291,14 @@ namespace IRaCIS.Api.Controllers } + [AllowAnonymous] + [HttpGet, Route("user/getPublicKey")] + public IResponseOutput GetPublicKey([FromServices] IOptionsMonitor _IRCEncreptOption) + { + var pemPublicKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.CurrentValue.Base64RSAPublicKey)); - + return ResponseOutput.Ok(pemPublicKey); + } [HttpGet, Route("imageShare/ShareImage")] diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index 62e075ff6..5d258c077 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -111,7 +111,7 @@ builder.Services.AddControllers(options => options.Filters.Add(); options.Filters.Add(); options.Filters.Add(); - options.Filters.Add(10); + //options.Filters.Add(10); options.Filters.Add(); @@ -122,7 +122,7 @@ builder.Services.AddOptions().Configure(_configuration.Ge builder.Services.AddOptions().Configure(_configuration.GetSection("BasicSystemConfig")); builder.Services.AddOptions().Configure(_configuration.GetSection("AliyunOSS")); builder.Services.AddOptions().Configure(_configuration.GetSection("ObjectStoreService")); -builder.Services.AddOptions().Configure(_configuration.GetSection("EncrypteResponseConfig")); +builder.Services.AddOptions().Configure(_configuration.GetSection("EncrypteResponseConfig")); builder.Services.AddOptions().Configure(_configuration.GetSection("SystemPacsConfig")); builder.Services.Configure(_configuration.GetSection("IRaCISBasicConfig")); @@ -218,6 +218,7 @@ var env = app.Environment; #region 配置中间件 +app.UseMiddleware(); // Configure the HTTP request pipeline. diff --git a/IRaCIS.Core.API/appsettings.json b/IRaCIS.Core.API/appsettings.json index dec14286d..529451e7f 100644 --- a/IRaCIS.Core.API/appsettings.json +++ b/IRaCIS.Core.API/appsettings.json @@ -60,7 +60,9 @@ "ImageShareExpireDays": 10 }, "EncrypteResponseConfig": { - "IsEnable": true, + "Base64RSAPublicKey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0NCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBaHp3T1hYTWYyaEFkS1ZoWHczYUYNCmNaT3QycE1lcmdEaFVrOUdQK2s4VDBrUjFTRVlGVGtzNlkzaEVvL0dRTExqMHZFYVV3bTNhSFNuTTl5NmdLRWoNCmY5cTN6dkoyZzRSQjE4Z0UrTnNWWi9DMkVRZ3k5OWFiWGc5TitGREVlT0NmSjlSRTJPV3JBQ2s0V0RPbFFUdXYNCnhvR2JmcnkwVElSaFBrOGtuYkFmVkZ1and1VXJGblpJZ0ExYXhKZVZ6aDhwcmV1SEgreW1jdHp6NVo4V1pSV3kNCi9ISURHUy90dkg2NUMra2l6cUxRYUpKNHYwODMrRGpaVTBmNzNCdkk5eWt1dW1saXFzY1pvU2preDFOUFJwSkUNCkFtMVFNQ0hMRCtFdzlHT2Vsc2Mwa1ZxdjdaeEF1TkFrMkZuUURNRk1BUmZuUFd0aGVhOGZYVTJsMW9ROWs3WDcNCmN3SURBUUFCDQotLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0NCg==", + "Base64RSAPrivateKey": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQ0KTUlJRW9nSUJBQUtDQVFFQWh6d09YWE1mMmhBZEtWaFh3M2FGY1pPdDJwTWVyZ0RoVWs5R1ArazhUMGtSMVNFWQ0KRlRrczZZM2hFby9HUUxMajB2RWFVd20zYUhTbk05eTZnS0VqZjlxM3p2SjJnNFJCMThnRStOc1ZaL0MyRVFneQ0KOTlhYlhnOU4rRkRFZU9DZko5UkUyT1dyQUNrNFdET2xRVHV2eG9HYmZyeTBUSVJoUGs4a25iQWZWRnVqd3VVcg0KRm5aSWdBMWF4SmVWemg4cHJldUhIK3ltY3R6ejVaOFdaUld5L0hJREdTL3R2SDY1QytraXpxTFFhSko0djA4Mw0KK0RqWlUwZjczQnZJOXlrdXVtbGlxc2Nab1Nqa3gxTlBScEpFQW0xUU1DSExEK0V3OUdPZWxzYzBrVnF2N1p4QQ0KdU5BazJGblFETUZNQVJmblBXdGhlYThmWFUybDFvUTlrN1g3Y3dJREFRQUJBb0lCQUNDRFoxNi9XWWFYZmpOZA0KQ29pemU2VFJZU2llVzI5eFJic0ExVDV6YUcwVmY4U1NsdFF2Y1dWYmw2UGJUa3BxMkF4MHJDUVB2M2xOSm8vNA0KL3h3QzRlS1E1c1ZLRlFWTXJIbmhISlRxTTJ6UWVpMkJINlBuaEdZcVh0QVhOdzFxejhrSEoyQlFZM3IvN2d5Qw0KcWpZVFVCRDFRem5HeThCanlXOXVIcnNNeDVPRHRRZWxBM3B1TFd1bXZNb3Z1L2JhaDZvTGtOSHY4b0VTdzhGSQ0KTllyTUtscHhFTjZaWUdwSTl2VTZnYUhuTmhEa2ExTHlvUnZ5NnA2dTRLR0FsRTc1VXk4T0dsdncydU5uay9sdg0KSEMyYnY5TnlCRGJpSFNDY0MyK1JXUXMrN0tNWFlwYnBvTVFCR0hqV01GRHVBODFaUCs1TWYxUm9yQUpRNGxrRw0KQnRDQThva0NnWUVBeWY4alBjcFIvQ3dJNU5MYnlwb3ZUWEFHVkFKMmtWRlJVUC9HT2ZOMkFyYWMvL20wdDJ5NA0KemNYVkJZc0pJeHkvVWYxRTFJNFg3VFg3V3NBNGxVNGlPTkwzTnN4dDBEbk1PV2tKUlBPZlF1bW1JaWw5QVRiYQ0KTnRVWFNlTmRoUFFGMGlCb21acFFJYWpSN1RmUnVBbzR6dmpTLzkzeXZZY0lIWU1zM0tjR00ya0NnWUVBcTJPbg0KZlp0RmhLTElGanVlRzRrNklGTWdjbytEUUh5TTFWSUp5Tk05K1o2TEgybzI5eDJCaSs2Qm82M2NKUjQ2STZncQ0KNWUrSTBvdzZRYmNQeTZUNHFSQ0o3Ujd6MllkdEw4eXdJTkNYS3U0cC9qaFNqNWJ1TzFJWlI3ZStSV29CakNtUQ0KWFd0ZVBCbldqWVlLdVRCazROc2FXV09GTXg1QndKdUp2MjBnQ0hzQ2dZQlV4QnFYM1lWV0cyeUlDZXh1TXhIUw0KbjBZb2p2Z090MTgyYkg5VTVsUUpnM1NTL3NqVmlHeHMvYTROSzNGa0tMWW93KzNVZk9TUmlPdTRBNTQ3R1pURw0KMzlFYVQrTnRWRFBkaTdSMkdQNG1hRUp0WjVlcm9NY2w1M3BrYVdOZlhiL3JrK29STzI2UkVYVTI1UXUrL1pzbA0KVDhuTDBlb0JtdDdPODdNcHpYV09zUUtCZ0ZxVGFQSGx2RUNUY3FEbFV2S0VmRmFXOTkvelhrOFhRNnA5RjdTdA0KaHVSRDJJeDZxcC9BVlRWcGo5Tzd6MHRDaFVGUTM1THpHMkVDUU10My9uNEdLbS9XMEwyakRRWWFIeWNTeXNZYw0KMXJjV2ROVG9XU0dQaDBtTVl0WFhFbFJHNkpoMVl0a3NJL29wUVkwN21MRTBGU3dNUHdtY29jbFpKVEN3UW9VTA0KRzlHL0FvR0FWM25kcWcydnUyR0x4TlRUbm1UTWRJNFB3UzBmN0V4VnVNUnRicGZyOWhKNzlDakVNTGFXQ1FsNg0KeE43TElMTnArNVQwQW1DZVBqcitkbnJkRUNidFZPTDFybDc3Z0krRkwzaVVqYmZmMVZqa0N3M0x6K3cyb1FFdA0KbGE4aTZrL1NRK01iYkRPaWRJOVczdlN6MmlJRlZobWJiK1Q2SlZwakxqNjlkblM3eUxZPQ0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0NCg==", + "IsResponseEncreptEnable": true, "ApiPathList": [ "/test/get" ] diff --git a/IRaCIS.Core.Application/BusinessFilter/Encryption/EncreptApiResultFilter.cs b/IRaCIS.Core.Application/BusinessFilter/Encryption/EncreptApiResultFilter.cs index bae8e48ad..0ff58ed56 100644 --- a/IRaCIS.Core.Application/BusinessFilter/Encryption/EncreptApiResultFilter.cs +++ b/IRaCIS.Core.Application/BusinessFilter/Encryption/EncreptApiResultFilter.cs @@ -16,9 +16,9 @@ namespace IRaCIS.Core.Application.BusinessFilter; /// public class EncreptApiResultFilter : IAsyncResultFilter { - private readonly IOptionsMonitor _encreptResponseMonitor; + private readonly IOptionsMonitor _encreptResponseMonitor; - public EncreptApiResultFilter(IOptionsMonitor encreptResponseMonitor) + public EncreptApiResultFilter(IOptionsMonitor encreptResponseMonitor) { _encreptResponseMonitor = encreptResponseMonitor; } @@ -26,7 +26,7 @@ public class EncreptApiResultFilter : IAsyncResultFilter public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) { - if (_encreptResponseMonitor.CurrentValue.IsEnable) + if (_encreptResponseMonitor.CurrentValue.IsResponseEncreptEnable) { if (context.Result is ObjectResult objectResult) diff --git a/IRaCIS.Core.Application/BusinessFilter/Encryption/EncryptionRequestMiddleware.cs b/IRaCIS.Core.Application/BusinessFilter/Encryption/EncryptionRequestMiddleware.cs index 055e306f9..b23917a09 100644 --- a/IRaCIS.Core.Application/BusinessFilter/Encryption/EncryptionRequestMiddleware.cs +++ b/IRaCIS.Core.Application/BusinessFilter/Encryption/EncryptionRequestMiddleware.cs @@ -1,5 +1,7 @@ using DocumentFormat.OpenXml.InkML; +using IRaCIS.Core.Domain.Share; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; @@ -13,55 +15,120 @@ public class EncryptionRequestMiddleware { private readonly RequestDelegate _next; - public EncryptionRequestMiddleware(RequestDelegate next) + private readonly IRCEncreptOption _IRCEncreptOption; + + public EncryptionRequestMiddleware(RequestDelegate next, IOptionsMonitor encreptResponseMonitor) { _next = next; + + _IRCEncreptOption = encreptResponseMonitor.CurrentValue; } public async Task InvokeAsync(HttpContext context) { + //模拟前端已经设置该请求头 + //context.Request.Headers["X-Encrypted-Key"] = "hW8JuJocBzIPWSHURUnYJMZ0l68g6uP9rEdMho8ioFO8amD6GIH+R6RIX5jVFzOwO+lmgBi+4gaVJGGkWJMTcoDTfzzzT1EmfPV+UhFLE9HWvCkEXmDOLE9xCHrbG8TrR1I9+Qd3cvo9HLmrQ58n13cJsM82FBw+reUgiWeklPCkEWM9br2qc9VkCp6gKzimTldNTWBezV86S6j3qHbZpVZm0atdDtGb+zSC9LLA3+oHQwRLJAAGSOAi8CUiRmIQsygRd824wBndkaH2ImEeRjBMs7PqCeK3KsoDp13yHdj2AE751gsfNzf4SF547UPf72m0F2/rBFgrSNy+Jz0T9w=="; + // 检查请求头中是否包含加密的对称密钥 if (context.Request.Headers.ContainsKey("X-Encrypted-Key")) { - var encryptedSymmetricKey = Convert.FromBase64String(context.Request.Headers["X-Encrypted-Key"]); - //// 使用私钥解密对称密钥 - //var decryptedSymmetricKey = RsaEncryptionHelper.DecryptRsa(encryptedSymmetricKey, _rsaPrivateKey); - //var aesKey = decryptedSymmetricKey[..32]; // 前32字节作为AES密钥 - //var aesIv = decryptedSymmetricKey[32..]; // 后面16字节作为IV + var encryptedSymmetricKeyStr = context.Request.Headers["X-Encrypted-Key"].ToString(); - //// 读取并解密请求体中的JSON数据 - //context.Request.EnableBuffering(); - //using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, leaveOpen: true)) - //{ - // var encryptedBody = await reader.ReadToEndAsync(); - // context.Request.Body.Position = 0; + var pemSecretKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.Base64RSAPrivateKey)); + + // 使用私钥解密对称密钥 + var decryptedSymmetricKey = RSAEncryption.Decrypt(pemSecretKey, encryptedSymmetricKeyStr); + + + #region 处理路径传递参数 + + // 处理路径参数解密 + var path = context.Request.Path.Value; + + // 假设加密的参数在路径中,按照顺序解密路径中的每个部分 + var pathSegments = path.Split('/', StringSplitOptions.RemoveEmptyEntries); + for (int i = 2; i < pathSegments.Length; i++) + { + if (!string.IsNullOrEmpty(pathSegments[i])) + { + try + { + var decryptedSegment = AesEncryption.Decrypt(pathSegments[i], decryptedSymmetricKey); + pathSegments[i] = decryptedSegment; + } + catch + { + // 如果不能解密该部分,保持原值 + } + } + } + + // 将解密后的路径重新拼接并设置到请求的Path + context.Request.Path = "/" + string.Join("/", pathSegments); + + #endregion + + #region 处理url 传递参数 + + // 处理 URL 查询参数的解密 + var queryParams = context.Request.Query.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToString()); + var decryptedQueryParams = new Dictionary(); + + foreach (var param in queryParams) + { + var encryptedValue = param.Value; + var decryptedValue = AesEncryption.Decrypt(encryptedValue, decryptedSymmetricKey); + decryptedQueryParams[param.Key] = decryptedValue; + } + + // 构造解密后的查询字符串 + var decryptedQueryString = new QueryString("?" + string.Join("&", decryptedQueryParams.Select(kvp => $"{kvp.Key}={kvp.Value}"))); + context.Request.QueryString = decryptedQueryString; + + #endregion + + #region 处理body传参 + + // 读取并解密请求体中的JSON数据 + context.Request.EnableBuffering(); + using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, leaveOpen: true)) + { + var encryptedBody = await reader.ReadToEndAsync(); + context.Request.Body.Position = 0; + + + if (!string.IsNullOrEmpty(encryptedBody)) + { + // 尝试解析为JObject + var encryptedJson = JObject.Parse(encryptedBody); + var decryptedJson = new JObject(); + + // 解密每个字段的值 + foreach (var property in encryptedJson.Properties()) + { + var encryptedValue = property.Value.ToString(); + var decryptedValue = AesEncryption.Decrypt(encryptedValue, decryptedSymmetricKey); + decryptedJson[property.Name] = decryptedValue; + } + + // 将解密后的JSON对象转换回字符串,并替换原始请求体 + var decryptedBody = decryptedJson.ToString(); + var bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(decryptedBody)); + context.Request.Body = bodyStream; + context.Request.ContentLength = bodyStream.Length; + bodyStream.Seek(0, SeekOrigin.Begin); + } + } + + #endregion - // // 尝试解析为JObject - // var encryptedJson = JObject.Parse(encryptedBody); - // var decryptedJson = new JObject(); - // // 解密每个字段的值 - // foreach (var property in encryptedJson.Properties()) - // { - // var encryptedValue = property.Value.ToString(); - // var decryptedValue = AesEncryptionHelper.DecryptString(encryptedValue, aesKey, aesIv); - // decryptedJson[property.Name] = decryptedValue; - // } - // // 将解密后的JSON对象转换回字符串,并替换原始请求体 - // var decryptedBody = decryptedJson.ToString(); - // var bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(decryptedBody)); - // context.Request.Body = bodyStream; - // context.Request.ContentLength = bodyStream.Length; - // bodyStream.Seek(0, SeekOrigin.Begin); } - - // 调用下一个中间件 await _next(context); } - } diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index 2c12fa561..f65699bcd 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -126,7 +126,7 @@ namespace IRaCIS.Application.Services - var model4= _mapper.Map(model1, model2); + var model4 = _mapper.Map(model1, model2); await _trialBodyPartRepository.FirstOrDefaultAsync(); @@ -245,9 +245,37 @@ namespace IRaCIS.Application.Services return ResponseOutput.Ok(); } - [UnitOfWork] - public async Task Get() + + public class TestEncrept { + public string Name { get; set; } + + public string Code { get; set; } + } + + public IResponseOutput TestEncreptTest(TestEncrept testModel) + { + return ResponseOutput.Ok(testModel); + } + + //etx5EzcF9XWA6ICzQB5ywEEextuhmUwaHM2TmyyCC8Q= + [HttpPut("{name}/{code}")] + public IResponseOutput TestEncreptTest2(string name, string code) + { + return ResponseOutput.Ok($"name:{name} Code: {code}"); + } + + public IResponseOutput TestEncreptTest3(string name, string Code) + { + return ResponseOutput.Ok($"name:{name} Code: {Code}"); + } + + + [UnitOfWork] + public async Task Get([FromServices] IOptionsMonitor _encreptResponseMonitor) + { + var _IRCEncreptOption = _encreptResponseMonitor.CurrentValue; + string plainText = "Hello, BouncyCastle!"; string key = "12345678901234567890123456789012"; // AES 密钥长度应为 16 字节(128 位) string iv = "your-iv-12345678"; // IV 长度为 16 字节 @@ -276,17 +304,32 @@ namespace IRaCIS.Application.Services Console.WriteLine($"解密后的数据: {decrypte}"); - // Generate RSA keys - var keyPair = RSAEncryption.GenerateRSAKeyPair(2048); + //// Generate RSA keys + //var keyPair = RSAEncryption.GenerateRSAKeyPair(2048); - // Export the public and private keys to PEM format - string publicKey = RSAEncryption.ExportPublicKey(keyPair.Public); - string privateKey = RSAEncryption.ExportPrivateKey(keyPair.Private); + //// Export the public and private keys to PEM format + //string publicKey = RSAEncryption.ExportPublicKey(keyPair.Public); + //string privateKey = RSAEncryption.ExportPrivateKey(keyPair.Private); + + //Console.WriteLine("Public Key:"); + //Console.WriteLine(publicKey); + //Console.WriteLine($"{Convert.ToBase64String(Encoding.UTF8.GetBytes(publicKey))}"); + //Console.WriteLine("\nPrivate Key:"); + //Console.WriteLine(privateKey); + //Console.WriteLine($"{Convert.ToBase64String(Encoding.UTF8.GetBytes(privateKey))}"); + + + + var publicKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.Base64RSAPublicKey)); + var privateKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.Base64RSAPrivateKey)); Console.WriteLine("Public Key:"); - Console.WriteLine(publicKey); - Console.WriteLine("\nPrivate Key:"); Console.WriteLine(privateKey); + Console.WriteLine("\nPrivate Key:"); + Console.WriteLine(publicKey); + + Console.WriteLine("encrept sys Key:"); + Console.WriteLine($"\n{RSAEncryption.Encrypt(publicKey, key)}"); // Data to encrypt string dataToEncrypt = "Hello, RSA!"; diff --git a/IRaCIS.Core.Domain/_Config/_AppSettings.cs b/IRaCIS.Core.Domain/_Config/_AppSettings.cs index 8afe0386d..be182ee8c 100644 --- a/IRaCIS.Core.Domain/_Config/_AppSettings.cs +++ b/IRaCIS.Core.Domain/_Config/_AppSettings.cs @@ -98,9 +98,15 @@ namespace IRaCIS.Core.Domain.Share - public class EncreptResponseOption + public class IRCEncreptOption { - public bool IsEnable { get; set; } + public string Base64RSAPublicKey { get; set;} + + public string Base64RSAPrivateKey { get; set; } + + + + public bool IsResponseEncreptEnable { get; set; } public List ApiPathList { get; set; } } From 7df247d5e7204d60dcc714d28089d377108506b8 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 19 Sep 2024 13:24:56 +0800 Subject: [PATCH 56/59] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E5=BA=9F=E5=BC=83=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Common/DTO/DictionaryModel.cs | 1 - IRaCIS.Core.Application/Service/Common/DictionaryService.cs | 4 ---- IRaCIS.Core.Application/Service/Common/_MapConfig.cs | 4 ++-- IRaCIS.Core.Domain/Common/Dictionary.cs | 1 - 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/DTO/DictionaryModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/DictionaryModel.cs index 8769f96a6..08267c180 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/DictionaryModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/DictionaryModel.cs @@ -136,7 +136,6 @@ namespace IRaCIS.Application.Contracts public Guid? ParentId { get; set; } public string ParentCode { get; set; } = string.Empty; - public int? ParentChildCodeEnum { get; set; } public string ChildGroup { get; set; } = string.Empty; diff --git a/IRaCIS.Core.Application/Service/Common/DictionaryService.cs b/IRaCIS.Core.Application/Service/Common/DictionaryService.cs index 57fe7ac1c..5ad938f17 100644 --- a/IRaCIS.Core.Application/Service/Common/DictionaryService.cs +++ b/IRaCIS.Core.Application/Service/Common/DictionaryService.cs @@ -407,7 +407,6 @@ namespace IRaCIS.Application.Services ChildGroup = x.Dictionary.ChildGroup, Code = x.Dictionary.Code, DataTypeEnum = x.Dictionary.DataTypeEnum, - ParentChildCodeEnum = x.Dictionary.Parent.ChildCodeEnum, ShowOrder = x.Dictionary.ShowOrder, ParentCode = x.ParentCode, CrterionDictionaryGroup = x.CrterionDictionaryGroup, @@ -427,7 +426,6 @@ namespace IRaCIS.Application.Services ChildGroup = x.Dictionary.ChildGroup, Code = x.Dictionary.Code, DataTypeEnum = x.Dictionary.DataTypeEnum, - ParentChildCodeEnum = x.Dictionary.Parent.ChildCodeEnum, ShowOrder = x.Dictionary.ShowOrder, ParentCode = x.ParentCode, CrterionDictionaryGroup = x.CrterionDictionaryGroup, @@ -521,7 +519,6 @@ namespace IRaCIS.Application.Services Code = x.Dictionary.Code, Description = x.Dictionary.Description, DataTypeEnum = x.Dictionary.DataTypeEnum, - ParentChildCodeEnum = x.Dictionary.Parent.ChildCodeEnum, ShowOrder = x.Dictionary.ShowOrder, ParentCode = x.ParentCode, Id = x.DictionaryId, @@ -565,7 +562,6 @@ namespace IRaCIS.Application.Services Code = x.Dictionary.Code, Description = x.Dictionary.Description, DataTypeEnum = x.Dictionary.DataTypeEnum, - ParentChildCodeEnum = x.Dictionary.Parent.ChildCodeEnum, ShowOrder = x.Dictionary.ShowOrder, ParentCode = x.ParentCode, Id = x.DictionaryId, diff --git a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs index 916cabf1f..8cd80d6a8 100644 --- a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs @@ -52,12 +52,12 @@ namespace IRaCIS.Core.Application.Service CreateMap(); CreateMap() - .ForMember(o => o.ParentChildCodeEnum, t => t.MapFrom(u => u.Parent.ChildCodeEnum)) + //.ForMember(o => o.ParentChildCodeEnum, t => t.MapFrom(u => u.Parent.ChildCodeEnum)) .ForMember(o => o.Value, t => t.MapFrom(u => isEn_Us ? u.Value : u.ValueCN)) .ForMember(o => o.ParentCode, t => t.MapFrom(u => u.Parent.Code)); CreateMap() - .ForMember(o => o.ParentChildCodeEnum, t => t.MapFrom(u => u.Parent.ChildCodeEnum)) + //.ForMember(o => o.ParentChildCodeEnum, t => t.MapFrom(u => u.Parent.ChildCodeEnum)) .ForMember(o => o.ParentCode, t => t.MapFrom(u => u.Parent.Code)); var token = ""; diff --git a/IRaCIS.Core.Domain/Common/Dictionary.cs b/IRaCIS.Core.Domain/Common/Dictionary.cs index a028e81cd..6e18c561a 100644 --- a/IRaCIS.Core.Domain/Common/Dictionary.cs +++ b/IRaCIS.Core.Domain/Common/Dictionary.cs @@ -29,7 +29,6 @@ namespace IRaCIS.Core.Domain.Models public string ChildGroup { get; set; } = string.Empty; - public int ChildCodeEnum { get; set; } public DicDataTypeEnum DataTypeEnum { get; set; } From 4e7ce826c81574459bba887ce16ef56323d5f2e4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 19 Sep 2024 13:59:00 +0800 Subject: [PATCH 57/59] =?UTF-8?q?=E6=B8=85=E7=90=86=E9=82=AE=E4=BB=B6?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/IRaCIS.Core.Application.xml | 6 ------ .../Service/Common/DTO/EmailNoticeConfigViewModel.cs | 2 -- .../Service/Document/DTO/TrialEmailNoticeConfigViewModel.cs | 2 -- IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs | 3 --- IRaCIS.Core.Domain/Document/TrialEmailNoticeConfig.cs | 2 -- 5 files changed, 15 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 1ce5ba12e..a645900c5 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -10817,9 +10817,6 @@ 业务层级 /// - - 邮件类型 /// - 邮件加急类型 /// @@ -11794,9 +11791,6 @@ 业务层级 /// - - 邮件类型 /// - 邮件加急类型 /// diff --git a/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs index c473097a0..52258fa1d 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs @@ -96,8 +96,6 @@ namespace IRaCIS.Core.Application.Contracts /// 业务层级 /// public int BusinessLevelEnum { get; set; } - /// 邮件类型 /// - public int EmailTypeEnum { get; set; } /// 邮件加急类型 /// public int EmailUrgentEnum { get; set; } diff --git a/IRaCIS.Core.Application/Service/Document/DTO/TrialEmailNoticeConfigViewModel.cs b/IRaCIS.Core.Application/Service/Document/DTO/TrialEmailNoticeConfigViewModel.cs index 76982a056..432e065bf 100644 --- a/IRaCIS.Core.Application/Service/Document/DTO/TrialEmailNoticeConfigViewModel.cs +++ b/IRaCIS.Core.Application/Service/Document/DTO/TrialEmailNoticeConfigViewModel.cs @@ -160,8 +160,6 @@ namespace IRaCIS.Core.Application.ViewModel /// 业务层级 /// public int BusinessLevelEnum { get; set; } - /// 邮件类型 /// - public int EmailTypeEnum { get; set; } /// 邮件加急类型 /// public int EmailUrgentEnum { get; set; } diff --git a/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs b/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs index 4f28ebf6b..2b0c7b1b7 100644 --- a/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs +++ b/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs @@ -39,9 +39,6 @@ namespace IRaCIS.Core.Domain.Models /// 业务层级 /// public int BusinessLevelEnum { get; set; } - /// 邮件类型 /// - public int EmailTypeEnum { get; set; } - /// 邮件加急类型 /// public int EmailUrgentEnum { get; set; } diff --git a/IRaCIS.Core.Domain/Document/TrialEmailNoticeConfig.cs b/IRaCIS.Core.Domain/Document/TrialEmailNoticeConfig.cs index 6160fb984..59f1c25c9 100644 --- a/IRaCIS.Core.Domain/Document/TrialEmailNoticeConfig.cs +++ b/IRaCIS.Core.Domain/Document/TrialEmailNoticeConfig.cs @@ -62,8 +62,6 @@ namespace IRaCIS.Core.Domain.Models /// 业务层级 /// public int BusinessLevelEnum { get; set; } - /// 邮件类型 /// - public int EmailTypeEnum { get; set; } /// 邮件加急类型 /// public int EmailUrgentEnum { get; set; } From b98df9dae8266ce8d46bb84392aa557a48495591 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 19 Sep 2024 16:40:17 +0800 Subject: [PATCH 58/59] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ExtraController.cs | 4 +- IRaCIS.Core.Application/TestService.cs | 15 +- .../Allocation/SubjectTaskCategory.cs | 61 ---- IRaCIS.Core.Domain/Common/CommonDocument.cs | 40 +-- IRaCIS.Core.Domain/Common/Dictionary.cs | 67 ++-- IRaCIS.Core.Domain/Common/FrontAuditConfig.cs | 296 +++++++++--------- IRaCIS.Core.Domain/Dcotor/Attachment.cs | 68 ++-- IRaCIS.Core.Domain/Dcotor/Doctor.cs | 228 +++++++------- IRaCIS.Core.Domain/Image/DicomInstance.cs | 107 ++++--- IRaCIS.Core.Domain/Image/DicomSeries.cs | 99 +++--- IRaCIS.Core.Domain/Image/DicomStudy.cs | 96 +++--- IRaCIS.Core.Domain/Institution/CRO.cs | 32 +- IRaCIS.Core.Domain/QC/CheckChallengeDialog.cs | 39 ++- .../ClinicalData/ClinicalDataSystemSet.cs | 97 ++---- .../ClinicalData/ClinicalDataTrialSet.cs | 122 +++----- .../ClinicalAnswerRowInfo.cs | 54 ++-- .../ClinicalQuestionAnswer/ClinicalForm.cs | 76 ++--- .../ClinicalQuestionAnswer.cs | 54 ++-- .../ClinicalTableAnswer.cs | 51 +-- .../ReadingCriterion/CriterionNidusSystem.cs | 65 ++-- .../ReadingCriterion/CriterionNidusTrial.cs | 32 +- IRaCIS.Core.Domain/Trial/DataInspection.cs | 142 ++++----- .../CodeTemplates/EFCore/EntityType.t4 | 2 + 23 files changed, 876 insertions(+), 971 deletions(-) delete mode 100644 IRaCIS.Core.Domain/Allocation/SubjectTaskCategory.cs diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs index e20a5051e..203a4fc97 100644 --- a/IRaCIS.Core.API/Controllers/ExtraController.cs +++ b/IRaCIS.Core.API/Controllers/ExtraController.cs @@ -295,9 +295,9 @@ namespace IRaCIS.Api.Controllers [HttpGet, Route("user/getPublicKey")] public IResponseOutput GetPublicKey([FromServices] IOptionsMonitor _IRCEncreptOption) { - var pemPublicKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.CurrentValue.Base64RSAPublicKey)); + //var pemPublicKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.CurrentValue.Base64RSAPublicKey)); - return ResponseOutput.Ok(pemPublicKey); + return ResponseOutput.Ok(_IRCEncreptOption.CurrentValue.Base64RSAPublicKey); } diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index f65699bcd..a66522634 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -253,7 +253,7 @@ namespace IRaCIS.Application.Services public string Code { get; set; } } - public IResponseOutput TestEncreptTest(TestEncrept testModel) + public IResponseOutput TestEncreptTest(TestEncrept testModel) { return ResponseOutput.Ok(testModel); } @@ -276,6 +276,12 @@ namespace IRaCIS.Application.Services { var _IRCEncreptOption = _encreptResponseMonitor.CurrentValue; + var publicKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.Base64RSAPublicKey)); + var privateKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.Base64RSAPrivateKey)); + + Console.WriteLine(RSAEncryption.Encrypt(publicKey, MD5Helper.Md5("123456"))); + + string plainText = "Hello, BouncyCastle!"; string key = "12345678901234567890123456789012"; // AES 密钥长度应为 16 字节(128 位) string iv = "your-iv-12345678"; // IV 长度为 16 字节 @@ -320,13 +326,12 @@ namespace IRaCIS.Application.Services - var publicKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.Base64RSAPublicKey)); - var privateKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.Base64RSAPrivateKey)); + Console.WriteLine("Public Key:"); - Console.WriteLine(privateKey); - Console.WriteLine("\nPrivate Key:"); Console.WriteLine(publicKey); + Console.WriteLine("\nPrivate Key:"); + Console.WriteLine(privateKey); Console.WriteLine("encrept sys Key:"); Console.WriteLine($"\n{RSAEncryption.Encrypt(publicKey, key)}"); diff --git a/IRaCIS.Core.Domain/Allocation/SubjectTaskCategory.cs b/IRaCIS.Core.Domain/Allocation/SubjectTaskCategory.cs deleted file mode 100644 index 9cf314130..000000000 --- a/IRaCIS.Core.Domain/Allocation/SubjectTaskCategory.cs +++ /dev/null @@ -1,61 +0,0 @@ - -//-------------------------------------------------------------------- -// 此代码由T4模板自动生成 byzhouhang 20210918 -// 生成时间 2022-06-07 14:09:29 -// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 -using System; -using IRaCIS.Core.Domain.Share; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Collections.Generic; - -namespace IRaCIS.Core.Domain.Models -{ - /// - ///是否需要拆表 - /// - [Table("SubjectTaskCategory")] - public class SubjectTaskCategory : BaseAddAuditEntity - { - - - #region 导航属性 - - [JsonIgnore] - [ForeignKey("SouceReadModuleId")] - public ReadModule ReadModule { get; set; } - - - [JsonIgnore] - [ForeignKey("SourceSubjectVisitId")] - public SubjectVisit SubjectVisit { get; set; } - - [JsonIgnore] - public Subject Subject { get; set; } - - #endregion - - public Guid TrialId { get; set; } - - public string TaskName { get; set; } = string.Empty; - public string TaskBlindName { get; set; } = string.Empty; - - //任务来源访视Id 方便回更访视读片状态 - public Guid? SourceSubjectVisitId { get; set; } - - public Guid? SouceReadModuleId { get; set; } - - - public ReadingCategory ReadingCategory { get; set; } - - public Guid SubjectId { get; set; } - - - - - - - - } - -} diff --git a/IRaCIS.Core.Domain/Common/CommonDocument.cs b/IRaCIS.Core.Domain/Common/CommonDocument.cs index 1b2af8ff8..6e7aad650 100644 --- a/IRaCIS.Core.Domain/Common/CommonDocument.cs +++ b/IRaCIS.Core.Domain/Common/CommonDocument.cs @@ -7,32 +7,32 @@ using System; using IRaCIS.Core.Domain.Share; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +using Microsoft.EntityFrameworkCore; +namespace IRaCIS.Core.Domain.Models; + + +[Comment("数据上传 | 数据导出 | 邮件附件 文件记录表 (需要同步)")] +[Table("CommonDocument")] +public class CommonDocument : BaseFullDeleteAuditEntity { - /// - ///CommonDocument - /// - [Table("CommonDocument")] - public class CommonDocument : BaseFullDeleteAuditEntity - { + [Comment(" 业务场景")] + public EmailBusinessScenario BusinessScenarioEnum { get; set; } - public string Code { get; set; } = String.Empty; + public string Code { get; set; } = null!; + [Comment(" 系统标准枚举")] + public CriterionType? CriterionTypeEnum { get; set; } - public string Name { get; set; } = String.Empty; + public string Description { get; set; } = null!; - public string NameCN { get; set; } = string.Empty; + [Comment(" 类型-上传|导出|邮件附件")] + public CommonDocumentFileType FileTypeEnum { get; set; } - public string Path { get; set; } = String.Empty; + public string Name { get; set; } = null!; + public string NameCN { get; set; } = null!; - public string Description { get; set; } = String.Empty; - - public CriterionType? CriterionTypeEnum { get; set; } - public CommonDocumentFileType FileTypeEnum { get; set; } - public EmailBusinessScenario BusinessScenarioEnum { get; set; } - - - } - + public string Path { get; set; } = null!; } + + diff --git a/IRaCIS.Core.Domain/Common/Dictionary.cs b/IRaCIS.Core.Domain/Common/Dictionary.cs index 6e18c561a..e8483c8fc 100644 --- a/IRaCIS.Core.Domain/Common/Dictionary.cs +++ b/IRaCIS.Core.Domain/Common/Dictionary.cs @@ -1,60 +1,63 @@ using IRaCIS.Core.Domain.Share; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +namespace IRaCIS.Core.Domain.Models; + +[Comment("̨ - ֵҪͬ")] +[Table("Dictionary")] +public partial class Dictionary : BaseFullAuditEntity { - [Table("Dictionary")] - public partial class Dictionary : BaseFullAuditEntity - { - #region - [JsonIgnore] - public List DoctorDicRelationList { get; set; } = new List(); + #region + [JsonIgnore] + public List DoctorDicRelationList { get; set; } = new List(); - [JsonIgnore] - [ForeignKey("ConfigTypeId")] - public Dictionary ConfigDictionary { get; set; } + [JsonIgnore] + [ForeignKey("ConfigTypeId")] + public Dictionary ConfigDictionary { get; set; } - [JsonIgnore] - [ForeignKey("ParentId")] - public Dictionary Parent { get; set; } - [JsonIgnore] - public List ChildList { get; set; } = new List(); + [JsonIgnore] + [ForeignKey("ParentId")] + public Dictionary Parent { get; set; } + [JsonIgnore] + public List ChildList { get; set; } = new List(); - #endregion + #endregion - public string ChildGroup { get; set; } = string.Empty; + [StringLength(400)] + public string ChildGroup { get; set; } = null!; + public string Code { get; set; } = null!; - public DicDataTypeEnum DataTypeEnum { get; set; } + public Guid? ConfigTypeId { get; set; } + [Comment(" ֵ- ö|bool|")] + public DicDataTypeEnum DataTypeEnum { get; set; } - [Column("Value")] - public string Value { get; set; } = string.Empty; + [StringLength(512)] + public string Description { get; set; } = null!; - [Column("ValueCN")] - public string ValueCN { get; set; } = string.Empty; + [Comment(" Ƿֵ")] + public bool IsConfig { get; set; } + public bool IsEnable { get; set; } - [StringLength(512)] - public string Description { get; set; } = string.Empty; + public Guid? ParentId { get; set; } - public int ShowOrder { get; set; } + public int ShowOrder { get; set; } - public string Code { get; set; } = string.Empty; + [StringLength(400)] + public string Value { get; set; } = null!; - public Guid? ParentId { get; set; } - - public bool IsEnable { get; set; } - - public Guid? ConfigTypeId { get; set; } + [StringLength(400)] + public string ValueCN { get; set; } = null!; - } } diff --git a/IRaCIS.Core.Domain/Common/FrontAuditConfig.cs b/IRaCIS.Core.Domain/Common/FrontAuditConfig.cs index 1efc058dc..235b1ff9a 100644 --- a/IRaCIS.Core.Domain/Common/FrontAuditConfig.cs +++ b/IRaCIS.Core.Domain/Common/FrontAuditConfig.cs @@ -9,215 +9,213 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Collections.Generic; -namespace IRaCIS.Core.Domain.Models +namespace IRaCIS.Core.Domain.Models; + +/// +///FrontAuditConfig +/// +[Table("FrontAuditConfig")] +public class FrontAuditConfig : BaseFullAuditEntity { - /// - ///FrontAuditConfig - /// - [Table("FrontAuditConfig")] - public class FrontAuditConfig : BaseFullAuditEntity - { - #region 导航属性 + #region 导航属性 - #endregion - public string Value { get; set; } = String.Empty; + #endregion + public string Value { get; set; } = String.Empty; - public string ValueCN { get; set; } = String.Empty; + public string ValueCN { get; set; } = String.Empty; - public string Description { get; set; } = String.Empty; + public string Description { get; set; } = String.Empty; - public string DescriptionCN { get; set; } = String.Empty; + public string DescriptionCN { get; set; } = String.Empty; - + - /// - /// 是否有签名 - /// - public bool IsHaveSign { get; set; } + /// + /// 是否有签名 + /// + public bool IsHaveSign { get; set; } - /// - /// 是否有原因 - /// - public bool IsHaveReason { get; set; } + /// + /// 是否有原因 + /// + public bool IsHaveReason { get; set; } - /// - /// 是否完成 - /// - public bool IsFinish { get; set; } + /// + /// 是否完成 + /// + public bool IsFinish { get; set; } - /// - /// 是否加入计划 - /// - public bool IsJoinPlan { get; set; } + /// + /// 是否加入计划 + /// + public bool IsJoinPlan { get; set; } - /// - /// 标识 - /// - public string Identification { get; set; } = string.Empty; + /// + /// 标识 + /// + public string Identification { get; set; } = string.Empty; - public Guid? ParentId { get; set; } + public Guid? ParentId { get; set; } - public bool IsEnable { get; set; } + public bool IsEnable { get; set; } - public int Sort { get; set; } + public int Sort { get; set; } - public Guid? ModuleTypeId { get; set; } + public Guid? ModuleTypeId { get; set; } - public Guid? ObjectTypeId { get; set; } - public Guid? OptTypeId { get; set; } + public Guid? ObjectTypeId { get; set; } + public Guid? OptTypeId { get; set; } - public Guid? ChildrenTypeId { get; set; } + public Guid? ChildrenTypeId { get; set; } - public int IsShowParent { get; set; } + public int IsShowParent { get; set; } - public string InterfaceName { get; set; } = String.Empty; + public string InterfaceName { get; set; } = String.Empty; - //前端使用 C M - public string ConfigType { get; set; } = String.Empty; + //前端使用 C M + public string ConfigType { get; set; } = String.Empty; - //翻译的字段名 这里有可能是一个数组名 那么具体的翻译字段名就不是这个了 - public string Code { get; set; } = String.Empty; + //翻译的字段名 这里有可能是一个数组名 那么具体的翻译字段名就不是这个了 + public string Code { get; set; } = String.Empty; - /// - /// 字段的英文值 - /// - public string CodeEn { get; set; } = string.Empty; + /// + /// 字段的英文值 + /// + public string CodeEn { get; set; } = string.Empty; - //前端渲染数组 数组名 和数组值 - public string ChildDataLabel { get; set; } = String.Empty; + //前端渲染数组 数组名 和数组值 + public string ChildDataLabel { get; set; } = String.Empty; - /// - /// 前端渲染数组 数组名 和数组值 英文名称 - /// - public string ChildDataEnLabel { get; set; } = string.Empty; - - public string ChildDataValue { get; set; } = String.Empty; + /// + /// 前端渲染数组 数组名 和数组值 英文名称 + /// + public string ChildDataEnLabel { get; set; } = string.Empty; + + public string ChildDataValue { get; set; } = String.Empty; - /// - /// 翻译的字典名(单个字段翻译的时候) - /// + /// + /// 翻译的字典名(单个字段翻译的时候) + /// - public string DictionaryCode { get; set; } = String.Empty; + public string DictionaryCode { get; set; } = String.Empty; - /// - /// 前端展示类型 Router, Array,Table - /// + /// + /// 前端展示类型 Router, Array,Table + /// - public string DataType { get; set; } = String.Empty; + public string DataType { get; set; } = String.Empty; - // 后端翻译的类型 对应前端界面 "",Dictionary,Date - public string EnumType { get; set; } = String.Empty; + // 后端翻译的类型 对应前端界面 "" Dictionary Date + public string EnumType { get; set; } = String.Empty; - /// - /// 翻译的类型 FrontAudit 的描述 可能是Id Code - /// - public string DictionaryType { get; set; } = String.Empty; + /// + /// 翻译的类型 FrontAudit 的描述 可能是Id Code + /// + public string DictionaryType { get; set; } = String.Empty; - /// - /// 后端翻译的 日期类型 - /// + /// + /// 后端翻译的 日期类型 + /// - public string DateType { get; set; } = String.Empty; + public string DateType { get; set; } = String.Empty; - /// 字典表 - public string ForeignKeyTableName { get; set; } = String.Empty; + /// 字典表 + public string ForeignKeyTableName { get; set; } = String.Empty; - /// 字典Value - public string ForeignKeyValue { get; set; } = String.Empty; + /// 字典Value + public string ForeignKeyValue { get; set; } = String.Empty; - /// 字典 - public string ForeignKeyText { get; set; } = String.Empty; + /// 字典 + public string ForeignKeyText { get; set; } = String.Empty; - /// - /// 英文的翻译 - /// - public string ForeignKeyEnText { get; set; } = string.Empty; + /// + /// 英文的翻译 + /// + public string ForeignKeyEnText { get; set; } = string.Empty; - public string TableConfigJsonStr { get; set; } = String.Empty; + public string TableConfigJsonStr { get; set; } = String.Empty; - public string UrlConfigJsonStr { get; set; } = String.Empty; + public string UrlConfigJsonStr { get; set; } = String.Empty; - #region 废弃 - //未知是否有用 - public bool IsConfig { get; set; } - /// - /// 是否为特殊类型 - /// - public bool IsSpecialType { get; set; } - public string DictionaryKey { get; set; } = string.Empty; + #region 废弃 + //未知是否有用 + public bool IsConfig { get; set; } + /// + /// 是否为特殊类型 + /// + public bool IsSpecialType { get; set; } + public string DictionaryKey { get; set; } = string.Empty; - public bool IsShowByTrialConfig { get; set; } - public string TrialConfigRelyFieldName { get; set; } = string.Empty; + public bool IsShowByTrialConfig { get; set; } + public string TrialConfigRelyFieldName { get; set; } = string.Empty; - #endregion - - } - - - - - public class UrlConfig - { - public bool IsRoute { get; set; } - - public string RoutePath { get; set; } = string.Empty; - - public bool IsHaveParameters { get; set; } - - public List ParameterList { get; set; } = new List(); - - public class ParameterConfig - { - public string UrlParameterName { get; set; } = String.Empty; - public string UrlParameterValueName { get; set; } = String.Empty; - } - } - - public class TableConfig - { - public bool IsList { get; set; } - public string ListName { get; set; } = String.Empty; - public bool IsFixedColumn { get; set; } - public string FixedColumnName { get; set; } = String.Empty; - - public string FixedColumnEnName { get; set; } = String.Empty; - public string ColumnName { get; set; } = String.Empty; - public string ColumnValue { get; set; } = String.Empty; - public bool IsMerge { get; set; } - public string MergeColumnName { get; set; } = String.Empty; - - public string MergeColumnEnName { get; set; } = String.Empty; - - public string ColumnEnName { get; set; } = String.Empty; - public bool IsPicture { get; set; } - - - public bool IsNeedTransalate { get; set; } - public string TranslateDictionaryName { get; set; } = String.Empty; - - - public bool IsDynamicTranslate { get; set; } - - } + #endregion + +} + + + + +public class UrlConfig +{ + public bool IsRoute { get; set; } + + public string RoutePath { get; set; } = string.Empty; + + public bool IsHaveParameters { get; set; } + + public List ParameterList { get; set; } = new List(); + + public class ParameterConfig + { + public string UrlParameterName { get; set; } = String.Empty; + public string UrlParameterValueName { get; set; } = String.Empty; + } +} + +public class TableConfig +{ + public bool IsList { get; set; } + public string ListName { get; set; } = String.Empty; + public bool IsFixedColumn { get; set; } + public string FixedColumnName { get; set; } = String.Empty; + + public string FixedColumnEnName { get; set; } = String.Empty; + public string ColumnName { get; set; } = String.Empty; + public string ColumnValue { get; set; } = String.Empty; + public bool IsMerge { get; set; } + public string MergeColumnName { get; set; } = String.Empty; + + public string MergeColumnEnName { get; set; } = String.Empty; + + public string ColumnEnName { get; set; } = String.Empty; + public bool IsPicture { get; set; } + + + public bool IsNeedTransalate { get; set; } + public string TranslateDictionaryName { get; set; } = String.Empty; + + + public bool IsDynamicTranslate { get; set; } } diff --git a/IRaCIS.Core.Domain/Dcotor/Attachment.cs b/IRaCIS.Core.Domain/Dcotor/Attachment.cs index 85aaf8f47..858043679 100644 --- a/IRaCIS.Core.Domain/Dcotor/Attachment.cs +++ b/IRaCIS.Core.Domain/Dcotor/Attachment.cs @@ -1,37 +1,49 @@ +using Microsoft.EntityFrameworkCore; using System; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +namespace IRaCIS.Core.Domain.Models; + +//public enum AttachmentType +//{ +// Avatar=1,//头像 +// Resume=2,//简历 +// GCP=3,//GCP证书 +// MedicalLicence=4,//医师资格证 +// PracticeCertificate=5,//执业资格证 +// LargeEquipmentWorkingCertificate=6,//大型器械上岗证 +// HighestDegreeCertificate=7//最高学历证书 +//} +[Comment("医生 - 简历|证书 文档表")] +[Table("Attachment")] +public class Attachment : BaseAddAuditEntity { - //public enum AttachmentType - //{ - // Avatar=1,//头像 - // Resume=2,//简历 - // GCP=3,//GCP证书 - // MedicalLicence=4,//医师资格证 - // PracticeCertificate=5,//执业资格证 - // LargeEquipmentWorkingCertificate=6,//大型器械上岗证 - // HighestDegreeCertificate=7//最高学历证书 - //} - [Table("Attachment")] - public partial class Attachment : BaseAddAuditEntity - { - [JsonIgnore] - public Doctor Doctor { get; set; } + [JsonIgnore] + public Doctor Doctor { get; set; } - public Guid DoctorId { get; set; } - public string Type { get; set; } = string.Empty; - public bool IsOfficial { get; set; } = false; - public string Path { get; set; } = string.Empty; - public string Code { get; set; } = string.Empty; - public DateTime? ExpiryDate { get; set; } - public string FileName { get; set; } = string.Empty; + [Comment(" 编码")] + [StringLength(400)] + public string Code { get; set; } = null!; - //language=1 中文, 2为英文 - public int Language { get; set; } = 0; + public Guid DoctorId { get; set; } - //public Guid CreateUserId { get; set; } = Guid.Empty; - //public DateTime? CreateTime { get; set; } - } + [Comment(" 过期时间")] + public DateTime? ExpiryDate { get; set; } + + public string FileName { get; set; } = null!; + + [Comment(" 是否正式简历")] + public bool IsOfficial { get; set; } + + [Comment(" 1 中文 2为英文")] + public int Language { get; set; } + + [StringLength(512)] + public string Path { get; set; } = null!; + + [Comment(" 文件类型名")] + [StringLength(400)] + public string Type { get; set; } = null!; } diff --git a/IRaCIS.Core.Domain/Dcotor/Doctor.cs b/IRaCIS.Core.Domain/Dcotor/Doctor.cs index 0d698ebb9..d05e5b886 100644 --- a/IRaCIS.Core.Domain/Dcotor/Doctor.cs +++ b/IRaCIS.Core.Domain/Dcotor/Doctor.cs @@ -1,186 +1,194 @@ using IRaCIS.Core.Domain.Share; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +namespace IRaCIS.Core.Domain.Models; + +[Comment("ҽ - Ϣ")] +[Table("Doctor")] +public class Doctor : BaseFullAuditEntity { - [Table("Doctor")] - public partial class Doctor : BaseFullAuditEntity - { - #region + #region - // - [JsonIgnore] - public List DoctorDicRelationList { get; set; } = new List(); - [JsonIgnore] - public List TrialExperienceCriteriaList { get; set; } + // + [JsonIgnore] + public List DoctorDicRelationList { get; set; } = new List(); + [JsonIgnore] + public List TrialExperienceCriteriaList { get; set; } - [JsonIgnore] - public List EnrollList { get; set; } + [JsonIgnore] + public List EnrollList { get; set; } - [JsonIgnore] - [ForeignKey("HospitalId")] - public Hospital Hospital { get; set; } - [JsonIgnore] - [ForeignKey("SpecialityId")] - public virtual Dictionary Speciality { get; set; } - [JsonIgnore] - [ForeignKey("DepartmentId")] - public virtual Dictionary Department { get; set; } + [JsonIgnore] + [ForeignKey("HospitalId")] + public Hospital Hospital { get; set; } + [JsonIgnore] + [ForeignKey("SpecialityId")] + public virtual Dictionary Speciality { get; set; } + [JsonIgnore] + [ForeignKey("DepartmentId")] + public virtual Dictionary Department { get; set; } - [JsonIgnore] - [ForeignKey("RankId")] - public virtual Dictionary Rank { get; set; } + [JsonIgnore] + [ForeignKey("RankId")] + public virtual Dictionary Rank { get; set; } - [JsonIgnore] - [ForeignKey("PositionId")] - public virtual Dictionary Position { get; set; } - [JsonIgnore] - public List AttachmentList { get; set; } - [JsonIgnore] - public List CriterionFileList { get; set; } + [JsonIgnore] + [ForeignKey("PositionId")] + public virtual Dictionary Position { get; set; } + [JsonIgnore] + public List AttachmentList { get; set; } + [JsonIgnore] + public List CriterionFileList { get; set; } - [JsonIgnore] - public User User { get; set; } - #endregion + [JsonIgnore] + public User User { get; set; } + #endregion + public bool AcceptingNewTrial { get; set; } - public string ReviewerCode { get; set; } = string.Empty; + public bool ActivelyReading { get; set; } - public int Code { get; set; } + [MaxLength] + public string? AdminComment { get; set; } - [StringLength(100)] - public string Phone { get; set; } = string.Empty; + public DateTime? AuditTime { get; set; } + public Guid AuditUserId { get; set; } - [StringLength(100)] - public string Password { get; set; } = string.Empty; + public string BlindName { get; set; } = null!; + public string BlindNameCN { get; set; } = null!; - [StringLength(50)] - public string ChineseName { get; set; } = string.Empty; + [MaxLength] + public string? BlindPublications { get; set; } - [StringLength(100)] - public string FirstName { get; set; } = string.Empty; + [StringLength(400)] + public string ChineseName { get; set; } = null!; + public int Code { get; set; } - [StringLength(100)] - public string LastName { get; set; } = string.Empty; + public ContractorStatusEnum CooperateStatus { get; set; } = ContractorStatusEnum.Noncooperation; - [NotMapped] - public string FullName => LastName + " / " + FirstName; + public Guid DepartmentId { get; set; } - public int Sex { get; set; } + [StringLength(400)] + public string DepartmentOther { get; set; } = null!; + [StringLength(400)] + public string DepartmentOtherCN { get; set; } = null!; - [StringLength(100)] - public string EMail { get; set; } = string.Empty; + [StringLength(400)] + public string EMail { get; set; } = null!; + [StringLength(400)] + public string FirstName { get; set; } = null!; - [StringLength(100)] - public string WeChat { get; set; } = string.Empty; + public int GCP { get; set; } + public Guid GCPId { get; set; } - [StringLength(1000)] - public string Introduction { get; set; } = string.Empty; + public Guid HospitalId { get; set; } - public Guid? DepartmentId { get; set; } = Guid.Empty; + public string HospitalOther { get; set; } = null!; + public string HospitalOtherCN { get; set; } = null!; - [StringLength(100)] - public string DepartmentOther { get; set; } = string.Empty; + [StringLength(2000)] + public string Introduction { get; set; } = null!; - public Guid? PhysicianId { get; set; } - public string Physician { get; set; } = string.Empty; - public string PhysicianCN { get; set; } = string.Empty; + public bool IsVirtual { get; set; } - public Guid? RankId { get; set; } = Guid.Empty; + public DateTime? LastLoginTime { get; set; } + [StringLength(400)] + public string LastName { get; set; } = null!; - [StringLength(100)] - public string RankOther { get; set; } = string.Empty; + public int Nation { get; set; } - public Guid? PositionId { get; set; } = Guid.Empty; + public Guid OrganizationId { get; set; } - [StringLength(100)] - public string PositionOther { get; set; } = string.Empty; + [MaxLength] + public string? OtherClinicalExperience { get; set; } - // Ƿɿ ζ һֱ - public Guid? HospitalId { get; set; } = Guid.Empty; + [MaxLength] + public string? OtherClinicalExperienceCN { get; set; } - [StringLength(200)] - public string HospitalOther { get; set; } = string.Empty; + [StringLength(400)] + public string Password { get; set; } = null!; - [StringLength(100)] - public string ReadingTypeOther { get; set; } = string.Empty; + [StringLength(400)] + public string Phone { get; set; } = null!; + public string PhotoPath { get; set; } = null!; - [StringLength(100)] - public string SubspecialityOther { get; set; } = string.Empty; + public string Physician { get; set; } = null!; - public int GCP { get; set; } + public string PhysicianCN { get; set; } = null!; - public Guid? GCPId { get; set; } = Guid.Empty; + public Guid? PhysicianId { get; set; } - public Guid OrganizationId { get; set; } = Guid.Empty; + public Guid? PositionId { get; set; } - public string OtherClinicalExperience { get; set; } = string.Empty; - public string OtherClinicalExperienceCN { get; set; } = string.Empty; + [StringLength(400)] + public string PositionOther { get; set; } = null!; - public ContractorStatusEnum CooperateStatus { get; set; } = ContractorStatusEnum.Noncooperation; + [StringLength(400)] + public string PositionOtherCN { get; set; } = null!; - public ResumeStatusEnum ResumeStatus { get; set; } = ResumeStatusEnum.Failed; + public Guid RankId { get; set; } + [StringLength(400)] + public string RankOther { get; set; } = null!; + [StringLength(400)] + public string RankOtherCN { get; set; } = null!; - [StringLength(512)] - public string PhotoPath { get; set; } = string.Empty; + [StringLength(400)] + public string ReadingTypeOther { get; set; } = null!; - [StringLength(512)] - public string ResumePath { get; set; } = string.Empty; - public Guid? SpecialityId { get; set; } = Guid.Empty; + [StringLength(400)] + public string ReadingTypeOtherCN { get; set; } = null!; - public string SpecialityOther { get; set; } = string.Empty; + [StringLength(512)] + public string ResumePath { get; set; } = null!; - public string AdminComment { get; set; } = string.Empty; + public ResumeStatusEnum ResumeStatus { get; set; } = ResumeStatusEnum.Failed; - public ReviewerInformationConfirmStatus ReviewStatus { get; set; } = ReviewerInformationConfirmStatus.ConfirmRefuse; + [StringLength(400)] + public string ReviewerCode { get; set; } = null!; - public bool AcceptingNewTrial { get; set; } = false; - public bool ActivelyReading { get; set; } = false; + public ReviewerInformationConfirmStatus ReviewStatus { get; set; } = ReviewerInformationConfirmStatus.ConfirmRefuse; - public DateTime? LastLoginTime { get; set; } + public int Sex { get; set; } - public Guid AuditUserId { get; set; } = Guid.Empty; + public Guid SpecialityId { get; set; } - public DateTime? AuditTime { get; set; } + [StringLength(400)] + public string SpecialityOther { get; set; } = null!; - public int Nation { get; set; } = 0; // ֧ͣ0-йҽCN1-ҽUS + [StringLength(400)] + public string SpecialityOtherCN { get; set; } = null!; + [StringLength(400)] + public string SubspecialityOther { get; set; } = null!; - public string ReadingTypeOtherCN { get; set; } = string.Empty; - public string HospitalOtherCN { get; set; } = string.Empty; - public string PositionOtherCN { get; set; } = string.Empty; - public string RankOtherCN { get; set; } = string.Empty; - public string DepartmentOtherCN { get; set; } = string.Empty; - public string SubspecialityOtherCN { get; set; } = string.Empty; - public string SpecialityOtherCN { get; set; } = string.Empty; + [StringLength(400)] + public string SubspecialityOtherCN { get; set; } = null!; + [StringLength(400)] + public string WeChat { get; set; } = null!; - public bool IsVirtual { get; set; } + [NotMapped] + public string FullName => LastName + " / " + FirstName; - public string BlindName { get; set; } = string.Empty; - public string BlindNameCN { get; set; } = string.Empty; - - - public string BlindPublications { get; set; } = string.Empty; - } } diff --git a/IRaCIS.Core.Domain/Image/DicomInstance.cs b/IRaCIS.Core.Domain/Image/DicomInstance.cs index 8893ae3b8..4931c820d 100644 --- a/IRaCIS.Core.Domain/Image/DicomInstance.cs +++ b/IRaCIS.Core.Domain/Image/DicomInstance.cs @@ -1,58 +1,85 @@ -using System; +using Microsoft.EntityFrameworkCore; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +namespace IRaCIS.Core.Domain.Models; + +[Comment("归档 - Instance表")] +[Table("DicomInstance")] +public class DicomInstance : BaseFullAuditEntity, IEntitySeqId { - [Table("DicomInstance")] - public class DicomInstance : BaseFullAuditEntity, IEntitySeqId - { - #region 导航属性 - [JsonIgnore] - [ForeignKey("SeriesId")] - public DicomSeries DicomSerie { get; set; } + #region 导航属性 + [JsonIgnore] + [ForeignKey("SeriesId")] + public DicomSeries DicomSerie { get; set; } - [JsonIgnore] - [ForeignKey("StudyId")] - public DicomStudy DicomStudy { get; set; } - #endregion + [JsonIgnore] + [ForeignKey("StudyId")] + public DicomStudy DicomStudy { get; set; } + #endregion + + public bool Anonymize { get; set; } + + public bool CPIStatus { get; set; } + + public long? FileSize { get; set; } + + [StringLength(500)] + public string FrameOfReferenceUID { get; set; } = null!; + + [StringLength(512)] + public string HtmlPath { get; set; } = null!; + + public int ImageColumns { get; set; } + + public int ImageRows { get; set; } + + [StringLength(400)] + public string ImagerPixelSpacing { get; set; } = null!; + + public int InstanceNumber { get; set; } + + public DateTime? InstanceTime { get; set; } + + public int NumberOfFrames { get; set; } + [MaxLength] + [Unicode(false)] + public string Path { get; set; } = null!; - public Guid SeqId { get; set; } - public Guid StudyId { get; set; } - public Guid SeriesId { get; set; } - public string StudyInstanceUid { get; set; } = String.Empty; - public string SeriesInstanceUid { get; set; } = String.Empty; - public string SopInstanceUid { get; set; } = String.Empty; - public int InstanceNumber { get; set; } - public DateTime? InstanceTime { get; set; } - public bool CPIStatus { get; set; } - public int ImageRows { get; set; } - public int ImageColumns { get; set; } - public int SliceLocation { get; set; } + [StringLength(400)] + public string PixelSpacing { get; set; } = null!; + public Guid SeqId { get; set; } - public string SliceThickness { get; set; } = String.Empty; - public int NumberOfFrames { get; set; } - public string PixelSpacing { get; set; } = String.Empty; + public Guid SeriesId { get; set; } - public string ImagerPixelSpacing { get; set; } = String.Empty; - public string FrameOfReferenceUID { get; set; } = String.Empty; - public string WindowCenter { get; set; } = String.Empty; - public string WindowWidth { get; set; } = String.Empty; + public string SeriesInstanceUid { get; set; } = null!; + public int SliceLocation { get; set; } - public Guid TrialId { get; set; } + [StringLength(400)] + public string SliceThickness { get; set; } = null!; - public Guid SubjectId { get; set; } - public Guid SubjectVisitId { get; set; } - public bool Anonymize { get; set; } - public string Path { get; set; } = String.Empty; + public string SopInstanceUid { get; set; } = null!; - public string HtmlPath { get; set; } = string.Empty; + public Guid StudyId { get; set; } - public long? FileSize { get; set; } + public string StudyInstanceUid { get; set; } = null!; - } + public Guid SubjectId { get; set; } + + public Guid SubjectVisitId { get; set; } + + public Guid TrialId { get; set; } + + [StringLength(400)] + public string WindowCenter { get; set; } = null!; + + [StringLength(400)] + public string WindowWidth { get; set; } = null!; } + + diff --git a/IRaCIS.Core.Domain/Image/DicomSeries.cs b/IRaCIS.Core.Domain/Image/DicomSeries.cs index a6f3b5ae0..7ac515c26 100644 --- a/IRaCIS.Core.Domain/Image/DicomSeries.cs +++ b/IRaCIS.Core.Domain/Image/DicomSeries.cs @@ -1,62 +1,79 @@ -using System; +using Microsoft.EntityFrameworkCore; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +namespace IRaCIS.Core.Domain.Models; + +[Comment("归档 - 序列表")] +public partial class DicomSeries : BaseFullDeleteAuditEntity, IEntitySeqId { - [Table("DicomSeries")] - public class DicomSeries : BaseFullDeleteAuditEntity, IEntitySeqId - { - #region 导航属性 - [JsonIgnore] - [ForeignKey("StudyId")] - public DicomStudy DicomStudy { get; set; } + #region 导航属性 + [JsonIgnore] + [ForeignKey("StudyId")] + public DicomStudy DicomStudy { get; set; } - [JsonIgnore] - public List DicomInstanceList { get; set; } + [JsonIgnore] + public List DicomInstanceList { get; set; } - [JsonIgnore] - public List SubjectCriteriaEvaluationVisitStudyFilterList { get; set; } - #endregion + [JsonIgnore] + public List SubjectCriteriaEvaluationVisitStudyFilterList { get; set; } + #endregion + public string AcquisitionNumber { get; set; } = null!; + public string AcquisitionTime { get; set; } = null!; - public Guid SeqId { get; set; } - public Guid StudyId { get; set; } - public string StudyInstanceUid { get; set; }=string.Empty; - public string SeriesInstanceUid { get; set; } = string.Empty; - public int SeriesNumber { get; set; } - public DateTime? SeriesTime { get; set; } - public string Modality { get; set; } = string.Empty; - public string Description { get; set; } = string.Empty; - public int InstanceCount { get; set; } - public string SliceThickness { get; set; } = string.Empty; + public string BodyPartExamined { get; set; } = null!; - public string ImagePositionPatient { get; set; } = string.Empty; - public string ImageOrientationPatient { get; set; } = string.Empty; - public string BodyPartExamined { get; set; } = string.Empty; - public string SequenceName { get; set; } = string.Empty; - public string ProtocolName { get; set; } = string.Empty; - public string ImagerPixelSpacing { get; set; } = string.Empty; + public string BodyPartForEdit { get; set; } = null!; - public string AcquisitionTime { get; set; } = string.Empty; - public string AcquisitionNumber { get; set; } = string.Empty; - public string TriggerTime { get; set; } = string.Empty; + [StringLength(500)] + public string Description { get; set; } = null!; - public Guid TrialId { get; set; } + public string ImageOrientationPatient { get; set; } = null!; - public Guid SubjectId { get; set; } - public Guid SubjectVisitId { get; set; } + public string ImagePositionPatient { get; set; } = null!; + [StringLength(1600)] + public string ImageResizePath { get; set; } = null!; - public string BodyPartForEdit { get; set; } = string.Empty; + public string ImagerPixelSpacing { get; set; } = null!; - public bool IsReading { get; set; } = true; + public int InstanceCount { get; set; } - public string ImageResizePath { get; set; }=string.Empty; + public bool IsReading { get; set; } = true; - public Guid? VisitTaskId { get; set; } + public string Modality { get; set; } = null!; - } + [StringLength(500)] + public string ProtocolName { get; set; } = null!; + + public Guid SeqId { get; set; } + + public string SequenceName { get; set; } = null!; + + public string SeriesInstanceUid { get; set; } = null!; + + public int SeriesNumber { get; set; } + + public DateTime? SeriesTime { get; set; } + + public string SliceThickness { get; set; } = null!; + + public Guid StudyId { get; set; } + + public string StudyInstanceUid { get; set; } = null!; + + public Guid SubjectId { get; set; } + + public Guid SubjectVisitId { get; set; } + + public Guid TrialId { get; set; } + + public string TriggerTime { get; set; } = null!; + + public Guid? VisitTaskId { get; set; } } + diff --git a/IRaCIS.Core.Domain/Image/DicomStudy.cs b/IRaCIS.Core.Domain/Image/DicomStudy.cs index be3b91965..02d3bfabe 100644 --- a/IRaCIS.Core.Domain/Image/DicomStudy.cs +++ b/IRaCIS.Core.Domain/Image/DicomStudy.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.EntityFrameworkCore; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -36,58 +37,75 @@ namespace IRaCIS.Core.Domain.Models #endregion + public string AccessionNumber { get; set; } = null!; + + public string AcquisitionNumber { get; set; } = null!; + + public string AcquisitionTime { get; set; } = null!; + + [StringLength(512)] + public string BodyPartExamined { get; set; } = null!; + + public string BodyPartForEdit { get; set; } = null!; + + public int Code { get; set; } + + [StringLength(1000)] + public string Description { get; set; } = null!; + + public int InstanceCount { get; set; } + + [StringLength(400)] + public string InstitutionName { get; set; } = null!; + + public bool IsDoubleReview { get; set; } + + public bool IsFromPACS { get; set; } + + public string Modalities { get; set; } = null!; + + public string ModalityForEdit { get; set; } = null!; + + public string PatientAge { get; set; } = null!; + + public string PatientBirthDate { get; set; } = null!; + + public string PatientId { get; set; } = null!; + + public string PatientName { get; set; } = null!; + + public string PatientSex { get; set; } = null!; + + [Comment(" 序列Id 避免内存移动")] public Guid SeqId { get; set; } - public Guid TrialId { get; set; } + public int SeriesCount { get; set; } + [StringLength(400)] + public string StudyCode { get; set; } = null!; + [Comment(" DicomTag.StudyID")] + public string StudyId { get; set; } = null!; + + [StringLength(500)] + public string StudyInstanceUid { get; set; } = null!; + + public DateTime? StudyTime { get; set; } public Guid SubjectId { get; set; } public Guid SubjectVisitId { get; set; } - public int Code { get; set; } = 0; + public Guid TrialId { get; set; } - public string StudyCode { get; set; } = string.Empty; + public string TriggerTime { get; set; } = null!; - public string StudyInstanceUid { get; set; } = string.Empty; - public DateTime? StudyTime { get; set; } - public string Modalities { get; set; } = string.Empty; + [Comment(" 上传时间")] + public DateTime? UploadedTime { get; set; } - public string Description { get; set; } = string.Empty; - public int SeriesCount { get; set; } = 0; - public int InstanceCount { get; set; } = 0; + public string Uploader { get; set; } = null!; - public string InstitutionName { get; set; } = string.Empty; - public string PatientId { get; set; } = string.Empty; - public string PatientName { get; set; } = string.Empty; - public string PatientAge { get; set; } = string.Empty; - public string PatientSex { get; set; } = string.Empty; - - public string StudyId { get; set; } = string.Empty; - public string AccessionNumber { get; set; } = string.Empty; - public string PatientBirthDate { get; set; } = string.Empty; - public string AcquisitionTime { get; set; } = string.Empty; - public string AcquisitionNumber { get; set; } = string.Empty; - public string TriggerTime { get; set; } = string.Empty; - - public string BodyPartExamined { get; set; } = string.Empty; - - public string BodyPartForEdit { get; set; } = string.Empty; - - public string ModalityForEdit { get; set; } = string.Empty; - - - - //0 未知 1 单重 2 双重 - public bool IsDoubleReview { get; set; } - - - - public bool IsFromPACS { get; set; } - - } diff --git a/IRaCIS.Core.Domain/Institution/CRO.cs b/IRaCIS.Core.Domain/Institution/CRO.cs index a592a7680..8d988648f 100644 --- a/IRaCIS.Core.Domain/Institution/CRO.cs +++ b/IRaCIS.Core.Domain/Institution/CRO.cs @@ -1,22 +1,30 @@ +using Microsoft.EntityFrameworkCore; using System; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +namespace IRaCIS.Core.Domain.Models; + +[Comment(" - CRO")] +[Table("CROCompany")] +public class CRO : BaseFullAuditEntity { - [Table("CROCompany")] - public partial class CRO : BaseFullAuditEntity - { - #region + #region - #endregion - public string CROName { get; set; } = string.Empty; - public string CRONameCN { get; set; } = string.Empty; - public string CROCode { get; set; } = string.Empty; + #endregion + public string CROCode { get; set; } = null!; - public bool IsTrialLevel { get; set; } + [StringLength(1000)] + public string CROName { get; set; } = null!; + [StringLength(1000)] + public string CRONameCN { get; set; } = null!; - public Guid? TrialId { get; set; } - } + [Comment(" ǷĿ")] + public bool IsTrialLevel { get; set; } + + public Guid? TrialId { get; set; } } + + diff --git a/IRaCIS.Core.Domain/QC/CheckChallengeDialog.cs b/IRaCIS.Core.Domain/QC/CheckChallengeDialog.cs index f956548f0..7e60e00dc 100644 --- a/IRaCIS.Core.Domain/QC/CheckChallengeDialog.cs +++ b/IRaCIS.Core.Domain/QC/CheckChallengeDialog.cs @@ -1,29 +1,36 @@ using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Share; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using System.Text; -namespace IRaCIS.Core.Domain.Models +namespace IRaCIS.Core.Domain.Models; + +[Comment("一致性核查 - 对话记录表")] +[Table("CheckChallengeDialog")] +public class CheckChallengeDialog : BaseAddAuditEntity { - - public class CheckChallengeDialog : BaseAddAuditEntity - { - #region 导航属性 - [JsonIgnore] - public SubjectVisit SubjectVisit { get; set; } - #endregion + #region 导航属性 + [JsonIgnore] + public SubjectVisit SubjectVisit { get; set; } + #endregion - public string TalkContent { get; set; } = string.Empty; - - public Guid SubjectVisitId { get; set; } + [Comment(" CRC是否需要回复 前端使用")] + public bool? IsCRCNeedReply { get; set; } + [Comment(" 核查的检查信息Json")] + [MaxLength] + public string ParamInfo { get; set; } = null!; - public UserTypeEnum UserTypeEnum { get; set; } + public Guid SubjectVisitId { get; set; } - - public bool? IsCRCNeedReply { get; set; } + [MaxLength] + public string TalkContent { get; set; } = null!; + + [Comment(" 核查过程中的操作用户类型")] + public UserTypeEnum UserTypeEnum { get; set; } - public string ParamInfo { get; set; } = string.Empty; - } } diff --git a/IRaCIS.Core.Domain/Reading/ClinicalData/ClinicalDataSystemSet.cs b/IRaCIS.Core.Domain/Reading/ClinicalData/ClinicalDataSystemSet.cs index 7e04dfa4f..09e241534 100644 --- a/IRaCIS.Core.Domain/Reading/ClinicalData/ClinicalDataSystemSet.cs +++ b/IRaCIS.Core.Domain/Reading/ClinicalData/ClinicalDataSystemSet.cs @@ -1,91 +1,54 @@ using IRaCIS.Core.Domain.Share; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; -namespace IRaCIS.Core.Domain.Models +namespace IRaCIS.Core.Domain.Models; + +[Comment("系统 - 临床数据配置")] +[Table("ClinicalDataSystemSet")] +public class ClinicalDataSystemSet : BaseAddAuditEntity { - /// - /// 临床资料系统配置 - /// - [Table("ClinicalDataSystemSet")] - public class ClinicalDataSystemSet : BaseAddAuditEntity - { - #region 导航属性 + #region 导航属性 - #endregion + [NotMapped] + public List CriterionEnumList => CriterionEnumListStr.Split('|', StringSplitOptions.RemoveEmptyEntries).Where(t => !string.IsNullOrEmpty(t) && int.TryParse(t.Trim(), out var s)).Select(t => int.Parse(t.Trim())).ToList(); - /// - /// 枚举(字典里面取的) - /// - public int ClinicalDataSetEnum { get; set; } + #endregion - /// - /// 名称 - /// - public string ClinicalDataSetName { get; set; } = string.Empty; + public ClinicalLevel ClinicalDataLevel { get; set; } - /// - /// 是否应用 - /// - public bool IsApply { get; set; } = false; + [StringLength(400)] + public string ClinicalDataSetEnName { get; set; } = null!; - /// - /// 英文名称 - /// - public string ClinicalDataSetEnName { get; set; } = string.Empty; + + [Comment(" 枚举(字典里面取的)")] + public int ClinicalDataSetEnum { get; set; } - /// - /// 临床级别 - /// - public ClinicalLevel ClinicalDataLevel { get; set; } + public string ClinicalDataSetName { get; set; } = null!; - /// - /// 上传方式 - /// - public ClinicalUploadType ClinicalUploadType { get; set; } - - - - /// - /// 是否启用 - /// - public bool IsEnable { get; set; } - - /// - /// 上传角色 - /// - public UploadRole UploadRole { get; set; } - - /// - /// 模板文件名称 - /// - public string FileName { get; set; } = string.Empty; - - /// - /// 文件路径 - /// - public string Path { get; set; } = string.Empty; - - public string CriterionEnumListStr { get; set; } = String.Empty; - - - - - [NotMapped] - public List CriterionEnumList => CriterionEnumListStr.Split('|', StringSplitOptions.RemoveEmptyEntries).Where(t => !string.IsNullOrEmpty(t) && int.TryParse(t.Trim(), out var s)).Select(t => int.Parse(t.Trim())).ToList(); - - //public List SystemClinicalDataCriterionList { get; set; } = new List(); - - } + [Comment("上传方式")] + public ClinicalUploadType ClinicalUploadType { get; set; } + [StringLength(512)] + public string CriterionEnumListStr { get; set; } = null!; + [StringLength(400)] + public string FileName { get; set; } = null!; + [Comment("是否应用")] + public bool IsApply { get; set; } + public bool IsEnable { get; set; } + [StringLength(4000)] + public string Path { get; set; } = null!; + public UploadRole UploadRole { get; set; } } diff --git a/IRaCIS.Core.Domain/Reading/ClinicalData/ClinicalDataTrialSet.cs b/IRaCIS.Core.Domain/Reading/ClinicalData/ClinicalDataTrialSet.cs index 478db8018..e67d254b0 100644 --- a/IRaCIS.Core.Domain/Reading/ClinicalData/ClinicalDataTrialSet.cs +++ b/IRaCIS.Core.Domain/Reading/ClinicalData/ClinicalDataTrialSet.cs @@ -6,105 +6,65 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Collections.Generic; using System.Linq; +using Microsoft.EntityFrameworkCore; -namespace IRaCIS.Core.Domain.Models +namespace IRaCIS.Core.Domain.Models; + +[Comment("项目 - 临床数据适应标准配置")] +[Table("ClinicalDataTrialSet")] +public class ClinicalDataTrialSet : BaseAddAuditEntity { - /// - /// 临床资料项目配置 - /// - [Table("ClinicalDataTrialSet")] - public class ClinicalDataTrialSet : BaseAddAuditEntity - { - #region 导航属性 + #region 导航属性 - [JsonIgnore] - public List ReadingClinicalDataList { get; set; } + [JsonIgnore] + public List ReadingClinicalDataList { get; set; } - [JsonIgnore] - [ForeignKey("TrialId")] - public Trial Trial { get; set; } + [JsonIgnore] + [ForeignKey("TrialId")] + public Trial Trial { get; set; } - [JsonIgnore] - public List TrialClinicalDataSetCriteriaList { get; set; } + [JsonIgnore] + public List TrialClinicalDataSetCriteriaList { get; set; } - [JsonIgnore] - public List TrialClinicalQuestionList { get; set; } - [JsonIgnore] - [ForeignKey("SystemClinicalDataSetId")] - public ClinicalDataSystemSet? ClinicalDataSystemSet { get; set; } - #endregion + [JsonIgnore] + public List TrialClinicalQuestionList { get; set; } + [JsonIgnore] + [ForeignKey("SystemClinicalDataSetId")] + public ClinicalDataSystemSet? ClinicalDataSystemSet { get; set; } + #endregion - public Guid TrialId { get; set; } + [Comment("临床级别")] + public ClinicalLevel ClinicalDataLevel { get; set; } - /// - /// 名称 - /// - public string ClinicalDataSetName { get; set; }=string.Empty; + [StringLength(400)] + public string ClinicalDataSetEnName { get; set; } = null!; - /// - /// 英文名称 - /// - public string ClinicalDataSetEnName { get; set; } = string.Empty; + public string ClinicalDataSetName { get; set; } = null!; - /// - /// 临床级别 - /// - public ClinicalLevel ClinicalDataLevel { get; set; } + [Comment("上传方式")] + public ClinicalUploadType ClinicalUploadType { get; set; } + [StringLength(512)] + public string CriterionEnumListStr { get; set; } = null!; - /// - /// 上传方式 - /// - public ClinicalUploadType ClinicalUploadType { get; set; } + [StringLength(400)] + public string FileName { get; set; } = null!; + [Comment("是否应用")] + public bool IsApply { get; set; } - /// - /// 系统的ClinicalDataSetId - /// - public Guid? SystemClinicalDataSetId { get; set; } - - /// - /// SystemClinicalDataSetId - /// - - - /// - /// 是否确认 - /// - public bool IsConfirm { get; set; } - - - /// - /// 是否应用 - /// - public bool IsApply { get; set; } = false; - - /// - /// 上传角色 - /// - public UploadRole UploadRole { get; set; } - - /// - /// 模板文件名称 - /// - public string FileName { get; set; } = string.Empty; - - /// - /// 文件路径 - /// - public string Path { get; set; } = string.Empty; - - - - public string CriterionEnumListStr { get; set; } = String.Empty; - - public List CriterionEnumList => CriterionEnumListStr.Split('|', StringSplitOptions.RemoveEmptyEntries).Where(t => !string.IsNullOrEmpty(t) && int.TryParse(t.Trim(), out var s)).Select(t => int.Parse(t.Trim())).ToList(); - - } + public bool IsConfirm { get; set; } + [StringLength(4000)] + public string Path { get; set; } = null!; + public Guid? SystemClinicalDataSetId { get; set; } + public Guid TrialId { get; set; } + public UploadRole UploadRole { get; set; } + public List CriterionEnumList => CriterionEnumListStr.Split('|', StringSplitOptions.RemoveEmptyEntries).Where(t => !string.IsNullOrEmpty(t) && int.TryParse(t.Trim(), out var s)).Select(t => int.Parse(t.Trim())).ToList(); } + diff --git a/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalAnswerRowInfo.cs b/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalAnswerRowInfo.cs index c08e94424..e036c418b 100644 --- a/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalAnswerRowInfo.cs +++ b/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalAnswerRowInfo.cs @@ -7,37 +7,31 @@ using System; using IRaCIS.Core.Domain.Share; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +using Microsoft.EntityFrameworkCore; +namespace IRaCIS.Core.Domain.Models; + + + +[Comment("受试者 - 临床表单表格问题行记录")] +[Table("ClinicalAnswerRowInfo")] +public class ClinicalAnswerRowInfo : BaseAddAuditEntity { - /// - ///ClinicalAnswerRowInfo - /// - [Table("ClinicalAnswerRowInfo")] - public class ClinicalAnswerRowInfo : BaseAddAuditEntity - { - #region 导航属性 + #region 导航属性 + + #endregion + + + [Comment(" 表单Id")] + public Guid ClinicalFormId { get; set; } + + [Comment(" 问题Id")] + public Guid QuestionId { get; set; } + + public int RowIndex { get; set; } + + [Comment(" 受试者Id")] + public Guid SubjectId { get; set; } +} - #endregion - public Guid SubjectId { get; set; } - - /// - /// 表单Id - /// - public Guid ClinicalFormId { get; set; } - - - /// - /// 问题Id - /// - public Guid QuestionId { get; set; } - - /// - /// RowIndex - /// - public int RowIndex { get; set; } - } - - -} diff --git a/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalForm.cs b/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalForm.cs index dfa39ad93..2143151fb 100644 --- a/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalForm.cs +++ b/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalForm.cs @@ -7,50 +7,42 @@ using System; using IRaCIS.Core.Domain.Share; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +using Microsoft.EntityFrameworkCore; +namespace IRaCIS.Core.Domain.Models; + + +[Comment("受试者 - 临床表单")] +[Table("ClinicalForm")] +public class ClinicalForm : BaseAddAuditEntity { - /// - ///ClinicalForm - /// - [Table("ClinicalForm")] - public class ClinicalForm : BaseAddAuditEntity - { - #region 导航属性 - [JsonIgnore] - [ForeignKey("ClinicalDataTrialSetId")] - public ClinicalDataTrialSet ClinicalDataTrialSet { get; set; } + #region 导航属性 + [JsonIgnore] + [ForeignKey("ClinicalDataTrialSetId")] + public ClinicalDataTrialSet ClinicalDataTrialSet { get; set; } - [JsonIgnore] - [ForeignKey("SubjectId")] - public Subject Subject { get; set; } - #endregion + [JsonIgnore] + [ForeignKey("SubjectId")] + public Subject Subject { get; set; } + #endregion - public Guid SubjectId { get; set; } + [Comment(" 检查日期")] + public DateTime? CheckDate { get; set; } + + public Guid ClinicalDataTrialSetId { get; set; } + + [Comment(" 截图地址")] + [StringLength(4000)] + public string PicturePath { get; set; } = null!; + + public Guid? ReadingId { get; set; } + + [Comment(" 受试者Id")] + public Guid SubjectId { get; set; } + + public Guid TrialId { get; set; } + + public Guid? VisitId { get; set; } +} - public Guid TrialId { get; set; } - - /// - /// 检查日期 - /// - public DateTime? CheckDate { get; set; } - - /// - /// 截图地址 - /// - public string PicturePath { get; set; } = string.Empty; - - - public Guid ClinicalDataTrialSetId { get; set; } - - /// - /// VisitId - /// - public Guid? ReadingId { get; set; } - - - - - } - -} + diff --git a/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalQuestionAnswer.cs b/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalQuestionAnswer.cs index 45cd279f7..74feb333b 100644 --- a/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalQuestionAnswer.cs +++ b/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalQuestionAnswer.cs @@ -7,42 +7,36 @@ using System; using IRaCIS.Core.Domain.Share; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +using Microsoft.EntityFrameworkCore; +namespace IRaCIS.Core.Domain.Models; + +[Comment("受试者 - 临床表单问题答案")] +[Table("ClinicalQuestionAnswer")] +public class ClinicalQuestionAnswer : BaseAddAuditEntity { - /// - ///ClinicalQuestionAnswer - /// - [Table("ClinicalQuestionAnswer")] - public class ClinicalQuestionAnswer : BaseAddAuditEntity - { - #region 导航属性 + #region 导航属性 - [JsonIgnore] - [ForeignKey("ClinicalFormId")] - public ClinicalForm ClinicalForm { get; set; } - #endregion + [JsonIgnore] + [ForeignKey("ClinicalFormId")] + public ClinicalForm ClinicalForm { get; set; } + #endregion - public Guid SubjectId { get; set; } - - /// - /// 表单Id - /// - public Guid ClinicalFormId { get; set; } - + [StringLength(4000)] + public string Answer { get; set; } = null!; - - /// - /// 问题Id - /// - public Guid QuestionId { get; set; } + public Guid ClinicalDataTrialSetId { get; set; } - public string Answer { get; set; } = string.Empty; + [Comment(" 表单Id")] + public Guid ClinicalFormId { get; set; } - public Guid ClinicalDataTrialSetId { get; set; } + [Comment(" 问题Id")] + public Guid QuestionId { get; set; } + + [Comment(" 受试者Id")] + public Guid SubjectId { get; set; } +} - } - - -} + + diff --git a/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalTableAnswer.cs b/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalTableAnswer.cs index e3fed2f34..11aa95f8b 100644 --- a/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalTableAnswer.cs +++ b/IRaCIS.Core.Domain/Reading/ClinicalQuestionAnswer/ClinicalTableAnswer.cs @@ -7,37 +7,38 @@ using System; using IRaCIS.Core.Domain.Share; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +using Microsoft.EntityFrameworkCore; +namespace IRaCIS.Core.Domain.Models; + +[Comment("受试者 - 临床表单表格问题答案")] +[Table("ClinicalTableAnswer")] +public partial class ClinicalTableAnswer : BaseAddAuditEntity { - /// - ///ClinicalTableAnswer - /// - [Table("ClinicalTableAnswer")] - public class ClinicalTableAnswer : BaseAddAuditEntity - { - #region 导航属性 - [JsonIgnore] - [ForeignKey("RowId")] - public ClinicalAnswerRowInfo ClinicalAnswerRowInfo{get; set;} - #endregion + #region 导航属性 + [JsonIgnore] + [ForeignKey("RowId")] + public ClinicalAnswerRowInfo ClinicalAnswerRowInfo { get; set; } + #endregion - public Guid SubjectId { get; set; } - + [Comment(" 答案")] + [StringLength(4000)] + public string Answer { get; set; } = null!; - public Guid ClinicalFormId { get; set; } + [Comment(" 表单Id")] + public Guid ClinicalFormId { get; set; } - public Guid QuestionId { get; set; } + [Comment(" 问题Id")] + public Guid QuestionId { get; set; } - public Guid RowId { get; set; } + [Comment(" 答案行的Id")] + public Guid RowId { get; set; } - public string Answer { get; set; }=string.Empty; + [Comment(" 受试者Id")] + public Guid SubjectId { get; set; } - public Guid TableQuestionId { get; set; } + public Guid TableQuestionId { get; set; } +} - - - } - - -} + + diff --git a/IRaCIS.Core.Domain/Reading/ReadingCriterion/CriterionNidusSystem.cs b/IRaCIS.Core.Domain/Reading/ReadingCriterion/CriterionNidusSystem.cs index 6ad40a4a8..f27caeccc 100644 --- a/IRaCIS.Core.Domain/Reading/ReadingCriterion/CriterionNidusSystem.cs +++ b/IRaCIS.Core.Domain/Reading/ReadingCriterion/CriterionNidusSystem.cs @@ -7,46 +7,31 @@ using System; using IRaCIS.Core.Domain.Share; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +using Microsoft.EntityFrameworkCore; +namespace IRaCIS.Core.Domain.Models; + + + +[Comment("系统标准 - 病灶器官表 (需要同步)")] +[Table("CriterionNidusSystem")] +public class CriterionNidusSystem : BaseAddAuditEntity { - /// - /// 标准病灶中间表 - /// - [Table("CriterionNidusSystem")] - public class CriterionNidusSystem : BaseAddAuditEntity - { - #region 导航属性 - [ForeignKey("CriterionId")] - [JsonIgnore] - public ReadingQuestionCriterionTrial TrialReadingCriterion { get; set; } - #endregion - /// - /// 标准ID - /// - public Guid CriterionId { get; set; } + #region 导航属性 + [ForeignKey("CriterionId")] + [JsonIgnore] + public ReadingQuestionCriterionTrial TrialReadingCriterion { get; set; } + #endregion + + public Guid CriterionId { get; set; } + + public bool IsSystemCriterion { get; set; } + + [Comment("病灶类型")] + public LesionType LesionType { get; set; } + + [Comment("器官类型")] + public OrganType OrganType { get; set; } +} - /// - /// 器官类型 - /// - public OrganType OrganType { get; set; } - - - /// - /// 病灶类型 - /// - public LesionType LesionType { get; set; } - - /// - /// 是否是系统标准 - /// - public bool IsSystemCriterion { get; set; } - - - - - - } - - -} + diff --git a/IRaCIS.Core.Domain/Reading/ReadingCriterion/CriterionNidusTrial.cs b/IRaCIS.Core.Domain/Reading/ReadingCriterion/CriterionNidusTrial.cs index 821203b13..78146a97f 100644 --- a/IRaCIS.Core.Domain/Reading/ReadingCriterion/CriterionNidusTrial.cs +++ b/IRaCIS.Core.Domain/Reading/ReadingCriterion/CriterionNidusTrial.cs @@ -7,28 +7,24 @@ using System; using IRaCIS.Core.Domain.Share; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +using Microsoft.EntityFrameworkCore; +namespace IRaCIS.Core.Domain.Models; + +[Comment("项目标准 - 病灶器官表")] +[Table("CriterionNidusTrial")] +public class CriterionNidusTrial : BaseAddAuditEntity { - /// - ///CriterionNidusTrial - /// - [Table("CriterionNidusTrial")] - public class CriterionNidusTrial : BaseAddAuditEntity - { - #region 导航属性 + #region 导航属性 - #endregion + #endregion - public Guid CriterionId { get; set; } + public Guid CriterionId { get; set; } - public LesionType LesionType { get; set; } + public LesionType LesionType { get; set; } - /// - /// 器官类型 - /// - public OrganType OrganType { get; set; } + public OrganType OrganType { get; set; } +} - } - -} + + diff --git a/IRaCIS.Core.Domain/Trial/DataInspection.cs b/IRaCIS.Core.Domain/Trial/DataInspection.cs index e37cb1b85..7d6dc9255 100644 --- a/IRaCIS.Core.Domain/Trial/DataInspection.cs +++ b/IRaCIS.Core.Domain/Trial/DataInspection.cs @@ -6,119 +6,95 @@ using System; using IRaCIS.Core.Domain.Share; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +using Microsoft.EntityFrameworkCore; +namespace IRaCIS.Core.Domain.Models; + +[Comment("稽查 - 记录表")] +[Table("DataInspection")] +public class DataInspection : BaseAddAuditEntity { - /// - ///DataInspection - /// - [Table("DataInspection")] - public class DataInspection : BaseAddAuditEntity - { + #region 导航属性 + [JsonIgnore] + [ForeignKey("TrialReadingCriterionId")] + public ReadingQuestionCriterionTrial TrialReadingCriterion { get; set; } + [JsonIgnore] + public VisitTask VisitTask { get; set; } + #endregion - #region 导航属性 - [JsonIgnore] - [ForeignKey("TrialReadingCriterionId")] - public ReadingQuestionCriterionTrial TrialReadingCriterion { get; set; } - #endregion + [Comment(" 批次Id")] + public Guid BatchId { get; set; } + [Comment(" 子类")] + public Guid? ChildrenTypeId { get; set; } - public Guid? TrialId { get; set; } + [Comment(" 创建人姓名")] + public string CreateUserName { get; set; } = null!; - public Guid? TrialSiteId { get; set; } + public string CreateUserRealName { get; set; } = null!; - public Guid? SubjectId { get; set; } + [Comment(" 阅片医生")] + public Guid? DoctorUserId { get; set; } + [Comment(" 被稽查实体名")] + public string EntityName { get; set; } = null!; - public Guid? SubjectVisitId { get; set; } + [Comment(" 要稽查对象Id")] + public Guid? GeneralId { get; set; } - public Guid? VisitTaskId { get; set; } + [Comment(" 标识")] + public string Identification { get; set; } = null!; - public VisitTask VisitTask { get; set; } + public string IP { get; set; } = null!; - public string IP { get; set; } = string.Empty; + [Comment(" 是否是前端添加")] + public bool? IsFrontAdd { get; set; } - public string Reason { get; set; } = string.Empty; + public bool? IsSign { get; set; } - public bool IsSign { get; set; } + [MaxLength] + public string? JsonDetail { get; set; } - /// - /// 签名ID - /// - public Guid? SignId { get; set; } + [Comment(" 上一条json")] + [MaxLength] + public string? LastJsonDetail { get; set; } - /// - /// 父类ID - /// + public Guid? ModuleTypeId { get; set; } - public Guid? ParentId { get; set; } + [Comment(" 被稽查对象外键1")] + public Guid? ObjectRelationParentId { get; set; } - /// - /// 子类 - /// - public Guid? ChildrenTypeId { get; set; } - /// - /// 对象类型 - /// - public Guid? ObjectTypeId { get; set; } + public Guid? ObjectRelationParentId2 { get; set; } - /// - /// 操作类型 - /// - public Guid? OptTypeId { get; set; } + public Guid? ObjectRelationParentId3 { get; set; } - /// - /// 功能模块 - /// - public Guid? ModuleTypeId { get; set; } + public Guid? ObjectTypeId { get; set; } - public string JsonDetail { get; set; } = string.Empty; + public Guid? OptTypeId { get; set; } - public string CreateUserName { get; set; } = string.Empty; + [Comment(" 父ID")] + public Guid? ParentId { get; set; } - public string CreateUserRealName { get; set; } = string.Empty; + public string Reason { get; set; } = null!; - public string RoleName { get; set; } = string.Empty; + [Comment(" 角色名称")] + public string RoleName { get; set; } = null!; - /// - /// 标识 - /// - public string Identification { get; set; } = string.Empty; + public Guid? SignId { get; set; } + public Guid? SubjectId { get; set; } - /// - /// 稽查的对象Id - /// - public Guid? GeneralId { get; set; } + public Guid? SubjectVisitId { get; set; } + public Guid? TrialId { get; set; } + public Guid? TrialReadingCriterionId { get; set; } - /// - /// 批次Id - /// - public Guid BatchId { get; set; } - - - /// - /// 稽查对象,关联的父对象Id - /// - public Guid? ObjectRelationParentId { get; set; } - - public Guid? ObjectRelationParentId2 { get; set; } - - public Guid? ObjectRelationParentId3 { get; set; } - - - public string EntityName { get; set; } = string.Empty; - - - public Guid? TrialReadingCriterionId { get; set; } - - public Guid? DoctorUserId { get; set; } - - - } - + public Guid? TrialSiteId { get; set; } + [Comment(" 访视计划ID")] + public Guid? VisitStageId { get; set; } + public Guid? VisitTaskId { get; set; } } + diff --git a/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 b/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 index db80a2a87..dadd73b8f 100644 --- a/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 +++ b/IRaCIS.Core.Test/CodeTemplates/EFCore/EntityType.t4 @@ -98,9 +98,11 @@ public partial class <#= EntityType.Name #>: BaseFullAuditEntity [StringLength(<#= maxLength.Value #>)] <# } + else if(maxLength.HasValue && maxLength == 200){} else { #> + [MaxLength] <# } From b5d117f6fa043626ba03c643bb1ba6b1990f84fe Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 19 Sep 2024 17:01:03 +0800 Subject: [PATCH 59/59] =?UTF-8?q?=E7=A8=BD=E6=9F=A5=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E7=BB=99=E9=BB=98=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dcotor/DoctorCriterionFile.cs | 87 +++++++------------ IRaCIS.Core.Domain/Trial/DataInspection.cs | 14 +-- .../Interceptor/AuditEntityInterceptor.cs | 3 +- 3 files changed, 42 insertions(+), 62 deletions(-) diff --git a/IRaCIS.Core.Domain/Dcotor/DoctorCriterionFile.cs b/IRaCIS.Core.Domain/Dcotor/DoctorCriterionFile.cs index 5a5edecf4..2b9f421ab 100644 --- a/IRaCIS.Core.Domain/Dcotor/DoctorCriterionFile.cs +++ b/IRaCIS.Core.Domain/Dcotor/DoctorCriterionFile.cs @@ -7,64 +7,43 @@ using System; using IRaCIS.Core.Domain.Share; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IRaCIS.Core.Domain.Models +using Microsoft.EntityFrameworkCore; +namespace IRaCIS.Core.Domain.Models; + +[Comment("医生 - 项目标准签名文档")] +[Table("DoctorCriterionFile")] +public class DoctorCriterionFile : BaseAddAuditEntity { - /// - ///DoctorCriterionFile - /// - [Table("DoctorCriterionFile")] - public class DoctorCriterionFile :BaseAddAuditEntity - { - #region 导航属性 - [JsonIgnore] - [ForeignKey("DoctorId")] - public Doctor Doctor { get; set; } - #endregion - /// - /// 文件名称 - /// - public string FileName { get; set; } = string.Empty; + #region 导航属性 + [JsonIgnore] + [ForeignKey("DoctorId")] + public Doctor Doctor { get; set; } + #endregion - /// - /// 文件路径 - /// - public string FilePath { get; set; } = string.Empty; + public string CriterionName { get; set; } = null!; - /// - /// 标准类型 - /// - public CriterionType CriterionType { get; set; } - - /// - /// 医生Id - /// - public Guid DoctorId { get; set; } - - /// - /// 备注 - /// - public string Remark { get; set; } = string.Empty; + [Comment("标准类型")] + public CriterionType CriterionType { get; set; } - /// - /// 文件类型 - /// - public CriterionFileType FileType { get; set; } - + public Guid DoctorId { get; set; } + + [StringLength(400)] + public string FileName { get; set; } = null!; + + [StringLength(4000)] + public string FilePath { get; set; } = null!; + + public CriterionFileType FileType { get; set; } + + public bool IsEnable { get; set; } + + public string Remark { get; set; } = null!; + + public Guid? TrialId { get; set; } + + public Guid? TrialReadingCriterionId { get; set; } + +} - /// - /// 是否启用 - /// - public bool IsEnable { get; set; } = true; - - - public string CriterionName { get; set; } = string.Empty; - public Guid? TrialReadingCriterionId { get; set; } - public Guid? TrialId { get; set; } - - - } - - -} diff --git a/IRaCIS.Core.Domain/Trial/DataInspection.cs b/IRaCIS.Core.Domain/Trial/DataInspection.cs index 7d6dc9255..d0422ccb9 100644 --- a/IRaCIS.Core.Domain/Trial/DataInspection.cs +++ b/IRaCIS.Core.Domain/Trial/DataInspection.cs @@ -29,23 +29,23 @@ public class DataInspection : BaseAddAuditEntity public Guid? ChildrenTypeId { get; set; } [Comment(" 创建人姓名")] - public string CreateUserName { get; set; } = null!; + public string CreateUserName { get; set; } = string.Empty; - public string CreateUserRealName { get; set; } = null!; + public string CreateUserRealName { get; set; } = string.Empty; [Comment(" 阅片医生")] public Guid? DoctorUserId { get; set; } [Comment(" 被稽查实体名")] - public string EntityName { get; set; } = null!; + public string EntityName { get; set; } = string.Empty; [Comment(" 要稽查对象Id")] public Guid? GeneralId { get; set; } [Comment(" 标识")] - public string Identification { get; set; } = null!; + public string Identification { get; set; } = string.Empty; - public string IP { get; set; } = null!; + public string IP { get; set; } = string.Empty; [Comment(" 是否是前端添加")] public bool? IsFrontAdd { get; set; } @@ -75,10 +75,10 @@ public class DataInspection : BaseAddAuditEntity [Comment(" 父ID")] public Guid? ParentId { get; set; } - public string Reason { get; set; } = null!; + public string Reason { get; set; } = string.Empty; [Comment(" 角色名称")] - public string RoleName { get; set; } = null!; + public string RoleName { get; set; } = string.Empty; public Guid? SignId { get; set; } diff --git a/IRaCIS.Core.Infra.EFCore/Interceptor/AuditEntityInterceptor.cs b/IRaCIS.Core.Infra.EFCore/Interceptor/AuditEntityInterceptor.cs index 3ec49f294..2ea86c02c 100644 --- a/IRaCIS.Core.Infra.EFCore/Interceptor/AuditEntityInterceptor.cs +++ b/IRaCIS.Core.Infra.EFCore/Interceptor/AuditEntityInterceptor.cs @@ -50,7 +50,8 @@ public class AuditEntityInterceptor(IUserInfo _userInfo, ILogger (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()) { // 检查属性是否为string类型,并且值为null foreach (var property in entry.Properties.Where(t=>t.Metadata.ClrType==typeof(string) && t.CurrentValue == null))