升级.net10

Test_IRC_Net10
hang 2026-04-29 15:56:41 +08:00
parent af1d4b3cd1
commit 8eaa6606c4
27 changed files with 256 additions and 711 deletions

9
Directory.Build.props Normal file
View File

@ -0,0 +1,9 @@
<Project>
<PropertyGroup>
<!-- 在这里定义所有项目共享的属性 -->
<TargetFramework>net10.0</TargetFramework>
<!-- 如果需要Nullable等全局设置也可以加在这里 -->
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@ -1,37 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.11" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.7" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.5" /> <PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" /> <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="11.0.0" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" /> <PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="AWSSDK.S3" Version="4.0.21" /> <PackageReference Include="AWSSDK.S3" Version="4.0.22.1" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.5.19" /> <PackageReference Include="AWSSDK.SecurityToken" Version="4.0.6.2" />
<PackageReference Include="DistributedLock.Core" Version="1.0.8" /> <PackageReference Include="DistributedLock.Core" Version="1.0.9" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.6" /> <PackageReference Include="DistributedLock.SqlServer" Version="1.0.7" />
<PackageReference Include="fo-dicom" Version="5.2.1" /> <PackageReference Include="fo-dicom" Version="5.2.6" />
<PackageReference Include="fo-dicom.Codecs" Version="5.16.1" /> <PackageReference Include="fo-dicom.Codecs" Version="5.16.7" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.1" /> <PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.7" />
<PackageReference Include="AutoMapper" Version="13.0.1" /> <PackageReference Include="AutoMapper" Version="16.1.1" />
<PackageReference Include="Minio" Version="6.0.4" /> <PackageReference Include="Minio" Version="7.0.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0"> <PackageReference Include="My.Extensions.Localization.Json" Version="4.0.0">
<TreatAsUsed>true</TreatAsUsed> <TreatAsUsed>true</TreatAsUsed>
</PackageReference> </PackageReference>
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" /> <PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.1.2" /> <PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.9.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" /> <PackageReference Include="Serilog.Extensions.Hosting" Version="10.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" /> <PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.7" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -56,7 +56,7 @@ var _configuration = builder.Configuration;
builder.Services.AddHealthChecks(); builder.Services.AddHealthChecks();
//本地化 //本地化
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources"); builder.Services.AddJsonLocalization(options => options.ResourcesPath = new[] { "Resources" });
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim() // 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()

View File

@ -1,8 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
@ -10,17 +8,17 @@
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" /> <PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="11.0.0" /> <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="11.0.0" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" /> <PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="AWSSDK.S3" Version="4.0.21" /> <PackageReference Include="AWSSDK.S3" Version="4.0.22.1" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.5.19" /> <PackageReference Include="AWSSDK.SecurityToken" Version="4.0.6.2" />
<PackageReference Include="DistributedLock.Core" Version="1.0.9" /> <PackageReference Include="DistributedLock.Core" Version="1.0.9" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.7" /> <PackageReference Include="DistributedLock.SqlServer" Version="1.0.7" />
<PackageReference Include="fo-dicom" Version="5.2.6" /> <PackageReference Include="fo-dicom" Version="5.2.6" />
<PackageReference Include="fo-dicom.Codecs" Version="5.16.7" /> <PackageReference Include="fo-dicom.Codecs" Version="5.16.7" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" /> <PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.7" />
<PackageReference Include="AutoMapper" Version="16.1.1" /> <PackageReference Include="AutoMapper" Version="16.1.1" />
<PackageReference Include="Minio" Version="7.0.0" /> <PackageReference Include="Minio" Version="7.0.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0"> <PackageReference Include="My.Extensions.Localization.Json" Version="4.0.0">
<TreatAsUsed>true</TreatAsUsed> <TreatAsUsed>true</TreatAsUsed>
</PackageReference> </PackageReference>
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" /> <PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />

View File

@ -13,7 +13,6 @@ using IRaCIS.Core.SCP.Service;
using MassTransit; using MassTransit;
using MassTransit.NewIdProviders; using MassTransit.NewIdProviders;
using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.DependencyInjection;
using Panda.DynamicWebApi; using Panda.DynamicWebApi;
using Serilog; using Serilog;
using Serilog.Events; using Serilog.Events;
@ -71,7 +70,7 @@ builder.Services.AddHostedService<FileSyncWorker>();
builder.Services.AddHealthChecks(); builder.Services.AddHealthChecks();
//本地化 //本地化
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources"); builder.Services.AddJsonLocalization(options => options.ResourcesPath = new[] { "Resources" });
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim() // 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()

View File

@ -1,43 +1,21 @@
using AlibabaCloud.SDK.Sts20150401; using AlibabaCloud.SDK.Sts20150401;
using Amazon.Auth.AccessControlPolicy;
using Amazon.SecurityToken; using Amazon.SecurityToken;
using AutoMapper;
using Azure.Core;
using IdentityModel.Client;
using IdentityModel.OidcClient;
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces; using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure.Extention; using IRaCIS.Core.Infrastructure.Extention;
using MassTransit; using MassTransit;
using MassTransit.Futures.Contracts;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Org.BouncyCastle.Tls;
using RestSharp;
using RestSharp.Authenticators;
using Serilog; using Serilog;
using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text; using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using ZiggyCreatures.Caching.Fusion;
using AssumeRoleRequest = Amazon.SecurityToken.Model.AssumeRoleRequest; using AssumeRoleRequest = Amazon.SecurityToken.Model.AssumeRoleRequest;
using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO;
namespace IRaCIS.Api.Controllers namespace IRaCIS.Api.Controllers
{ {

View File

@ -1,11 +1,9 @@
using AutoMapper; using AutoMapper;
using ExcelDataReader; using ExcelDataReader;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.BusinessFilter; using IRaCIS.Core.Application.BusinessFilter;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.Dicom; using IRaCIS.Core.Application.Contracts.Dicom;
using IRaCIS.Core.Application.Contracts.Dicom.DTO; using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Command; using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Application.Service; using IRaCIS.Core.Application.Service;
@ -17,8 +15,6 @@ using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention; using IRaCIS.Core.Infrastructure.Extention;
using MassTransit.Mediator; using MassTransit.Mediator;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
@ -27,21 +23,15 @@ using Microsoft.AspNetCore.StaticFiles;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using MiniExcelLibs; using MiniExcelLibs;
using Newtonsoft.Json; using Newtonsoft.Json;
using SharpCompress.Archives; using SharpCompress.Archives;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Data; using System.Data;
using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Path = System.IO.Path; using Path = System.IO.Path;
namespace IRaCIS.Core.API.Controllers namespace IRaCIS.Core.API.Controllers
@ -132,7 +122,7 @@ namespace IRaCIS.Core.API.Controllers
//处理压缩文件 //处理压缩文件
if (fileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".rar", StringComparison.OrdinalIgnoreCase)) if (fileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".rar", StringComparison.OrdinalIgnoreCase))
{ {
var archive = ArchiveFactory.Open(section.Body); var archive = ArchiveFactory.OpenArchive(section.Body);
foreach (var entry in archive.Entries) foreach (var entry in archive.Entries)
{ {
@ -213,7 +203,7 @@ namespace IRaCIS.Core.API.Controllers
//处理压缩文件 //处理压缩文件
if (fileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".rar", StringComparison.OrdinalIgnoreCase)) if (fileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".rar", StringComparison.OrdinalIgnoreCase))
{ {
var archive = ArchiveFactory.Open(section.Body); var archive = ArchiveFactory.OpenArchive(section.Body);
foreach (var entry in archive.Entries) foreach (var entry in archive.Entries)
{ {

View File

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<SignAssembly>false</SignAssembly> <SignAssembly>false</SignAssembly>
<UserSecretsId>354572d4-9e15-4099-807c-63a2d29ff9f2</UserSecretsId> <UserSecretsId>354572d4-9e15-4099-807c-63a2d29ff9f2</UserSecretsId>
<LangVersion>default</LangVersion> <LangVersion>default</LangVersion>
@ -69,22 +68,22 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" /> <PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.14" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.15"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="ConfigMapFileProvider" Version="2.0.1" /> <PackageReference Include="ConfigMapFileProvider" Version="2.0.1" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.20" /> <PackageReference Include="Hangfire.AspNetCore" Version="1.8.23" />
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" /> <PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
<PackageReference Include="Hangfire.InMemory" Version="1.0.0" /> <PackageReference Include="Hangfire.InMemory" Version="1.0.0" />
<PackageReference Include="Hangfire.SqlServer" Version="1.8.20" /> <PackageReference Include="Hangfire.SqlServer" Version="1.8.23" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.7" />
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" /> <PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.Email" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.Email" Version="4.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.1" /> <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="10.1.7" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -378,6 +378,11 @@
LowerCamelCaseJsonAttribute 可以设置类小写返回给前端 LowerCamelCaseJsonAttribute 可以设置类小写返回给前端
</summary> </summary>
</member> </member>
<member name="T:Program">
<summary>
Auto-generated public partial Program class for top-level statement apps.
</summary>
</member>
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService"> <member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
<summary> <summary>
对称可逆加密 对称可逆加密
@ -413,5 +418,49 @@
<param name="withPrivate"></param> <param name="withPrivate"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Type)">
<summary>
Generates a documentation comment ID for a type.
Example: T:Namespace.Outer+Inner`1 becomes T:Namespace.Outer.Inner`1
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Reflection.PropertyInfo)">
<summary>
Generates a documentation comment ID for a property.
Example: P:Namespace.ContainingType.PropertyName or for an indexer P:Namespace.ContainingType.Item(System.Int32)
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Type,System.String)">
<summary>
Generates a documentation comment ID for a property given its container type and property name.
Example: P:Namespace.ContainingType.PropertyName
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Reflection.MethodInfo)">
<summary>
Generates a documentation comment ID for a method (or constructor).
For example:
M:Namespace.ContainingType.MethodName(ParamType1,ParamType2)~ReturnType
M:Namespace.ContainingType.#ctor(ParamType)
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.GetTypeDocId(System.Type,System.Boolean,System.Boolean)">
<summary>
Generates a documentation ID string for a type.
This method handles nested types (replacing '+' with '.'),
generic types, arrays, pointers, by-ref types, and generic parameters.
The <paramref name="includeGenericArguments"/> flag controls whether
constructed generic type arguments are emitted, while <paramref name="omitGenericArity"/>
controls whether the generic arity marker (e.g. "`1") is appended.
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.NormalizeDocId(System.String)">
<summary>
Normalizes a documentation comment ID to match the compiler-style format.
Strips the return type suffix for ordinary methods but retains it for conversion operators.
</summary>
<param name="docId">The documentation comment ID to normalize.</param>
<returns>The normalized documentation comment ID.</returns>
</member>
</members> </members>
</doc> </doc>

View File

@ -101,7 +101,7 @@ builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
builder.Services.AddHealthChecks(); builder.Services.AddHealthChecks();
builder.Services.AddSerilog(); builder.Services.AddSerilog();
//本地化 //本地化
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources"); builder.Services.AddJsonLocalization(options => options.ResourcesPath = new[] { "Resources" });
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim() // 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
builder.Services.AddControllers(options => builder.Services.AddControllers(options =>

View File

@ -1,15 +1,7 @@
using Microsoft.AspNetCore.Builder; using Microsoft.OpenApi;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters; using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI; using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.ComponentModel; using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
namespace IRaCIS.Core.API; namespace IRaCIS.Core.API;
@ -52,17 +44,20 @@ public static class SwaggerSetup
services.AddSwaggerGen(options => services.AddSwaggerGen(options =>
{ {
typeof(SwaggerVersion).GetFields(BindingFlags.Public | BindingFlags.Static).ToList() // 使用反射获取字段并动态创建 Swagger 文档
.ForEach(field => typeof(SwaggerVersion).GetFields(BindingFlags.Public | BindingFlags.Static)
{ .ToList()
var description = field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? field.Name; .ForEach(field =>
options.SwaggerDoc(field.Name, new Microsoft.OpenApi.Models.OpenApiInfo {
{ var description = field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? field.Name;
Version = field.Name, options.SwaggerDoc(field.Name, new OpenApiInfo
Description = $"{field.Name} API", {
Title = description // 使用Description作为Title Version = field.Name,
}); Description = $"{field.Name} API",
}); Title = description // 使用 Description 作为 Title
});
});
// 接口排序 // 接口排序
options.OrderActionsBy(o => o.GroupName); options.OrderActionsBy(o => o.GroupName);

View File

@ -1,9 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>default</LangVersion> <LangVersion>default</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile> <GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup> </PropertyGroup>
@ -35,10 +33,10 @@
<PackageReference Include="IdentityModel.OidcClient" Version="6.0.0" /> <PackageReference Include="IdentityModel.OidcClient" Version="6.0.0" />
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" /> <PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" /> <PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="AWSSDK.S3" Version="4.0.21" /> <PackageReference Include="AWSSDK.S3" Version="4.0.22.1" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.5.19" /> <PackageReference Include="AWSSDK.SecurityToken" Version="4.0.6.2" />
<PackageReference Include="DocX" Version="5.0.0" /> <PackageReference Include="DocX" Version="5.0.0" />
<PackageReference Include="FreeSpire.Doc" Version="12.2.0" /> <PackageReference Include="FreeSpire.Doc" Version="14.4.0" />
<PackageReference Include="ExcelDataReader" Version="3.8.0" /> <PackageReference Include="ExcelDataReader" Version="3.8.0" />
<PackageReference Include="ExcelDataReader.DataSet" Version="3.8.0" /> <PackageReference Include="ExcelDataReader.DataSet" Version="3.8.0" />
<PackageReference Include="DistributedLock.Redis" Version="1.1.1" /> <PackageReference Include="DistributedLock.Redis" Version="1.1.1" />
@ -47,23 +45,23 @@
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" /> <PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" />
<PackageReference Include="fo-dicom.Codecs" Version="5.16.7" /> <PackageReference Include="fo-dicom.Codecs" Version="5.16.7" />
<PackageReference Include="IP2Region.Net" Version="3.0.2" /> <PackageReference Include="IP2Region.Net" Version="3.0.2" />
<PackageReference Include="MailKit" Version="4.15.1" /> <PackageReference Include="MailKit" Version="4.16.0" />
<PackageReference Include="Masa.Contrib.Service.MinimalAPIs" Version="1.1.0" /> <PackageReference Include="Masa.Contrib.Service.MinimalAPIs" Version="1.1.0" />
<PackageReference Include="MaxMind.GeoIP2" Version="5.4.1" /> <PackageReference Include="MaxMind.GeoIP2" Version="5.4.1" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.10" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.7" />
<PackageReference Include="MimeKit" Version="4.15.1" /> <PackageReference Include="MimeKit" Version="4.16.0" />
<PackageReference Include="MiniExcel" Version="1.41.2" /> <PackageReference Include="MiniExcel" Version="1.43.1" />
<PackageReference Include="Minio" Version="6.0.3" /> <PackageReference Include="Minio" Version="7.0.0" />
<PackageReference Include="MiniWord" Version="0.9.2" /> <PackageReference Include="MiniWord" Version="0.9.2" />
<PackageReference Include="Serilog.AspNetCore" Version="10.0.0" /> <PackageReference Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0"> <PackageReference Include="My.Extensions.Localization.Json" Version="4.0.0">
<TreatAsUsed>true</TreatAsUsed> <TreatAsUsed>true</TreatAsUsed>
</PackageReference> </PackageReference>
<PackageReference Include="NPOI" Version="2.7.4" /> <PackageReference Include="NPOI" Version="2.7.4" />
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" /> <PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
<PackageReference Include="RestSharp" Version="114.0.0" /> <PackageReference Include="RestSharp" Version="114.0.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" /> <PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="10.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -17295,17 +17295,17 @@
</member> </member>
<member name="F:IRaCIS.Core.Application.ViewModel.AccessToDialogueEnum.Question"> <member name="F:IRaCIS.Core.Application.ViewModel.AccessToDialogueEnum.Question">
<summary> <summary>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 质疑
</summary> </summary>
</member> </member>
<member name="F:IRaCIS.Core.Application.ViewModel.AccessToDialogueEnum.Consistency"> <member name="F:IRaCIS.Core.Application.ViewModel.AccessToDialogueEnum.Consistency">
<summary> <summary>
һ<EFBFBD><EFBFBD><EFBFBD>Ժ˲<EFBFBD> 一致性核查
</summary> </summary>
</member> </member>
<member name="T:IRaCIS.Core.Application.ViewModel.CopyFrontAuditConfigItemDto"> <member name="T:IRaCIS.Core.Application.ViewModel.CopyFrontAuditConfigItemDto">
<summary> <summary>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 复制
</summary> </summary>
</member> </member>
<member name="T:IRaCIS.Core.Application.ViewModel.SystemNoticeView"> <member name="T:IRaCIS.Core.Application.ViewModel.SystemNoticeView">
@ -21859,5 +21859,49 @@
<member name="M:IRaCIS.Application.Interfaces.ITrialEnrollmentService.ConfirmReviewer(System.Guid,System.Guid[],System.Int32)"> <member name="M:IRaCIS.Application.Interfaces.ITrialEnrollmentService.ConfirmReviewer(System.Guid,System.Guid[],System.Int32)">
<summary>入组流程-向CRO提交医生[Submit]</summary> <summary>入组流程-向CRO提交医生[Submit]</summary>
</member> </member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Type)">
<summary>
Generates a documentation comment ID for a type.
Example: T:Namespace.Outer+Inner`1 becomes T:Namespace.Outer.Inner`1
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Reflection.PropertyInfo)">
<summary>
Generates a documentation comment ID for a property.
Example: P:Namespace.ContainingType.PropertyName or for an indexer P:Namespace.ContainingType.Item(System.Int32)
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Type,System.String)">
<summary>
Generates a documentation comment ID for a property given its container type and property name.
Example: P:Namespace.ContainingType.PropertyName
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.CreateDocumentationId(System.Reflection.MethodInfo)">
<summary>
Generates a documentation comment ID for a method (or constructor).
For example:
M:Namespace.ContainingType.MethodName(ParamType1,ParamType2)~ReturnType
M:Namespace.ContainingType.#ctor(ParamType)
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.GetTypeDocId(System.Type,System.Boolean,System.Boolean)">
<summary>
Generates a documentation ID string for a type.
This method handles nested types (replacing '+' with '.'),
generic types, arrays, pointers, by-ref types, and generic parameters.
The <paramref name="includeGenericArguments"/> flag controls whether
constructed generic type arguments are emitted, while <paramref name="omitGenericArity"/>
controls whether the generic arity marker (e.g. "`1") is appended.
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OpenApi.Generated.DocumentationCommentIdHelper.NormalizeDocId(System.String)">
<summary>
Normalizes a documentation comment ID to match the compiler-style format.
Strips the return type suffix for ordinary methods but retains it for conversion operators.
</summary>
<param name="docId">The documentation comment ID to normalize.</param>
<returns>The normalized documentation comment ID.</returns>
</member>
</members> </members>
</doc> </doc>

View File

@ -1,6 +1,4 @@
using Azure.Core; using IdentityModel.Client;
using IdentityModel;
using IdentityModel.Client;
using IRaCIS.Core.Application.Service.OAuth; using IRaCIS.Core.Application.Service.OAuth;
using MassTransit; using MassTransit;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
@ -8,18 +6,11 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Utilities.Net;
using RestSharp; using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Http;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service namespace IRaCIS.Core.Application.Service
{ {

View File

@ -1,30 +1,17 @@
using Aliyun.OSS; using Aliyun.OSS;
using DocumentFormat.OpenXml.Spreadsheet;
using FellowOakDicom; using FellowOakDicom;
using FellowOakDicom.Imaging; using FellowOakDicom.Imaging;
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.BusinessFilter;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Helper.OtherTool;
using IRaCIS.Core.Application.Service.BusinessFilter;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infra.EFCore.Context; using IRaCIS.Core.Infra.EFCore.Context;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Encryption; using IRaCIS.Core.Infrastructure.Encryption;
using IRaCIS.Core.Infrastructure.NewtonsoftJson; using IRaCIS.Core.Infrastructure.NewtonsoftJson;
using MassTransit; using MassTransit;
using MassTransit.Caching.Internals;
using MassTransit.Mediator;
using MathNet.Numerics;
using MaxMind.GeoIP2;
using Medallion.Threading; using Medallion.Threading;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -32,24 +19,14 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using MiniExcelLibs; using MiniExcelLibs;
using Minio.DataModel;
using NPOI.SS.Formula.Functions;
using NPOI.XWPF.UserModel; using NPOI.XWPF.UserModel;
using SharpCompress.Common;
using SixLabors.ImageSharp; using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing;
using System.Collections.Concurrent;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq.Dynamic.Core; using System.Linq.Dynamic.Core;
using System.Reactive.Subjects;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using static IRaCIS.Core.Domain.Share.StaticData;

View File

@ -1,8 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>..\bin</OutputPath> <OutputPath>..\bin</OutputPath>

View File

@ -1,11 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>..\bin</OutputPath> <OutputPath>..\bin</OutputPath>
</PropertyGroup> </PropertyGroup>
@ -16,8 +9,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="EntityFrameworkCore.Projectables.Abstractions" Version="3.0.4" /> <PackageReference Include="EntityFrameworkCore.Projectables.Abstractions" Version="6.0.3" />
<PackageReference Include="MassTransit" Version="8.4.0" /> <PackageReference Include="MassTransit" Version="8.5.9" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,6 +1,5 @@
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using System.Linq;
using ZstdSharp.Unsafe;
namespace IRaCIS.Core.Domain.Models; namespace IRaCIS.Core.Domain.Models;

View File

@ -1,245 +0,0 @@
using System.Collections;
using System.Reflection;
namespace IRaCIS.Core.Infra.EFCore;
public static class DbContextExt
{
/// <summary>
/// 获取变化的实体信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <returns></returns>
public static IEnumerable<ChangeEntry> GetChanges<T>(this DbContext db)
{
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
{
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()
};
});
}
/// <summary>
/// 获取变化的实体信息
/// </summary>
/// <param name="db"></param>
/// <returns></returns>
public static IEnumerable<ChangeEntry> 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()
};
});
}
/// <summary>
/// 获取添加的实体信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <returns></returns>
public static IEnumerable<ChangeEntry> GetAdded<T>(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()
};
});
}
/// <summary>
/// 获取添加的实体信息
/// </summary>
/// <param name="db"></param>
/// <returns></returns>
public static IEnumerable<ChangeEntry> 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()
};
});
}
/// <summary>
/// 获取移除的实体信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <returns></returns>
public static IEnumerable<ChangeEntry> GetRemoved<T>(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()
};
});
}
/// <summary>
/// 获取移除的实体信息
/// </summary>
/// <param name="db"></param>
/// <returns></returns>
public static IEnumerable<ChangeEntry> 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()
};
});
}
/// <summary>
/// 获取所有的变更信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <returns></returns>
public static IEnumerable<ChangeEntry> GetAllChanges<T>(this DbContext db)
{
return GetChanges<T>(db).Union(GetAdded<T>(db)).Union(GetRemoved<T>(db));
}
/// <summary>
/// 获取所有的变更信息
/// </summary>
/// <param name="db"></param>
/// <returns></returns>
public static IEnumerable<ChangeEntry> GetAllChanges(this DbContext db)
{
return GetChanges(db).Union(GetAdded(db)).Union(GetRemoved(db));
}
}
public class ChangePropertyInfo
{
/// <summary>
/// 属性
/// </summary>
public PropertyInfo PropertyInfo { get; set; }
/// <summary>
/// 原始值
/// </summary>
public object OriginalValue { get; set; }
/// <summary>
/// 新值
/// </summary>
public object CurrentValue { get; set; }
/// <summary>
/// 是否是主键
/// </summary>
public bool IsPrimaryKey { get; set; }
/// <summary>
/// 是否是外键
/// </summary>
public bool IsForeignKey { get; set; }
}
public class ChangeEntry
{
/// <summary>
/// 所属实体
/// </summary>
public object Entity { get; set; }
/// <summary>
/// 实体类型
/// </summary>
public Type EntityType { get; set; }
/// <summary>
/// 变更类型
/// </summary>
public EntityState EntityState { get; set; }
/// <summary>
/// 字段变更信息
/// </summary>
public List<ChangePropertyInfo> ChangeProperties { get; set; }
}

View File

@ -1,11 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>..\bin</OutputPath> <OutputPath>..\bin</OutputPath>
</PropertyGroup> </PropertyGroup>
@ -21,22 +14,21 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="EFCore.BulkExtensions" Version="8.1.3" /> <PackageReference Include="EFCore.BulkExtensions" Version="10.0.1" />
<PackageReference Include="EntityFrameworkCore.Triggered" Version="3.2.2" /> <PackageReference Include="EntityFrameworkCore.Triggered" Version="3.2.2" />
<PackageReference Include="EntityFrameworkCore.Projectables" Version="3.0.4" /> <PackageReference Include="EntityFrameworkCore.Projectables" Version="6.0.3" />
<PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="8.1.3" /> <PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="10.0.0" />
<PackageReference Include="MassTransit" Version="8.4.0" /> <PackageReference Include="MassTransit.EntityFrameworkCore" Version="8.5.9" />
<PackageReference Include="MassTransit.EntityFrameworkCore" Version="8.4.0" /> <PackageReference Include="MassTransit.Hangfire" Version="8.5.9" />
<PackageReference Include="MassTransit.Hangfire" Version="8.4.0" /> <PackageReference Include="Hangfire.Core" Version="1.8.23" />
<PackageReference Include="Hangfire.Core" Version="1.8.18" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.7" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.7" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.19" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.19">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.19"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.7">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>

View File

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Query;
using System.Reflection; using System.Reflection;
namespace IRaCIS.Core.Infra.EFCore namespace IRaCIS.Core.Infra.EFCore
@ -6,37 +7,14 @@ namespace IRaCIS.Core.Infra.EFCore
public static class DynamicRelationalExtensions public static class DynamicRelationalExtensions
{ {
//升级efcore9 RelationalQueryableExtensions-> EntityFrameworkQueryableExtensions ////升级efcore9 RelationalQueryableExtensions-> EntityFrameworkQueryableExtensions
static MethodInfo UpdateMethodInfo = //static MethodInfo UpdateMethodInfo =
typeof(RelationalQueryableExtensions).GetMethod(nameof(RelationalQueryableExtensions.ExecuteUpdate)); // typeof(EntityFrameworkQueryableExtensions).GetMethod(nameof(EntityFrameworkQueryableExtensions.ExecuteUpdate));
static MethodInfo UpdateAsyncMethodInfo = static MethodInfo UpdateAsyncMethodInfo =
typeof(RelationalQueryableExtensions).GetMethod(nameof(RelationalQueryableExtensions.ExecuteUpdateAsync)); typeof(EntityFrameworkQueryableExtensions).GetMethod(nameof(EntityFrameworkQueryableExtensions.ExecuteUpdateAsync));
#region 避免使用
public static int ExecuteUpdate(this IQueryable query, string fieldName, object? fieldValue)
{
var updateBody = BuildUpdateBody(query.ElementType,
new Dictionary<string, object?> { { fieldName, fieldValue } });
return (int)UpdateMethodInfo.MakeGenericMethod(query.ElementType).Invoke(null, new object?[] { query, updateBody });
}
public static int ExecuteUpdate(this IQueryable query, IReadOnlyDictionary<string, object?> fieldValues)
{
var updateBody = BuildUpdateBody(query.ElementType, fieldValues);
return (int)UpdateMethodInfo.MakeGenericMethod(query.ElementType).Invoke(null, new object?[] { query, updateBody });
}
public static Task<int> ExecuteUpdateAsync(this IQueryable query, string fieldName, object? fieldValue, CancellationToken cancellationToken = default)
{
var updateBody = BuildUpdateBody(query.ElementType,
new Dictionary<string, object?> { { fieldName, fieldValue } });
return (Task<int>)UpdateAsyncMethodInfo.MakeGenericMethod(query.ElementType).Invoke(null, new object?[] { query, updateBody, cancellationToken })!;
}
#endregion
public static Dictionary<string, object?> ExtractFieldValues<TSource>(this Expression<Func<TSource, TSource>> updateFactory) public static Dictionary<string, object?> ExtractFieldValues<TSource>(this Expression<Func<TSource, TSource>> updateFactory)
{ {
@ -64,50 +42,63 @@ namespace IRaCIS.Core.Infra.EFCore
public static Task<int> ExecuteUpdateAsync(this IQueryable query, IReadOnlyDictionary<string, object?> fieldValues, CancellationToken cancellationToken = default) public static Task<int> ExecuteUpdateAsync(this IQueryable query, IReadOnlyDictionary<string, object?> fieldValues, CancellationToken cancellationToken = default)
{ {
var updateBody = BuildUpdateBody(query.ElementType, fieldValues);
return (Task<int>)UpdateAsyncMethodInfo.MakeGenericMethod(query.ElementType).Invoke(null, new object?[] { query, updateBody, cancellationToken })!; ParameterExpression propertyParam = Expression.Parameter(query.ElementType, "p");
Type SetPropertyBuilder = typeof(UpdateSettersBuilder<>).MakeGenericType(query.ElementType);
Action<object> BuilderAction = r => { };
foreach (KeyValuePair<string, object?> FieldValue in fieldValues)
{
MemberExpression propertyExp = Expression.PropertyOrField(propertyParam, FieldValue.Key);
MethodInfo? SetPropertyMethodInfo = (SetPropertyBuilder.GetMethods()
.FirstOrDefault(r => r.Name == nameof(UpdateSettersBuilder<>.SetProperty) && r.GetParameters().Any(p => p.ParameterType.BaseType == typeof(object)))?
.MakeGenericMethod(propertyExp.Type)) ?? throw new Exception("SetPropertyBuilder.SetProperty method is not found");
BuilderAction += r => SetPropertyMethodInfo.Invoke(r, [Expression.Lambda(propertyExp, propertyParam), FieldValue.Value]);
}
return (Task<int>)UpdateAsyncMethodInfo.MakeGenericMethod(query.ElementType).Invoke(null, [query, BuilderAction, cancellationToken])!;
} }
static LambdaExpression BuildUpdateBody(Type entityType, IReadOnlyDictionary<string, object?> fieldValues)
{
var setParam = Expression.Parameter(typeof(SetPropertyCalls<>).MakeGenericType(entityType), "s");
var objParam = Expression.Parameter(entityType, "e");
Expression setBody = setParam; //static LambdaExpression BuildUpdateBody(Type entityType, IReadOnlyDictionary<string, object?> fieldValues)
//{
// var setParam = Expression.Parameter(typeof(SetPropertyCalls<>).MakeGenericType(entityType), "s");
// var objParam = Expression.Parameter(entityType, "e");
foreach (var pair in fieldValues) // Expression setBody = setParam;
{
var propExpression = Expression.PropertyOrField(objParam, pair.Key);
var valueExpression = ValueForType(propExpression.Type, pair.Value);
// s.SetProperty(e => e.SomeField, value) // foreach (var pair in fieldValues)
setBody = Expression.Call(setBody, nameof(SetPropertyCalls<object>.SetProperty), // {
new[] { propExpression.Type }, Expression.Lambda(propExpression, objParam), valueExpression); // var propExpression = Expression.PropertyOrField(objParam, pair.Key);
// var valueExpression = ValueForType(propExpression.Type, pair.Value);
} // // s.SetProperty(e => e.SomeField, value)
// setBody = Expression.Call(setBody, nameof(SetPropertyCalls<object>.SetProperty),
// new[] { propExpression.Type }, Expression.Lambda(propExpression, objParam), valueExpression);
// s => s.SetProperty(e => e.SomeField, value) // }
var updateBody = Expression.Lambda(setBody, setParam);
return updateBody; // // s => s.SetProperty(e => e.SomeField, value)
} // var updateBody = Expression.Lambda(setBody, setParam);
static Expression ValueForType(Type desiredType, object? value) // return updateBody;
{ //}
if (value == null)
{
return Expression.Default(desiredType);
}
if (value.GetType() != desiredType) //static Expression ValueForType(Type desiredType, object? value)
{ //{
return Expression.Convert(Expression.Constant(value), desiredType); // if (value == null)
} // {
// return Expression.Default(desiredType);
// }
return Expression.Constant(value); // if (value.GetType() != desiredType)
} // {
// return Expression.Convert(Expression.Constant(value), desiredType);
// }
// return Expression.Constant(value);
//}
} }
} }

View File

@ -60,7 +60,7 @@ namespace IRaCIS.Core.Infra.EFCore
/// <summary>批量更新相当于原生sql 没用EF跟踪方式所有查询出来再更新 浪费性能)</summary> /// <summary>批量更新相当于原生sql 没用EF跟踪方式所有查询出来再更新 浪费性能)</summary>
Task<bool> BatchUpdateNoTrackingAsync(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TEntity>> updateFactory, bool isAutoIncludeTimeAndUser = true); Task<bool> BatchUpdateNoTrackingAsync(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TEntity>> updateFactory, bool isAutoIncludeTimeAndUser = true);
Task<bool> ExecuteUpdateAsync(Expression<Func<TEntity, bool>> where, Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls); Task<bool> ExecuteUpdateAsync(Expression<Func<TEntity, bool>> where, Action<UpdateSettersBuilder<TEntity>> setPropertyCalls);
#endregion #endregion

View File

@ -1,6 +1,7 @@
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention; using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Query;
using System.Reflection; using System.Reflection;
@ -220,6 +221,8 @@ namespace IRaCIS.Core.Infra.EFCore
} }
return await _dbContext.Set<T>().IgnoreQueryFilters().Where(where).ExecuteUpdateAsync(fieldValues).ConfigureAwait(false) > 0; return await _dbContext.Set<T>().IgnoreQueryFilters().Where(where).ExecuteUpdateAsync(fieldValues).ConfigureAwait(false) > 0;
} }
@ -228,7 +231,8 @@ namespace IRaCIS.Core.Infra.EFCore
} }
public static async Task<bool> ExecuteUpdateAsync<T>(this IRaCISDBContext _dbContext, Expression<Func<T, bool>> where, Expression<Func<SetPropertyCalls<T>, SetPropertyCalls<T>>> setPropertyCalls) where T : Entity
public static async Task<bool> ExecuteUpdateAsync<T>(this IRaCISDBContext _dbContext, Expression<Func<T, bool>> where, Action<UpdateSettersBuilder<T>> setPropertyCalls ) where T : Entity
{ {
return await _dbContext.Set<T>().Where(where).ExecuteUpdateAsync<T>(setPropertyCalls) > 0; return await _dbContext.Set<T>().Where(where).ExecuteUpdateAsync<T>(setPropertyCalls) > 0;

View File

@ -306,7 +306,7 @@ namespace IRaCIS.Core.Infra.EFCore
/// <summary>EF core 7+ 原生批量更新方法 </summary> /// <summary>EF core 7+ 原生批量更新方法 </summary>
public async Task<bool> ExecuteUpdateAsync(Expression<Func<TEntity, bool>> where, Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls) public async Task<bool> ExecuteUpdateAsync(Expression<Func<TEntity, bool>> where, Action<UpdateSettersBuilder<TEntity>> setPropertyCalls)
{ {
return await _dbContext.ExecuteUpdateAsync(where, setPropertyCalls); return await _dbContext.ExecuteUpdateAsync(where, setPropertyCalls);
} }

View File

@ -1,205 +0,0 @@
using SharpCompress.Archives;
using SharpCompress.Common;
using SharpCompress.Readers;
using SharpCompress.Writers;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace IRaCIS.Core.Infrastructure.Extention
{
/// <summary>
/// 7z压缩
/// </summary>
public static class SevenZipCompressor
{
/// <summary>
/// 将多个文件压缩到一个内存流中可保存为zip文件方便于web方式下载
/// </summary>
/// <param name="files">多个文件路径文件或文件夹或网络路径http/https</param>
/// <param name="rootdir"></param>
/// <returns>文件流</returns>
public static MemoryStream ZipStream(List<string> files, string rootdir = "")
{
using var archive = CreateZipArchive(files, rootdir);
var ms = new MemoryStream();
archive.SaveTo(ms, new WriterOptions(CompressionType.Deflate)
{
LeaveStreamOpen = true,
ArchiveEncoding = new ArchiveEncoding()
{
Default = Encoding.UTF8
}
});
return ms;
}
/// <summary>
/// 压缩多个文件
/// </summary>
/// <param name="files">多个文件路径,文件或文件夹</param>
/// <param name="zipFile">压缩到...</param>
/// <param name="rootdir">压缩包内部根文件夹</param>
/// <param name="archiveType"></param>
public static void Zip(List<string> files, string zipFile, string rootdir = "", ArchiveType archiveType = ArchiveType.SevenZip)
{
using var archive = CreateZipArchive(files, rootdir, archiveType);
archive.SaveTo(zipFile, new WriterOptions(CompressionType.Deflate)
{
LeaveStreamOpen = true,
ArchiveEncoding = new ArchiveEncoding()
{
Default = Encoding.UTF8
}
});
}
/// <summary>
/// 解压文件,自动检测压缩包类型
/// </summary>
/// <param name="compressedFile">rar文件</param>
/// <param name="dir">解压到...</param>
/// <param name="ignoreEmptyDir">忽略空文件夹</param>
public static void Decompress(string compressedFile, string dir = "", bool ignoreEmptyDir = true)
{
if (string.IsNullOrEmpty(dir))
{
dir = Path.GetDirectoryName(compressedFile);
}
using Stream stream = File.OpenRead(compressedFile);
using var reader = ReaderFactory.Open(stream);
while (reader.MoveToNextEntry())
{
if (ignoreEmptyDir)
{
reader.WriteEntryToDirectory(dir, new ExtractionOptions()
{
ExtractFullPath = true,
Overwrite = true
});
}
else
{
if (!reader.Entry.IsDirectory)
{
reader.WriteEntryToDirectory(dir, new ExtractionOptions()
{
ExtractFullPath = true,
Overwrite = true
});
}
}
}
}
/// <summary>
/// 创建zip包
/// </summary>
/// <param name="files"></param>
/// <param name="rootdir"></param>
/// <param name="archiveType"></param>
/// <returns></returns>
private static IWritableArchive CreateZipArchive(List<string> files, string rootdir, ArchiveType archiveType = ArchiveType.SevenZip)
{
var archive = ArchiveFactory.Create(archiveType);
var dic = GetFileEntryMaps(files);
var remoteUrls = files.Distinct().Where(s => s.StartsWith("http")).Select(s =>
{
try
{
return new Uri(s);
}
catch (UriFormatException)
{
return null;
}
}).Where(u => u != null).ToList();
foreach (var pair in dic)
{
archive.AddEntry(Path.Combine(rootdir, pair.Value), pair.Key);
}
if (!remoteUrls.Any())
{
return archive;
}
var streams = new ConcurrentDictionary<string, Stream>();
using var httpClient = new HttpClient();
Parallel.ForEach(remoteUrls, url =>
{
httpClient.GetAsync(url).ContinueWith(async t =>
{
if (t.IsCompleted)
{
var res = await t;
if (res.IsSuccessStatusCode)
{
Stream stream = await res.Content.ReadAsStreamAsync();
streams[Path.Combine(rootdir, Path.GetFileName(HttpUtility.UrlDecode(url.AbsolutePath)))] = stream;
}
}
}).Wait();
});
foreach (var kv in streams)
{
archive.AddEntry(kv.Key, kv.Value, true);
}
return archive;
}
/// <summary>
/// 获取文件路径和zip-entry的映射
/// </summary>
/// <param name="files"></param>
/// <returns></returns>
private static Dictionary<string, string> GetFileEntryMaps(List<string> files)
{
var fileList = new List<string>();
void GetFilesRecurs(string path)
{
//遍历目标文件夹的所有文件
fileList.AddRange(Directory.GetFiles(path));
//遍历目标文件夹的所有文件夹
foreach (string directory in Directory.GetDirectories(path))
{
GetFilesRecurs(directory);
}
}
files.Where(s => !s.StartsWith("http")).ForEach(s =>
{
if (Directory.Exists(s))
{
GetFilesRecurs(s);
}
else
{
fileList.Add(s);
}
});
if (!fileList.Any())
{
return new Dictionary<string, string>();
}
var dirname = new string(fileList.First().Substring(0, fileList.Min(s => s.Length)).TakeWhile((c, i) => fileList.All(s => s[i] == c)).ToArray());
if (!Directory.Exists(dirname))
{
dirname = Directory.GetParent(dirname).FullName;
}
var dic = fileList.ToDictionary(s => s, s => s.Substring(dirname.Length));
return dic;
}
}
}

View File

@ -1,25 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>..\bin</OutputPath> <OutputPath>..\bin</OutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" /> <PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="10.0.0" /> <PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="11.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.7" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.10" /> <PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="10.0.7" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.7" />
<PackageReference Include="SharpCompress" Version="0.39.0" /> <PackageReference Include="SharpCompress" Version="0.47.4" />
<PackageReference Include="SharpZipLib" Version="1.4.2" /> <PackageReference Include="SharpZipLib" Version="1.4.2" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" /> <PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.6.0.2" /> <PackageReference Include="System.Linq.Dynamic.Core" Version="1.7.2" />
<PackageReference Include="ZiggyCreatures.FusionCache" Version="2.4.0" /> <PackageReference Include="ZiggyCreatures.FusionCache" Version="2.6.0" />
</ItemGroup> </ItemGroup>

View File

@ -1,9 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
@ -49,11 +46,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Fluid.Core" Version="2.21.0" /> <PackageReference Include="Fluid.Core" Version="2.31.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.19" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="8.0.19" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="10.0.7" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.11" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.19"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>