Compare commits

..

31 Commits

Author SHA1 Message Date
hang d49b5663ba 阅片期查询bug
continuous-integration/drone/push Build is running Details
2026-06-15 14:27:47 +08:00
hang e1386da5ae CRC CRA退出,过滤重传审批列表
continuous-integration/drone/push Build is running Details
2026-06-15 11:10:00 +08:00
hang b9f9af06f4 屏蔽swager 报错接口 2026-06-11 09:44:44 +08:00
he 01a79e0612 新增接口 GetNoneDicomMarkList
continuous-integration/drone/push Build is passing Details
2026-06-10 15:12:07 +08:00
he 3e69d72597 添加标记名称字段
continuous-integration/drone/push Build is passing Details
2026-06-10 14:13:15 +08:00
he f69c7af9d6 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10 2026-06-09 16:33:19 +08:00
he ae03503d76 添加NumberOfFrames 2026-06-09 16:33:18 +08:00
hang 39eade67f0 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10 2026-06-09 16:32:55 +08:00
hang e6d7a0c0e0 返回默认值,如果没有任务 2026-06-09 16:32:53 +08:00
he 98103451e9 添加 SopInstanceUid
continuous-integration/drone/push Build is passing Details
2026-06-09 16:18:33 +08:00
he b64eed88cf 高亮修改
continuous-integration/drone/push Build is passing Details
2026-06-09 16:07:12 +08:00
he bafe61ae64 Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10 2026-06-09 15:45:53 +08:00
he 0579c4aeda 功能添加 2026-06-09 15:45:52 +08:00
hang 7599e06b9d 重新触发测试
continuous-integration/drone/push Build is passing Details
2026-06-09 15:19:51 +08:00
hang 8e77d2e3ed 请求改为post 2026-06-09 15:05:46 +08:00
hang c2a129c56a Merge branch 'Test_IRC_Net10' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net10 2026-06-09 15:05:21 +08:00
hang 111d5509bc 医生阅片统计+受试者完成任务状态返回 2026-06-09 15:05:19 +08:00
he 7c9987f3de 获取标记信息
continuous-integration/drone/push Build is passing Details
2026-06-09 14:58:02 +08:00
hang f1471b6424 访视结束,状态回退
continuous-integration/drone/push Build is running Details
2026-06-08 11:35:26 +08:00
hang 935369c05c zip流方式下载影像
continuous-integration/drone/push Build is running Details
2026-06-05 11:27:27 +08:00
hang 2b03f382bd 术语替换-先完整准确匹配,匹配了就跳过,否则就关键字匹配替换
continuous-integration/drone/push Build is running Details
2026-06-04 16:28:17 +08:00
he 152a142d82 添加新增修改表格问题限制
continuous-integration/drone/push Build is failing Details
2026-06-04 14:41:26 +08:00
hang f55ce703b0 升级net10 自动打包分支修改
continuous-integration/drone/push Build is running Details
2026-06-04 14:12:09 +08:00
hang a08c8a0d64 升级除开收费包以外所有其他包 2026-06-04 13:45:31 +08:00
hang 76dd0c46ae 处理.net10编译错误 2026-06-04 13:19:38 +08:00
hang 1e8056f689 .net10 -合并编译错误 2026-06-04 13:19:17 +08:00
hang 388dac5f8d 删除无用包 2026-04-30 09:01:24 +08:00
hang ec0a4aeef9 降级automapper 2026-04-29 20:39:41 +08:00
hang 8bf0be9699 ClosedXML 替代 npoi 修改 2026-04-29 20:19:01 +08:00
hang 7707b339dc 打印运行时版本 2026-04-29 16:57:27 +08:00
hang 8eaa6606c4 升级.net10 2026-04-29 15:56:41 +08:00
82 changed files with 43317 additions and 22192 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,35 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.11" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.1.5" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.8" />
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="11.0.0" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="AWSSDK.S3" Version="4.0.21" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.5.19" />
<PackageReference Include="AWSSDK.S3" Version="4.0.24" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.7" />
<PackageReference Include="DistributedLock.Core" Version="1.0.8" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.6" />
<PackageReference Include="fo-dicom" Version="5.2.1" />
<PackageReference Include="fo-dicom.Codecs" Version="5.16.1" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Minio" Version="6.0.4" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
<PackageReference Include="DistributedLock.Core" Version="1.0.9" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.7" />
<PackageReference Include="fo-dicom" Version="5.2.6" />
<PackageReference Include="fo-dicom.Codecs" Version="5.16.7" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.8" />
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Minio" Version="7.0.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="4.0.0">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.1.2" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.9.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="10.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.1" />
</ItemGroup>
<ItemGroup>

View File

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

View File

@ -1,8 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
@ -10,17 +8,17 @@
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="11.0.0" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="AWSSDK.S3" Version="4.0.21" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.5.19" />
<PackageReference Include="AWSSDK.S3" Version="4.0.24" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.7" />
<PackageReference Include="DistributedLock.Core" Version="1.0.9" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.7" />
<PackageReference Include="fo-dicom" Version="5.2.6" />
<PackageReference Include="fo-dicom.Codecs" Version="5.16.7" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
<PackageReference Include="AutoMapper" Version="16.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.8" />
<PackageReference Include="AutoMapper" Version="14.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>
</PackageReference>
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
@ -28,7 +26,7 @@
<PackageReference Include="Serilog.Extensions.Hosting" Version="10.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.7" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.1" />
</ItemGroup>
<ItemGroup>

View File

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

View File

@ -1,76 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
"SyncConfigList": [
{
"Domain": "irc.uat.extimaging.com",
"Primary": "AliyunOSS",
"Target": "AWS",
"UploadRegion": "CN",
"TargetRegion": "US",
"IsOpenSync": true
},
{
"Domain": "lili.uat.extimaging.com",
"Primary": "AWS",
"Target": "AliyunOSS",
"UploadRegion": "US",
"TargetRegion": "CN",
"IsOpenSync": true
}
],
"AliyunOSS": {
"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
},
// AWS S3
"AWS": {
// AWS S3 Region
"Region": "us-east-1",
// AWS S3 访
"EndPoint": "s3.us-east-1.amazonaws.com",
// 使 SSL
"UseSSL": true,
// AWS S3 ARN
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
// AWS S3 访 ID
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
// AWS S3 访 Secret
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
// AWS S3 Bucket
"BucketName": "ei-med-s3-lili-uat-store",
// AWS S3 访
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
// AWS S3
"DurationSeconds": 7200
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_HeAnShu;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server101.132.253.119,1435;Database=Uat_HeAnShu_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"CalledAEList": [
"STORESCP"
],
"ServerPort": 11112
}
}

View File

@ -1,76 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
"SyncConfigList": [
{
"Domain": "irc.uat.extimaging.com",
"Primary": "AliyunOSS",
"Target": "AWS",
"UploadRegion": "CN",
"TargetRegion": "US",
"IsOpenSync": true
},
{
"Domain": "lili.uat.extimaging.com",
"Primary": "AWS",
"Target": "AliyunOSS",
"UploadRegion": "US",
"TargetRegion": "CN",
"IsOpenSync": true
}
],
"AliyunOSS": {
"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
},
// AWS S3
"AWS": {
// AWS S3 Region
"Region": "us-east-1",
// AWS S3 访
"EndPoint": "s3.us-east-1.amazonaws.com",
// 使 SSL
"UseSSL": true,
// AWS S3 ARN
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
// AWS S3 访 ID
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
// AWS S3 访 Secret
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
// AWS S3 Bucket
"BucketName": "ei-med-s3-lili-uat-store",
// AWS S3 访
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
// AWS S3
"DurationSeconds": 7200
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_Tailimed;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server101.132.253.119,1435;Database=Uat_Tailimed_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"DicomSCPServiceConfig": {
"CalledAEList": [
"STORESCP"
],
"ServerPort": 11112
}
}

View File

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

View File

@ -1,11 +1,9 @@
using AutoMapper;
using ExcelDataReader;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.BusinessFilter;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.Dicom;
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Application.Service;
@ -17,8 +15,6 @@ using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit.Mediator;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
@ -27,21 +23,15 @@ using Microsoft.AspNetCore.StaticFiles;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using MiniExcelLibs;
using Newtonsoft.Json;
using SharpCompress.Archives;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Path = System.IO.Path;
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))
{
var archive = ArchiveFactory.Open(section.Body);
var archive = ArchiveFactory.OpenArchive(section.Body);
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))
{
var archive = ArchiveFactory.Open(section.Body);
var archive = ArchiveFactory.OpenArchive(section.Body);
foreach (var entry in archive.Entries)
{

View File

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<SignAssembly>false</SignAssembly>
<UserSecretsId>354572d4-9e15-4099-807c-63a2d29ff9f2</UserSecretsId>
<LangVersion>default</LangVersion>
@ -69,22 +68,21 @@
<ItemGroup>
<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.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.15">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<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.InMemory" Version="1.0.0" />
<PackageReference Include="Hangfire.SqlServer" Version="1.8.20" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
<PackageReference Include="Hangfire.SqlServer" Version="1.8.23" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.8" />
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.Email" Version="4.1.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.2.1" />
</ItemGroup>
<ItemGroup>

View File

@ -378,6 +378,11 @@
LowerCamelCaseJsonAttribute 可以设置类小写返回给前端
</summary>
</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">
<summary>
对称可逆加密
@ -413,5 +418,49 @@
<param name="withPrivate"></param>
<returns></returns>
</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>
</doc>

View File

@ -103,7 +103,7 @@ builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
builder.Services.AddHealthChecks();
builder.Services.AddSerilog();
//本地化
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddJsonLocalization(options => options.ResourcesPath = new[] { "Resources" });
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
builder.Services.AddControllers(options =>
@ -286,6 +286,7 @@ try
#region 运行环境 部署平台
Log.Logger.Warning($"当前环境:{enviromentName}");
Log.Logger.Warning($".NET 运行时版本:{Environment.Version}");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{

View File

@ -55,22 +55,6 @@
},
"applicationUrl": "http://0.0.0.0:6100"
},
"IRaCIS.Uat_Tailimed": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Uat_Tailimed"
},
"applicationUrl": "http://0.0.0.0:6100"
},
"IRaCIS.Uat_HeAnShu": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Uat_HeAnShu"
},
"applicationUrl": "http://0.0.0.0:6100"
},
"IRaCIS.Prod_IRC": {
"commandName": "Project",
"launchBrowser": true,

View File

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

View File

@ -7,10 +7,10 @@
}
},
"ConnectionStrings": {
"RemoteNew": "Server=10.10.10.49,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=10.10.10.49,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
//"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
//"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
//"RemoteNew": "Server=10.10.10.49,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
//"Hangfire": "Server=10.10.10.49,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
},
"WeComNoticeConfig": {
"IsOpenWeComNotice": true,

View File

@ -1,143 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_HeAnShu;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=101.132.253.119,1435;Database=Uat_HeAnShu_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"WeComNoticeConfig": {
"IsOpenWeComNotice": true,
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
"APINoticeUserList": [ "u", "wait..." ],
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
"SyncConfigList": [
{
"Domain": "irc.uat.rayplus.net",
"Primary": "AliyunOSS",
"Target": "AWS",
"UploadRegion": "CN",
"TargetRegion": "US",
"IsOpenSync": false
},
{
"Domain": "lili.uat.extimaging.com",
"Primary": "AWS",
"Target": "AliyunOSS",
"UploadRegion": "US",
"TargetRegion": "CN",
"IsOpenSync": false
}
],
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tFUCCmz5TwghZHsj45Y",
"AccessKeySecret": "8evrBy1fVfzJG25i67Jm0xqn9Xcw2T",
"RoleArn": "acs:ram::1078130221702011:role/uat-oss-access",
"BucketName": "rayplus-irc-uat-store",
"ViewEndpoint": "https://rayplus-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"MinIO": {
"endPoint": "hir-oss.uat.extimaging.com",
"port": "80",
"useSSL": false,
"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
//"port": "443",
//"useSSL": true,
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
"bucketName": "irc-uat"
},
"AWS": {
"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
}
},
"BasicSystemConfig": {
//
"QCRiskControl": true,
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 120,
"OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90,
// 1 Elevate 2 Extensive
"TemplateType": 2,
//MFA
"UserMFAVerifyMinutes": 1440
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.163.com",
"Imap": "imap.qiye.163.com",
"ImapPort": 993,
"FromEmail": "service@heanshu.com",
"FromName": "Uat HeAnShu Imaging System",
"AuthorizationCode": "j#cAPU%XgvcHWn3N",
"SiteUrl": "https://irc.uat.heanshu.com",
"PlatformName": "HeAnShu",
"PlatformNameCN": "禾安枢影像云平台",
"SystemShortName": "HeAnShu",
"OrganizationName": "HeAnShu",
"OrganizationNameCN": "HeAnShu",
"CompanyName": "HeAnShu",
"CompanyNameCN": "禾安枢软件科技有限公司",
"CompanyShortName": "HeAnShu",
"CompanyShortNameCN": "禾安枢",
"IsEnv_US": false,
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
"CronEmailDefaultCulture": "zh-CN"
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "101.132.253.119"
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]
}
}

View File

@ -1,143 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.253.119,1435;Database=Uat_Tailimed;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=101.132.253.119,1435;Database=Uat_Tailimed_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"WeComNoticeConfig": {
"IsOpenWeComNotice": true,
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
"APINoticeUserList": [ "u", "wait..." ],
"VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621b97b96f74e6f3d" ]
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",
"IsOpenStoreSync": true,
"ApiDeployRegion": "CN",
"SyncConfigList": [
{
"Domain": "irc.uat.rayplus.net",
"Primary": "AliyunOSS",
"Target": "AWS",
"UploadRegion": "CN",
"TargetRegion": "US",
"IsOpenSync": false
},
{
"Domain": "lili.uat.extimaging.com",
"Primary": "AWS",
"Target": "AliyunOSS",
"UploadRegion": "US",
"TargetRegion": "CN",
"IsOpenSync": false
}
],
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
"AccessKeyId": "LTAI5tFUCCmz5TwghZHsj45Y",
"AccessKeySecret": "8evrBy1fVfzJG25i67Jm0xqn9Xcw2T",
"RoleArn": "acs:ram::1078130221702011:role/uat-oss-access",
"BucketName": "rayplus-irc-uat-store",
"ViewEndpoint": "https://rayplus-irc-uat-store.oss-cn-shanghai.aliyuncs.com",
"Region": "oss-cn-shanghai",
"DurationSeconds": 7200
},
"MinIO": {
"endPoint": "hir-oss.uat.extimaging.com",
"port": "80",
"useSSL": false,
"viewEndpoint": "http://hir-oss.uat.extimaging.com/irc-uat",
//"port": "443",
//"useSSL": true,
//"viewEndpoint": "https://hir-oss.uat.extimaging.com/irc-uat",
"accessKey": "b9Ul0e98xPzt6PwRXA1Q",
"secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ",
"bucketName": "irc-uat"
},
"AWS": {
"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
}
},
"BasicSystemConfig": {
//
"QCRiskControl": true,
"OpenUserComplexPassword": true,
"OpenSignDocumentBeforeWork": true,
"OpenLoginLimit": true,
"LoginMaxFailCount": 5,
"LoginFailLockMinutes": 30,
"AutoLoginOutMinutes": 120,
"OpenLoginMFA": false,
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90,
// 1 Elevate 2 Extensive
"TemplateType": 2,
//MFA
"UserMFAVerifyMinutes": 1440
},
"SystemEmailSendConfig": {
"Port": 465,
"Host": "smtp.qiye.aliyun.com",
"Imap": "imap.qiye.aliyun.com",
"ImapPort": 993,
"FromEmail": "service@mail.rayplus.net",
"FromName": "Uat RayPlus Imaging System",
"AuthorizationCode": "crefHpx3WtenFr6X",
"SiteUrl": "https://irc.uat.rayplus.net/login",
"PlatformName": "RayPlus",
"PlatformNameCN": "睿佳影像云平台",
"SystemShortName": "RayPlus",
"OrganizationName": "RayPlus",
"OrganizationNameCN": "RayPlus",
"CompanyName": "RayPlus",
"CompanyNameCN": "睿佳(武汉)软件科技有限公司",
"CompanyShortName": "RayPlus",
"CompanyShortNameCN": "睿佳",
"IsEnv_US": false,
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
"CronEmailDefaultCulture": "zh-CN"
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "101.132.253.119"
},
"RequestDuplicationOptions": {
"IsEnabled": true,
"DuplicationWindowMs": 200,
"CacheTimeSeconds": 5,
"ExcludedPaths": [
]
}
}

View File

@ -1,16 +1,8 @@
using DocumentFormat.OpenXml.Office.CustomUI;
using FellowOakDicom;
using FellowOakDicom;
using FellowOakDicom.Media;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using NPOI.Util;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Helper
{

View File

@ -199,7 +199,6 @@ public static class SendEmailHelper
}
return true;
}

View File

@ -1,6 +1,4 @@
using IRaCIS.Core.Domain.Share;
using NPOI.XWPF.UserModel;
using System.Globalization;
using System.Globalization;
using Xceed.Document.NET;
using Xceed.Words.NET;
@ -54,42 +52,42 @@ public static class WordTempleteHelper
}
public static void Npoi_GetInternationalTempleteStream(string filePath, Stream memoryStream)
{
//public static void Npoi_GetInternationalTempleteStream(string filePath, Stream memoryStream)
//{
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
// var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
XWPFDocument doc = new XWPFDocument(fs);
// using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
// {
// XWPFDocument doc = new XWPFDocument(fs);
// 查找包含指定书签的段落及其索引
var bookmarkParagraph = doc.Paragraphs
.FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == StaticData.CultureInfo.en_US_bookMark));
// // 查找包含指定书签的段落及其索引
// var bookmarkParagraph = doc.Paragraphs
// .FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == StaticData.CultureInfo.en_US_bookMark));
if (bookmarkParagraph != null)
{
int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph);
// if (bookmarkParagraph != null)
// {
// int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph);
if (isEn_US)
{
// 从书签所在段落开始,删除之前的所有段落
for (int i = bookmarkIndex - 1; i >= 0; i--)
{
doc.RemoveBodyElement(i);
}
}
else
{
// 删除书签之后的所有段落
for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--)
{
doc.RemoveBodyElement(i);
}
}
}
doc.Write(memoryStream);
}
}
// if (isEn_US)
// {
// // 从书签所在段落开始,删除之前的所有段落
// for (int i = bookmarkIndex - 1; i >= 0; i--)
// {
// doc.RemoveBodyElement(i);
// }
// }
// else
// {
// // 删除书签之后的所有段落
// for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--)
// {
// doc.RemoveBodyElement(i);
// }
// }
// }
// doc.Write(memoryStream);
// }
//}
}

View File

@ -1,15 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using RestSharp;
using Newtonsoft.Json;
using IRaCIS.Core.Infrastructure.Extention;
using NPOI.SS.Formula.Functions;
namespace IRaCIS.Core.Application.Helper.OtherTool
{

View File

@ -1,9 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>default</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
@ -32,13 +30,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ClosedXML" Version="0.105.0" />
<PackageReference Include="IdentityModel.OidcClient" Version="6.0.0" />
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="AWSSDK.S3" Version="4.0.21" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.5.19" />
<PackageReference Include="AWSSDK.S3" Version="4.0.24" />
<PackageReference Include="AWSSDK.SecurityToken" Version="4.0.7" />
<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.DataSet" Version="3.8.0" />
<PackageReference Include="DistributedLock.Redis" Version="1.1.1" />
@ -47,23 +46,22 @@
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.2.6" />
<PackageReference Include="fo-dicom.Codecs" Version="5.16.7" />
<PackageReference Include="IP2Region.Net" Version="3.0.2" />
<PackageReference Include="MailKit" Version="4.15.1" />
<PackageReference Include="MailKit" Version="4.17.0" />
<PackageReference Include="Masa.Contrib.Service.MinimalAPIs" Version="1.1.0" />
<PackageReference Include="MaxMind.GeoIP2" Version="5.4.1" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.10" />
<PackageReference Include="MimeKit" Version="4.15.1" />
<PackageReference Include="MiniExcel" Version="1.41.2" />
<PackageReference Include="Minio" Version="6.0.3" />
<PackageReference Include="MaxMind.GeoIP2" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.8" />
<PackageReference Include="MimeKit" Version="4.17.0" />
<PackageReference Include="MiniExcel" Version="1.44.1" />
<PackageReference Include="Minio" Version="7.0.0" />
<PackageReference Include="MiniWord" Version="0.9.2" />
<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>
</PackageReference>
<PackageReference Include="NPOI" Version="2.7.4" />
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
<PackageReference Include="RestSharp" Version="114.0.0" />
<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>

View File

@ -59,17 +59,17 @@
</member>
<member name="P:IRaCIS.Core.Application.Service.ExcelExportHelper.DynamicColumnConfig.AutoColumnStartIndex">
<summary>
增加动态列开始索引 从0 开始算
增加动态列开始索引 npoi从0开始 现在ClosedXML 从1开始
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.ExcelExportHelper.DynamicColumnConfig.AutoColumnTitleRowIndex">
<summary>
动态列开始的行index 从0开始
动态列开始的行index npoi从0开始 现在ClosedXML 从1开始
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.ExcelExportHelper.DynamicColumnConfig.TempalteLastColumnIndex">
<summary>
模板列最后的索引
模板列最后的索引 npoi从0开始 现在ClosedXML 从1开始
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.ExcelExportHelper.DynamicColumnConfig.ColumnIdNameList">
@ -102,20 +102,6 @@
Excel Title Name
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Service.ExcelExportHelper.CDISC_DataExport_Async(System.String,IRaCIS.Application.Contracts.ExcelExportInfo,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument},Microsoft.AspNetCore.Hosting.IWebHostEnvironment,IRaCIS.Application.Interfaces.IDictionaryService,System.Type,System.Nullable{IRaCIS.Core.Domain.Share.CriterionType},IRaCIS.Core.Application.Service.ExcelExportHelper.DynamicColumnConfig)">
<summary>
暂时废弃--合并到上面
</summary>
<param name="code"></param>
<param name="data"></param>
<param name="_commonDocumentRepository"></param>
<param name="_hostEnvironment"></param>
<param name="_dictionaryService"></param>
<param name="translateType"></param>
<param name="criterionType"></param>
<param name="dynamicColumnConfig"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ExcelExportHelper.ExportTemplateAsync(IRaCIS.Application.Contracts.ExportTemplateServiceDto)">
<summary>
导出文件模板
@ -2421,12 +2407,6 @@
<param name="batchAddList"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.TrialEmailNoticeConfigService.TestSystemEmailConfigAsync">
<summary>
测试系统配置文件中的邮件配置
</summary>
<returns></returns>
</member>
<member name="T:IRaCIS.Core.Application.Service.TrialFileTypeService">
<summary>
项目文件类型
@ -3719,29 +3699,6 @@
<param name="code"></param>
<returns></returns>
</member>
<member name="T:IRaCIS.Core.Application.Service.MinimalApiService.FileToPDFService">
<summary>
上传文件转PDF 或者给url 这边下载然后转PDF
</summary>
<param name="_hostEnvironment"></param>
</member>
<member name="M:IRaCIS.Core.Application.Service.MinimalApiService.FileToPDFService.#ctor(Microsoft.AspNetCore.Hosting.IWebHostEnvironment)">
<summary>
上传文件转PDF 或者给url 这边下载然后转PDF
</summary>
<param name="_hostEnvironment"></param>
</member>
<!-- Badly formed XML comment ignored for member "T:IRaCIS.Core.Application.Service.MinimalApiService.TestMinimalApiService" -->
<!-- Badly formed XML comment ignored for member "M:IRaCIS.Core.Application.Service.MinimalApiService.TestMinimalApiService.#ctor(IRaCIS.Core.Domain.Share.IUserInfo,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Infra.EFCore.TestLength})" -->
<member name="M:IRaCIS.Core.Application.Service.MinimalApiService.TestMinimalApiService.TestEfcoreJson">
<summary>
测试efcore json 列支持情况
https://devblogs.microsoft.com/dotnet/array-mapping-in-ef-core-8/
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.HIRActivateService.GetAuthorizationCodeInfo(System.String,Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Application.Contracts.SystemHospitalOption})">
<summary>
获取授权码明文信息
@ -3904,6 +3861,15 @@
The ID token, which can be used to verify the identity of the user.
</summary>
</member>
<!-- Badly formed XML comment ignored for member "T:IRaCIS.Core.Application.Service.MinimalApiService.TestMinimalApiService" -->
<!-- Badly formed XML comment ignored for member "M:IRaCIS.Core.Application.Service.MinimalApiService.TestMinimalApiService.#ctor(IRaCIS.Core.Domain.Share.IUserInfo,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Infra.EFCore.TestLength})" -->
<member name="M:IRaCIS.Core.Application.Service.MinimalApiService.TestMinimalApiService.TestEfcoreJson">
<summary>
测试efcore json 列支持情况
https://devblogs.microsoft.com/dotnet/array-mapping-in-ef-core-8/
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.QCCommon.VerifyIsCRCSubmmitAsync(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Domain.Share.IUserInfo,System.Nullable{System.Guid})">
<summary>
验证CRC 是否已提交 已提交 就不允许进行任何操作如果是IQC 那么还验证是否是当前任务领取人
@ -9756,6 +9722,16 @@
融合的病灶
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetMarkListInDto.VisitTaskId">
<summary>
任务Id
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.NoneDicomMarkInfo.MarkId">
<summary>
标记的唯一标识符
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetCustomTagInDto.VisitTaskId">
<summary>
任务Id
@ -14844,6 +14820,20 @@
<param name="inQuery"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetMarkList(IRaCIS.Core.Application.Service.Reading.Dto.GetMarkListInDto)">
<summary>
获取标记信息
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetNoneDicomMarkList(IRaCIS.Core.Application.Service.Reading.Dto.GetMarkListInDto)">
<summary>
获取非DICOM标记信息
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.GetManualList(IRaCIS.Core.Application.Service.Reading.Dto.GetManualListInDto)">
<summary>
获取手册
@ -16079,6 +16069,12 @@
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.DoctorWorkloadService.GetDoctorUserTrialReadingStat(IRaCIS.Application.Contracts.TrialReadingStatQuery)">
<summary>
获取项目阅片统计
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.DoctorWorkloadService.GetTrialEnrollmentWorkloadStats(IRaCIS.Application.Contracts.WorkLoadDoctorQueryDTO)">
<summary>
获取某个项目入组的医生工作量统计列表
@ -17512,17 +17508,17 @@
</member>
<member name="F:IRaCIS.Core.Application.ViewModel.AccessToDialogueEnum.Question">
<summary>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
质疑
</summary>
</member>
<member name="F:IRaCIS.Core.Application.ViewModel.AccessToDialogueEnum.Consistency">
<summary>
һ<EFBFBD><EFBFBD><EFBFBD>Ժ˲<EFBFBD>
一致性核查
</summary>
</member>
<member name="T:IRaCIS.Core.Application.ViewModel.CopyFrontAuditConfigItemDto">
<summary>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
复制
</summary>
</member>
<member name="T:IRaCIS.Core.Application.ViewModel.SystemNoticeView">
@ -22106,5 +22102,49 @@
<member name="M:IRaCIS.Application.Interfaces.ITrialEnrollmentService.ConfirmReviewer(System.Guid,System.Guid[],System.Int32)">
<summary>入组流程-向CRO提交医生[Submit]</summary>
</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>
</doc>

View File

@ -1,27 +1,9 @@
using DocumentFormat.OpenXml.Office2013.Excel;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Vml;
using DocumentFormat.OpenXml.Wordprocessing;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain;
using IRaCIS.Core.Domain.BaseModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using MassTransit;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.Extensions.Options;
using MimeKit;
using NPOI.SS.Formula.Functions;
using NPOI.Util;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.MassTransit.Consumer;

View File

@ -1,10 +1,6 @@
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using IRaCIS.Core.Domain.BaseModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Domain.BaseModel;
using MassTransit;
using NPOI.SS.Formula.Functions;
using System.Globalization;
public class CultureInfoFilter<T> (IRepository<EventStoreRecord> _eventStoreRecordRepository) : IFilter<ConsumeContext<T>> where T : DomainEvent
{

View File

@ -1,5 +1,4 @@
using DocumentFormat.OpenXml;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Consumer;
@ -10,16 +9,8 @@ using MassTransit;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using MimeKit;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Reactive.Joins;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.MassTransit.Recurring
{

View File

@ -4,19 +4,13 @@
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share;
using MailKit;
using MailKit.Net.Imap;
using MailKit.Search;
using MailKit.Security;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using System.Text.RegularExpressions;
namespace IRaCIS.Core.Application.Contracts

View File

@ -1,27 +1,15 @@
using DocumentFormat.OpenXml.Spreadsheet;
using ClosedXML.Excel;
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infra.EFCore.Migrations;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using NPOI.HPSF;
using NPOI.POIFS.Properties;
using NPOI.SS.Formula.Functions;
using NPOI.XSSF.UserModel;
using System.ComponentModel.Design;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using static IRaCIS.Core.Application.Service.ExcelExportHelper;
@ -153,9 +141,9 @@ namespace IRaCIS.Core.Application.Service.Common
var dynamicColumnConfig = new DynamicColumnConfig()
{
AutoColumnTitleRowIndex = 2,
AutoColumnStartIndex = 7,
TempalteLastColumnIndex = 6,
AutoColumnTitleRowIndex = 3, //2
AutoColumnStartIndex = 8, //7
TempalteLastColumnIndex = 7, //6
DynamicItemDicName = "TranslateDicName",
DynamicItemValueName = "Answer",
DynamicItemTitleName = "QuestionName",
@ -167,7 +155,7 @@ namespace IRaCIS.Core.Application.Service.Common
};
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(StaticData.Export.TrialQCResult_Export, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCQuestionResult_Export), dynamicColumnConfig: dynamicColumnConfig);
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(StaticData.Export.TrialQCResult_Export, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCQuestionResult_Export), dynamicColumnConfig: dynamicColumnConfig);
return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
@ -1239,55 +1227,60 @@ namespace IRaCIS.Core.Application.Service.Common
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(StaticData.Export.TrialSubjectProgressList_Export, exportInfo, /*"", */_commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectProgressDto));
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(StaticData.Export.TrialSubjectProgressList_Export, exportInfo, /*"", */_commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectProgressDto));
// 使用NPOI 进行二次处理
var wb = new XSSFWorkbook(memoryStream);
var sheet = wb.GetSheetAt(0);
// 使用 ClosedXML 进行二次处理
using var workbook = new XLWorkbook(memoryStream);
var worksheet = workbook.Worksheet(1); // 获取第一个工作表索引从1开始
foreach (var subject in list)
{
var index = list.IndexOf(subject);
var row = sheet.GetRow(index + 4);
// ClosedXML 行索引从1开始原来 NPOI 从0开始所以 +1
var row = worksheet.Row(index + 4 + 1); // NPOI: index + 4, ClosedXML: +1 = index + 5
foreach (var item in subject.TotalList)
{
//从第五列开始动态写
var visitIndex = subject.TotalList.IndexOf(item) + 4;
// 从第五列开始动态写ClosedXML 列索引从1开始
var visitIndex = subject.TotalList.IndexOf(item) + 4 + 1; // NPOI: +4, ClosedXML: +1 = +5
var cell = row.CreateCell(visitIndex);
var cell = row.Cell(visitIndex);
if (item.IsLostVisit == true)
{
cell.CellStyle = sheet.GetRow(1).GetCell(7).CellStyle;
//cell.CellStyle = sheet.GetRow(1).GetCell(7).CellStyle;
// 复制样式 - ClosedXML 需要先获取源样式,然后应用到目标单元格
var sourceCell = worksheet.Row(2).Cell(8); // 原 NPOI: GetRow(1).GetCell(7) -> +1 转换
cell.Style = sourceCell.Style;
}
else
{
switch (item.ReadingStatus)
{
case ReadingStatusEnum.ImageNotSubmit:
cell.CellStyle = sheet.GetRow(1).GetCell(1).CellStyle;
cell.Style = worksheet.Row(2).Cell(2).Style; // NPOI: (1,1) -> ClosedXML: (2,2)
break;
case ReadingStatusEnum.ImageQuality:
cell.CellStyle = sheet.GetRow(1).GetCell(2).CellStyle;
cell.Style = worksheet.Row(2).Cell(3).Style; // (1,2) -> (2,3)
break;
case ReadingStatusEnum.ConsistencyCheck:
cell.CellStyle = sheet.GetRow(1).GetCell(3).CellStyle;
cell.Style = worksheet.Row(2).Cell(4).Style; // (1,3) -> (2,4)
break;
case ReadingStatusEnum.TaskAllocate:
cell.CellStyle = sheet.GetRow(1).GetCell(4).CellStyle;
cell.Style = worksheet.Row(2).Cell(5).Style;// (1,4) -> (2,5)
break;
case ReadingStatusEnum.ImageReading:
cell.CellStyle = sheet.GetRow(1).GetCell(5).CellStyle;
cell.Style = worksheet.Row(2).Cell(6).Style;// (1,5) -> (2,6)
break;
case ReadingStatusEnum.ReadCompleted:
cell.CellStyle = sheet.GetRow(1).GetCell(6).CellStyle;
cell.Style = worksheet.Row(2).Cell(7).Style; // (1,6) -> (2,7)
break;
default:
@ -1297,12 +1290,13 @@ namespace IRaCIS.Core.Application.Service.Common
cell.SetCellValue(item.TaskName);
cell.SetValue(item.TaskName);
}
}
// 保存到 MemoryStream
var memoryStream2 = new MemoryStream();
wb.Write(memoryStream2, true);
workbook.SaveAs(memoryStream2);
memoryStream2.Seek(0, SeekOrigin.Begin);
return new FileStreamResult(memoryStream2, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
@ -2709,9 +2703,10 @@ namespace IRaCIS.Core.Application.Service.Common
var dynamicColumnConfig = new DynamicColumnConfig()
{
//可读的列表名行索引,不是{{}} 模板行索引
AutoColumnTitleRowIndex = 2,
AutoColumnStartIndex = 5,
TempalteLastColumnIndex = 4,
AutoColumnTitleRowIndex = 3, //2
AutoColumnStartIndex = 6, //5
TempalteLastColumnIndex = 5, //4
DynamicItemDicName = "TranslateDicName",
DynamicItemValueName = "QuestionValue",
DynamicItemTitleName = "QuestionName",
@ -2722,7 +2717,7 @@ namespace IRaCIS.Core.Application.Service.Common
};
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(AnalysisDynamicCommonExport), criterion.CriterionType, dynamicColumnConfig);
var (memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(AnalysisDynamicCommonExport), criterion.CriterionType, dynamicColumnConfig);
return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
@ -2867,7 +2862,8 @@ namespace IRaCIS.Core.Application.Service.Common
if (!criterion.IsArbitrationReading)
{
//仲裁阅片 才有裁判阅片明细表 同时要把模板里面的三列给去掉
removeColumnIndexList = new List<int>() { 6, 7, 8 };
//removeColumnIndexList = new List<int>() { 6, 7, 8 };
removeColumnIndexList = new List<int>() { 7, 8 ,9};
}
//阅片结果表 和阅片结果明细表 没有肿瘤学的时候需要移除肿瘤学三个字段
@ -2876,7 +2872,8 @@ namespace IRaCIS.Core.Application.Service.Common
{
if (inQuery.ReadingExportType == ExportResult.TableOfAssessmentResults || inQuery.ReadingExportType == ExportResult.DetailedTableOfAssessmentResults)
{
removeColumnIndexList = removeColumnIndexList.Union(new List<int>() { 9, 10, 11 }).ToList();
//removeColumnIndexList = removeColumnIndexList.Union(new List<int>() { 9, 10, 11 }).ToList();
removeColumnIndexList = removeColumnIndexList.Union(new List<int>() { 10, 11, 12 }).ToList();
}
}
}
@ -2903,7 +2900,7 @@ namespace IRaCIS.Core.Application.Service.Common
//阅片结果表
export_Template = StaticData.Export.CommonReading_Export;
}
//斑块表
//斑块表
else if (inQuery.ReadingExportType == ExportResult.OCT_ReadingLession_Export)
{
//OCT
@ -3170,7 +3167,7 @@ namespace IRaCIS.Core.Application.Service.Common
addLessionInfoList.Add(new CommonQuesionInfo() { QuestionName = _userInfo.IsEn_Us ? "Lesion Type" : "病灶类型", QuestionValue = lession.LessionType, TranslateDicName = "LesionType" });
}
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionName = t.QuestionName, OptionTypeEnum = t.OptionTypeEnum, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName ,Unit=t.Unit});
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionName = t.QuestionName, OptionTypeEnum = t.OptionTypeEnum, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName, Unit = t.Unit });
//有三部分组成 外层问题+ 没有配置病灶编号和类型+ 动态的表格问题
var dynamicLessionInfoList = item.QuestionAnswerList.Union(addLessionInfoList).Union(dynamicPartialLessionInfoList).ToList();
@ -3358,9 +3355,10 @@ namespace IRaCIS.Core.Application.Service.Common
dynamicColumnConfig = new DynamicColumnConfig()
{
AutoColumnTitleRowIndex = 2,
AutoColumnStartIndex = 6,
TempalteLastColumnIndex = 11,
AutoColumnTitleRowIndex = 3, //2
AutoColumnStartIndex = 7, //6
TempalteLastColumnIndex = 12,//11
DynamicItemDicName = "TranslateDicName",
DynamicItemValueName = "QuestionValue",
DynamicItemTitleName = "QuestionName",
@ -3372,7 +3370,7 @@ namespace IRaCIS.Core.Application.Service.Common
TranslateDicNameList = translateDicNameList
};
if (export_Template == StaticData.Export.ReadingLession_Export || export_Template == StaticData.Export.CommonJudgeReadingDetail_Export || export_Template== StaticData.Export.OCT_ReadingLession_Export)
if (export_Template == StaticData.Export.ReadingLession_Export || export_Template == StaticData.Export.CommonJudgeReadingDetail_Export || export_Template == StaticData.Export.OCT_ReadingLession_Export)
{
dynamicColumnConfig.TempalteLastColumnIndex = 8;
}
@ -3391,7 +3389,7 @@ namespace IRaCIS.Core.Application.Service.Common
var trialConfigTableQuestionList = _trialReadingTableQuestionRepository.Where(t => t.TrialId == trialId && t.TrialCriterionId == trialReadingCriterionId).Where(t => t.ExportResultStr.Contains(((int)inQuery.ReadingExportType).ToString()))
.Select(t => new ExportQuestionBasicInfo()
{
QuestionId = t.Id,
QuestionId = t.Id,
TableName = _userInfo.IsEn_Us ? t.ReadingQuestionTrial.QuestionEnName : t.ReadingQuestionTrial.QuestionName,
QuestionName = _userInfo.IsEn_Us ? t.QuestionEnName : t.QuestionName,
CDISCCode = t.CDISCCode,
@ -3435,7 +3433,7 @@ namespace IRaCIS.Core.Application.Service.Common
var dynamicLessionInfoList = new List<CommonQuesionInfo>();
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionId = t.TableQuesionId,OptionTypeEnum=t.OptionTypeEnum, QuestionName = t.QuestionName, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName, CDISCCode = t.CDISCCode, Unit = t.Unit });
var dynamicPartialLessionInfoList = lession.LessionAnswerList.Select(t => new CommonQuesionInfo() { QuestionId = t.TableQuesionId, OptionTypeEnum = t.OptionTypeEnum, QuestionName = t.QuestionName, QuestionValue = t.QuestionValue, TranslateDicName = t.TranslateDicName, CDISCCode = t.CDISCCode, Unit = t.Unit });
//两部分组成 外层问题+ 动态的表格问题
dynamicLessionInfoList = item.QuestionAnswerList.Union(dynamicPartialLessionInfoList).ToList();
@ -3458,9 +3456,9 @@ namespace IRaCIS.Core.Application.Service.Common
dynamicColumnConfig = new DynamicColumnConfig()
{
AutoColumnTitleRowIndex = 1,
AutoColumnStartIndex = 6,
TempalteLastColumnIndex = 10,
AutoColumnTitleRowIndex = 2, //1
AutoColumnStartIndex = 7, //6
TempalteLastColumnIndex = 11, //10
DynamicItemDicName = "TranslateDicName",
DynamicItemValueName = "QuestionValue",
DynamicItemTitleName = "QuestionName",
@ -3543,9 +3541,9 @@ namespace IRaCIS.Core.Application.Service.Common
dynamicColumnConfig = new DynamicColumnConfig()
{
AutoColumnTitleRowIndex = 1,
AutoColumnStartIndex = 6,
TempalteLastColumnIndex = 15,
AutoColumnTitleRowIndex = 2, //1
AutoColumnStartIndex = 7, //6
TempalteLastColumnIndex = 16, //15
DynamicItemDicName = "TranslateDicName",
DynamicItemValueName = "QuestionValue",
DynamicItemTitleName = "QuestionName",
@ -3578,9 +3576,9 @@ namespace IRaCIS.Core.Application.Service.Common
dynamicColumnConfig = new DynamicColumnConfig()
{
AutoColumnTitleRowIndex = 1,
AutoColumnStartIndex = 6,
TempalteLastColumnIndex = 10,
AutoColumnTitleRowIndex = 2, //1
AutoColumnStartIndex = 7, //6
TempalteLastColumnIndex = 11, //10
DynamicItemDicName = "TranslateDicName",
DynamicItemValueName = "QuestionValue",
DynamicItemTitleName = "QuestionName",
@ -3650,12 +3648,12 @@ namespace IRaCIS.Core.Application.Service.Common
if (inQuery.ReadingExportType == ExportResult.NoneTumorCDISC)
{
(memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig);
(memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig);
}
else
{
(memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig);
(memoryStream, fileName) = await ExcelExportHelper.DataExport_ClosedXMLAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig);
}

View File

@ -1,26 +1,15 @@
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using MiniExcelLibs.OpenXml;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Asn1.X509;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service.Common;

View File

@ -1,32 +1,9 @@
using Amazon.Runtime.Internal.Transform;
using DocumentFormat.OpenXml.Bibliography;
using DocumentFormat.OpenXml.Office2010.CustomUI;
using DocumentFormat.OpenXml.Office2021.DocumentTasks;
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using MailKit;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;
using NetTopologySuite.Triangulate.Tri;
using NPOI.OpenXmlFormats.Spreadsheet;
using NPOI.SS.Formula.Functions;
using NPOI.Util;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static IRaCIS.Core.Application.Service.ExcelExportHelper;
namespace IRaCIS.Core.Application.Service.Common;

View File

@ -1,44 +1,22 @@
using Aliyun.OSS;
using CommunityToolkit.HighPerformance;
using DocumentFormat.OpenXml.EMMA;
using DocumentFormat.OpenXml.Office.CustomUI;
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.Office2013.Drawing.ChartStyle;
using FellowOakDicom;
using FellowOakDicom.Imaging;
using FellowOakDicom.Imaging.Render;
using FellowOakDicom.IO.Buffer;
using Hangfire.Common;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Medallion.Threading;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using NPOI.Util;
using Org.BouncyCastle.Utilities.Zlib;
using SharpCompress.Common;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO.Compression;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using static IRaCIS.Core.Application.Service.TestService;
using static IRaCIS.Core.Application.Service.TrialImageDownloadService;
using static IRaCIS.Core.Domain.Share.StaticData;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
namespace IRaCIS.Core.Application.Service
{
@ -63,7 +41,7 @@ namespace IRaCIS.Core.Application.Service
try
{
#region 方式一 有的必须在内存中,不能用这种
#region 方式一 有的多帧必须在内存中,不能用这种
//await using var source = await sourceFactory();
//// 如果你是从 stream 打开
//var dicomFile = await DicomFile.OpenAsync(source);
@ -242,6 +220,7 @@ namespace IRaCIS.Core.Application.Service
var skipCount = 0;
foreach (var downloadVisit in downloadVisits)
{
visitIndex++;
var downloadInfo = _trialRepository.Where(t => t.Id == trialId).Select(t => new
{
t.ResearchProgramNo,
@ -467,7 +446,7 @@ namespace IRaCIS.Core.Application.Service
var zipPath = Path.Combine(trialFolderPath, visitFolderName + ".zip");
Log.Logger.Warning($"[{visitIndex}] {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}开始打包下载访视:{visitFolderName}");
Log.Logger.Warning($"[{visitIndex}] {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 开始打包下载访视:{visitFolderName}");
try
{
@ -475,14 +454,14 @@ namespace IRaCIS.Core.Application.Service
//Log.Logger.Warning($"zip exists={File.Exists(zipPath)} size={new FileInfo(zipPath).Length}");
Log.Logger.Warning($"[{visitIndex}] {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}访视打包下载完成:{visitFolderName}");
Log.Logger.Warning($"[{visitIndex}] {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 下载完成:{visitFolderName}");
DownloadLogger.Write(logFilePath, visitItem.SubjectCode, visitItem.VisitNum, visitItem.VisitName, "Success");
}
catch (Exception ex)
{
Log.Logger.Warning($"出现异常{ex}删除压缩包:{visitFolderName}");
Log.Logger.Warning($"出现异常{ex}自动删除压缩包:{visitFolderName}");
//如果有异常,删除失败的压缩包
if (File.Exists(zipPath))
{

View File

@ -4,26 +4,10 @@
// 生成时间 2025-03-27 06:13:33Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure.Extention;
using System.Threading.Tasks;
using IRaCIS.Core.Infra.EFCore;
using AutoMapper.Execution;
using System.Linq;
using IRaCIS.Core.Infrastructure;
using DocumentFormat.OpenXml.Office2010.Excel;
using MassTransit;
using NPOI.POIFS.Properties;
using Org.BouncyCastle.Crypto;
using Microsoft.AspNetCore.Http;
using IRaCIS.Core.Application.Contracts;
using Microsoft.EntityFrameworkCore;
using static Microsoft.Extensions.Logging.EventSource.LoggingEventSource;
using NPOI.SS.Formula.Functions;
using EFCore.BulkExtensions;
namespace IRaCIS.Core.Application.Service;

View File

@ -20,8 +20,6 @@ namespace IRaCIS.Core.Application.Interfaces
Task<IResponseOutput> AddOrUpdateTrialEmailNoticeConfig(TrialEmailNoticeConfigAddOrEdit addOrEditTrialEmailNoticeConfig);
Task<IResponseOutput> TestSystemEmailConfigAsync();
Task<IResponseOutput> DeleteTrialEmailNoticeConfig(Guid trialEmailNoticeConfigId);
Task<string> BaseBusinessScenarioSendEmailAsync(Guid visitTaskId, bool? isMedicalReviewAndSuggestApplyReReading = null, EmailStoreSendMode emailStoreMode = EmailStoreSendMode.StoreLocalSend, string sendFileRelativePath = "");

View File

@ -5,18 +5,10 @@
//--------------------------------------------------------------------
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.MassTransit.Consumer;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using MassTransit.Mediator;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using NPOI.SS.Formula.Functions;
using System.Linq;
using System.Linq.Dynamic.Core;
namespace IRaCIS.Core.Application.Services

View File

@ -56,7 +56,6 @@ namespace IRaCIS.Core.Application.Service
/// <summary>
/// 获取项目邮箱
/// </summary>
@ -1808,9 +1807,6 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
private async Task TestEmailConfigAsync(TrialEmailNoticeConfigAddOrEdit config)
{
@ -1909,18 +1905,6 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
}
/// <summary>
/// 测试系统配置文件中的邮件配置
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> TestSystemEmailConfigAsync()
{
await SendEmailHelper.TestEmailConfigAsync(_systemEmailSendConfig.CurrentValue);
return ResponseOutput.Ok();
}
[TrialGlobalLimit("AfterStopCannNotOpt")]
[HttpDelete("{trialEmailNoticeConfigId:guid}")]
public async Task<IResponseOutput> DeleteTrialEmailNoticeConfig(Guid trialEmailNoticeConfigId)

View File

@ -1,31 +1,18 @@
using DocumentFormat.OpenXml.EMMA;
using FellowOakDicom;
using FellowOakDicom.Media;
using FellowOakDicom;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using MassTransit.Initializers;
using MathNet.Numerics;
using Medallion.Threading;
using Microsoft.AspNetCore.Mvc;
using NetTopologySuite.Mathematics;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using System.Data;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Web;
using ZiggyCreatures.Caching.Fusion;
namespace IRaCIS.Core.Application.Service.ImageAndDoc
{

View File

@ -3,15 +3,9 @@
// 生成时间 2021-12-06 10:54:55
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using DocumentFormat.OpenXml.EMMA;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using Medallion.Threading;
using Microsoft.AspNetCore.Mvc;
using NPOI.SS.Formula.Functions;
using System.ComponentModel.DataAnnotations;
namespace IRaCIS.Core.Application.Contracts

View File

@ -2,24 +2,14 @@
using FellowOakDicom.Imaging;
using FellowOakDicom.IO.Buffer;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MathNet.Numerics;
using Medallion.Threading;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;
using NetTopologySuite.Algorithm;
using SharpCompress.Common;
using SkiaSharp;
using System.Data;
using System.Drawing;
using ZiggyCreatures.Caching.Fusion;
namespace IRaCIS.Core.Application.Service.ImageAndDoc
{

View File

@ -1,16 +1,8 @@
using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Service.DTO;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Configuration;
using NPOI.HPSF;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service
{

View File

@ -1,137 +1,137 @@
using IRaCIS.Core.Application.Helper;
using MassTransit;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using RestSharp;
using SharpCompress.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//using IRaCIS.Core.Application.Helper;
//using MassTransit;
//using Microsoft.AspNetCore.Authorization;
//using Microsoft.AspNetCore.Builder;
//using Microsoft.AspNetCore.Hosting;
//using Microsoft.AspNetCore.Http;
//using Microsoft.AspNetCore.Mvc;
//using Microsoft.AspNetCore.StaticFiles;
//using RestSharp;
//using SharpCompress.Common;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service.MinimalApiService
{
/// <summary>
/// 上传文件转PDF 或者给url 这边下载然后转PDF
///
/// </summary>
/// <param name="_hostEnvironment"></param>
[ApiExplorerSettings(GroupName = "Institution")]
public class FileToPDFService(IWebHostEnvironment _hostEnvironment) : ServiceBase
{
//namespace IRaCIS.Core.Application.Service.MinimalApiService
//{
// /// <summary>
// /// 上传文件转PDF 或者给url 这边下载然后转PDF
// ///
// /// </summary>
// /// <param name="_hostEnvironment"></param>
// [ApiExplorerSettings(GroupName = "Institution")]
// public class FileToPDFService(IWebHostEnvironment _hostEnvironment) : ServiceBase
// {
[AllowAnonymous]
[RoutePattern(HttpMethod = "Post")]
public async Task<IResult> UploadFileAsync([FromForm] IFormFile file)
{
var tempFileName = NewId.NextGuid() + file.FileName;
var tempPDFName = Path.GetFileNameWithoutExtension(tempFileName) + ".pdf";
// [AllowAnonymous]
// [RoutePattern(HttpMethod = "Post")]
// public async Task<IResult> UploadFileAsync([FromForm] IFormFile file)
// {
// var tempFileName = NewId.NextGuid() + file.FileName;
// var tempPDFName = Path.GetFileNameWithoutExtension(tempFileName) + ".pdf";
// 获取wwwroot目录
var wwwRootPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "temp");
// // 获取wwwroot目录
// var wwwRootPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "temp");
// 检查wwwroot/temp目录是否存在不存在则创建
if (!Directory.Exists(wwwRootPath))
{
Directory.CreateDirectory(wwwRootPath);
}
// // 检查wwwroot/temp目录是否存在不存在则创建
// if (!Directory.Exists(wwwRootPath))
// {
// Directory.CreateDirectory(wwwRootPath);
// }
// 文件保存路径
var pdfFilePath = Path.Combine(wwwRootPath, tempPDFName);
var tempFilePath = Path.Combine(wwwRootPath, tempFileName);
// // 文件保存路径
// var pdfFilePath = Path.Combine(wwwRootPath, tempPDFName);
// var tempFilePath = Path.Combine(wwwRootPath, tempFileName);
using var stream = File.OpenWrite(tempFilePath);
await file.CopyToAsync(stream);
// using var stream = File.OpenWrite(tempFilePath);
// await file.CopyToAsync(stream);
FileConvertHelper.ConvertWordToPdf(tempFilePath, Path.GetDirectoryName(pdfFilePath));
// FileConvertHelper.ConvertWordToPdf(tempFilePath, Path.GetDirectoryName(pdfFilePath));
var fileBytes = await File.ReadAllBytesAsync(pdfFilePath);
// var fileBytes = await File.ReadAllBytesAsync(pdfFilePath);
// 清理临时上传的文件和pdf
if (File.Exists(pdfFilePath))
{
File.Delete(pdfFilePath);
}
if (File.Exists(tempFilePath))
{
File.Delete(tempFilePath);
}
// // 清理临时上传的文件和pdf
// if (File.Exists(pdfFilePath))
// {
// File.Delete(pdfFilePath);
// }
// if (File.Exists(tempFilePath))
// {
// File.Delete(tempFilePath);
// }
new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(tempPDFName), out var contentType);
// new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(tempPDFName), out var contentType);
return Results.File(fileBytes, contentType);
// return Results.File(fileBytes, contentType);
}
// }
public async Task<IResult> GetPDFFileAsync(string fileUrl)
{
var tempFileName = NewId.NextGuid() + Path.GetFileName(fileUrl);
var tempPDFName = Path.GetFileNameWithoutExtension(tempFileName) + ".pdf";
// public async Task<IResult> GetPDFFileAsync(string fileUrl)
// {
// var tempFileName = NewId.NextGuid() + Path.GetFileName(fileUrl);
// var tempPDFName = Path.GetFileNameWithoutExtension(tempFileName) + ".pdf";
// 获取wwwroot目录
var wwwRootPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "temp");
// // 获取wwwroot目录
// var wwwRootPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "temp");
// 检查wwwroot/temp目录是否存在不存在则创建
if (!Directory.Exists(wwwRootPath))
{
Directory.CreateDirectory(wwwRootPath);
}
// // 检查wwwroot/temp目录是否存在不存在则创建
// if (!Directory.Exists(wwwRootPath))
// {
// Directory.CreateDirectory(wwwRootPath);
// }
// 文件保存路径
var pdfFilePath = Path.Combine(wwwRootPath, tempPDFName);
var tempFilePath = Path.Combine(wwwRootPath, tempFileName);
// // 文件保存路径
// var pdfFilePath = Path.Combine(wwwRootPath, tempPDFName);
// var tempFilePath = Path.Combine(wwwRootPath, tempFileName);
//请求url获取文件
var client = new RestClient(fileUrl);
// //请求url获取文件
// var client = new RestClient(fileUrl);
var request = new RestRequest(fileUrl, Method.Get);
// var request = new RestRequest(fileUrl, Method.Get);
var response = await client.ExecuteAsync(request);
// var response = await client.ExecuteAsync(request);
// 检查响应是否成功
if (response.IsSuccessful)
{
// 将响应内容写入到本地文件
await File.WriteAllBytesAsync(tempFilePath, response.RawBytes);
// // 检查响应是否成功
// if (response.IsSuccessful)
// {
// // 将响应内容写入到本地文件
// await File.WriteAllBytesAsync(tempFilePath, response.RawBytes);
FileConvertHelper.ConvertWordToPdf(tempFilePath, Path.GetDirectoryName(pdfFilePath));
// FileConvertHelper.ConvertWordToPdf(tempFilePath, Path.GetDirectoryName(pdfFilePath));
var fileBytes = await File.ReadAllBytesAsync(pdfFilePath);
// var fileBytes = await File.ReadAllBytesAsync(pdfFilePath);
// 清理临时上传的文件和pdf
if (File.Exists(pdfFilePath))
{
File.Delete(pdfFilePath);
}
if (File.Exists(tempFilePath))
{
File.Delete(tempFilePath);
}
// // 清理临时上传的文件和pdf
// if (File.Exists(pdfFilePath))
// {
// File.Delete(pdfFilePath);
// }
// if (File.Exists(tempFilePath))
// {
// File.Delete(tempFilePath);
// }
new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(tempPDFName), out var contentType);
// new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(tempPDFName), out var contentType);
return Results.File(fileBytes, contentType);
}
else
{
Console.WriteLine($"下载文件失败: {response.ErrorMessage}");
// return Results.File(fileBytes, contentType);
// }
// else
// {
// Console.WriteLine($"下载文件失败: {response.ErrorMessage}");
return Results.Problem("下载文件失败", statusCode: StatusCodes.Status500InternalServerError);
// return Results.Problem("下载文件失败", statusCode: StatusCodes.Status500InternalServerError);
}
// }
}
// }
}
}
// }
//}

View File

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

View File

@ -1,15 +1,10 @@
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit.Initializers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using NPOI.SS.Formula.Functions;
using System.Linq;
namespace IRaCIS.Core.Application.Image.QA
{
@ -45,8 +40,10 @@ namespace IRaCIS.Core.Application.Image.QA
public async Task<IResponseOutput<PageOutput<ImageBackViewModel>>> GetImageBackList(ImageBackQueryDto inQuery)
{
var svExpression = QCCommon.GetSubjectVisitImageBackRecordFilter(inQuery.VisitPlanArray);
var isCRC = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA;
var query = _subjectVisitImageBackRecordReposiotry.Where(t => t.SubjectVisit.TrialId == inQuery.TrialId)
.WhereIf(isCRC == true, t => t.SubjectVisit.Trial.TrialSiteUserList.Any(t => t.UserId == _userInfo.UserRoleId))
.WhereIf(inQuery.TrialSiteId != null, t => t.SubjectVisit.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode))
.WhereIf(!string.IsNullOrEmpty(inQuery.VisitName), t => t.SubjectVisit.VisitName.Contains(inQuery.VisitName))

View File

@ -1,14 +1,8 @@
using AutoMapper;
using AutoMapper.EquivalencyExpression;
using AutoMapper.EquivalencyExpression;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Migrations;
using NPOI.SS.Formula.Functions;
using System.Linq;
namespace IRaCIS.Core.Application.Service
{

View File

@ -192,6 +192,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public class GetReadingReportEvaluationOutDto
{
public Guid? VisitTaskId { get; set; }
public object ReportCalculateResult { get; set; }
@ -452,6 +453,58 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public List<AdditionalQuestionAnswer> AnswerList { get; set; } = new List<AdditionalQuestionAnswer>();
}
public class GetMarkListInDto
{
/// <summary>
/// 任务Id
/// </summary>
public Guid VisitTaskId { get; set; }
}
public class MarkListInfo
{
public string MeasureData { get; set; } = string.Empty;
public string PicturePath { get; set; } = string.Empty;
public Guid? InstanceId { get; set; }
public Guid? SeriesId { get; set; }
public Guid? StudyId { get; set; }
public string MarkName { get; set; } = string.Empty;
public string StudyInstanceUid { get; set; }
public string SopInstanceUid { get; set; }
public int NumberOfFrames { get; set; }
}
public class NoneDicomMarkInfo
{
public Guid? StudyId { get; set; }
public Guid? NoneDicomFileId { get; set; }
public string Path { get; set; }
public string PicturePath { get; set; } = string.Empty;
public string MeasureData { get; set; } = string.Empty;
public string MarkTool { get; set; }
public string MarkName { get; set; }
public string FileName { get; set; } = string.Empty;
/// <summary>
/// 标记的唯一标识符
/// </summary>
public Guid? MarkId { get; set; }
}
public class GetCustomTagInDto
{
/// <summary>
@ -544,6 +597,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public string Value { get; set; }
public string DictionaryCode { get; set; }
public bool IsHighlight { get; set; } = false;
}
public class ChartItem

View File

@ -1,16 +1,12 @@
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using Panda.DynamicWebApi.Attributes;
using System.Reflection;
using System.Text;

View File

@ -1,31 +1,19 @@
using Amazon.Runtime.Internal.Transform;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments;
using DocumentFormat.OpenXml;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.ImageAndDoc;
using IRaCIS.Core.Application.Service.OAuth;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.Service.ReadingCalculate.Interface;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using NPOI.POIFS.Properties;
using NPOI.SS.Formula.Functions;
using Panda.DynamicWebApi.Attributes;
using System.Linq;
using ZiggyCreatures.Caching.Fusion;
namespace IRaCIS.Core.Application.Service
{
@ -452,6 +440,81 @@ namespace IRaCIS.Core.Application.Service
return result;
}
/// <summary>
/// 获取标记信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<MarkListInfo>> GetMarkList(GetMarkListInDto inDto)
{
var questionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId&&x.InstanceId!=null)
.Select(x => new MarkListInfo() {
MeasureData = x.MeasureData,
PicturePath = x.PicturePath,
InstanceId = x.InstanceId,
SeriesId = x.SeriesId,
StudyId = x.StudyId,
MarkName= x.OrderMarkName,
SopInstanceUid = x.Instance.SopInstanceUid,
StudyInstanceUid = x.Instance.StudyInstanceUid,
NumberOfFrames= x.Instance.NumberOfFrames,
}).ToListAsync();
var rowMarkList=await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.InstanceId != null)
.Select(x => new MarkListInfo()
{
MeasureData = x.MeasureData,
PicturePath = x.PicturePath,
InstanceId = x.InstanceId,
SeriesId = x.SeriesId,
StudyId = x.StudyId,
MarkName = x.RowMark,
SopInstanceUid = x.Instance.SopInstanceUid,
StudyInstanceUid = x.Instance.StudyInstanceUid,
NumberOfFrames = x.Instance.NumberOfFrames,
}).ToListAsync();
return questionMarkList.Union(rowMarkList).ToList();
}
/// <summary>
/// 获取非DICOM标记信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<NoneDicomMarkInfo>> GetNoneDicomMarkList(GetMarkListInDto inDto)
{
var markList = await _readingNoneDicomMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).Include(x => x.NoneDicomStudyFile)
.Select(x => new NoneDicomMarkInfo()
{
StudyId = x.StudyId,
NoneDicomFileId = x.NoneDicomFileId,
Path = x.Path,
PicturePath = x.PicturePath,
MeasureData = x.MeasureData,
MarkTool = x.MarkTool,
MarkName = x.OrderMarkName,
FileName = x.NoneDicomStudyFile==null? string.Empty: x.NoneDicomStudyFile.FileName,
MarkId = x.MarkId,
}).ToListAsync();
return markList;
}
/// <summary>
/// 获取手册
/// </summary>

View File

@ -1,12 +1,8 @@
using DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using Microsoft.AspNetCore.Mvc;
using NPOI.POIFS.Properties;
using Panda.DynamicWebApi.Attributes;
using System.Collections.Generic;
namespace IRaCIS.Core.Application.Service
{

View File

@ -527,7 +527,7 @@ namespace IRaCIS.Core.Application.Service
var subjectVisitQuery = _subjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId)/*.Where(t => t.IsLostVisit == false)*/
.Where(t => t.Subject.IsSubjectQuit == false || (t.Subject.IsSubjectQuit == true && t.SubmitState == SubmitStateEnum.Submitted))
.Where(sv => sv.Subject.FinalSubjectVisitId == null ? true : sv.VisitNum <= sv.Subject.LatestSubjectVisit.VisitNum).Select(sv => new ReadModuleView()
.Where(sv => sv.Subject.FinalSubjectVisitId == null ? true : sv.VisitNum <= sv.Subject.FinalSubjectVisit.VisitNum).Select(sv => new ReadModuleView()
{
Id = sv.Id,
CreateTime = sv.CreateTime,

View File

@ -1,14 +1,9 @@
using DocumentFormat.OpenXml.Drawing;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using NPOI.Util;
namespace IRaCIS.Core.Application.Service
{

View File

@ -30,6 +30,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
IRepository<OrganInfo> _organInfoRepository,
IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository,
IRepository<ReadingJudgeInfo> _readingJudgeInfoRepository,
IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<TumorAssessment_IRECIST1Point1> _tumorAssessmentRepository,
IGeneralCalculateService _generalCalculateService,
@ -508,12 +509,14 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
TrialId = task.TrialId,
VisitTaskId = task.Id,
});
data.VisitTaskId= task.Id;
}
return data;
}
EvaluationColumn BuildEvaluationTable(GetReadingReportEvaluationOutDto r1, GetReadingReportEvaluationOutDto r2)
async Task<EvaluationColumn> BuildEvaluationTable(GetReadingReportEvaluationOutDto r1, GetReadingReportEvaluationOutDto r2)
{
EvaluationColumn result = new EvaluationColumn()
{
@ -537,6 +540,54 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
break;
}
Arm? highlightArm = null;
ArbitrationRule? highlightRule = null;
decimal? highlightVisitTaskNum = null;
if (r1.VisitTaskId != null && r2.VisitTaskList != null)
{
var judgeInfo =await _visitTaskRepository.Where(x => x.SubjectId == inDto.SubjectId && x.TrialReadingCriterionId == inDto.TrialCriterionId
&& x.TaskState == TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned
&& x.ReadingCategory== ReadingCategory.Judge
).OrderByDescending(x => x.VisitTaskNum).Include(x=>x.JudgeResultTask).FirstOrDefaultAsync();
if (judgeInfo != null && judgeInfo.JudgeResultTask != null)
{
if (judgeInfo.JudgeResultTask.ArmEnum == Arm.DoubleReadingArm1
|| judgeInfo.JudgeResultTask.ArmEnum == Arm.DoubleReadingArm2)
{
highlightArm = judgeInfo.JudgeResultTask.ArmEnum;
highlightRule = criterion.ArbitrationRule;
highlightVisitTaskNum = judgeInfo.VisitTaskNum;
}
}
}
void SetHighlight(List<EvaluationValue> data, Arm arm)
{
if (highlightArm != arm || highlightVisitTaskNum == null)
{
return;
}
if (highlightRule == ArbitrationRule.Reading)
{
for (var index = 0; index < data.Count && index < highlightVisitTaskNum.Value; index++)
{
data[index].IsHighlight = true;
}
}
else if (highlightRule == ArbitrationRule.Visit)
{
var index = decimal.ToInt32(decimal.Floor(highlightVisitTaskNum.Value));
if (index >= 0 && index < data.Count)
{
data[index].IsHighlight = true;
}
}
}
result.Evaluation.Add(visitTaskName.Select(x => new EvaluationValue()
@ -570,6 +621,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
r1data = r1data.Concat(Enumerable.Repeat(new EvaluationValue() { Value = "" }, length))
.Take(length)
.ToList();
SetHighlight(r1data, Arm.DoubleReadingArm1);
result.Evaluation.Add(r1data);
@ -601,6 +653,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
r2data = r2data.Concat(Enumerable.Repeat(new EvaluationValue() { Value = "" }, length))
.Take(length)
.ToList();
SetHighlight(r2data, Arm.DoubleReadingArm2);
result.Evaluation.Add(r2data);
}
@ -679,7 +732,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
}
result.Evaluation = BuildEvaluationTable(r1Data, r2Data);
result.Evaluation =await BuildEvaluationTable(r1Data, r2Data);
if (r1Data != null)
{
var r1Target = await BuildTargetChart(r1Data, Arm.DoubleReadingArm1);

View File

@ -1,18 +1,11 @@
using DocumentFormat.OpenXml.EMMA;
using DocumentFormat.OpenXml.Presentation;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using MathNet.Numerics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using MiniExcelLibs;
using System;
namespace IRaCIS.Core.Application.Service.ReadingCalculate
{

View File

@ -1,11 +1,8 @@
using DocumentFormat.OpenXml.EMMA;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using NPOI.Util;
namespace IRaCIS.Core.Application.Service.ReadingCalculate
{

View File

@ -3,36 +3,17 @@
// 生成时间 2021-12-23 13:20:59
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Vml.Spreadsheet;
using IdentityModel;
using IdentityModel.OidcClient;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.Service.OAuth;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Medallion.Threading;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.VisualBasic;
using MimeKit;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using Panda.DynamicWebApi.Attributes;
using StackExchange.Redis;
using System.Security.Policy;
using System.Text.RegularExpressions;
using static MassTransit.ValidationResultExtensions;
namespace IRaCIS.Core.Application.Contracts
{

View File

@ -1,17 +1,8 @@
using FellowOakDicom;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit.Serialization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Storage.Json;
using NPOI.SS.Formula.Functions;
using System;
namespace IRaCIS.Core.Application.Service
{

View File

@ -1,19 +1,11 @@
using DocumentFormat.OpenXml.Office2010.ExcelAc;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using NPOI.SS.Formula.Functions;
using Panda.DynamicWebApi.Attributes;
using ZiggyCreatures.Caching.Fusion;
using static IRaCIS.Core.Domain.Share.StaticData;
namespace IRaCIS.Core.Application.Service
{

View File

@ -1,16 +1,6 @@
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infra.EFCore.Common;
using Microsoft.AspNetCore.Mvc;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static IRaCIS.Core.Application.Service.ExcelExportHelper;
namespace IRaCIS.Core.Application;

View File

@ -90,6 +90,7 @@ namespace IRaCIS.Application.Contracts
public class SubjectQueryView : SubjectCommand
{
public bool IsHaveTaskFinished { get; set; }
public DateTime? OutEnrollmentTime { get; set; }
public DateTime? VisitOverTime { get; set; }

View File

@ -39,6 +39,7 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode))
.ForMember(d => d.LatestBlindName, u => u.MapFrom(s => s.LatestSubjectVisit.BlindName))
.ForMember(d => d.LatestVisitName, u => u.MapFrom(s => s.LatestSubjectVisit.VisitName))
.ForMember(d => d.IsHaveTaskFinished, u => u.MapFrom(s => s.SubjectVisitTaskList.Any(t => t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned)))
//.ForMember(d => d.FinalSubjectVisitId, u => u.MapFrom(s => s.SubjectVisitList.Where(t => t.IsFinalVisit).Select(c => (Guid?)c.Id).FirstOrDefault()))

View File

@ -177,6 +177,17 @@ namespace IRaCIS.Application.Contracts
public bool IsEnable { get; set; }
}
public class TrialReadingStatQuery
{
[NotDefault]
public Guid TrialId { get; set; }
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
public List<Guid?> DoctorUserIdList { get; set; } = new List<Guid?>();
}
public class WorkLoadDoctorQueryDTO : PageInput
{
@ -212,7 +223,7 @@ namespace IRaCIS.Application.Contracts
public class WorkLoadAndTrainingDTO
{
public Guid? DoctorUserId { get; set; }
public Guid DoctorId { get; set; }/*=Guid.Empty;*/
public string Code { get; set; } = String.Empty;
public string FirstName { get; set; } = String.Empty;
@ -356,6 +367,7 @@ namespace IRaCIS.Application.Contracts
public class DoctorTaskStat
{
public Guid? DoctorUserId { get; set; }
public CriterionType? CriterionType { get; set; }
public Guid TrialReadingCriterionId { get; set; }

View File

@ -193,6 +193,58 @@ namespace IRaCIS.Core.Application.Service
return ResponseOutput.Result(success2);
}
/// <summary>
/// 获取项目阅片统计
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<List<DoctorTaskStat>> GetDoctorUserTrialReadingStat(TrialReadingStatQuery inQuery)
{
var list = _enrollRepository.Where(x => x.TrialId == inQuery.TrialId && x.EnrollStatus >= EnrollStatus.ConfirmIntoGroup)
.WhereIf(inQuery.DoctorUserIdList.Count > 0, t => inQuery.DoctorUserIdList.Contains(t.DoctorUserId))
.SelectMany(t => t.DoctorUser.VisitTaskList.Where(t => t.TrialReadingCriterion.IsConfirm && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.Where(x => x.TaskState == TaskState.Effect && x.TrialId == inQuery.TrialId))
.GroupBy(x => new { x.TrialReadingCriterionId, x.TrialReadingCriterion.CriterionType, x.DoctorUserId })
.Select(g => new DoctorTaskStat()
{
DoctorUserId = g.Key.DoctorUserId,
PendingCount = g.Count(x => x.ReadingTaskState != ReadingTaskState.HaveSigned),
TotalCount = g.Count(),
ComplectedCount = g.Count(x => x.ReadingTaskState == ReadingTaskState.HaveSigned),
TrialReadingCriterionId = g.Key.TrialReadingCriterionId,
CriterionType = g.Key.CriterionType,
}).ToList();
// 获取所有符合条件的医生ID
var allDoctorIds = _enrollRepository
.Where(x => x.TrialId == inQuery.TrialId
&& x.EnrollStatus >= EnrollStatus.ConfirmIntoGroup)
.WhereIf(inQuery.DoctorUserIdList.Count > 0,
t => inQuery.DoctorUserIdList.Contains(t.DoctorUserId))
.Select(x => x.DoctorUserId)
.Distinct()
.ToList();
// 补全缺失的医生记录
var missingDoctors = allDoctorIds
.Except(list.Select(r => r.DoctorUserId))
.Select(doctorId => new DoctorTaskStat()
{
DoctorUserId = doctorId,
PendingCount = 0,
TotalCount = 0,
ComplectedCount = 0,
TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
})
.ToList();
list.AddRange(missingDoctors);
return list;
}
/// <summary>
/// 获取某个项目入组的医生工作量统计列表
/// </summary>
@ -254,6 +306,8 @@ namespace IRaCIS.Core.Application.Service
//}).ToList(),
DoctorUserId = intoGroup.DoctorUserId,
DoctorId = doctor.Id,
Code = doctor.ReviewerCode,
FirstName = doctor.FirstName,

View File

@ -20,7 +20,6 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MiniExcelLibs;
using Newtonsoft.Json;
using NPOI.XWPF.UserModel;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing;
@ -50,6 +49,7 @@ namespace IRaCIS.Core.Application.Service
IRepository<DicomSeries> _dicomSeriesRepository,
IRepository<UserRole> _userRoleRepository,
IRepository<TrialBodyPart> _trialBodyPartRepository,
IRepository<SubjectVisit> _subjectVisitRepository,
IOSSService _IOSSService,
IDistributedLockProvider _distributedLockProvider,
ILogger<TestService> _logger, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService
@ -57,6 +57,7 @@ namespace IRaCIS.Core.Application.Service
public static int IntValue = 100;
public class ModelVerifyCommand
{
public int? IntNUllValue { get; set; }
@ -220,72 +221,72 @@ namespace IRaCIS.Core.Application.Service
#region 数据库查询
// var downloadInfo = _trialRepository.Where(t => t.Id == trialId).Select(t => new
// {
// t.ResearchProgramNo,
// t.TrialCode,
// var downloadInfo = _trialRepository.Where(t => t.Id == trialId).Select(t => new
// {
// t.ResearchProgramNo,
// t.TrialCode,
// VisitList = t.SubjectVisitList.Where(t => t.VisitTaskList.Any(t => t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.SourceSubjectVisitId != null && t.DoctorUserId != null))
// //.Where(t=>subjectCodeList.Contains(t.Subject.Code))
// .Select(sv => new
// {
// SubjectVisitId = sv.Id,
// TrialSiteCode = sv.TrialSite.TrialSiteCode,
// SubjectCode = sv.Subject.Code,
// VisitName = sv.VisitName,
// VisitNum = sv.VisitNum,
// StudyList = sv.StudyList.Select(u => new
// {
// StudyId = u.Id,
// u.PatientId,
// u.StudyTime,
// u.StudyCode,
// u.StudyInstanceUid,
// u.StudyDIRPath,
// VisitList = t.SubjectVisitList.Where(t => t.VisitTaskList.Any(t => t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.SourceSubjectVisitId != null && t.DoctorUserId != null))
// //.Where(t=>subjectCodeList.Contains(t.Subject.Code))
// .Select(sv => new
// {
// SubjectVisitId = sv.Id,
// TrialSiteCode = sv.TrialSite.TrialSiteCode,
// SubjectCode = sv.Subject.Code,
// VisitName = sv.VisitName,
// VisitNum = sv.VisitNum,
// StudyList = sv.StudyList.Select(u => new
// {
// StudyId = u.Id,
// u.PatientId,
// u.StudyTime,
// u.StudyCode,
// u.StudyInstanceUid,
// u.StudyDIRPath,
// SeriesList = u.SeriesList.Where(t => t.IsReading).Select(z => new
// {
// z.Modality,
// SeriesList = u.SeriesList.Where(t => t.IsReading).Select(z => new
// {
// z.Modality,
// InstancePathList = z.DicomInstanceList.Where(t => t.IsReading).Select(k => new
// {
// InstanceId = k.Id,
// k.Path,
// k.IsEncapsulated,
// k.NumberOfFrames,
// }).ToList()
// })
// InstancePathList = z.DicomInstanceList.Where(t => t.IsReading).Select(k => new
// {
// InstanceId = k.Id,
// k.Path,
// k.IsEncapsulated,
// k.NumberOfFrames,
// }).ToList()
// })
// }).ToList(),
// }).ToList(),
// NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => t.IsReading).Select(nd => new
// {
// nd.Modality,
// nd.StudyCode,
// nd.ImageDate,
// NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => t.IsReading).Select(nd => new
// {
// nd.Modality,
// nd.StudyCode,
// nd.ImageDate,
// FileList = nd.NoneDicomFileList.Where(t => t.IsReading).Select(file => new
// {
// file.FileName,
// file.Path,
// file.FileType
// }).ToList()
// }).ToList()
// }).OrderBy(t => t.SubjectCode).ThenBy(t => t.VisitNum).ToList()
// FileList = nd.NoneDicomFileList.Where(t => t.IsReading).Select(file => new
// {
// file.FileName,
// file.Path,
// file.FileType
// }).ToList()
// }).ToList()
// }).OrderBy(t => t.SubjectCode).ThenBy(t => t.VisitNum).ToList()
// }).FirstOrDefault();
// }).FirstOrDefault();
// var acturalDownList = downloadInfo.VisitList.Where(t => !oldVisits.Any(old => old.VisitNum == t.VisitNum && old.SubjectCode == t.SubjectCode &&
//old.VisitName.Trim().ToLower() == t.VisitName.Trim().ToLower())).ToList();
// var acturalDownList = downloadInfo.VisitList.Where(t => !oldVisits.Any(old => old.VisitNum == t.VisitNum && old.SubjectCode == t.SubjectCode &&
//old.VisitName.Trim().ToLower() == t.VisitName.Trim().ToLower())).ToList();
// var diffList = downloadVisit.Where(t => !acturalDownList.Any(old => old.SubjectCode.Trim() == t.SubjectCode.Trim() &&
//old.VisitName.Trim().ToLower() == t.VisitName.Trim().ToLower())).ToList();
// var diffList = downloadVisit.Where(t => !acturalDownList.Any(old => old.SubjectCode.Trim() == t.SubjectCode.Trim() &&
//old.VisitName.Trim().ToLower() == t.VisitName.Trim().ToLower())).ToList();
// string diffPath = @$"C:\Users\PC\Desktop\diff.xlsx";
// MiniExcel.SaveAs(diffPath, diffList);
// string diffPath = @$"C:\Users\PC\Desktop\diff.xlsx";
// MiniExcel.SaveAs(diffPath, diffList);
#endregion
@ -295,8 +296,12 @@ namespace IRaCIS.Core.Application.Service
//创建一个模型验证的方法
[AllowAnonymous]
[HttpPost("{email}")]
public async Task<IResponseOutput> PostModelVerify(ModelVerifyCommand modelVerify)
public async Task<IResponseOutput> PostModelVerify(/*ModelVerifyCommand modelVerify,*/ Guid subjectVisitId)
{
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).Include(x => x.CurrentActionUser).FirstNotNullAsync();
var subjectVisit2 = await (_subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x => x.Subject).Include(x => x.CurrentActionUser)).FirstNotNullAsync();
var webhook = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=cdd97aab-d256-4f07-9145-a0a2b1555322";
//await WeComNotifier.SendErrorAsync(webhook, "http://irc.test.extimaging.com/login", new Exception("测试异常"), new[] { "ZhouHang" });
@ -1418,113 +1423,113 @@ namespace IRaCIS.Core.Application.Service
[AllowAnonymous]
public async Task<string> testDoc([FromServices] IWebHostEnvironment env, string email)
{
#region DocX 测试
//using (DocX document = DocX.Load("C:\\Users\\hang\\Desktop\\test.docx"))
//{
// // 查找书签
// var bookmarkCn_Start = document.Bookmarks.FirstOrDefault(b => b.Name == "zh_cn");
// var bookmarkEn_Start = document.Bookmarks.FirstOrDefault(b => b.Name == "en_us");
//[AllowAnonymous]
//public async Task<string> testDoc([FromServices] IWebHostEnvironment env, string email)
//{
// #region DocX 测试
// //using (DocX document = DocX.Load("C:\\Users\\hang\\Desktop\\test.docx"))
// //{
// // // 查找书签
// // var bookmarkCn_Start = document.Bookmarks.FirstOrDefault(b => b.Name == "zh_cn");
// // var bookmarkEn_Start = document.Bookmarks.FirstOrDefault(b => b.Name == "en_us");
// if (bookmarkCn_Start != null && bookmarkEn_Start != null)
// {
// // 获取书签的起始位置
// int bookmarkCNStartPos = bookmarkCn_Start.Paragraph.StartIndex;
// // if (bookmarkCn_Start != null && bookmarkEn_Start != null)
// // {
// // // 获取书签的起始位置
// // int bookmarkCNStartPos = bookmarkCn_Start.Paragraph.StartIndex;
// var bookmarkENStartPos = bookmarkEn_Start.Paragraph.StartIndex;
// // var bookmarkENStartPos = bookmarkEn_Start.Paragraph.StartIndex;
// // // 创建一个要删除段落的列表
// List<Paragraph> paragraphsToRemove = new List<Paragraph>();
// // // // 创建一个要删除段落的列表
// // List<Paragraph> paragraphsToRemove = new List<Paragraph>();
// foreach (var item in document.Paragraphs)
// {
// // foreach (var item in document.Paragraphs)
// // {
// //中文模板在前,英文在后,英文模板,就删除英文之前的,中文模板就删除英文之后的
// //_userInfo.IsEn_Us? item.EndIndex< bookmarkENStartPos :item.StartIndex>= bookmarkENStartPos
// if (item.StartIndex>= bookmarkENStartPos)
// {
// paragraphsToRemove.Add(item);
// // //中文模板在前,英文在后,英文模板,就删除英文之前的,中文模板就删除英文之后的
// // //_userInfo.IsEn_Us? item.EndIndex< bookmarkENStartPos :item.StartIndex>= bookmarkENStartPos
// // if (item.StartIndex>= bookmarkENStartPos)
// // {
// // paragraphsToRemove.Add(item);
// }
// }
// // }
// // }
// foreach (var paragraph in paragraphsToRemove)
// {
// document.RemoveParagraph(paragraph);
// }
// // foreach (var paragraph in paragraphsToRemove)
// // {
// // document.RemoveParagraph(paragraph);
// // }
// }
// // }
// // 保存修改
// document.SaveAs("C:\\Users\\hang\\Desktop\\test1.docx");
//}
#endregion
// // // 保存修改
// // document.SaveAs("C:\\Users\\hang\\Desktop\\test1.docx");
// //}
// #endregion
using (FileStream fs = new FileStream("C:\\Users\\hang\\Desktop\\test.docx", FileMode.Open, FileAccess.Read))
{
XWPFDocument doc = new XWPFDocument(fs);
// using (FileStream fs = new FileStream("C:\\Users\\hang\\Desktop\\test.docx", FileMode.Open, FileAccess.Read))
// {
// XWPFDocument doc = new XWPFDocument(fs);
// 查找包含指定书签的段落及其索引
var bookmarkParagraph = doc.Paragraphs
.FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == "en_us"));
// // 查找包含指定书签的段落及其索引
// var bookmarkParagraph = doc.Paragraphs
// .FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == "en_us"));
if (bookmarkParagraph != null)
{
int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph);
// if (bookmarkParagraph != null)
// {
// int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph);
// 删除书签之后的所有段落
for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--)
{
doc.RemoveBodyElement(i);
}
// // 删除书签之后的所有段落
// for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--)
// {
// doc.RemoveBodyElement(i);
// }
}
else
{
throw new BusinessValidationFailedException("word 模板没有英文书签");
}
// }
// else
// {
// throw new BusinessValidationFailedException("word 模板没有英文书签");
// }
// 创建一个要删除段落的列表
// // 创建一个要删除段落的列表
//XWPFParagraph bookmarkParagraph = null;
// //XWPFParagraph bookmarkParagraph = null;
//foreach (var paragraph in doc.Paragraphs)
//{
// //foreach (var paragraph in doc.Paragraphs)
// //{
// foreach (var bookmark in paragraph.GetCTP().GetBookmarkStartList())
// {
// if (bookmark.name == "en_us")
// {
// bookmarkParagraph = paragraph;
// break;
// }
// }
//}
// // foreach (var bookmark in paragraph.GetCTP().GetBookmarkStartList())
// // {
// // if (bookmark.name == "en_us")
// // {
// // bookmarkParagraph = paragraph;
// // break;
// // }
// // }
// //}
//// 从书签所在段落开始,删除之前的所有段落
//for (int i = bookmarkIndex - 1; i >= 0; i--)
//{
// doc.RemoveBodyElement(i);
//}
// //// 从书签所在段落开始,删除之前的所有段落
// //for (int i = bookmarkIndex - 1; i >= 0; i--)
// //{
// // doc.RemoveBodyElement(i);
// //}
using (FileStream outStream = new FileStream("C:\\Users\\hang\\Desktop\\test1.docx", FileMode.Create, FileAccess.Write))
{
doc.Write(outStream);
}
}
// using (FileStream outStream = new FileStream("C:\\Users\\hang\\Desktop\\test1.docx", FileMode.Create, FileAccess.Write))
// {
// doc.Write(outStream);
// }
// }
return "hiddenEmail";
}
// return "hiddenEmail";
//}
[AllowAnonymous]

View File

@ -58,6 +58,7 @@ namespace IRaCIS.Core.Application.Triggers
// 出组 状态发生了变更
if (context.Entity.Status == SubjectStatus.OutOfVisit && context.Entity.Status != context.UnmodifiedEntity?.Status)
{
//设置末次方式
if (context.Entity.FinalSubjectVisitId != null)
{
if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == dbSubject.Id && t.IsFinalVisit && t.Id != dbSubject.FinalSubjectVisitId))
@ -85,6 +86,19 @@ namespace IRaCIS.Core.Application.Triggers
//末次访视后的 访视设置为不可用
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == dbSubject.Id && t.VisitNum > sv.VisitNum, u => new SubjectVisit() { VisitExecuted = VisitExecutedEnum.Unavailable });
}
//撤销状态
else
{
var sv = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == dbSubject.FinalSubjectVisitId).IfNullThrowException();
sv.IsFinalVisit = false;
await _subjectVisitRepository.SaveChangesAsync();
//末次访视后的 访视设置为未执行
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == dbSubject.Id && t.VisitNum > sv.VisitNum, u => new SubjectVisit() { VisitExecuted = VisitExecutedEnum.UnExecuted });
}
}
}

View File

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

View File

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

View File

@ -8,6 +8,10 @@ public class ReadingNoneDicomMark : BaseAddAuditEntity
[JsonIgnore]
[ForeignKey("StudyId")]
public NoneDicomStudy NoneDicomStudy { get; set; }
[JsonIgnore]
[ForeignKey("NoneDicomFileId")]
public NoneDicomStudyFile NoneDicomStudyFile { get; set; }
#endregion
public Guid VisitTaskId { get; set; }

View File

@ -10,6 +10,10 @@ public class ReadingTaskQuestionMark : BaseAddAuditEntity
[ForeignKey("QuestionId")]
public ReadingQuestionTrial? ReadingQuestionTrial { get; set; }
[JsonIgnore]
[ForeignKey("InstanceId")]
public DicomInstance Instance { get; set; }
[JsonIgnore]
[ForeignKey("VisitTaskId")]
public VisitTask VisitTask { get; set; }

View File

@ -1,6 +1,5 @@
using IRaCIS.Core.Domain.Share;
using System.Linq;
using ZstdSharp.Unsafe;
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">
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>..\bin</OutputPath>
</PropertyGroup>
@ -21,22 +14,21 @@
</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.Projectables" Version="3.0.4" />
<PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="8.1.3" />
<PackageReference Include="MassTransit" Version="8.4.0" />
<PackageReference Include="MassTransit.EntityFrameworkCore" Version="8.4.0" />
<PackageReference Include="MassTransit.Hangfire" Version="8.4.0" />
<PackageReference Include="Hangfire.Core" Version="1.8.18" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.10" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.19">
<PackageReference Include="EntityFrameworkCore.Projectables" Version="6.0.5" />
<PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="10.0.1" />
<PackageReference Include="MassTransit.EntityFrameworkCore" Version="8.5.9" />
<PackageReference Include="MassTransit.Hangfire" Version="8.5.9" />
<PackageReference Include="Hangfire.Core" Version="1.8.23" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.19">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@ -104,6 +104,7 @@ public static class DBContext_Ext
.Select(t => t.EmailDelaySeconds).FirstOrDefault();
Console.WriteLine("qc领取任务" + DateTime.Now.ToShortTimeString() + $"延时{delaySeconds}");
if (delaySeconds > 0)
{
subjectVisit.AddDomainEvent(new QCClaimTaskEvent() { IsPd = subjectVisit.PDState == PDStateEnum.PDProgress, SubjectVisitId = subjectVisit.Id, DelaySeconds = delaySeconds, CurrentActionUserId = (Guid)subjectVisit.CurrentActionUserId });

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Query;
using System.Reflection;
namespace IRaCIS.Core.Infra.EFCore
@ -6,37 +7,14 @@ namespace IRaCIS.Core.Infra.EFCore
public static class DynamicRelationalExtensions
{
//升级efcore9 RelationalQueryableExtensions-> EntityFrameworkQueryableExtensions
static MethodInfo UpdateMethodInfo =
typeof(RelationalQueryableExtensions).GetMethod(nameof(RelationalQueryableExtensions.ExecuteUpdate));
////升级efcore9 RelationalQueryableExtensions-> EntityFrameworkQueryableExtensions
//static MethodInfo UpdateMethodInfo =
// typeof(EntityFrameworkQueryableExtensions).GetMethod(nameof(EntityFrameworkQueryableExtensions.ExecuteUpdate));
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)
{
@ -64,50 +42,63 @@ namespace IRaCIS.Core.Infra.EFCore
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)
{
var propExpression = Expression.PropertyOrField(objParam, pair.Key);
var valueExpression = ValueForType(propExpression.Type, pair.Value);
// Expression setBody = setParam;
// s.SetProperty(e => e.SomeField, value)
setBody = Expression.Call(setBody, nameof(SetPropertyCalls<object>.SetProperty),
new[] { propExpression.Type }, Expression.Lambda(propExpression, objParam), valueExpression);
// foreach (var pair in fieldValues)
// {
// 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)
{
if (value == null)
{
return Expression.Default(desiredType);
}
// return updateBody;
//}
if (value.GetType() != desiredType)
{
return Expression.Convert(Expression.Constant(value), desiredType);
}
//static Expression ValueForType(Type desiredType, object? value)
//{
// 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>
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

View File

@ -1,6 +1,7 @@
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Query;
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;
}
@ -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;

View File

@ -306,7 +306,7 @@ namespace IRaCIS.Core.Infra.EFCore
/// <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);
}

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">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>..\bin</OutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.10" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
<PackageReference Include="SharpCompress" Version="0.39.0" />
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="11.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="10.0.8" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.8" />
<PackageReference Include="SharpCompress" Version="0.49.1" />
<PackageReference Include="SharpZipLib" Version="1.4.2" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.6.0.2" />
<PackageReference Include="ZiggyCreatures.FusionCache" Version="2.4.0" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.7.2" />
<PackageReference Include="ZiggyCreatures.FusionCache" Version="2.6.0" />
</ItemGroup>

View File

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

View File

@ -1,71 +1,4 @@
kind: pipeline
type: ssh
name: ssh-linux-uat-irc-build-image
platform:
os: Linux
arch: 386
clone:
disable: true
server:
host: 101.132.253.119
user: root
password:
from_secret: test_ssh_pwd
steps:
- name: publish-uat-irc
commands:
- bash /opt/1panel/xc-deploy-new/Uat_IRC/devops-publish/uat-branch-publish.sh
- name: notify-wecom
commands:
- bash /opt/1panel/xc-deploy-new/devops-center/drone-notify-wecom.sh "$DRONE_BUILD_STATUS" "$DRONE_REPO_NAME" "$DRONE_BRANCH" "$DRONE_BUILD_NUMBER" "4355b98e-1e72-4678-8dfb-2fc6ad0bf449" "$DRONE_COMMIT_MESSAGE" "$DRONE_COMMIT_AUTHOR" "Uat_IRC_API Uat_IRC_SCP_API" "irc.uat.extimaging.com"
when:
status:
- success
- failure
trigger:
branch:
- Uat_IRC_Net8
---
kind: pipeline
type: ssh
name: ssh-linux-uat-Tailimed-build-image
platform:
os: Linux
arch: 386
clone:
disable: true
server:
host: 101.132.253.119
user: root
password:
from_secret: test_ssh_pwd
steps:
- name: publish-uat-irc
commands:
- bash /opt/1panel/xc-deploy-new/Uat_Tailimed/devops-publish/uat-branch-publish.sh
- name: notify-wecom
commands:
- bash /opt/1panel/xc-deploy-new/devops-center/drone-notify-wecom.sh "$DRONE_BUILD_STATUS" "$DRONE_REPO_NAME" "$DRONE_BRANCH" "$DRONE_BUILD_NUMBER" "4355b98e-1e72-4678-8dfb-2fc6ad0bf449" "$DRONE_COMMIT_MESSAGE" "$DRONE_COMMIT_AUTHOR" "Uat_IRC_API Uat_IRC_SCP_API" "irc.uat.rayplus.net"
when:
status:
- success
- failure
trigger:
branch:
- Uat_Tailimed_Net8
---
kind: pipeline
type: ssh
name: ssh-linux-test-irc-publish
@ -96,7 +29,8 @@ steps:
- failure
trigger:
branch:
- Test_IRC_Net10
- Test_IRC_Net10