Compare commits

...

104 Commits

Author SHA1 Message Date
hang da57773cd3 邮箱验证修改
continuous-integration/drone/push Build is passing
2024-05-31 17:42:59 +08:00
hang d3c2ded3d4 返回 SliceThickness
continuous-integration/drone/push Build is passing
2024-05-31 15:56:29 +08:00
hang 37e7ab575f Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-31 15:39:31 +08:00
hang 39a9a0c05d 日志遗漏接口
continuous-integration/drone/push Build is passing
2024-05-31 09:09:28 +08:00
hang 570c5863c0 ip所在地遗漏
continuous-integration/drone/push Build is passing
2024-05-30 16:04:42 +08:00
hang 343f9211e2 区域 依赖注入
continuous-integration/drone/push Build is passing
2024-05-30 15:57:53 +08:00
hang 4b7fff9869 修改日志区域
continuous-integration/drone/push Build is passing
2024-05-30 15:53:16 +08:00
hang 1b1ac3ee65 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-28 17:39:04 +08:00
he 37b4860668 修改
continuous-integration/drone/push Build is passing
2024-05-28 14:44:54 +08:00
he 96f3ecb45d 代码提交
continuous-integration/drone/push Build is passing
2024-05-28 14:33:15 +08:00
he 4966a32bcb 问题修改
continuous-integration/drone/push Build is passing
2024-05-27 15:07:46 +08:00
he 07dcb6fe47 稽查翻译修改
continuous-integration/drone/push Build is passing
2024-05-24 14:55:24 +08:00
he f802897b14 修改
continuous-integration/drone/push Build is passing
2024-05-23 16:19:20 +08:00
he 0642b9e4fb Merge branch 'Test.Study' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-23 15:01:17 +08:00
he f945793d6d 稽查翻译修改 2024-05-23 15:01:16 +08:00
hang 7b4eb7a459 修改Study 加急设置
continuous-integration/drone/push Build is passing
2024-05-23 13:50:46 +08:00
hang 5fbebe9cc0 一致性核查通过自动关闭质疑
continuous-integration/drone/push Build is passing
2024-05-23 11:16:09 +08:00
hang 6feb2b20f8 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-23 09:15:26 +08:00
hang 2f87048f65 修改导表格式 2024-05-23 09:15:26 +08:00
he 5e613fd9d3 Merge branch 'Test.Study' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-23 09:08:30 +08:00
he 3fa4db75d0 异常修改 2024-05-23 09:08:29 +08:00
hang 0c4bc87ee9 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-23 09:00:15 +08:00
hang 6fb0562a0b 修改邮箱验证正则 2024-05-23 09:00:15 +08:00
he 10fc07ec03 修改
continuous-integration/drone/push Build is passing
2024-05-22 17:56:28 +08:00
he 400421a337 修改
continuous-integration/drone/push Build is passing
2024-05-22 17:53:31 +08:00
he 4983def85b Merge branch 'Test.Study' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-22 17:49:01 +08:00
he d60a2567c1 修改 2024-05-22 17:48:59 +08:00
hang 2cd9716e68 修改临床数据维护
continuous-integration/drone/push Build is passing
2024-05-22 17:39:28 +08:00
hang 1cf0ac0c53 临床数据bug
continuous-integration/drone/push Build is passing
2024-05-22 09:42:26 +08:00
hang 74dd5369cb 增加查询条件
continuous-integration/drone/push Build is passing
2024-05-20 17:43:18 +08:00
hang 9d6a046d7f 清理多余的字段
continuous-integration/drone/push Build is passing
2024-05-20 15:36:10 +08:00
hang a31eef5ccd 修改评估结果
continuous-integration/drone/push Build is passing
2024-05-20 15:34:24 +08:00
hang 21beeecb7d Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-20 15:19:31 +08:00
hang c5c3c3334d 缓存清理 2024-05-20 15:19:29 +08:00
he 92008fe6ba Merge branch 'Test.Study' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-05-20 15:10:02 +08:00
he 138a967283 修改 2024-05-20 15:10:01 +08:00
hang ed72ed9a5e 自定义阅片显示评估结果
continuous-integration/drone/push Build is passing
2024-05-20 15:04:25 +08:00
hang 5d0dca121f 修改site 和hospital 以及增加字段
continuous-integration/drone/push Build is passing
2024-05-20 14:34:35 +08:00
hang 3d656dfa17 修改提交事务地点
continuous-integration/drone/push Build is passing
2024-05-16 14:25:55 +08:00
hang 7adb291a0f 先一致性核查,再确认标准的时候,批量生成任务的时候,前序任务是否需要签名但是没签名状态有误
continuous-integration/drone/push Build is passing
2024-05-16 14:02:20 +08:00
hang 3c790965fe 阅片界面调整-查询条件 2024-05-15 13:27:39 +08:00
hang da4fe122ab 重阅跟踪修改 2024-05-15 13:27:14 +08:00
hang e029f32bad 迁移study 打包
continuous-integration/drone/push Build is failing
2024-05-06 14:00:43 +08:00
hang 4320f06b77 x 2024-04-17 10:06:51 +08:00
hang ac43952c18 修改测试环境存放bucket 2024-04-17 09:59:42 +08:00
hang 5ef97ff742 修改PI 自动审核通过的 2024-04-15 17:01:32 +08:00
hang 2c8056c77b 设置访视上入组和pd默认值 2024-04-15 16:17:17 +08:00
hang 5ac6e186c0 修改中心调研bug 需要迁移 2024-04-10 14:54:56 +08:00
hang e4e02225c5 稽查排序修改,需要迁移 2024-04-08 17:40:01 +08:00
hang 72b21fc021 study 列表修改
continuous-integration/drone/push Build is passing
2024-04-07 15:01:47 +08:00
he b8175c8ed5 修改 2024-04-02 13:09:17 +08:00
hang 885b115927 修改访视默认值 2024-03-19 10:45:54 +08:00
hang 776c8f5c5e 修改阅片任务查询 2024-03-19 10:05:17 +08:00
hang 5564d8cc42 一致性分析修改 2024-03-06 14:09:19 +08:00
hang 2b9d3785d6 修改生产配置文件
continuous-integration/drone/push Build is passing
2024-02-02 17:40:19 +08:00
hang 46db19f513 修改邮件bug
continuous-integration/drone/push Build is passing
2024-02-02 15:22:25 +08:00
hang 3a479fe724 修改邮件发送
continuous-integration/drone/push Build is passing
2024-02-02 15:20:34 +08:00
hang a1afb299b3 修改邮件发送bug 2024-02-02 15:03:37 +08:00
hang c54074dd3d Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-02-01 16:54:24 +08:00
he 203bce15ea 修改查询阅片图像
continuous-integration/drone/push Build is passing
2024-02-01 13:40:37 +08:00
he c1096ae473 阅片图像查询修改
continuous-integration/drone/push Build is passing
2024-02-01 13:30:20 +08:00
hang f2cd5f35e3 [修改一致性核查模板] 2024-01-31 16:37:17 +08:00
hang 40afae1f37 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-31 11:05:38 +08:00
hang 845c532134 [修改subject 查询 不依赖系统site] 2024-01-31 11:04:36 +08:00
hang 8615c90ebe 【修改 查询写入dicom的信息】 2024-01-31 11:04:29 +08:00
he eb1d90e304 study去掉疲劳阅片
continuous-integration/drone/push Build is passing
2024-01-29 14:34:50 +08:00
hang 88f015183d [赋值study code dicom]
continuous-integration/drone/push Build is passing
2024-01-26 12:36:42 +08:00
hang 4f9560c3a6 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-26 11:11:59 +08:00
hang 9abb78400a [site搜索三个名字] 2024-01-26 09:41:03 +08:00
he 8f5e2c5b0c 添加LimitShow 限制显示
continuous-integration/drone/push Build is passing
2024-01-25 16:03:35 +08:00
he efe96203d9 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-25 16:00:35 +08:00
hang 65de94079a Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-25 15:52:57 +08:00
hang 6e706c4fc9 [上传监控增加字段] 2024-01-25 15:52:31 +08:00
hang 84e2e14b73 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-24 14:20:22 +08:00
hang 49d4a71f36 [修改回退] 2024-01-24 14:20:20 +08:00
hang 7dcf73176c 去掉内存缓存
continuous-integration/drone/push Build is passing
2024-01-24 12:28:33 +08:00
hang f9bf9d752c 测试
continuous-integration/drone/push Build is passing
2024-01-24 12:20:38 +08:00
hang acac7ec995 升级net8 准备
continuous-integration/drone/push Build is passing
2024-01-24 12:17:02 +08:00
hang 6cfcb9bfe1 修改测试
continuous-integration/drone/push Build is passing
2024-01-24 11:22:20 +08:00
hang 9adf2ad52b 请求前端国际化增加缓存-需要迁移 2024-01-24 11:21:47 +08:00
hang 403885ef3f 修改国际化取消权限限制 2024-01-24 11:21:43 +08:00
hang 7b1a0affbe 增加前端国际化修改 2024-01-24 11:21:32 +08:00
hang 85897f990d [邮件模板启用与否没用bug修复]
continuous-integration/drone/push Build is passing
2024-01-24 10:14:18 +08:00
hang be477818d7 [AWS 对接上传 需要传递文件大小] 2024-01-24 10:13:22 +08:00
hang 41bbb75407 [修改重传没有检查id] 2024-01-24 10:13:13 +08:00
hang fd9fdcb8be [修改医生bug 和site bug] 2024-01-24 10:13:06 +08:00
hang 0e8ecdaf46 [上传失败过,返回标志] 2024-01-24 10:12:22 +08:00
hang 81b033885e [上传监控增加字段] 2024-01-24 10:11:06 +08:00
hang fca2a81c66 [遗漏 get set] 2024-01-24 10:10:59 +08:00
hang 353f5df217 [修改上传,失败数量传递不准问题] 2024-01-24 10:10:54 +08:00
hang 4874533804 [增加默认值] 2024-01-24 10:10:48 +08:00
hang 025a8e7af1 [上传增加稽查字段]迁移 2024-01-24 10:10:40 +08:00
hang 79c5824051 统一日志记录信息 2024-01-24 10:08:32 +08:00
hang 2c47842e13 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study 2024-01-24 10:03:24 +08:00
hang 39d9cefda9 [上传监控修改,增加搜索条件] 2024-01-24 09:58:51 +08:00
hang 2c0d1cdc82 [邮件模板启用与否没用bug修复] 2024-01-24 09:55:22 +08:00
hang af77d5be56 修改邮件模板
continuous-integration/drone/push Build is passing
2024-01-22 11:09:19 +08:00
he f662a988e0 修改 2024-01-16 10:27:48 +08:00
hang b9cace17b2 Merge branch 'Test.Study' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test.Study
continuous-integration/drone/push Build is passing
2024-01-15 16:10:46 +08:00
hang c8d0ef9043 修改study 配置文件 2024-01-15 16:10:44 +08:00
hang 2491fd1fff 请求前端国际化增加缓存-需要迁移 2024-01-11 18:03:25 +08:00
hang 7cc9731edf 修改国际化取消权限限制 2024-01-11 18:03:21 +08:00
hang ff333219d4 增加前端国际化修改 2024-01-11 18:03:16 +08:00
hang 0eae520f0d 适配AWS 和MinIO
continuous-integration/drone/push Build is passing
2024-01-11 17:59:49 +08:00
90 changed files with 1905 additions and 958 deletions
@@ -146,7 +146,7 @@ namespace IRaCIS.Api.Controllers
var ossOptions = serviceOption.AliyunOSS;
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO ,AliyunOSS= serviceOption.AliyunOSS });
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO, AliyunOSS = serviceOption.AliyunOSS, AWS = serviceOption.AWS });
#region token
//IClientProfile profile = DefaultProfile.GetProfile(ossOptions.RegionId, ossOptions.AccessKeyId, ossOptions.AccessKeySecret);
@@ -189,11 +189,11 @@ namespace IRaCIS.Api.Controllers
}
else if (Enum.TryParse<ObjectStoreUse>(serviceOption.ObjectStoreUse, out var parsedValue) && parsedValue == ObjectStoreUse.MinIO)
{
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO });
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO, AWS = serviceOption.AWS });
}
else
{
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO });
return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO, AWS = serviceOption.AWS });
}
}
@@ -800,7 +800,7 @@ namespace IRaCIS.Core.API.Controllers
templateFileStream.Seek(0, SeekOrigin.Begin);
var ossRelativePath = oSSService.UploadToOSS(fileStream, "InspectionUpload/Check", $"{Guid.NewGuid()}_" + realFileName);
var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/Check", realFileName);
await _repository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId });
@@ -1024,7 +1024,7 @@ namespace IRaCIS.Core.API.Controllers
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_TemplateUploadData"));
}
var ossRelativePath = oSSService.UploadToOSS(fileStream, "InspectionUpload/SiteSurvey", $"{Guid.NewGuid()}_"+ realFileName);
var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/SiteSurvey", realFileName);
await _inspectionFileRepository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId });
-126
View File
@@ -1,126 +0,0 @@
using System;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;
using MediatR;
using IRaCIS.Core.Application.MediatR.Handlers;
using System.Threading.Tasks;
using MassTransit;
using MassTransit.NewIdProviders;
using System.IO;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Application.Helper;
using System.Runtime.InteropServices;
namespace IRaCIS.Core.API
{
public class Program
{
public readonly string environment;
public static async Task Main(string[] args)
{
try
{
//以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数)
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
var enviromentName = config["ASPNETCORE_ENVIRONMENT"];
if (string.IsNullOrWhiteSpace(enviromentName))
{
var index = Array.IndexOf(args, "--env");
enviromentName = index > -1
? args[index + 1]
: "Development";
}
//Dicom 浏览
//ImageManager.SetImplementation(WinFormsImageManager.Instance);
var host = CreateHostBuilder(args)
.UseEnvironment(enviromentName) //命令行传入环境
.ConfigureAppConfiguration((hostContext, config) =>
{
//Console.WriteLine(hostContext.HostingEnvironment.EnvironmentName);
config.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{enviromentName}.json", false, true);
})
.Build();
//// Serilog
SerilogExtension.AddSerilogSetup(enviromentName, host.Services);
Log.Logger.Warning($"当前环境:{enviromentName}");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Log.Logger.Warning($"当前部署平台环境:windows");
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Log.Logger.Warning($"当前部署平台环境:linux");
}
else
{
Log.Logger.Warning($"当前部署平台环境:OSX or FreeBSD");
}
NewId.SetProcessIdProvider(new CurrentProcessIdProvider());
host.Run();
}
catch (Exception e)
{
Log.Logger.Error(e.InnerException is null ? e.Message + e.StackTrace : e.InnerException?.Message + e.InnerException?.StackTrace);
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel((context, options) =>
{
//设置应用服务器Kestrel请求体最大为1GB // if don't set default value is: 30 MB
options.Limits.MaxRequestBodySize = long.MaxValue;
options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(30);
options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(20);
});
//webBuilder.UseSerilog();//在宿主机启动的时候配置serilog,与微软ILogger进行整合
webBuilder.UseStartup<Startup>();
}).UseSerilog()
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
private static async Task InitCache(IHost host)
{
var _repository = host.Services.GetService(typeof(IRepository)) as IRepository;
//初始化 国际化数据,并且监测国际化文件变更
//await InternationalizationHelper.InitInternationlizationDataAndWatchJsonFileAsync(_repository);
}
}
}
+309
View File
@@ -0,0 +1,309 @@
using System;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;
using MediatR;
using IRaCIS.Core.Application.MediatR.Handlers;
using System.Threading.Tasks;
using MassTransit;
using MassTransit.NewIdProviders;
using System.IO;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Application.Helper;
using System.Runtime.InteropServices;
using Microsoft.AspNetCore.Builder;
using IRaCIS.Core.API;
using Autofac;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.HttpOverrides;
using IRaCIS.Application.Services.BackGroundJob;
using LogDashboard;
using OfficeOpenXml.Utils;
using IP2Region.Net.Abstractions;
using IP2Region.Net.XDB;
#region
//以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数)
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
var enviromentName = config["ASPNETCORE_ENVIRONMENT"];
if (string.IsNullOrWhiteSpace(enviromentName))
{
var index = Array.IndexOf(args, "--env");
enviromentName = index > -1
? args[index + 1]
: "Development";
}
#endregion
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
EnvironmentName = enviromentName
});
#region windows
//foreach (var arg in args)
//{
// Console.WriteLine(arg);
//}
int urlsIndex = Array.FindIndex(args, arg => arg != null && arg.StartsWith("--urls"));
if (urlsIndex > -1)
{
var url = args[urlsIndex].Substring("--urls=".Length);
Console.WriteLine(url);
builder.WebHost.UseUrls(url);
}
#endregion
#region
NewId.SetProcessIdProvider(new CurrentProcessIdProvider());
builder.Configuration.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{enviromentName}.json", false, true);
builder.Host
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
containerBuilder.RegisterModule<AutofacModuleSetup>();
})
.UseWindowsService().UseSerilog();
#endregion
#region
var _configuration = builder.Configuration;
//健康检查
builder.Services.AddHealthChecks();
//本地化
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
builder.Services.AddControllers(options =>
{
//options.Filters.Add<LogActionFilter>();
options.Filters.Add<ModelActionFilter>();
options.Filters.Add<ProjectExceptionFilter>();
options.Filters.Add<UnitOfWorkFilter>();
if (_configuration.GetSection("BasicSystemConfig").GetValue<bool>("OpenLoginLimit"))
{
options.Filters.Add<LimitUserRequestAuthorization>();
}
})
.AddNewtonsoftJsonSetup(); // NewtonsoftJson 序列化 处理
builder.Services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig"));
builder.Services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
builder.Services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
builder.Services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
builder.Services.AddDynamicWebApiSetup();
//AutoMapper
builder.Services.AddAutoMapperSetup();
//EF ORM QueryWithNoLock
builder.Services.AddEFSetup(_configuration);
//Http 响应压缩
builder.Services.AddResponseCompressionSetup();
//Swagger Api 文档
builder.Services.AddSwaggerSetup();
//JWT Token 验证
builder.Services.AddJWTAuthSetup(_configuration);
// MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<ConsistencyVerificationHandler>());
// EasyCaching 缓存
builder.Services.AddEasyCachingSetup(_configuration);
// hangfire 定时任务框架 有界面,更友好~
builder.Services.AddhangfireSetup(_configuration);
//
builder.Services.AddQuartZSetup(_configuration);
//Serilog 日志可视化 LogDashboard日志
builder.Services.AddLogDashboardSetup();
builder.Services.AddJsonConfigSetup(_configuration);
//转发头设置 获取真实IP
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
//Dicom影像渲染图片 跨平台
builder.Services.AddDicomSetup();
// 实时应用
builder.Services.AddSignalR();
builder.Services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
//builder.Services.AddMemoryCache();
#region
////上传限制 配置
//builder.Services.Configure<FormOptions>(options =>
//{
// options.MultipartBodyLengthLimit = int.MaxValue;
// options.ValueCountLimit = int.MaxValue;
// options.ValueLengthLimit = int.MaxValue;
//});
//IP 限流 可设置白名单 或者黑名单
//services.AddIpPolicyRateLimitSetup(_configuration);
// 用户类型 策略授权
//services.AddAuthorizationPolicySetup(_configuration);
#endregion
builder.Services.AddSingleton<ISearcher>(new Searcher(CachePolicy.Content, Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, "ip2region.xdb")));
#endregion
var app = builder.Build();
var env = app.Environment;
#region
// Configure the HTTP request pipeline.
//本地化
app.UseLocalization();
app.UseForwardedHeaders();
//响应压缩
app.UseResponseCompression();
//app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
//不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();
//app.UseMiddleware<MultiDiskStaticFilesMiddleware>();
//LogDashboard
app.UseLogDashboard("/LogDashboard");
//hangfire
app.UseHangfireConfig(env);
////限流 中间件
//app.UseIpRateLimiting();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
//app.UseHsts();
}
// 特殊异常处理 比如 404
app.UseStatusCodePagesWithReExecute("/Error/{0}");
SwaggerSetup.Configure(app, env);
////serilog 记录请求的用户信息
app.UseSerilogConfig(env);
app.UseRouting();
app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
//app.UseIRacisHostStaticFileStore(env);
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapHub<UploadHub>("/UploadHub");
app.MapHealthChecks("/health");
// Serilog
SerilogExtension.AddSerilogSetup(enviromentName, app.Services);
var hangfireJobService = app.Services.GetRequiredService<IIRaCISHangfireJob>();
await hangfireJobService.InitHangfireJobTaskAsync();
#endregion
try
{
#region
Log.Logger.Warning($"当前环境:{enviromentName}");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Log.Logger.Warning($"当前部署平台环境:windows");
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Log.Logger.Warning($"当前部署平台环境:linux");
}
else
{
Log.Logger.Warning($"当前部署平台环境:OSX or FreeBSD");
}
#endregion
Log.Logger.Warning($"ContentRootPath{env.ContentRootPath}");
string parentDirectory = Path.GetFullPath(Path.Combine(env.ContentRootPath, ".."));
Log.Logger.Warning($"ContentRootPath——parentDirectory{parentDirectory}");
//Log.Logger.Warning($"ContentRootPath——GetParent{Directory.GetParent(env.ContentRootPath).Parent.FullName}");
//Log.Logger.Warning($"ContentRootPath——xx{Path.GetDirectoryName(Path.GetDirectoryName(env.ContentRootPath))}");
app.Run();
}
catch (Exception e)
{
Log.Logger.Error(e.InnerException is null ? e.Message + e.StackTrace : e.InnerException?.Message + e.InnerException?.StackTrace);
}
-262
View File
@@ -1,262 +0,0 @@
using Autofac;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using IRaCIS.Core.Application.Filter;
using LogDashboard;
using MediatR;
using IRaCIS.Core.Application.MediatR.Handlers;
using Microsoft.Extensions.Logging;
using AspNetCoreRateLimit;
using Microsoft.AspNetCore.HttpOverrides;
using IRaCIS.Core.Infra.EFCore;
using System.Globalization;
using Microsoft.AspNetCore.Localization;
using Localization;
using Magicodes.ExporterAndImporter.Core.Filters;
using IRaCIS.Core.Application.MediatR.CommandAndQueries;
using IRaCIS.Core.Infra.EFCore.Common;
using Invio.Extensions.Authentication.JwtBearer;
using Microsoft.AspNetCore.SignalR;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.StaticFiles;
using IRaCIS.Application.Services.BackGroundJob;
using IRaCIS.Core.Application.Helper;
using Microsoft.AspNetCore.Http;
using Autofac.Core;
using DocumentFormat.OpenXml.InkML;
using EasyCaching.Core;
namespace IRaCIS.Core.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
_configuration = configuration;
}
public ILogger<Startup> _logger { get; }
public IConfiguration _configuration { get; }
//// ConfigureContainer is where you can register things directly
//// with Autofac. This runs after ConfigureServices so the things
//// here will override registrations made in ConfigureServices.
//// Don't build the container; that gets done for you by the factory.
// for castle
public void ConfigureContainer(ContainerBuilder containerBuilder)
{
containerBuilder.RegisterModule<AutofacModuleSetup>();
#region Test
//containerBuilder.RegisterType<ClinicalDataService>().PropertiesAutowired().InstancePerLifetimeScope();//注册仓储
//var container = containerBuilder.Build();
//// Now you can resolve services using Autofac. For example,
//// this line will execute the lambda expression registered
//// to the IConfigReader service.
//using (var scope = container.BeginLifetimeScope())
//{
// var reader = scope.Resolve<BaseService>();
// var test = scope.Resolve<ClinicalDataService>();
// var test2 = scope.Resolve<IClinicalDataService>();
// var test3 = scope.Resolve<IEFUnitOfWork<IRaCISDBContext>>();
//}
#endregion
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//健康检查
services.AddHealthChecks();
//本地化
services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
services.AddControllers(options =>
{
//options.Filters.Add<LogActionFilter>();
options.Filters.Add<ModelActionFilter>();
options.Filters.Add<ProjectExceptionFilter>();
options.Filters.Add<UnitOfWorkFilter>();
if (_configuration.GetSection("BasicSystemConfig").GetValue<bool>("OpenLoginLimit"))
{
options.Filters.Add<LimitUserRequestAuthorization>();
}
})
.AddNewtonsoftJsonSetup(); // NewtonsoftJson 序列化 处理
services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig"));
services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
services.AddDynamicWebApiSetup();
//AutoMapper
services.AddAutoMapperSetup();
//EF ORM QueryWithNoLock
services.AddEFSetup(_configuration);
//Http 响应压缩
services.AddResponseCompressionSetup();
//Swagger Api 文档
services.AddSwaggerSetup();
//JWT Token 验证
services.AddJWTAuthSetup(_configuration);
// MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系
services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<ConsistencyVerificationHandler>());
// EasyCaching 缓存
services.AddEasyCachingSetup(_configuration);
//services.AddDistributedMemoryCache();
// hangfire 定时任务框架 有界面,更友好~
services.AddhangfireSetup(_configuration);
// QuartZ 定时任务框架 使用了hangfire 暂时不用,后续需要可以打开,已经配好
services.AddQuartZSetup(_configuration);
// 保护上传文件
//services.AddStaticFileAuthorizationSetup();
////HttpReports 暂时废弃
//services.AddHttpReports().AddHttpTransport();
//Serilog 日志可视化 LogDashboard日志
services.AddLogDashboardSetup();
//上传限制 配置
services.Configure<FormOptions>(options =>
{
options.MultipartBodyLengthLimit = int.MaxValue;
options.ValueCountLimit = int.MaxValue;
options.ValueLengthLimit = int.MaxValue;
});
//IP 限流 可设置白名单 或者黑名单
//services.AddIpPolicyRateLimitSetup(_configuration);
// 用户类型 策略授权
//services.AddAuthorizationPolicySetup(_configuration);
services.AddJsonConfigSetup(_configuration);
//转发头设置 获取真实IP
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
//Dicom影像渲染图片 跨平台
services.AddDicomSetup();
// 实时应用
services.AddSignalR();
services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
//services.AddSingleton<IImportResultFilter, ImportResultFilteTest>();
services.AddMemoryCache();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public async void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//app.UsePathBase(PathString.FromUriComponent("/api"));
//本地化
app.UseLocalization();
app.UseForwardedHeaders();
//响应压缩
app.UseResponseCompression();
//app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
//不需要 token 访问的静态文件 wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();
//LogDashboard
app.UseLogDashboard("/back/logs");
//hangfire
app.UseHangfireConfig(env);
////暂时废弃
//app.UseHttpReports();
////限流 中间件
//app.UseIpRateLimiting();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
//app.UseHsts();
}
Console.WriteLine("当前环境: " + env.EnvironmentName);
//app.UseMiddleware<AuthMiddleware>();
// 特殊异常处理 比如 404
app.UseStatusCodePagesWithReExecute("/Error/{0}");
SwaggerSetup.Configure(app, env);
////serilog 记录请求的用户信息
app.UseSerilogConfig(env);
app.UseRouting();
app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
//app.UseIRacisHostStaticFileStore(env);
app.UseMiddleware<MultiDiskStaticFilesMiddleware>();
app.UseAuthentication();
//app.UseJwtBearerQueryString();
app.UseAuthorization();
////文件伺服 必须带Token 访问
////app.UseIRacisHostStaticFileStore(env);
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<UploadHub>("/UploadHub");
endpoints.MapHealthChecks("/health");
});
var hangfireJobService = app.ApplicationServices.GetRequiredService<IIRaCISHangfireJob>();
await hangfireJobService.InitHangfireJobTaskAsync();
//有的时候每调用
//HangfireJobHelper.NotImmediatelyOnceOnlyJob<IIRaCISHangfireJob>(t => t.InitHangfireJobTaskAsync(),TimeSpan.FromSeconds(1));
}
}
}
@@ -17,7 +17,7 @@ namespace IRaCIS.Core.API
app.UseSerilogRequestLogging(opts
=>
{
opts.MessageTemplate = "{TokenUserRealName} {TokenUserType} {ClientIp} {RequestIP} {Host} {Protocol} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
opts.MessageTemplate = "{TokenUserRealName} {TokenUserTypeShortName} {ClientIp} {LocalIP} {Host} {Protocol} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
opts.EnrichDiagnosticContext = SerilogHelper.EnrichFromRequest;
});
@@ -1,4 +1,5 @@
using IRaCIS.Core.Infrastructure.Extention;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Http;
using Serilog;
using System;
@@ -41,9 +42,9 @@ namespace IRaCIS.Core.API
// Set the content-type of the Response at this point
diagnosticContext.Set("ContentType", httpContext.Response.ContentType);
diagnosticContext.Set("TokenUserRealName", httpContext?.User?.FindFirst("realName")?.Value);
diagnosticContext.Set("TokenUserRealName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.RealName)?.Value);
diagnosticContext.Set("TokenUserType", httpContext?.User?.FindFirst("userTypeEnumName")?.Value);
diagnosticContext.Set("TokenUserTypeShortName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value);
// Retrieve the IEndpointFeature selected for the request
var endpoint = httpContext.GetEndpoint();
@@ -50,7 +50,8 @@ namespace IRaCIS.Core.API
//triggerOptions.AddTrigger<AddlTrialUserTrigger>();
triggerOptions.AddTrigger<VisitTaskIsFrontTaskNeedSignButNotSignTrigger>();
triggerOptions.AddTrigger<VisitTaskIAfterSignTrigger>();
triggerOptions.AddTrigger<UserLogTrigger>();
});
@@ -26,24 +26,26 @@ namespace IRaCIS.Core.API
//控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning,
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3} ] {LocalIP} {ClientIp} {TokenUserRealName} {TokenUserType} {Message:lj} {Properties:j}{NewLine} {Exception}")
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}")
.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day,
outputTemplate: "{Timestamp:HH:mm:ss} || {Level} || {SourceContext:l} || {Message} ||{Exception} ||end {NewLine}");
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}");
//.WriteTo.MSSqlServer("Data Source=DESKTOP-4TU9A6M;Initial Catalog=CoreFrame;User ID=sa;Password=123456", "logs", autoCreateSqlTable: true, restrictedToMinimumLevel: LogEventLevel.Information)//从左至右四个参数分别是数据库连接字符串、表名、如果表不存在是否创建、最低等级。Serilog会默认创建一些列。
if (environment == "Production")
{
config.WriteTo.Email(new EmailConnectionInfo()
{
EmailSubject = "系统警告,请速速查看!",//邮件标题
FromEmail = "test@extimaging.com",//发件人邮箱
MailServer = "smtp.qiye.aliyun.com",//smtp服务器地址
NetworkCredentials = new NetworkCredential("test@extimaging.com", "SHzyyl2021"),//两个参数分别是发件人邮箱与客户端授权码
Port = 465,//端口号
ToEmail = "872297557@qq.com"//收件人
}, restrictedToMinimumLevel: LogEventLevel.Error,
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [ {Level} {ClientIp} {ClientAgent} {TokenUserRealName} {TokenUserType} ] || [path: {RequestPath} arguments: {RequestBody}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine})");
}
//if (environment == "Production")
//{
// config.WriteTo.Email(new EmailConnectionInfo()
// {
// EmailSubject = "系统警告,请速速查看!",//邮件标题
// FromEmail = "test@extimaging.com",//发件人邮箱
// MailServer = "smtp.qiye.aliyun.com",//smtp服务器地址
// NetworkCredentials = new NetworkCredential("test@extimaging.com", "SHzyyl2021"),//两个参数分别是发件人邮箱与客户端授权码
// Port = 465,//端口号
// ToEmail = "872297557@qq.com"//收件人
// }, restrictedToMinimumLevel: LogEventLevel.Error,
// outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [ {Level} {ClientIp} {ClientAgent} {TokenUserRealName} {TokenUserType} ] || [path: {RequestPath} arguments: {RequestBody}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine})");
//}
//扩展方法 获取上下文的ip 用户名 用户类型
Log.Logger = config.Enrich.WithHttpContextInfo(serviceProvider).CreateLogger();
+4 -2
View File
@@ -30,8 +30,10 @@
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.193.237,1434;Database=Prod_Study;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=101.132.193.237,1434;Database=Prod_Study_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
//"RemoteNew": "Server=47.117.165.18,1434;Database=Prod_Study;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
//"Hangfire": "Server=47.117.165.18,1434;Database=Prod_Study_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_Study;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_Study_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
},
"BasicSystemConfig": {
+18 -8
View File
@@ -20,18 +20,28 @@
},
"MinIO": {
"endpoint": "http://192.168.3.68",
"port": "8001",
"endPoint": "123.56.94.154",
"port": "9001",
"useSSL": true,
"accessKey": "fbStsVYCIPKHQneeqMwD",
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"bucketName": "study-test",
"viewEndpoint": "http://study.test.extimaging.com/oss/study-test"
},
"AWS": {
"endPoint": "s3.us-east-1.amazonaws.com",
"useSSL": false,
"accessKey": "IDFkwEpWej0b4DtiuThL",
"secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h",
"bucketName": "test"
"accessKey": "AKIAZQ3DRSOHFPJJ6FEU",
"secretKey": "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",
"bucketName": "ei-irc-test-store",
"viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/"
}
},
"ConnectionStrings": {
"RemoteNew": "Server=123.56.94.154,1435;Database=Test_Study;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=123.56.94.154,1435;Database=Test_Study_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_Study;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
"Hangfire": "Server=106.14.89.110,1435;Database=Test_Study_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
},
"BasicSystemConfig": {
@@ -55,7 +65,7 @@
"FromName": "Test_Study",
"AuthorizationCode": "zhanying123",
"SiteUrl": "http://test.study.extimaging.com/login"
"SiteUrl": "http://study.test.extimaging.com/login"
}
}
+1 -1
View File
@@ -53,7 +53,7 @@
"FromEmail": "uat-study@extimaging.com",
"FromName": "Uat_Study",
"AuthorizationCode": "zhanying123",
"SiteUrl": "http://uat.study.extimaging.com/login"
"SiteUrl": "http://study.uat.extimaging.com/login"
}
}
@@ -31,7 +31,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -28,7 +28,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -18,7 +18,7 @@
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -14,7 +14,7 @@
Thank you for using our IRC imaging system.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
{0}
{0}.
</div>
<div style='line-height: 24px;font-size: 16px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
@@ -42,7 +42,7 @@
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -43,7 +43,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -40,7 +40,7 @@
</a>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -8,7 +8,7 @@
<div style='padding-left: 40px;background: #f6f6f6;font-size: 16px'>
<div style='padding-top: 20px;font-size: 16px'>
<div style='line-height: 40px;font-size: 16px'>
Dear {0} ,
Dear {0} ,
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
The site survey questionnaire you filled in has been rejected. Details are as follows:
@@ -43,7 +43,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -43,7 +43,7 @@
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -8,17 +8,17 @@
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
亲爱的用户 ,
Hello {0},
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
感谢您使用展影云平台。
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{0},验证码是: {1},请在3分钟内输入该验证码,进行后续操作。如非本人操作,请忽略该邮件。
{1},验证码是: {2},请在3分钟内输入该验证码,进行后续操作。如非本人操作,请忽略该邮件。
</div>
<div style='line-height: 24px;font-size: 14px;color:#333;margin-top: 20px;padding-bottom: 40px;'>
<div>祝您顺利!/Best Regards</div>
<div>祝您顺利!</div>
<div style="font-size: 14px;">展影医疗</div>
</div>
</div>
@@ -8,13 +8,13 @@
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 16px'>
Dear Sir or Madam:
Hello {0},
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
Thank you for using our imaging system.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
{0}, the verification code is {1}. Please enter this code within 3 minutes for follow-up operations.
{1}, the verification code is {2}. Please enter this code within 3 minutes for follow-up operations.
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;font-size: 16px'>
If you are not the intended person, please ignore this email.
@@ -32,8 +32,10 @@ namespace IRaCIS.Core.Application.Filter
if (context.Exception.GetType() == typeof(BusinessValidationFailedException))
{
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message,ApiResponseCodeEnum.BusinessValidationFailed));
}
var error = context.Exception as BusinessValidationFailedException;
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, error!.Code));
}
else if(context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException))
{
context.Result = new JsonResult(ResponseOutput.NotOk( context.Exception.Message, ApiResponseCodeEnum.DataNotExist));
+186 -50
View File
@@ -3,6 +3,8 @@ using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Infrastructure;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Minio.DataModel.Args;
using Minio;
using NPOI.HPSF;
using SharpCompress.Common;
using System;
@@ -13,17 +15,24 @@ using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
using SkiaSharp;
namespace IRaCIS.Core.Application.Helper
{
public class MinIOOptions
public class MinIOOptions : AWSOptions
{
public string endpoint { get; set; }
public string port { get; set; }
public int port { get; set; }
}
public class AWSOptions
{
public string endPoint { get; set; }
public bool useSSL { get; set; }
public string accessKey { get; set; }
public string secretKey { get; set; }
public string bucketName { get; set; }
public string viewEndpoint { get; set; }
}
public class AliyunOSSOptions
@@ -48,6 +57,8 @@ namespace IRaCIS.Core.Application.Helper
public AliyunOSSOptions AliyunOSS { get; set; }
public MinIOOptions MinIO { get; set; }
public AWSOptions AWS { get; set; }
}
public class ObjectStoreDTO
@@ -58,6 +69,8 @@ namespace IRaCIS.Core.Application.Helper
public MinIOOptions MinIO { get; set; }
public AWSOptions AWS { get; set; }
}
public class AliyunOSSTempToken
@@ -81,76 +94,110 @@ namespace IRaCIS.Core.Application.Helper
AWS = 2,
}
public interface IOSSService
{
public string UploadToOSS(Stream fileStream, string oosFolderPath, string fileRealName);
public string UploadToOSS(string localFilePath, string oosFolderPath);
public Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName);
public Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath);
public void DownLoadFromOSS(string ossRelativePath, string localFilePath);
public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath);
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
}
public class OSSService : IOSSService
{
public AliyunOSSOptions _OSSConfig { get; set; }
public OssClient _ossClient { get; set; }
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
public OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options)
{
var ossOptions = options.CurrentValue;
_OSSConfig = ossOptions.AliyunOSS;
_ossClient = new OssClient(_OSSConfig.endPoint, _OSSConfig.accessKeyId, _OSSConfig.accessKeySecret);
ObjectStoreServiceOptions = options.CurrentValue;
}
/// <summary>
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
/// </summary>
/// <param name="fileStream"></param>
/// <param name="oosFolderPath"></param>
/// <param name="fileRealName"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public string UploadToOSS(Stream fileStream, string oosFolderPath,string fileRealName)
public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName)
{
var ossRelativePath = oosFolderPath + "/" + fileRealName;
try
var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}";
//var ossRelativePath = oosFolderPath + "/" + fileRealName;
using (var memoryStream = new MemoryStream())
{
using (var memoryStream = new MemoryStream())
fileStream.Seek(0, SeekOrigin.Begin);
fileStream.CopyTo(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
fileStream.Seek(0, SeekOrigin.Begin);
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
fileStream.CopyTo(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
// 上传文件
var result = _ossClient.PutObject(_OSSConfig.bucketName, ossRelativePath, memoryStream);
var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, memoryStream);
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{
var minIOConfig = ObjectStoreServiceOptions.MinIO;
return "/" + ossRelativePath;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
var putObjectArgs = new PutObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithStreamData(memoryStream)
.WithObjectSize(memoryStream.Length);
await minioClient.PutObjectAsync(putObjectArgs);
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
var minIOConfig = ObjectStoreServiceOptions.AWS;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
var putObjectArgs = new PutObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithStreamData(memoryStream)
.WithObjectSize(memoryStream.Length);
await minioClient.PutObjectAsync(putObjectArgs);
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
}
catch (Exception ex)
{
throw new BusinessValidationFailedException("oss上传失败" + ex.Message);
}
return "/" + ossRelativePath;
}
/// <summary>
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
/// </summary>
@@ -158,38 +205,124 @@ namespace IRaCIS.Core.Application.Helper
/// <param name="oosFolderPath"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public string UploadToOSS(string localFilePath, string oosFolderPath)
public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath)
{
var localFileName = Path.GetFileName(localFilePath);
var ossRelativePath = oosFolderPath + "/" + localFileName;
var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}";
//var ossRelativePath = oosFolderPath + "/" + localFileName;
try
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
// 上传文件
var result = _ossClient.PutObject(_OSSConfig.bucketName, ossRelativePath, localFilePath);
var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, localFilePath);
return ossRelativePath;
}
catch (Exception ex)
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{
throw new BusinessValidationFailedException("oss上传失败" + ex.Message);
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
var putObjectArgs = new PutObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithFileName(localFilePath);
await minioClient.PutObjectAsync(putObjectArgs);
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
var minIOConfig = ObjectStoreServiceOptions.AWS;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
var putObjectArgs = new PutObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithFileName(localFilePath);
await minioClient.PutObjectAsync(putObjectArgs);
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
return "/" + ossRelativePath;
}
public void DownLoadFromOSS(string ossRelativePath, string localFilePath)
public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath)
{
ossRelativePath = ossRelativePath.TrimStart('/');
try
{
var result = _ossClient.GetObject(_OSSConfig.bucketName, ossRelativePath);
// 将下载的文件流保存到本地文件
using (var fs = File.OpenWrite(localFilePath))
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
result.Content.CopyTo(fs);
fs.Close();
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
// 上传文件
var result = _ossClient.GetObject(aliConfig.bucketName, ossRelativePath);
// 将下载的文件流保存到本地文件
using (var fs = File.OpenWrite(localFilePath))
{
result.Content.CopyTo(fs);
fs.Close();
}
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
var getObjectArgs = new GetObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithFile(localFilePath);
await minioClient.GetObjectAsync(getObjectArgs);
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
var minIOConfig = ObjectStoreServiceOptions.AWS;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}")
.WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL)
.Build();
var getObjectArgs = new GetObjectArgs()
.WithBucket(minIOConfig.bucketName)
.WithObject(ossRelativePath)
.WithFile(localFilePath);
await minioClient.GetObjectAsync(getObjectArgs);
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
}
catch (Exception ex)
@@ -199,6 +332,9 @@ namespace IRaCIS.Core.Application.Helper
}
}
@@ -77,6 +77,7 @@
<PackageReference Include="fo-dicom.Codecs" Version="5.10.8" />
<PackageReference Include="FreeSpire.Doc" Version="11.6.0" />
<PackageReference Include="Hangfire.Core" Version="1.8.5" />
<PackageReference Include="IP2Region.Net" Version="2.0.2" />
<PackageReference Include="Magicodes.IE.Core" Version="2.7.4.5" />
<PackageReference Include="Magicodes.IE.Csv" Version="2.7.4.5">
<TreatAsUsed>true</TreatAsUsed>
@@ -89,6 +90,7 @@
<PackageReference Include="MediatR" Version="12.1.1" />
<PackageReference Include="MimeKit" Version="4.2.0" />
<PackageReference Include="MiniExcel" Version="1.31.2" />
<PackageReference Include="Minio" Version="6.0.1" />
<PackageReference Include="MiniWord" Version="0.7.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.0.0">
<TreatAsUsed>true</TreatAsUsed>
@@ -106,4 +108,10 @@
<ProjectReference Include="..\IRaCIS.Core.Infra.EFCore\IRaCIS.Core.Infra.EFCore.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="Resources\ip2region.xdb">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
@@ -94,17 +94,16 @@
<param name="type"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Helper.OSSService.UploadToOSS(System.IO.Stream,System.String,System.String)">
<member name="M:IRaCIS.Core.Application.Helper.OSSService.UploadToOSSAsync(System.IO.Stream,System.String,System.String)">
<summary>
oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
</summary>
<param name="fileStream"></param>
<param name="oosFolderPath"></param>
<param name="fileRealName"></param>
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>
<member name="M:IRaCIS.Core.Application.Helper.OSSService.UploadToOSS(System.String,System.String)">
<member name="M:IRaCIS.Core.Application.Helper.OSSService.UploadToOSSAsync(System.String,System.String)">
<summary>
oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
</summary>
@@ -548,6 +547,32 @@
InternationalizationService
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Service.InternationalizationService.GetFrontInternationalizationList">
<summary>
前端国际化内容接口
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.InternationalizationService.BatchAddOrUpdateFrontInternationalization(System.Collections.Generic.List{IRaCIS.Core.Application.ViewModel.BatchInternationalizationDto})">
<summary>
前端批量提交,后端判断不存在就添加,存在就更新
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.InternationalizationService.BatchAddInternationalization(IRaCIS.Core.Application.ViewModel.BatchAddInternationalization)">
<summary>
后端之前批量添加接口
</summary>
<param name="batchAdd"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.InternationalizationService.AddOrUpdateInternationalization(IRaCIS.Core.Application.ViewModel.InternationalizationAddOrEdit)">
<summary>
前后端添加的时候,区分了,前端判断重复多了多了一个路由 路由+标识唯一
</summary>
<param name="addOrEditInternationalization"></param>
<returns></returns>
</member>
<member name="T:IRaCIS.Core.Application.Service.PublishLogService">
<summary>
PublishLogService
@@ -953,7 +978,7 @@
<param name="currentInspectionId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.SetDataInspectionDateType(System.Collections.Generic.List{System.String},System.String)">
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.SetDataInspectionDateType(System.Collections.Generic.List{System.String},System.String,System.String)">
<summary>
格式化日期和时间
</summary>
@@ -961,7 +986,7 @@
<param name="jsonStr"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.GetInspectionEnumValue(System.Collections.Generic.List{System.String},System.String)">
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.GetInspectionEnumValue(System.Collections.Generic.List{System.String},System.String,System.String)">
<summary>
获取外键表数据
</summary>
@@ -969,7 +994,7 @@
<param name="jsonStr"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.SetEnum(System.Guid,System.Collections.Generic.List{System.String},System.String)">
<member name="M:IRaCIS.Core.Application.Service.FrontAuditConfigService.SetEnum(System.Guid,System.Collections.Generic.List{System.String},System.String,System.String)">
<summary>
获取枚举
</summary>
@@ -4496,6 +4521,11 @@
是否是第一次转化的任务
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetRelatedVisitTaskOutDto.IsExistsClinicalData">
<summary>
是否存在临床数据
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetGlobalReadingInfoInDto.UsingOriginalData">
<summary>
当新答案为空的时候 是否是有原数据
@@ -5886,6 +5916,11 @@
限制编辑
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionTrialAddOrEdit.LimitShow">
<summary>
限制显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionTrialAddOrEdit.MaxAnswerLength">
<summary>
最大答案长度
@@ -5964,6 +5999,11 @@
限制编辑
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionSystemAddOrEdit.LimitShow">
<summary>
限制显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionSystemAddOrEdit.MaxAnswerLength">
<summary>
最大答案长度
@@ -6307,6 +6347,11 @@
限制编辑
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionTrialView.LimitShow">
<summary>
限制显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionTrialView.MaxAnswerLength">
<summary>
最大答案长度
@@ -6357,6 +6402,11 @@
限制编辑
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionSystemView.LimitShow">
<summary>
限制显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionSystemView.MaxAnswerLength">
<summary>
最大答案长度
@@ -6692,6 +6742,11 @@
限制编辑
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionSystemInDto.LimitShow">
<summary>
限制显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionSystemInDto.MaxAnswerLength">
<summary>
最大答案长度
@@ -7017,6 +7072,11 @@
限制编辑
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionTrialInDto.LimitShow">
<summary>
限制显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionTrialInDto.MaxAnswerLength">
<summary>
最大答案长度
@@ -12414,6 +12474,12 @@
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Application.Services.TestService.OldLocalImageResizeJpg(IRaCIS.Core.Application.Helper.IOSSService,IRaCIS.Core.Infra.EFCore.IRepository,Microsoft.AspNetCore.Hosting.IWebHostEnvironment)">
<summary>
维护OSS 影像数据
</summary>
<returns></returns>
</member>
<member name="T:IRaCIS.Application.Contracts.DoctorSearchDTO">
<summary>
Reviewer 列表查询参数
Binary file not shown.
@@ -56,9 +56,15 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid SiteId { get; set; }
public string BlindTrialSiteCode { get; set; }
public String TrialSiteCode { get; set; } = String.Empty;
public string SubjectCode { get; set; } = String.Empty;
public string MedicalNo { get; set; } = string.Empty;
public string BlindSubjectCode { get; set; } = string.Empty;
public bool IsPMSetBack { get; set; }
@@ -358,7 +364,10 @@ namespace IRaCIS.Core.Application.ViewModel
{
public Guid TrialId { get; set; }
public Guid TrialReadingCriterionId { get; set; }
public Guid? SubjectId { get; set; }
public Guid TrialReadingCriterionId { get; set; }
public string? SubjectCode { get; set; } = null;
@@ -431,6 +440,7 @@ namespace IRaCIS.Core.Application.ViewModel
public DateTime? LatestReplyTimeBegin { get; set; }
public DateTime? LatestReplyTimeEnd { get; set; }
public string? RequestReReadingReason { get; set; }
}
public class PIAuditTaskEnrollOrPdCommand
@@ -280,12 +280,12 @@ namespace IRaCIS.Core.Application.Service
var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated;
}
await _visitTaskRepository.SaveChangesAsync();
}
}
await _visitTaskRepository.SaveChangesAsync();
}
@@ -26,6 +26,7 @@ using IRaCIS.Application.Services.BackGroundJob;
using Magicodes.ExporterAndImporter.Core.Extension;
using Hangfire;
using MassTransit;
using static IRaCIS.Core.Domain.Models.ReadingQuestionTrial;
namespace IRaCIS.Core.Application.Service.Allocation
{
@@ -103,7 +104,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
var list = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId && t.IsConfirm)
.OrderBy(t => t.ShowOrder)
.Select(t => new TrialReadingCriterionDto() { TrialReadingCriterionId = t.Id, IsAutoCreate = t.IsAutoCreate, IsAdditionalAssessment = t.IsAdditionalAssessment, TrialReadingCriterionName = t.CriterionName, CriterionType = t.CriterionType, ReadingType = t.ReadingType, ReadingInfoSignTime = t.ReadingInfoSignTime })
.Select(t => new TrialReadingCriterionDto() { TrialReadingCriterionId = t.Id, IsAutoCreate = t.IsAutoCreate, IsAdditionalAssessment = t.IsAdditionalAssessment, TrialReadingCriterionName = t.CriterionName, CriterionType = t.CriterionType, ReadingType = t.ReadingType, ReadingInfoSignTime = t.ReadingInfoSignTime , IsReadingPeriod= t.IsReadingPeriod })
.ToListAsync();
return list.AsQueryable().WhereIf(isHaveSigned == true, t => t.ReadingInfoSignTime != null)
@@ -209,8 +210,8 @@ namespace IRaCIS.Core.Application.Service.Allocation
.WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
.WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1))
.WhereIf(trialConfig?.EnrollConfirmDefaultUserType == UserTypeEnum.MIM && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM, t => t.SourceSubjectVisit.IsBaseLine == true)
.WhereIf(trialConfig?.PDProgressDefaultUserType == UserTypeEnum.MIM && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM, t => t.SourceSubjectVisit.IsBaseLine == false)
.WhereIf(trialConfig?.EnrollConfirmDefaultUserType == UserTypeEnum.MIM && trialConfig?.PDProgressDefaultUserType != UserTypeEnum.MIM && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM , t => t.SourceSubjectVisit.IsBaseLine == true)
.WhereIf(trialConfig?.EnrollConfirmDefaultUserType != UserTypeEnum.MIM && trialConfig?.PDProgressDefaultUserType == UserTypeEnum.MIM && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM, t => t.SourceSubjectVisit.IsBaseLine == false)
.WhereIf(queryVisitTask.IsWaitPIAudit == true, t => t.FirstAuditUserId == null)
.WhereIf(queryVisitTask.IsWaitPIAudit == false, t => t.FirstAuditUserId != null)
.WhereIf(queryVisitTask.PIAuditState != null, t => t.PIAuditState == queryVisitTask.PIAuditState)
@@ -226,6 +227,8 @@ namespace IRaCIS.Core.Application.Service.Allocation
public async Task<IResponseOutput<PageOutput<PIReaingTaskView>>> GetPIReadingAuditList(VisitTaskQuery queryVisitTask)
{
//CriterionType? criterionType = _trialReadingCriterionRepository.Where(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t=>t.CriterionType).FirstOrDefault();
var visitTaskQueryable = GetReadingTaskQueryable(queryVisitTask)
.ProjectTo<PIReaingTaskView>(_mapper.ConfigurationProvider);
@@ -237,6 +240,8 @@ namespace IRaCIS.Core.Application.Service.Allocation
var questionList = _readingQuestionTrialRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.ReadingQuestionCriterionTrialId == queryVisitTask.TrialReadingCriterionId)
.Where(t => t.IsJudgeQuestion == true)
//.WhereIf(criterionType!=null&& criterionType!=CriterionType.SelfDefine,t=>t.IsJudgeQuestion==true)
// .WhereIf(criterionType != null && criterionType == CriterionType.SelfDefine, t => t.AssessmentResultEnum == AssessmentResultType.AssessmentResult)
.Select(t => new { QuestionId = t.Id, QuestionName = _userInfo.IsEn_Us ? t.QuestionEnName : t.QuestionName ,t.DictionaryCode}).ToList();
trialTaskConfig!.OtherObj = questionList;
@@ -418,6 +423,8 @@ namespace IRaCIS.Core.Application.Service.Allocation
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == queryVisitTask.ReadingCategory)
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.RequestReReadingReason), t => t.RequestReReadingReason.Contains(queryVisitTask.RequestReReadingReason))
.WhereIf(queryVisitTask.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == queryVisitTask.RequestReReadingResultEnum)
.WhereIf(queryVisitTask.PIAuditState != null, t => t.OriginalReReadingTask.PIAuditState == queryVisitTask.PIAuditState)
@@ -656,39 +663,40 @@ namespace IRaCIS.Core.Application.Service.Allocation
var visitQuery = _visitTaskRepository
.Where(x => x.TrialId == inDto.TrialId && x.TaskState == TaskState.Effect)
//PI 读基线的时候,subject 如果PI基线没阅片完,SR就不能看
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline,
.WhereIf(inDto.SubjectId!=null,t=>t.SubjectId==inDto.SubjectId)
//PI 读基线的时候,subject 如果PI基线没阅片完,SR就不能看
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline && readingDivisionEnum == ReadingDivisionEnum.PIandSR,
t => t.Subject.SubjectVisitTaskList.Any(c => c.SourceSubjectVisit.IsBaseLine == true && c.ReadingTaskState == ReadingTaskState.HaveSigned && c.TaskState == TaskState.Effect && c.TrialReadingCriterionId == trialReadingCriterionId))
//PI 读随访的时候, subject 如果SR基线没阅片完,PI就不能看
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllVisit,
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllVisit && readingDivisionEnum == ReadingDivisionEnum.PIandSR,
t => t.Subject.SubjectVisitTaskList.Any(c => c.SourceSubjectVisit.IsBaseLine == true && c.ReadingTaskState == ReadingTaskState.HaveSigned && c.TaskState == TaskState.Effect && c.TrialReadingCriterionId == trialReadingCriterionId))
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR, t => t.Subject.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id))
// 仅仅SR阅片 PI 没有任务列表
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.OnlySR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI, t => t.TrialId == Guid.Empty)
//PI查看 PI阅片所有基线
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline,
t => t.SourceSubjectVisit.IsBaseLine == true)
//PI 阅片所有
// PI查看 PI 阅片所有
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllBaselineandVisit,
t => true)
// PI查看 PI 阅片访视
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllVisit,
t => t.SourceSubjectVisit.IsBaseLine == false)
//SR查看 PI阅片所有基线
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline,
t => t.SourceSubjectVisit.IsBaseLine == false)
//SR 不阅片
//SR查看 PI 阅片所有
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaselineandVisit,
t => t.TrialId == Guid.Empty)
//SR查看 PI 阅片访视
.WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllVisit,
t => t.SourceSubjectVisit.IsBaseLine == true)
@@ -1547,7 +1555,10 @@ namespace IRaCIS.Core.Application.Service.Allocation
#region
var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault();
//var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault();
var origenalTask = await _visitTaskRepository.FindAsync(task.Id);
foreach (var influenceTask in influenceTaskList)
{
@@ -1610,7 +1621,9 @@ namespace IRaCIS.Core.Application.Service.Allocation
await SetMedicalReviewInvalidAsync(currentVisitList);
var origenalTask = currentVisitList.Where(t => t.Id == task.Id).First();
//var origenalTask = currentVisitList.Where(t => t.Id == task.Id).First();
var origenalTask = await _visitTaskRepository.FindAsync(task.Id);
foreach (var influenceTask in currentVisitList)
{
@@ -4,6 +4,7 @@ using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using static IRaCIS.Core.Domain.Models.ReadingQuestionTrial;
namespace IRaCIS.Core.Application.Service
{
@@ -63,8 +64,10 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.SiteId, t => t.MapFrom(u => u.Subject.SiteId))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindTrialSiteCode :*/ u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindSubjectCode :*/ u.Subject.Code))
.ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.Subject.MedicalNo))
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
@@ -83,7 +86,8 @@ namespace IRaCIS.Core.Application.Service
CreateMap<VisitTask, ReadingTaskView>().IncludeBase<VisitTask, VisitTaskView>()
.ForMember(t=>t.PIReadingResultList,u=>u.MapFrom(c=>c.ReadingTaskQuestionAnswerList
.Where(t=>t.ReadingQuestionTrial.IsJudgeQuestion==true ).Select(d=>new PIReadingResult() { QuestionId= d.ReadingQuestionTrialId,Answer=d.Answer})));
.Where(t=> /*t.ReadingQuestionCriterionTrial.CriterionType==CriterionType.SelfDefine? t.ReadingQuestionTrial.AssessmentResultEnum == AssessmentResultType.AssessmentResult:*/ t.ReadingQuestionTrial.IsJudgeQuestion==true)
.Select(d=>new PIReadingResult() { QuestionId= d.ReadingQuestionTrialId,Answer=d.Answer})));
CreateMap<VisitTask, PIReaingTaskView>().IncludeBase<VisitTask, ReadingTaskView>()
.ForMember(o => o.FirstAuditUserName, t => t.MapFrom(u => u.FirstAuditUser.UserName))
@@ -165,13 +169,13 @@ namespace IRaCIS.Core.Application.Service
CreateMap<VisitTask, TaskMedicalReviewView>()
.ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code));
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u =>/* u.IsAnalysisCreate == true ? u.BlindTrialSiteCode :*/ u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindSubjectCode :*/ u.Subject.Code));
CreateMap<VisitTask, GenerateMedicalReviewTaskView>()
.ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindTrialSiteCode :*/ u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindSubjectCode :*/ u.Subject.Code))
.ForMember(o => o.GeneratedMedicalReviewCount, t => t.MapFrom(u => u.TaskMedicalReviewList.Count()))
.ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.Subject.MedicalNo))
.ForMember(o => o.IsGeneratedJudge, t => t.MapFrom(u => u.JudgeVisitTaskId != null))
@@ -42,6 +42,8 @@ namespace IRaCIS.Core.Application.ViewModel
public string Value { get; set; } = string.Empty;
public string ValueCN { get; set; } = string.Empty;
public string FrontType { get; set; } = string.Empty;
public int InternationalizationType { get; set; }
}
@@ -55,19 +57,23 @@ namespace IRaCIS.Core.Application.ViewModel
}
public class BatchAddInternationalizationDto
public class BatchInternationalizationDto
{
public string Description { get; set; } = string.Empty;
public string Code { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
public string FrontType { get; set; } = string.Empty;
public string ValueCN { get; set; } = string.Empty;
}
public class InternationalizationSimpleDto
public class BatchAddInternationalizationDto : BatchInternationalizationDto
{
public string Code { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
public string ValueCN { get; set; } = string.Empty;
}
public class InternationalizationSimpleDto: BatchInternationalizationDto
{
}
}
@@ -755,6 +755,7 @@ namespace IRaCIS.Core.Application.Service.Common
//.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null)
.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
@@ -10,6 +10,9 @@ using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Helper;
using EasyCaching.Core;
using IRaCIS.Core.Domain.Share;
using OfficeOpenXml.FormulaParsing.Utilities;
namespace IRaCIS.Core.Application.Service
{
@@ -19,28 +22,77 @@ namespace IRaCIS.Core.Application.Service
[ApiExplorerSettings(GroupName = "Common")]
public class InternationalizationService : BaseService, IInternationalizationService
{
private readonly IEasyCachingProvider _provider;
private readonly IRepository<Internationalization> _internationalizationRepository;
public InternationalizationService(IRepository<Internationalization> internationalizationRepository)
public InternationalizationService(IRepository<Internationalization> internationalizationRepository, IEasyCachingProvider provider)
{
_internationalizationRepository = internationalizationRepository;
_provider = provider;
}
/// <summary>
/// 前端国际化内容接口
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public async Task<List<InternationalizationSimpleDto>> GetFrontInternationalizationList()
[HttpGet]
public async Task<IEnumerable<InternationalizationSimpleDto>> GetFrontInternationalizationList()
{
var cacheList= _provider.Get<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front).Value;
var list = await _internationalizationRepository.Where(t => t.InternationalizationType == 0).Select(t => new InternationalizationSimpleDto()
if(cacheList != null && cacheList.Count!=0)
{
Code = t.Code,
Value = t.Value,
ValueCN = t.ValueCN
}).ToListAsync();
return cacheList;
}
else
{
var list = await _internationalizationRepository.Where(t => t.InternationalizationType == 0).Select(t => new InternationalizationSimpleDto()
{
Code = t.Code,
Value = t.Value,
ValueCN = t.ValueCN,
FrontType = t.FrontType,
Description = t.Description,
}).ToListAsync();
return list;
_provider.Set<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front, list, TimeSpan.FromDays(1));
return list;
}
}
/// <summary>
/// 前端批量提交,后端判断不存在就添加,存在就更新
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public async Task<IResponseOutput> BatchAddOrUpdateFrontInternationalization(List<BatchInternationalizationDto> batchList)
{
foreach (var item in batchList)
{
var find = await _internationalizationRepository.FirstOrDefaultAsync(t => t.Code == item.Code && t.Description == item.Description && t.InternationalizationType == 0);
if (find != null)
{
_mapper.Map(item, find);
}
else
{
var mapItem = _mapper.Map<Internationalization>(item);
mapItem.InternationalizationType = 0;
mapItem.State = 1;
await _internationalizationRepository.AddAsync(mapItem);
}
}
await _internationalizationRepository.SaveChangesAsync();
//清理缓存
_provider.Set<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front, new List<InternationalizationSimpleDto>(), TimeSpan.FromDays(1));
return ResponseOutput.Ok();
}
[HttpPost]
@@ -63,6 +115,11 @@ namespace IRaCIS.Core.Application.Service
return pageList;
}
/// <summary>
/// 后端之前批量添加接口
/// </summary>
/// <param name="batchAdd"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> BatchAddInternationalization(BatchAddInternationalization batchAdd)
{
@@ -87,21 +144,39 @@ namespace IRaCIS.Core.Application.Service
await _internationalizationRepository.SaveChangesAsync();
//清理缓存
_provider.Set<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front, new List<InternationalizationSimpleDto>(), TimeSpan.FromDays(1));
return ResponseOutput.Ok();
}
/// <summary>
/// 前后端添加的时候,区分了,前端判断重复多了多了一个路由 路由+标识唯一
/// </summary>
/// <param name="addOrEditInternationalization"></param>
/// <returns></returns>
public async Task<IResponseOutput> AddOrUpdateInternationalization(InternationalizationAddOrEdit addOrEditInternationalization)
{
var internationalizationType = addOrEditInternationalization.InternationalizationType;
//后端验证标识重复与否
var verifyExp1 = new EntityVerifyExp<Internationalization>()
{
VerifyExp = t => t.Code == addOrEditInternationalization.Code && t.InternationalizationType == addOrEditInternationalization.InternationalizationType,
VerifyMsg = $"该类型已有{addOrEditInternationalization.Code}名称的国际化标识",
IsVerify = true
IsVerify = internationalizationType == 1
};
var entity = await _internationalizationRepository.InsertOrUpdateAsync(addOrEditInternationalization, true, verifyExp1);
//前端验证标识重复与否
var verifyExp2 = new EntityVerifyExp<Internationalization>()
{
VerifyExp = t => t.Code == addOrEditInternationalization.Code && t.InternationalizationType == addOrEditInternationalization.InternationalizationType && t.Description == addOrEditInternationalization.Description,
VerifyMsg = $"该类型已有{addOrEditInternationalization.Description}下的{addOrEditInternationalization.Code}名称的国际化标识",
IsVerify = internationalizationType == 0
};
var entity = await _internationalizationRepository.InsertOrUpdateAsync(addOrEditInternationalization, true, verifyExp1, verifyExp2);
if (addOrEditInternationalization.InternationalizationType == 1)
{
@@ -109,6 +184,9 @@ namespace IRaCIS.Core.Application.Service
}
//清理缓存
_provider.Set<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front, new List<InternationalizationSimpleDto>(), TimeSpan.FromDays(1));
return ResponseOutput.Ok(entity.Id.ToString());
}
@@ -118,6 +196,9 @@ namespace IRaCIS.Core.Application.Service
public async Task<IResponseOutput> DeleteInternationalization(Guid internationalizationId)
{
var success = await _internationalizationRepository.DeleteFromQueryAsync(t => t.Id == internationalizationId, true);
//清理缓存
_provider.Set<List<InternationalizationSimpleDto>>(StaticData.InternationalData.Front, new List<InternationalizationSimpleDto>(), TimeSpan.FromDays(1));
return ResponseOutput.Ok();
}
@@ -177,6 +177,7 @@ namespace IRaCIS.Application.Services
builder.HtmlBody = string.Format(templateInfo,
"",
//---您正在进行邮箱重置密码操作
_localizer["Mail_ResettingPassword"],
verificationCode
@@ -244,6 +245,7 @@ namespace IRaCIS.Application.Services
builder.HtmlBody = string.Format(templateInfo,
"",
//---您正在参与展影医疗IRC项目
_localizer["Mail_IRCProject"],
verificationCode
@@ -310,6 +312,7 @@ namespace IRaCIS.Application.Services
builder.HtmlBody = string.Format(templateInfo,
"",
//---您正在参与展影医疗IRC项目中心调研工作
_localizer["Mail_CenterResearchReminder"],
verificationCode
@@ -74,6 +74,9 @@ namespace IRaCIS.Core.Application.Service
CreateMap<Internationalization, InternationalizationView>();
CreateMap<Internationalization, InternationalizationAddOrEdit>().ReverseMap();
CreateMap<Internationalization, BatchInternationalizationDto>().ReverseMap();
CreateMap<BatchAddInternationalizationDto, InternationalizationAddOrEdit>();
@@ -356,7 +356,7 @@ namespace IRaCIS.Core.Application.Service
.Include(t => t.TrialEmailNoticeUserList).Include(t => t.TrialEmailBlackUserList).FirstOrDefaultAsync();
if (trialEmailConfig == null || trialEmailConfig.IsAutoSend == false)
if (trialEmailConfig == null || trialEmailConfig.IsAutoSend == false || trialEmailConfig.IsEnable==false)
{
return;
}
@@ -477,7 +477,7 @@ namespace IRaCIS.Core.Application.Service
.Include(t => t.TrialEmailNoticeUserList).Include(t => t.TrialEmailBlackUserList).FirstOrDefaultAsync();
if (trialEmailConfig == null || trialEmailConfig.IsAutoSend == false)
if (trialEmailConfig == null || trialEmailConfig.IsAutoSend == false || trialEmailConfig.IsEnable==false)
{
return (null, null);
}
@@ -1322,13 +1322,14 @@ namespace IRaCIS.Core.Application.Service
/// </summary>
/// <param name="queryEmailNoticeConfig"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<TrialSelectEmailNoticeConfigView>> GetSysEmailNoticeConfigList(EmailNoticeConfigQuery queryEmailNoticeConfig)
{
var emailNoticeConfigQueryable = _emailNoticeConfigRepository
.WhereIf(queryEmailNoticeConfig.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == queryEmailNoticeConfig.BusinessScenarioEnum)
.WhereIf(queryEmailNoticeConfig.IsReturnRequired != null, t => t.IsReturnRequired == queryEmailNoticeConfig.IsReturnRequired)
.WhereIf(queryEmailNoticeConfig.IsEnable != null, t => t.IsEnable == queryEmailNoticeConfig.IsEnable)
.WhereIf(queryEmailNoticeConfig.CriterionTypeEnum != null, t => t.CriterionTypeEnum == queryEmailNoticeConfig.CriterionTypeEnum)
.ProjectTo<TrialSelectEmailNoticeConfigView>(_mapper.ConfigurationProvider, new { trialId = queryEmailNoticeConfig.TrialId });
return await emailNoticeConfigQueryable.ToPagedListAsync(queryEmailNoticeConfig.PageIndex, queryEmailNoticeConfig.PageSize, queryEmailNoticeConfig.SortField, queryEmailNoticeConfig.Asc);
@@ -30,6 +30,8 @@ namespace IRaCIS.Core.Application.Contracts
public bool IsDeleted { get; set; }
public bool IsReading { get; set; } = true;
public string SliceThickness { get; set; } = String.Empty;
public string ImageResizePath { get; set; }
}
@@ -38,8 +40,8 @@ namespace IRaCIS.Core.Application.Contracts
public class DicomTrialSiteSubjectInfo
{
public string TrialSiteCode { get; set; } = string.Empty;
public string SiteCode { get; set; } = string.Empty;
public string SiteName { get; set; } = string.Empty;
public string TrialSiteAliasName { get; set; } = string.Empty;
public string SubjectCode { get; set; } = string.Empty;
public int? SubjectAge { get; set; }
public string SubjectSex { get; set; } = string.Empty;
@@ -42,6 +42,7 @@ namespace IRaCIS.Core.Application.Contracts
//[JsonIgnore]
//public int NoneDicomCode { get; set; }
public string RecordPath { get; set; } = string.Empty;
public bool IsDicom { get; set; }
}
@@ -173,7 +174,16 @@ namespace IRaCIS.Core.Application.Contracts
public string[]? VisitPlanArray { get; set; }
}
public Guid? VisitTaskId { get; set; }
public bool? IsDicom { get; set; }
public string? Uploader { get; set; }
public bool? IsSuccess { get; set; }
public string? StudyCode { get; set; }
}
public class PreArchiveDicomStudyCommand
@@ -215,6 +225,8 @@ namespace IRaCIS.Core.Application.Contracts
public int FailedFileCount { get; set; }
public string RecordPath { get; set; }
public AddOrUpdateStudyDto Study { get; set; }
@@ -151,7 +151,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
studyMonitor.UploadFinishedTime = DateTime.Now;
studyMonitor.ArchiveFinishedTime = DateTime.Now;
studyMonitor.FailedFileCount = incommand.FailedFileCount;
studyMonitor.IsSuccess = true;
studyMonitor.IsSuccess = incommand.FailedFileCount==0;
studyMonitor.RecordPath=incommand.RecordPath;
//上传
if (studyMonitor.IsDicomReUpload == false)
@@ -209,6 +210,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
series.SubjectId = incommand.SubjectId;
series.SubjectVisitId = incommand.SubjectVisitId;
//前端传递的数量不准,上传的时候,把失败的也加进来了,以实际数组的数字为准
series.InstanceCount = seriesItem.InstanceList.Count;
await _dicomSeriesRepository.AddAsync(series);
foreach (var instanceItem in seriesItem.InstanceList)
@@ -241,6 +245,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var study = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == studyId);
//重传的时候也要赋值检查Id
studyMonitor.StudyId = study.Id;
studyMonitor.StudyCode = study.StudyCode;
//特殊处理逻辑
study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Union(study.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct());
@@ -457,6 +464,10 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
.WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId)
.WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId)
.WhereIf(studyQuery.SiteId != null, t => t.SiteId == studyQuery.SiteId)
.WhereIf(studyQuery.IsDicom != null, t => t.IsDicom == studyQuery.IsDicom )
.WhereIf(!string.IsNullOrWhiteSpace(studyQuery.Uploader), t => t.Uploader.UserName.Contains(studyQuery.Uploader))
.WhereIf(studyQuery.IsSuccess != null, t => t.IsSuccess == studyQuery.IsSuccess)
.WhereIf(!string.IsNullOrWhiteSpace(studyQuery.StudyCode), t => t.StudyCode.Contains(studyQuery.StudyCode))
.Select(t => new UnionStudyMonitorModel()
{
TrialId = t.TrialId,
@@ -489,7 +500,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
ArchiveFinishedTime = t.ArchiveFinishedTime,
RecordPath=t.RecordPath,
IsDicomReUpload = t.IsDicomReUpload,
StudyId = t.Id,
@@ -62,6 +62,7 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.UploadedTime, t => t.MapFrom(u => u.CreateTime))
.ForMember(o => o.Uploader, t => t.MapFrom(u => u.Uploader.LastName + " / " + u.Uploader.FirstName))
.ForMember(o => o.StudyId, t => t.MapFrom(u => u.Id))
.ForMember(o => o.IsHaveUploadFailed, t => t.MapFrom(u => u.DicomStudyMonitorList.Any(t=>t.FailedFileCount>0)))
.ForMember(o => o.Modalities, t => t.MapFrom(u => string.Join('、', u.SeriesList.Select(t => t.Modality).Distinct()) ));
@@ -80,6 +81,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<DicomInstance, DicomInstanceDTO>()
.ForMember(o => o.IsDeleted, t => t.MapFrom(u => u.DicomSerie.IsDeleted))
.ForMember(o => o.SliceThickness, t => t.MapFrom(u => u.DicomSerie.SliceThickness))
.ForMember(o => o.IsReading, t => t.MapFrom(u => u.DicomSerie.IsReading));
CreateMap<DicomStudy, DicomStudyDTO>();
CreateMap<DicomSeries, DicomSeriesDTO>();
@@ -319,9 +319,9 @@ namespace IRaCIS.Core.Application.Service
{
continue;
}
str = await GetInspectionEnumValue(listIdentification, str);
str = await SetEnum(dto.TrialId, listIdentification, str);
str = await SetDataInspectionDateType(listIdentification, str);
str = await GetInspectionEnumValue(listIdentification, item.Identification, str);
str = await SetEnum(dto.TrialId, listIdentification, item.Identification, str);
str = await SetDataInspectionDateType(listIdentification, item.Identification, str);
jsonDict[nameof(InspectionJsonDetail.Data)] = JsonConvert.DeserializeObject<object>(str);
@@ -331,9 +331,9 @@ namespace IRaCIS.Core.Application.Service
{
continue;
}
str2 = await GetInspectionEnumValue(listIdentification, str2);
str2 = await SetEnum(dto.TrialId, listIdentification, str2);
str2 = await SetDataInspectionDateType(listIdentification, str2);
str2 = await GetInspectionEnumValue(listIdentification, item.Identification, str2);
str2 = await SetEnum(dto.TrialId, listIdentification, item.Identification, str2);
str2 = await SetDataInspectionDateType(listIdentification, item.Identification, str2);
jsonDict[nameof(InspectionJsonDetail.CommonData)] = JsonConvert.DeserializeObject<object>(str2);
#endregion
@@ -456,20 +456,23 @@ namespace IRaCIS.Core.Application.Service
/// <param name="identificationList"></param>
/// <param name="jsonStr"></param>
/// <returns></returns>
private async Task<string> SetDataInspectionDateType(List<string> identificationList, string jsonStr)
private async Task<string> SetDataInspectionDateType(List<string> identificationList,string identification, string jsonStr)
{
var list = await (from parent in _frontAuditConfigRepository.AsQueryable().Where(x => identificationList.Contains(x.Identification))
join child in _frontAuditConfigRepository.AsQueryable().Where(x => x.EnumType == "Date" && x.IsEnable) on parent.Id equals child.ParentId
select new DateDto()
{
Code = child.Code,
Identification= parent.Identification,
Code = child.Code,
DateType = child.DateType,
}).ToListAsync();
list = list.GroupBy(x => new { x.Code }, (key, lst) => new DateDto()
{
Code = key.Code,
DateType = lst.Max(x => x.DateType),
DateType = lst.FirstOrDefault(y => y.Identification == identification)?.DateType ?? lst.Max(x => x.DateType),
}).ToList();
var jsonDataDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(jsonStr);
@@ -519,23 +522,25 @@ namespace IRaCIS.Core.Application.Service
///// <param name="ForeignKeyValue">外键value</param>
///// <param name="ForeignKeyText">要查询的外键值</param>
///// <param name="value">传入的纸</param>
private async Task<string> GetInspectionEnumValue(List<string> identificationList, string jsonStr)
private async Task<string> GetInspectionEnumValue(List<string> identificationList,string identification, string jsonStr)
{
var list = await (from u in _frontAuditConfigRepository.Where(x => identificationList.Contains(x.Identification))
join p in _frontAuditConfigRepository.Where(x => x.EnumType == "Foreign" && x.IsEnable) on u.Id equals p.ParentId
select new
{
Key = p.Code,
ForeignKeyValue = p.ForeignKeyValue,
Identification=u.Identification,
ForeignKeyValue = p.ForeignKeyValue,
ForeignKeyText = p.ForeignKeyText,
ForeignKeyTable = p.ForeignKeyTableName
}).ToListAsync();
list = list.GroupBy(x => new { x.Key }, (key, lst) => new
{
Key = key.Key,
ForeignKeyValue = lst.Max(x => x.ForeignKeyValue),
ForeignKeyText = lst.Max(x => x.ForeignKeyText),
ForeignKeyTable = lst.Max(x => x.ForeignKeyTable),
Identification=string.Empty,
ForeignKeyValue= lst.FirstOrDefault(y => y.Identification == identification)?.ForeignKeyValue ?? lst.Max(x => x.ForeignKeyValue),
ForeignKeyText = lst.FirstOrDefault(y => y.Identification == identification)?.ForeignKeyText ?? lst.Max(x => x.ForeignKeyText),
ForeignKeyTable = lst.FirstOrDefault(y => y.Identification == identification)?.ForeignKeyTable ?? lst.Max(x => x.ForeignKeyTable),
}).ToList();
@@ -585,7 +590,7 @@ namespace IRaCIS.Core.Application.Service
/// <param name="identificationList">标识</param>
/// <param name="jsonStr">Json对象</param>
/// <returns></returns>
private async Task<string> SetEnum(Guid trialId, List<string> identificationList, string jsonStr)
private async Task<string> SetEnum(Guid trialId, List<string> identificationList, string identification, string jsonStr)
{
if (jsonStr == null || jsonStr == "null")
{
@@ -598,27 +603,41 @@ namespace IRaCIS.Core.Application.Service
join p in _frontAuditConfigRepository.Where(x => (x.DictionaryCode != string.Empty && x.EnumType == "Dictionary") || (x.DataType == "Table") && x.IsEnable) on u.Id equals p.ParentId
select new
{
//前端展示类型
DataType = p.DataType,
TableConfigJsonStr = p.TableConfigJsonStr,
Key = p.Code,
Key = p.Code,
Identification = u.Identification,
//前端展示类型
DataType = p.DataType,
TableConfigJsonStr = p.TableConfigJsonStr,
Code = p.DictionaryCode,
Type = p.DictionaryType
}).ToListAsync();
//两条不同的标识 但是里面配置有相同的翻译字典
list = list.Distinct().ToList();
list = list.GroupBy(x => new { x.Key }, (key, lst) => new
{
Key = key.Key,
Identification = string.Empty,
DataType = lst.FirstOrDefault(y => y.Identification == identification)?.DataType ?? lst.Max(x => x.DataType),
TableConfigJsonStr = lst.FirstOrDefault(y => y.Identification == identification)?.TableConfigJsonStr ?? lst.Max(x => x.TableConfigJsonStr),
Code = lst.FirstOrDefault(y => y.Identification == identification)?.Code ?? lst.Max(x => x.Code),
Type = lst.FirstOrDefault(y => y.Identification == identification)?.Type ?? lst.Max(x => x.Type),
// 添加单双审
var trialtype = await _trialRepository.AsQueryable().Where(x => x.Id == trialId).Select(x => x.QCProcessEnum).FirstOrDefaultAsync();
}).ToList();
// 添加单双审
var trialtype = await _trialRepository.AsQueryable().Where(x => x.Id == trialId).Select(x => x.QCProcessEnum).FirstOrDefaultAsync();
if (!list.Any(x => x.Key == "AuditState"))
{
list.Add(new
{
DataType = string.Empty,
TableConfigJsonStr = string.Empty,
Key = "AuditState",
{
Key = "AuditState",
Identification = string.Empty,
DataType = string.Empty,
TableConfigJsonStr = string.Empty,
Code = trialtype == TrialQCProcess.SingleAudit ? "AuditStatePE" : "AuditStateRC",
Type = "Code",
});
@@ -1076,7 +1095,8 @@ namespace IRaCIS.Core.Application.Service
[HttpGet]
public async Task<List<string>> GetModuleTypeDescriptionList(Guid moduleTypeId)
{
var result = await _frontAuditConfigRepository.Where(x => x.ModuleTypeId == moduleTypeId && x.ObjectTypeId != null && x.OptTypeId != null && x.Description.Length > 0).Select(x => new { x.Description, x.DescriptionCN, x.Sort }).OrderBy(t => t.Sort).Select(t => _userInfo.IsEn_Us? t.Description:t.DescriptionCN).Distinct().ToListAsync();
var result =( await _frontAuditConfigRepository.Where(x => x.ModuleTypeId == moduleTypeId && x.ObjectTypeId != null && x.OptTypeId != null && x.Description.Length > 0).Select(x => new { x.Description, x.DescriptionCN, x.Sort }).OrderBy(t => t.Sort).ToListAsync()
).Select(t => _userInfo.IsEn_Us? t.Description:t.DescriptionCN).Distinct().ToList();
return result;
}
@@ -3,9 +3,9 @@ using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Contracts
{
public class SiteDTO: SiteCommand
public class SiteDTO : SiteCommand
{
}
public class SiteCommand
@@ -24,7 +24,7 @@ namespace IRaCIS.Application.Contracts
public string AliasName { get; set; } = string.Empty;
public string City { get; set; } = string.Empty;
public string Country { get; set; } = string.Empty;
public Guid? HospitalId { get; set; }
public Guid? HospitalId { get; set; }
public string DirectorName { get; set; } = string.Empty;
public string DirectorPhone { get; set; } = string.Empty;
public string ContactName { get; set; } = string.Empty;
@@ -35,6 +35,9 @@ namespace IRaCIS.Application.Contracts
{
public Guid Id { get; set; }
public string SiteName { get; set; } = String.Empty;
public string SiteNameCN { get; set; } = String.Empty;
public string City { get; set; } = String.Empty;
public string Province { get; set; } = string.Empty;
@@ -3,18 +3,20 @@ using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infra.EFCore;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Infrastructure;
using Microsoft.Data.Sqlite;
namespace IRaCIS.Application.Services
{
[ ApiExplorerSettings(GroupName = "Institution")]
[ApiExplorerSettings(GroupName = "Institution")]
public class HospitalService : BaseService, IHospitalService
{
private readonly IRepository<Hospital> _hospitalRepository;
private readonly IRepository<Site> _siteRepository;
public HospitalService(IRepository<Hospital> hospitalRepository )
public HospitalService(IRepository<Hospital> hospitalRepository, IRepository<Site> siteRepository)
{
_hospitalRepository = hospitalRepository;
_siteRepository = siteRepository;
}
/// <summary> 获取所有医院列表 </summary>
@@ -37,15 +39,26 @@ namespace IRaCIS.Application.Services
var exp1 = new EntityVerifyExp<Hospital>()
{
VerifyExp = x => x.SiteId == hospitalCommand.SiteId && hospitalCommand.SiteId != null,
//---已经存在同名的医院,请确认
//---当前中心已经添加到其他医院了
VerifyMsg = _localizer["Hospital_SiteAdded"]
};
var hospital = await _hospitalRepository.InsertOrUpdateAsync(hospitalCommand, true, exp,exp1);
var hospital = await _hospitalRepository.InsertOrUpdateAsync(hospitalCommand, true, exp, exp1);
//手动解绑医院与site的关系
if (hospitalCommand.SiteId == null && hospital.SiteId != null)
{
await _siteRepository.BatchUpdateNoTrackingAsync(t => t.Id == hospital.SiteId, u => new Site() { HospitalId = null });
}
//手动绑
if (hospitalCommand.SiteId != null)
{
await _siteRepository.BatchUpdateNoTrackingAsync(t => t.Id == hospitalCommand.SiteId, u => new Site() { HospitalId = hospital.Id });
}
return ResponseOutput.Ok(hospital.Id.ToString());
}
@@ -54,11 +67,6 @@ namespace IRaCIS.Application.Services
[HttpDelete("{hospitalId:guid}")]
public async Task<IResponseOutput> DeleteHospital(Guid hospitalId)
{
//if (_userRepository.Find().Any(t => t.OrganizationId == hospitalId))
//{
// return ResponseOutput.NotOk("该医院下存在用户,暂时无法删除。");
//}
var success = await _hospitalRepository.BatchDeleteNoTrackingAsync(x => x.Id == hospitalId);
@@ -67,12 +75,12 @@ namespace IRaCIS.Application.Services
/// <summary> 分页获取医院列表 </summary>
[HttpPost]
public async Task<PageOutput<HospitalDTO>> GetHospitalPageList(HospitalQueryDTO hospitalSearchModel)
public async Task<PageOutput<HospitalDTO>> GetHospitalPageList(HospitalQueryDTO hospitalSearchModel)
{
var hospitalQueryable =
_hospitalRepository
.WhereIf(hospitalSearchModel.HospitalName!=null, t => t.HospitalName.Contains(hospitalSearchModel.HospitalName!) || t.HospitalNameCN.Contains(hospitalSearchModel.HospitalName!))
.WhereIf(hospitalSearchModel.HospitalName != null, t => t.HospitalName.Contains(hospitalSearchModel.HospitalName!) || t.HospitalNameCN.Contains(hospitalSearchModel.HospitalName!))
.WhereIf(hospitalSearchModel.City != null, t => t.City.Contains(hospitalSearchModel.City!) || t.HospitalNameCN.Contains(hospitalSearchModel.City!))
.WhereIf(hospitalSearchModel.Province != null, t => t.Province.Contains(hospitalSearchModel.Province!) || t.HospitalNameCN.Contains(hospitalSearchModel.Province!))
.ProjectTo<HospitalDTO>(_mapper.ConfigurationProvider);
@@ -4,6 +4,7 @@ using IRaCIS.Core.Infra.EFCore;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Share;
using Medallion.Threading;
using IRaCIS.Core.Domain.Models;
namespace IRaCIS.Application.Services
{
@@ -13,12 +14,14 @@ namespace IRaCIS.Application.Services
private readonly IRepository<Site> _siteRepository;
private readonly IRepository<TrialSiteUser> _trialSiteUserRepository;
private readonly IDistributedLockProvider _distributedLockProvider;
private readonly IRepository<Hospital> _hospitalRepository;
public SiteService(IRepository<Site> siteRepository, IRepository<TrialSiteUser> trialSiteUserRepository, IDistributedLockProvider distributedLockProvider)
public SiteService(IRepository<Site> siteRepository, IRepository<TrialSiteUser> trialSiteUserRepository, IDistributedLockProvider distributedLockProvider, IRepository<Hospital> hospitalRepository)
{
_siteRepository = siteRepository;
_trialSiteUserRepository = trialSiteUserRepository;
_distributedLockProvider = distributedLockProvider;
_hospitalRepository = hospitalRepository;
}
/// <summary> 分页获取研究中心列表 </summary>
@@ -32,7 +35,7 @@ namespace IRaCIS.Application.Services
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.City), t => t.City.Contains(searchModel.City))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Country), t => t.Country.Contains(searchModel.Country))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Province), t => t.Province.Contains(searchModel.Province))
.ProjectTo<SiteSelectDTO>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us });
.ProjectTo<SiteSelectDTO>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us });
return await siteQueryable.ToPagedListAsync(searchModel.PageIndex, searchModel.PageSize, string.IsNullOrWhiteSpace(searchModel.SortField) ? "SiteName" : searchModel.SortField, searchModel.Asc);
@@ -67,11 +70,23 @@ namespace IRaCIS.Application.Services
siteCommand.Code = await _siteRepository.Select(t => t.Code).DefaultIfEmpty().MaxAsync() + 1;
siteCommand.SiteCode = AppSettings.GetCodeStr(siteCommand.Code, nameof(User));
siteCommand.SiteCode = AppSettings.GetCodeStr(siteCommand.Code, nameof(Site));
}
var site = await _siteRepository.InsertOrUpdateAsync(siteCommand, true, exp);
//手动解绑医院与site的关系
if (siteCommand.HospitalId == null && site.HospitalId != null)
{
await _hospitalRepository.BatchUpdateNoTrackingAsync(t => t.Id == site.HospitalId, u => new Hospital() { SiteId = null });
}
//手动绑
if (siteCommand.HospitalId != null)
{
await _hospitalRepository.BatchUpdateNoTrackingAsync(t => t.Id == siteCommand.HospitalId, u => new Hospital() { SiteId = site.Id });
}
return ResponseOutput.Ok(site.Id.ToString());
}
@@ -34,6 +34,8 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid? LoginUserId { get; set; }
public Guid? OptUserId { get; set; }
public string IPRegion { get; set; }
}
///<summary>UserLogQuery 列表查询参数模型</summary>
@@ -47,10 +49,17 @@ namespace IRaCIS.Core.Application.ViewModel
public string? LoginFaildName { get; set; }
public string? LoginUserName { get; set; }
public DateTime? BeginDate { get; set; }
public DateTime? EndDate { get; set; }
public UserTypeEnum? LoginUserTypeEnum { get; set; }
public Guid? UserTypeId { get; set; }
public Guid? UserId { get; set; }
}
@@ -12,6 +12,7 @@ using Microsoft.Identity.Client;
using static IRaCIS.Core.Domain.Share.StaticData;
using IRaCIS.Core.Application.ViewModel;
using Medallion.Threading;
using EasyCaching.Core;
namespace IRaCIS.Application.Services
{
@@ -25,7 +26,7 @@ namespace IRaCIS.Application.Services
private readonly IRepository<UserLog> _userLogRepository;
private readonly IDistributedLockProvider _distributedLockProvider;
private readonly IMemoryCache _cache;
private readonly IEasyCachingProvider _cache;
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
@@ -34,7 +35,7 @@ namespace IRaCIS.Application.Services
IMailVerificationService mailVerificationService,
IRepository<VerificationCode> verificationCodeRepository,
IMemoryCache cache,
IEasyCachingProvider cache,
IRepository<TrialUser> userTrialRepository,
IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig,
IRepository<UserLog> userLogRepository
@@ -128,7 +129,7 @@ namespace IRaCIS.Application.Services
{
//检查手机或者邮箱是否有效
if (!Regex.IsMatch(email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"))
if (!Regex.IsMatch(email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
{
//---Please input a legal email
return ResponseOutput.NotOk(_localizer["User_LegalEmail"]);
@@ -310,7 +311,7 @@ namespace IRaCIS.Application.Services
{
//检查手机或者邮箱是否有效
if (!Regex.IsMatch(email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"))
if (!Regex.IsMatch(email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
{
//---请输入一个正确的邮箱。
@@ -629,7 +630,7 @@ namespace IRaCIS.Application.Services
string cacheKey = $"{cachePrefix}{userName}";
// 从缓存中获取登录失败次数
int? failCount = _cache.Get<int?>(cacheKey);
int? failCount = _cache.Get<int?>(cacheKey).Value;
if (failCount == null)
{
@@ -660,7 +661,9 @@ namespace IRaCIS.Application.Services
failCount++;
_cache.Set(cacheKey, failCount, TimeSpan.FromMinutes(lockoutMinutes));
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId=Guid.Empty, LoginFaildName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError }, true);
var errorPwdUserId = await _userRepository.Where(u => u.UserName == userName).Select(t => t.Id).FirstOrDefaultAsync();
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = errorPwdUserId, OptUserId=Guid.Empty, LoginFaildName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError }, true);
return ResponseOutput.NotOk(_localizer["User_CheckNameOrPw"], new LoginReturnDTO());
@@ -693,15 +696,22 @@ namespace IRaCIS.Application.Services
[HttpPost]
public async Task<PageOutput<UserLogView>> GetUserLogList(UserLogQuery inQuery)
{
DateTime? trialCreateTime = inQuery.TrialId != null ? _repository.Where<Trial>(t => t.Id == inQuery.TrialId).Select(t => t.CreateTime).FirstOrDefault() : null;
var userLogQueryable =
_userLogRepository
.WhereIf(inQuery.TrialId != null, t => t.LoginUser.UserTrials.Any(c => c.TrialId == inQuery.TrialId && c.UserId == t.LoginUserId))
.WhereIf(inQuery.TrialId != null, t => t.LoginUser.UserTrials.Any(c => c.TrialId == inQuery.TrialId && (c.UserId == t.LoginUserId || c.UserId == t.OptUserId)))
.WhereIf(trialCreateTime != null, t => t.CreateTime >= trialCreateTime)
.WhereIf(inQuery.OptType != null, t => t.OptType == inQuery.OptType)
.WhereIf(inQuery.UserId != null, t => t.LoginUserId == inQuery.UserId)
.WhereIf(inQuery.BeginDate != null, t => t.CreateTime >= inQuery.BeginDate)
.WhereIf(inQuery.EndDate != null, t => t.CreateTime <= inQuery.EndDate)
.WhereIf(!string.IsNullOrEmpty(inQuery.LoginUserName), t => t.LoginUser.UserName.Contains(inQuery.LoginUserName!))
.WhereIf(!string.IsNullOrEmpty(inQuery.LoginFaildName), t => t.LoginFaildName.Contains(inQuery.LoginFaildName!))
.WhereIf(!string.IsNullOrEmpty(inQuery.IP), t => t.IP.Contains(inQuery.IP!))
.WhereIf(inQuery.LoginUserTypeEnum != null, t => t.LoginUser.UserTypeEnum == inQuery.LoginUserTypeEnum)
.WhereIf(inQuery.UserTypeId != null, t => t.LoginUser.UserTypeId == inQuery.UserTypeId)
.ProjectTo<UserLogView>(_mapper.ConfigurationProvider);
var pageList = await userLogQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? "Id" : inQuery.SortField, inQuery.Asc);
@@ -386,7 +386,7 @@ namespace IRaCIS.Core.Application.Contracts.DTO
public string ModalityForEdit { get; set; } = string.Empty;
public bool IsHaveUploadFailed { get; set; }
}
public class QASeriesInfoDto
@@ -1099,6 +1099,8 @@ namespace IRaCIS.Core.Application.Contracts
public int? Age { get; set; }
public string Sex { get; set; } = string.Empty;
public bool IsHaveUploadFailed { get; set; }
}
@@ -925,7 +925,7 @@ namespace IRaCIS.Core.Application.Image.QA
return new GetNextIQCQualityOutDto() { };
break;
case TrialQCProcess.SingleAudit:
visitList = await _subjectVisitRepository.Where(x => x.SubmitState != SubmitStateEnum.None && x.TrialId == inDto.TrialId && x.PreliminaryAuditUserId != _userInfo.Id && (x.CurrentActionUserId == _userInfo.Id || (x.AuditState != AuditStateEnum.PrimaryQCPassed && !x.IsTake))).Include(x => x.Subject).ToListAsync();
visitList = await _subjectVisitRepository.Where(x => x.SubmitState == SubmitStateEnum.Submitted && x.TrialId == inDto.TrialId && x.PreliminaryAuditUserId!= _userInfo.Id&&(x.CurrentActionUserId == _userInfo.Id || (x.AuditState != AuditStateEnum.PrimaryQCPassed && !x.IsTake))).Include(x => x.Subject).ToListAsync();
subjectVisit = visitList.Where(x => x.SubjectId == inDto.SubjectId).OrderBy(x => x.VisitNum).FirstOrDefault();
if (subjectVisit != null)
@@ -953,7 +953,7 @@ namespace IRaCIS.Core.Application.Image.QA
break;
case TrialQCProcess.DoubleAudit:
visitList = await _subjectVisitRepository.Where(x => x.SubmitState != SubmitStateEnum.None && x.TrialId == inDto.TrialId &&
visitList = await _subjectVisitRepository.Where(x => x.SubmitState == SubmitStateEnum.Submitted && x.TrialId == inDto.TrialId &&
((x.CurrentActionUserId == _userInfo.Id)||(!x.IsTake&& x.AuditState != AuditStateEnum.QCPassed&& (x.PreliminaryAuditUserId != _userInfo.Id)))
).Include(x => x.Subject).ToListAsync();
if (subjectVisit != null)
@@ -1224,7 +1224,7 @@ namespace IRaCIS.Core.Application.Image.QA
var trialId = cRCRequestToQCCommand.TrialId;
var trialConfig = (await _trialRepository
.Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification, t.IsUrgent, t.IsHaveFirstGiveMedicineDate, t.ClinicalInformationTransmissionEnum })
.Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification, t.IsUrgent, t.IsEnrollementQualificationConfirm,t.IsPDProgressView, t.IsHaveFirstGiveMedicineDate, t.ClinicalInformationTransmissionEnum })
.FirstOrDefaultAsync(t => t.TrialId == cRCRequestToQCCommand.TrialId)).IfNullThrowException();
//找到符合配置的标准 确认的并且签名的、双重,有序,阅片期仲裁
@@ -1307,10 +1307,15 @@ namespace IRaCIS.Core.Application.Image.QA
//已确认临床数据完整性
dbSubjectVisit.IsConfirmedClinicalData = true;
// 根据项目配置 设置访视的入组确认和pd进展
// CRC 上传的基线数据签名
dbSubjectVisit.IsEnrollmentConfirm= dbSubjectVisit.IsBaseLine && trialConfig.IsEnrollementQualificationConfirm ?true:false;
await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(x =>
dbSubjectVisit.PDState = dbSubjectVisit.IsBaseLine==false && trialConfig.IsPDProgressView ? PDStateEnum.PDProgress:PDStateEnum.None;
// CRC 上传的基线数据签名
await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(x =>
(x.ClinicalDataTrialSet.ClinicalDataLevel== ClinicalLevel.Subject|| x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)&&
@@ -1355,40 +1360,40 @@ namespace IRaCIS.Core.Application.Image.QA
//dbSubjectVisit.Subject.IsMissingImages = await _subjectVisitRepository.AnyAsync(t => (t.VisitNum < maxVisitNum && t.SubmitState != SubmitStateEnum.Submitted && t.IsLostVisit == false));
//项目或者Subject IsUrgent 提交时 访视也设置为紧急
if (trialConfig.IsUrgent || dbSubjectVisit.Subject.IsUrgent || (dbSubjectVisit.PDState == PDStateEnum.PDProgress && !dbSubjectVisit.IsBaseLine) || (dbSubjectVisit.IsEnrollmentConfirm && dbSubjectVisit.IsBaseLine))
if (trialConfig.IsUrgent || dbSubjectVisit.Subject.IsUrgent || (dbSubjectVisit.IsEnrollmentConfirm && dbSubjectVisit.IsBaseLine))
{
if (dbSubjectVisit.PDState == PDStateEnum.PDProgress)
{
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(x => x.SubjectId == dbSubjectVisit.SubjectId && x.VisitNum <= dbSubjectVisit.VisitNum, x => new SubjectVisit()
{
IsUrgent = true
});
//if (dbSubjectVisit.PDState == PDStateEnum.PDProgress)
//{
// await _subjectVisitRepository.BatchUpdateNoTrackingAsync(x => x.SubjectId == dbSubjectVisit.SubjectId && x.VisitNum <= dbSubjectVisit.VisitNum, x => new SubjectVisit()
// {
// IsUrgent = true
// });
// await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => trialInOrderCriterionIdList.Contains(x.TrialReadingCriterionId) && x.SubjectId == dbSubjectVisit.SubjectId &&
// dbSubjectVisit.VisitNum <= x.VisitTaskNum && x.VisitTaskNum < Math.Ceiling(dbSubjectVisit.VisitNum + 0.01m) // 当前的访视 全局 裁判 及之前 全都加急
// && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.TaskState == TaskState.Effect, x => new VisitTask()
// {
// IsUrgent = true,
// TaskUrgentType = TaskUrgentType.PDProgress,
// IsCanEditUrgentState = false,
// });
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => trialInOrderCriterionIdList.Contains(x.TrialReadingCriterionId)&& x.SubjectId == dbSubjectVisit.SubjectId&&
dbSubjectVisit.VisitNum<= x.VisitTaskNum && x.VisitTaskNum < Math.Ceiling(dbSubjectVisit.VisitNum+0.01m) // 当前的访视 全局 裁判 及之前 全都加急
&& x.ReadingTaskState != ReadingTaskState.HaveSigned && x.TaskState == TaskState.Effect, x => new VisitTask()
{
// await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => trialInOrderCriterionIdList.Contains(x.TrialReadingCriterionId) && x.SubjectId == dbSubjectVisit.SubjectId
// && x.VisitTaskNum < dbSubjectVisit.VisitNum // 当前的访视 全局 裁判 及之前 全都加急
// && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.TaskState == TaskState.Effect, x => new VisitTask()
// {
IsUrgent = true,
TaskUrgentType = TaskUrgentType.PDProgress,
IsCanEditUrgentState=false,
});
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => trialInOrderCriterionIdList.Contains(x.TrialReadingCriterionId) && x.SubjectId == dbSubjectVisit.SubjectId
&& x.VisitTaskNum < dbSubjectVisit.VisitNum // 当前的访视 全局 裁判 及之前 全都加急
&& x.ReadingTaskState != ReadingTaskState.HaveSigned && x.TaskState == TaskState.Effect, x => new VisitTask()
{
IsUrgent = true,
TaskUrgentType = TaskUrgentType.Other,
TaskUrgentRemake= "后续访视设为pd",
IsCanEditUrgentState = false,
});
}
else if (dbSubjectVisit.IsEnrollmentConfirm)
// IsUrgent = true,
// TaskUrgentType = TaskUrgentType.Other,
// TaskUrgentRemake = "后续访视设为pd",
// IsCanEditUrgentState = false,
// });
//}
//else
if (dbSubjectVisit.IsEnrollmentConfirm)
{
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(x => x.Id == dbSubjectVisit.Id, x => new SubjectVisit()
{
@@ -1420,14 +1425,14 @@ namespace IRaCIS.Core.Application.Image.QA
dbSubjectVisit.IsUrgent = true;
//PD确认的紧急会把前面所有未QC完成的访视均标记为紧急
////PD确认的紧急会把前面所有未QC完成的访视均标记为紧急
var previosSVlist = await _subjectVisitRepository.Where(t => t.SubjectId == dbSubjectVisit.SubjectId && t.VisitNum < dbSubjectVisit.VisitNum && t.IsUrgent == false && t.SubmitState == SubmitStateEnum.Submitted, true).ToListAsync();
//var previosSVlist = await _subjectVisitRepository.Where(t => t.SubjectId == dbSubjectVisit.SubjectId && t.VisitNum < dbSubjectVisit.VisitNum && t.IsUrgent == false && t.SubmitState == SubmitStateEnum.Submitted, true).ToListAsync();
previosSVlist.ForEach(t =>
{
t.IsUrgent = true;
});
//previosSVlist.ForEach(t =>
//{
// t.IsUrgent = true;
//});
}
@@ -104,7 +104,7 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.Subject.Code))
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode))
.ForMember(d => d.CheckDialogStr, u => u.MapFrom(t => string.Join(" | ", t.CheckChallengeDialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUser.UserName + " " + c.CreateTime.ToString("yyyy-mm-dd hh:mm:ss") + " :" + c.TalkContent))))
.ForMember(d => d.CheckDialogStr, u => u.MapFrom(t => string.Join(" | ", t.CheckChallengeDialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUser.UserName + " " + c.CreateTime.ToString("yyyy-MM-dd HH:mm:ss") + " :" + c.TalkContent))))
.ForMember(d => d.ModalityList, c => c.MapFrom(s =>
(s.NoneDicomStudyList.Select(t => t.Modality)
.Union(s.StudyList.Select(k => k.ModalityForEdit))).Distinct()))
@@ -395,6 +395,8 @@ namespace IRaCIS.Core.Application.Service
|| t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count() > 0)
|| t.PreviousSurgeryList.Any()))
.ForMember(d => d.IsHaveUploadFailed, u => u.MapFrom(t => t.StudyList.SelectMany(c=>c.DicomStudyMonitorList).Any(h => h.FailedFileCount>0) ))
//.ForMember(d => d.VisitName, u => u.MapFrom(t =>t.InPlan? t.VisitStage.VisitName : t.VisitName))
//.ForMember(d => d.VisitNum, u => u.MapFrom(t => t.InPlan ? t.VisitStage.VisitNum : t.VisitNum))
//.ForMember(d => d.VisitDay, u => u.MapFrom(t => t.InPlan ? t.VisitStage.VisitDay : t.VisitDay))
@@ -190,23 +190,24 @@ namespace IRaCIS.Application.Services
.WhereIf(inDto.IsBaseline, x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
.WhereIf(!inDto.IsBaseline, x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
.Where(x => x.ClinicalDataTrialSet.TrialId == inDto.TrialId && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC)
.Include(x=>x.ClinicalDataTrialSet)
.OrderBy(x=>x.ClinicalDataTrialSet.CreateTime)
.Include(x => x.ClinicalDataTrialSet)
.OrderBy(x => x.ClinicalDataTrialSet.CreateTime)
.Select(x => new GetCRCClinicalDataOutDto()
{
Id = x.Id,
ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us) ,
ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us),
ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
ClinicalDataSetEnName=x.ClinicalDataTrialSet.ClinicalDataSetEnName,
ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName,
ClinicalDataTrialSetId = x.ClinicalDataTrialSet.Id,
FileName = x.ClinicalDataTrialSet.FileName,
UploadRole = x.ClinicalDataTrialSet.UploadRole,
Path = x.ClinicalDataTrialSet.Path,
IsBlind = x.IsBlind,
IsComplete = x.IsComplete,
ClinicalFromList=x.Subject.ClinicalFormList.Where(y=>y.ReadingId==x.ReadingId&&y.ClinicalDataTrialSetId==x.ClinicalDataTrialSetId).Select(y=> new ClinicalFromData() {
CheckDate=y.CheckDate,
ClinicalFormId=y.Id
ClinicalFromList = x.Subject.ClinicalFormList.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
{
CheckDate = y.CheckDate,
ClinicalFormId = y.Id
}).ToList(),
PDFFileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
{
@@ -215,7 +216,7 @@ namespace IRaCIS.Application.Services
Path = y.Path,
CreateTime = y.CreateTime,
}).ToList(),
}).ToListAsync();
var previousHistoryList = await _previousHistoryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousHistoryView>(_mapper.ConfigurationProvider).ToListAsync();
@@ -287,7 +288,7 @@ namespace IRaCIS.Application.Services
//}
data.IsBlind = inDto.IsBlind;
data.IsComplete=inDto.IsComplete;
data.IsComplete = inDto.IsComplete;
data.IsSign = true;
data.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned;
@@ -304,7 +305,24 @@ namespace IRaCIS.Application.Services
await this.iServiceProvider.GetService<IReadingImageTaskService>().AddOncologyTask(readingId);
await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, inDto.TrialReadingCriterionId);
//如果先生成了任务,再签名subject级别 PM 临床数据,那么会导致其他标准的任务签名状态无法得到维护
if (await _repository.AnyAsync<ClinicalDataTrialSet>(t => t.Id == data.ClinicalDataTrialSetId && t.UploadRole == UploadRole.PM && t.ClinicalDataLevel == ClinicalLevel.Subject))
{
var needDealTrialReadingCriterionIdList = _repository.Where<ClinicalDataTrialSet>(t => t.Id == data.ClinicalDataTrialSetId)
.SelectMany(t => t.TrialClinicalDataSetCriteriaList)
.Select(u => u.TrialReadingCriterionId).Distinct().ToList();
foreach (var trialReadingCriterionId in needDealTrialReadingCriterionIdList)
{
await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, trialReadingCriterionId);
}
}
else
{
await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, inDto.TrialReadingCriterionId);
}
return ResponseOutput.Result(result);
}
@@ -313,7 +331,7 @@ namespace IRaCIS.Application.Services
public async Task DealVisiTaskClinicalDataSignedAsync(Guid trialId, Guid subjectId, Guid readingId, bool isVisit, Guid trialReadingCritrialId)
{
//获取确认的临床数据配置
var trialClinicalDataSetList = _clinicalDataTrialSetRepository.Where(t => t.TrialId == trialId && t.IsConfirm).Include(t => t.TrialClinicalDataSetCriteriaList).ToList();
var trialClinicalDataSetList = _clinicalDataTrialSetRepository.Where(t => t.TrialId == trialId && t.IsConfirm).Include(t => t.TrialClinicalDataSetCriteriaList).ToList();
//var criterionType = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == trialReadingCritrialId).Select(t => t.CriterionType).FirstOrDefaultAsync();
@@ -328,7 +346,7 @@ namespace IRaCIS.Application.Services
{
var isBaseLine = await _subjectVisitRepository.Where(t => t.Id == readingId).Select(t => t.IsBaseLine).FirstOrDefaultAsync();
//判断是否基线
if (isBaseLine)
@@ -414,7 +432,7 @@ namespace IRaCIS.Application.Services
}
//有序阅片才维护 IsFrontTaskNeedSignButNotSign 这个状态
if (_readingQuestionCriterionTrialRepository.Any(t=>t.Id==trialReadingCritrialId && t.IsReadingTaskViewInOrder == true))
if (_readingQuestionCriterionTrialRepository.Any(t => t.Id == trialReadingCritrialId && t.IsReadingTaskViewInOrder == true))
{
@@ -429,8 +447,8 @@ namespace IRaCIS.Application.Services
(t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)
// 前序存在 未一致性核查未通过的
|| t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum>sv.VisitNum)
|| t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum)
))
.Select(t => t.Id);
@@ -442,7 +460,7 @@ namespace IRaCIS.Application.Services
var visitTaskIdQueryable2 = _visitTaskRepository.Where(visitTaskLambda) //该Subject 该标准的任务
.Where(t => t.IsFrontTaskNeedSignButNotSign == true &&
//前序任务 不存在需要签名 但是没签名
@@ -461,14 +479,14 @@ namespace IRaCIS.Application.Services
}
}
// 废弃 接口合并到签名哪里
[HttpPut]
public async Task<IResponseOutput> PMClinicalDataConfirm(PMClinicalDataConfirmCommand command)
{
@@ -522,7 +540,7 @@ namespace IRaCIS.Application.Services
keyValuePairs.Add(ModuleTypeEnum.Oncology, ClinicalLevel.OncologyRead);
var usedIdsQuery = _readingClinicalDataRepository.Where(x => x.ReadingId == inDto.ReadingId && x.Id != inDto.ReadingClinicalDataId).Select(x => x.ClinicalDataTrialSetId);
@@ -537,20 +555,20 @@ namespace IRaCIS.Application.Services
.WhereIf(inDto.IsVisit && !inDto.IsBaseLine, x => x.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
.WhereIf(!inDto.IsVisit, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead || x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
.WhereIf(readModule != null, x => x.ClinicalDataLevel == keyValuePairs[readModule!.ModuleType])
.WhereIf(inDto.TrialReadingCriterionId!=null,x=>x.TrialClinicalDataSetCriteriaList.Any(y=>y.TrialReadingCriterionId== inDto.TrialReadingCriterionId))
.WhereIf(inDto.TrialReadingCriterionId != null, x => x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == inDto.TrialReadingCriterionId))
//.WhereIf(criterion!=null,x=>x.CriterionEnumListStr.Contains($"|{(int)criterion.CriterionType}|"))
.Select(x => new GetTrialClinicalDataSelectOutDto()
{
ClinicalDataLevel = x.ClinicalDataLevel,
ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us),
ClinicalDataSetEnName=x.ClinicalDataSetEnName,
ClinicalDataSetEnName = x.ClinicalDataSetEnName,
ClinicalUploadType = x.ClinicalUploadType,
FileName = x.FileName,
Path = x.Path,
Id = x.Id,
CriterionEnumList = x.CriterionEnumList,
}).ToListAsync();
return clinicalList;
}
@@ -699,20 +717,21 @@ namespace IRaCIS.Application.Services
Path = y.Path,
CreateTime = y.CreateTime,
}).ToList(),
});
var result = new List<GetReadingClinicalDataListOutDto>();
if (!inDto.IsOnlyGetCRCReadModule)
{
result = await resultQuery.ToListAsync();
result = await resultQuery.ToListAsync();
}
var readingIds = result.Select(x => x.ReadingId).ToList();
var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId??default(Guid))).ToListAsync();
result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x => {
var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId ?? default(Guid))).ToListAsync();
result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x =>
{
x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId&&y.ClinicalDataTrialSetId==x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
{
CheckDate = y.CheckDate,
ClinicalFormId = y.Id
@@ -723,35 +742,36 @@ namespace IRaCIS.Application.Services
// 这里处理CRC上传 阅片期的临床数据
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId)
.WhereIf(inDto.SelectIsSign,x=>x.IsPMConfirm)
.WhereIf(!inDto.SelectIsSign, x => x.IsCRCConfirm)
.FirstOrDefaultAsync();
.WhereIf(inDto.SelectIsSign, x => x.IsPMConfirm)
.WhereIf(!inDto.SelectIsSign, x => x.IsCRCConfirm)
.FirstOrDefaultAsync();
if (readModule != null)
{
var moduleCriterionFromList = await _readModuleCriterionFromRepository
.WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalForm.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId)
.Where(x => x.ReadModuleId == readModule.Id).Select(x => new{
ClinicalFormId= x.ClinicalFormId,
CheckDate= x.ClinicalForm.CheckDate,
ClinicalDataTrialSetId= x.ClinicalForm.ClinicalDataTrialSetId
}).ToListAsync();
.Where(x => x.ReadModuleId == readModule.Id).Select(x => new
{
ClinicalFormId = x.ClinicalFormId,
CheckDate = x.ClinicalForm.CheckDate,
ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSetId
}).ToListAsync();
var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC && x.ClinicalUploadType == ClinicalUploadType.Structuring)
.WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead)
.WhereIf(readModule.ReadingSetType == ReadingSetType.TumorReading, x => x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
.Where(x=>x.TrialClinicalDataSetCriteriaList.Any(y=>y.TrialReadingCriterionId==readModule.TrialReadingCriterionId))
.Where(x => x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == readModule.TrialReadingCriterionId))
.Select(x => new GetReadingClinicalDataListOutDto()
{
ClinicalDataLevel = x.ClinicalDataLevel,
SubjectId = inDto.SubjectId,
ReadingId = default(Guid),
IsCRCApplicationRevoke=readModule.IsCRCApplicationRevoke,
IsCRCConfirm= readModule.IsCRCConfirm,
IsPMConfirm= readModule.IsPMConfirm,
IsCRCApplicationRevoke = readModule.IsCRCApplicationRevoke,
IsCRCConfirm = readModule.IsCRCConfirm,
IsPMConfirm = readModule.IsPMConfirm,
ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us),
ClinicalDataSetEnName = x.ClinicalDataSetEnName,
ClinicalDataTrialSetId = x.Id,
@@ -762,7 +782,7 @@ namespace IRaCIS.Application.Services
IsCRCUpload = x.UploadRole == UploadRole.CRC,
IsNeedMerge = true,
ReadModuleId = readModule.Id,
TrialClinicalDataSetCriteriaList=x.TrialClinicalDataSetCriteriaList,
TrialClinicalDataSetCriteriaList = x.TrialClinicalDataSetCriteriaList,
//FileCount = x.FileCount,
//ReadingClinicalDataState = x.ReadingClinicalDataState,
@@ -791,8 +811,8 @@ namespace IRaCIS.Application.Services
});
result.AddRange(clinicalresult);
}
result.AddRange(clinicalresult);
}
@@ -813,7 +833,7 @@ namespace IRaCIS.Application.Services
result = result.Where(x => x.UploadRole == UploadRole.PM).ToList();
break;
case GetClinicalType.CRCConfirm:
result = result.Where(x => x.UploadRole == UploadRole.CRC&&x.IsCRCConfirm&&!x.IsPMConfirm).ToList();
result = result.Where(x => x.UploadRole == UploadRole.CRC && x.IsCRCConfirm && !x.IsPMConfirm).ToList();
break;
case GetClinicalType.HasSign:
result = result.Where(x => x.IsSign).ToList();
@@ -849,15 +869,15 @@ namespace IRaCIS.Application.Services
{
var resultQuery = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId)
.Where(x => x.ReadingId == inDto.ReadingId)
.WhereIf(inDto.ClinicalDataTrialSetId!=null, x=>x.ClinicalDataTrialSetId==inDto.TrialReadingCriterionId)
.Where(x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t=>t.TrialReadingCriterionId==inDto.TrialReadingCriterionId))
.WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.TrialReadingCriterionId)
.Where(x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId))
.Select(x => new GetReadingClinicalDataListOutDto()
{
ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
SubjectId = x.SubjectId,
ReadingId = x.ReadingId,
ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us),
ClinicalDataSetEnName =x.ClinicalDataTrialSet.ClinicalDataSetEnName,
ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName,
ClinicalDataTrialSetId = x.ClinicalDataTrialSetId,
IsSign = x.IsSign,
ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
@@ -884,7 +904,8 @@ namespace IRaCIS.Application.Services
var readingIds = result.Select(x => x.ReadingId).ToList();
var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId ?? default(Guid))).ToListAsync();
result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x => {
result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x =>
{
x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
{
@@ -895,77 +916,78 @@ namespace IRaCIS.Application.Services
});
// 这里处理CRC上传 阅片期的临床数据
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId&&x.IsCRCConfirm)
var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId && x.IsCRCConfirm)
.FirstOrDefaultAsync();
if (readModule != null)
{
var moduleCriterionFromList = await _readModuleCriterionFromRepository.Where(x => x.ReadModuleId == readModule.Id)
var moduleCriterionFromList = await _readModuleCriterionFromRepository.Where(x => x.ReadModuleId == readModule.Id)
.WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalForm.ClinicalDataTrialSetId == inDto.TrialReadingCriterionId)
.Select(x => new {
ClinicalFormId = x.ClinicalFormId,
CheckDate = x.ClinicalForm.CheckDate,
ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSetId
.Select(x => new
{
ClinicalFormId = x.ClinicalFormId,
CheckDate = x.ClinicalForm.CheckDate,
ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSetId
}).ToListAsync();
}).ToListAsync();
var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC&&x.ClinicalUploadType== ClinicalUploadType.Structuring)
.WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading,x=>x.ClinicalDataLevel== ClinicalLevel.ImageRead)
var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC && x.ClinicalUploadType == ClinicalUploadType.Structuring)
.WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead)
.WhereIf(readModule.ReadingSetType == ReadingSetType.TumorReading, x => x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
.Where(x => x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == readModule.TrialReadingCriterionId))
.Select(x => new GetReadingClinicalDataListOutDto()
{
{
ClinicalDataLevel = x.ClinicalDataLevel,
SubjectId = inDto.SubjectId,
ReadingId = default(Guid),
IsCRCApplicationRevoke= readModule.IsCRCApplicationRevoke,
ClinicalDataLevel = x.ClinicalDataLevel,
SubjectId = inDto.SubjectId,
ReadingId = default(Guid),
IsCRCApplicationRevoke = readModule.IsCRCApplicationRevoke,
IsCRCConfirm = readModule.IsCRCConfirm,
IsPMConfirm=readModule.IsPMConfirm,
IsPMConfirm = readModule.IsPMConfirm,
ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us),
ClinicalDataSetEnName = x.ClinicalDataSetEnName,
ClinicalDataTrialSetId = x.Id,
IsSign = readModule.IsPMConfirm,
ClinicalUploadType = x.ClinicalUploadType,
Id = default(Guid),
UploadRole = x.UploadRole,
IsCRCUpload = x.UploadRole == UploadRole.CRC,
IsNeedMerge = true,
ReadModuleId = readModule.Id,
//FileCount = x.FileCount,
ClinicalDataSetEnName = x.ClinicalDataSetEnName,
ClinicalDataTrialSetId = x.Id,
IsSign = readModule.IsPMConfirm,
ClinicalUploadType = x.ClinicalUploadType,
Id = default(Guid),
UploadRole = x.UploadRole,
IsCRCUpload = x.UploadRole == UploadRole.CRC,
IsNeedMerge = true,
ReadModuleId = readModule.Id,
//FileCount = x.FileCount,
//ReadingClinicalDataState = x.ReadingClinicalDataState,
//ReadingClinicalDataState = x.ReadingClinicalDataState,
//FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
//{
// Id = y.Id,
// FileName = y.FileName,
// Path = y.Path,
// CreateTime = y.CreateTime,
//}).ToList()
//FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
//{
// Id = y.Id,
// FileName = y.FileName,
// Path = y.Path,
// CreateTime = y.CreateTime,
//}).ToList()
}).ToListAsync();
}).ToListAsync();
clinicalresult.ForEach(x =>
{
x.FileCount = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Count();
x.ClinicalFromList = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).OrderBy(y => y.CheckDate).Select(x => new ClinicalFromData
{
CheckDate = x.CheckDate,
ClinicalFormId = x.ClinicalFormId
clinicalresult.ForEach(x =>
{
x.FileCount = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Count();
x.ClinicalFromList = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).OrderBy(y => y.CheckDate).Select(x => new ClinicalFromData
{
CheckDate = x.CheckDate,
ClinicalFormId = x.ClinicalFormId
}).ToList();
}).ToList();
x.IsSign = readModule.IsPMConfirm ?true : false;
x.IsSign = readModule.IsPMConfirm ? true : false;
x.ReadingClinicalDataState = readModule.IsPMConfirm ? ReadingClinicalDataStatus.HaveSigned : ReadingClinicalDataStatus.HaveChecked;
});
});
result.AddRange(clinicalresult);
}
result.AddRange(clinicalresult);
}
if (inDto.GetClinicalType != null)
@@ -976,7 +998,7 @@ namespace IRaCIS.Application.Services
result = result.Where(x => x.UploadRole == UploadRole.PM).ToList();
break;
case GetClinicalType.CRCConfirm:
result = result.Where(x => x.UploadRole == UploadRole.CRC&&x.IsCRCConfirm&&!x.IsPMConfirm).ToList();
result = result.Where(x => x.UploadRole == UploadRole.CRC && x.IsCRCConfirm && !x.IsPMConfirm).ToList();
break;
case GetClinicalType.HasSign:
result = result.Where(x => x.IsSign).ToList();
@@ -984,7 +1006,7 @@ namespace IRaCIS.Application.Services
}
}
return result;
}
@@ -1162,7 +1162,13 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// 是否是第一次转化的任务
/// </summary>
public bool IsFirstChangeTask { get; set; } = false;
}
/// <summary>
/// 是否存在临床数据
/// </summary>
public bool IsExistsClinicalData { get; set; } = false;
}
public class GetVisitReadingQuestionOutDto
{
@@ -5,6 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static IRaCIS.Core.Domain.Models.ReadingQuestionTrial;
namespace IRaCIS.Core.Application.Service.Reading.Dto
{
@@ -346,6 +347,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 最大答案长度
/// </summary>
@@ -454,6 +460,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 最大答案长度
/// </summary>
@@ -1000,6 +1011,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 最大答案长度
/// </summary>
@@ -1029,7 +1045,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public List<string> RelevanceValueList { get; set; }
public List<CalculateInfo> CalculateQuestionList { get; set; }
}
}
public class ReadingQuestionSystemView
{
@@ -1058,6 +1075,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 最大答案长度
/// </summary>
@@ -1560,6 +1582,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 最大答案长度
/// </summary>
@@ -1916,6 +1943,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 最大答案长度
/// </summary>
@@ -1953,8 +1985,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public List<string> ParentTriggerValueList { get; set; }
public List<string> RelevanceValueList { get; set; }
}
}
public class GetSystemCriterionSelectDto
{
@@ -1013,8 +1013,8 @@ namespace IRaCIS.Application.Services
SynchronizeTime = DateTime.Now,
IsMustGlobalReading = systemCriterion.IsMustGlobalReading,
IseCRFShowInDicomReading=systemCriterion.IseCRFShowInDicomReading,
IsGlobalReading = systemCriterion.IsMustGlobalReading ? true : trialCriterion.IsGlobalReading,
IsReadingPeriod = systemCriterion.IsMustGlobalReading ? true : trialCriterion.IsReadingPeriod,
//IsGlobalReading = systemCriterion.IsMustGlobalReading ? true : trialCriterion.IsGlobalReading,
//IsReadingPeriod = systemCriterion.IsMustGlobalReading ? true : trialCriterion.IsReadingPeriod,
}) ;
@@ -89,7 +89,6 @@ namespace IRaCIS.Application.Services
IRepository<User> userRepository,
IEasyCachingProvider provider,
IRepository<ReadingCustomTag> readingCustomTagRepository,
IMemoryCache cache,
IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository,
IRepository<ReadingTrialCriterionDictionary> readingTrialCriterionDictionaryRepository,
IRepository<TumorAssessment_RECIST1Point1> tumorAssessmentRepository,
@@ -540,7 +539,21 @@ namespace IRaCIS.Application.Services
}).ToListAsync();
if (!taskInfo.TrialReadingCriterion.IsReadingTaskViewInOrder)
foreach (var item in result)
{
var clinicalDataList = await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
{
SubjectId = taskInfo.SubjectId,
TrialId = taskInfo.TrialId,
VisitTaskId = item.VisitTaskId,
});
item.IsExistsClinicalData = clinicalDataList.Count > 0;
}
if (!taskInfo.TrialReadingCriterion.IsReadingTaskViewInOrder)
{
result = result.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToList();
}
@@ -749,6 +762,16 @@ namespace IRaCIS.Application.Services
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
if (taskinfo.VisitTaskNum == 0)
{
questions = questions.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow).ToList();
}
else
{
questions = questions.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow).ToList();
}
questions.ForEach(x =>
{
x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(taskinfo.IsConvertedTask);
@@ -973,8 +996,18 @@ namespace IRaCIS.Application.Services
if (inDto.TaskId != null)
{
taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.TaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
if (taskInfo.VisitTaskNum == 0)
{
qusetionList = qusetionList.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow).ToList();
qusetionList.ForEach(x =>
}
else
{
qusetionList = qusetionList.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow).ToList();
}
qusetionList.ForEach(x =>
{
x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(taskInfo.IsConvertedTask);
});
@@ -2296,6 +2329,7 @@ namespace IRaCIS.Application.Services
var subjectTaskList = (await _visitTaskService.GetOrderReadingIQueryable(new GetOrderReadingIQueryableInDto()
{
TrialId = inDto.TrialId,
SubjectId=inDto.SubjectId,
TrialReadingCriterionId = trialReadingCriterionId!.Value,
Page = new PageInput()
{
@@ -2317,7 +2351,7 @@ namespace IRaCIS.Application.Services
if (currentSubject == null)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"]);
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
}
task = currentSubject.UnReadCanReadTaskList.Select(x => new GetReadingTaskDto()
@@ -2390,7 +2424,7 @@ namespace IRaCIS.Application.Services
if (task == null)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"]);
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
}
if (task.SubjectCode.IsNullOrEmpty())
@@ -2479,51 +2513,51 @@ namespace IRaCIS.Application.Services
[HttpPost]
public async Task VerifyReadingRestTime()
{
var cacheKey = _userInfo.Id.ToString() + "RestTime";
//var cacheKey = _userInfo.Id.ToString() + "RestTime";
var value = _provider.Get<string>(cacheKey).Value;
if (value == null)
{
_provider.Set(cacheKey, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(5));
// _cache.Set(cacheKey, DateTime.Now.ToString(), TimeSpan.FromHours(5));
//var value = _provider.Get<string>(cacheKey).Value;
//if (value == null)
//{
// _provider.Set(cacheKey, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(5));
// // _cache.Set(cacheKey, DateTime.Now.ToString(), TimeSpan.FromHours(5));
}
else
{
#region
var cacheDate = DateTime.Parse(value.ToString());
int timespanMin = (DateTime.Now - cacheDate).Minutes;
if (timespanMin > 120 && timespanMin < 140)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", 2, 20]);
}
else if (timespanMin > 140)
{
cacheDate = cacheDate.AddMinutes((Math.Floor((double)(timespanMin / 140))) * 140);
_provider.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
// _cache.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
//}
//else
//{
// #region 两小时
// var cacheDate = DateTime.Parse(value.ToString());
// int timespanMin = (DateTime.Now - cacheDate).Minutes;
// if (timespanMin > 120 && timespanMin < 140)
// {
// throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", 2, 20]);
// }
// else if (timespanMin > 140)
// {
// cacheDate = cacheDate.AddMinutes((Math.Floor((double)(timespanMin / 140))) * 140);
// _provider.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
// // _cache.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
}
#endregion
// }
// #endregion
#region 5
//var cacheDate = DateTime.Parse(value.ToString());
//int timespanMin = (DateTime.Now - cacheDate).Minutes;
//if (timespanMin >= 5 && timespanMin <= 10)
//{
// throw new BusinessValidationFailedException("您已连续阅片2个小时,请休息20分钟后,再继续阅片。");
//}
//else if (timespanMin > 10)
//{
// cacheDate = cacheDate.AddMinutes((Math.Floor((double)(timespanMin / 10))) * 10);
// _cache.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
// #region 测试用的5分钟
// //var cacheDate = DateTime.Parse(value.ToString());
// //int timespanMin = (DateTime.Now - cacheDate).Minutes;
// //if (timespanMin >= 5 && timespanMin <= 10)
// //{
// // throw new BusinessValidationFailedException("您已连续阅片2个小时,请休息20分钟后,再继续阅片。");
// //}
// //else if (timespanMin > 10)
// //{
// // cacheDate = cacheDate.AddMinutes((Math.Floor((double)(timespanMin / 10))) * 10);
// // _cache.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
//}
#endregion
// //}
// #endregion
}
//}
@@ -107,7 +107,7 @@ namespace IRaCIS.Core.Application.Contracts
public bool? IsGenerateAccount { get; set; }
public Guid? TrialRoleNameId { get; set; }
public int? TrialRoleCode { get; set; }
public TrialSiteUserStateEnum? State { get; set; }
@@ -66,7 +66,7 @@ namespace IRaCIS.Core.Application.Contracts
public async Task<IResponseOutput> SendEmialVerifyCode(SendEmialVerifyCodeInDto userInfo)
{
//检查手机或者邮箱是否有效
if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"))
if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
{
//---请输入正确的邮箱地址。
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_InvalidEmail"]);
@@ -124,7 +124,7 @@ namespace IRaCIS.Core.Application.Contracts
public async Task<IResponseOutput> SendVerifyCode(SiteSurveySendVerifyCode userInfo)
{
//检查手机或者邮箱是否有效
if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"))
if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
{
//---请输入正确的邮箱地址。
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_InvalidEmail"]);
@@ -531,6 +531,7 @@ namespace IRaCIS.Core.Application.Contracts
var groupSelectIdQuery =
_trialSiteSurveyRepository.Where(t => t.TrialId == queryParam.TrialId)
.WhereIf(queryParam.SiteId != null, t => t.SiteId == queryParam.SiteId)
.WhereIf(!string.IsNullOrEmpty(queryParam.FormWriterKeyInfo), t => (t.UserName).Contains(queryParam.FormWriterKeyInfo) || t.Email.Contains(queryParam.FormWriterKeyInfo) || t.Phone.Contains(queryParam.FormWriterKeyInfo))
.GroupBy(t => t.SiteId)
.Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First());
@@ -538,6 +539,7 @@ namespace IRaCIS.Core.Application.Contracts
var query = _trialSiteUserSurveyRepository
.Where(t => groupSelectIdQuery.Contains(t.TrialSiteSurveyId))
.WhereIf(queryParam.TrialRoleCode != null, t => t.TrialRoleCode == queryParam.TrialRoleCode)
.WhereIf(queryParam.UserTypeId != null, t => t.UserTypeId == queryParam.UserTypeId)
.WhereIf(queryParam.IsGenerateAccount != null, t => t.IsGenerateAccount == queryParam.IsGenerateAccount)
.WhereIf(queryParam.State != null && queryParam.State != TrialSiteUserStateEnum.OverTime, t => t.InviteState == queryParam.State)
@@ -53,6 +53,16 @@ namespace IRaCIS.Application.Contracts
public string RealName { get; set; } = String.Empty;
public string UserName { get; set; } = String.Empty;
}
public class TrialUserBasicInfo
{
public Guid UserTypeId { get; set; }
public string UserName { get; set; }
public string FullName { get; set; }
public Guid UserId { get; set; }
}
public class TrialMaintenanceDTO : UserTrialCommand
{
@@ -62,7 +62,13 @@ namespace IRaCIS.Application.Services
#endregion
[HttpGet]
public async Task<List<TrialUserBasicInfo>> GetTrialUserList(Guid trialId)
{
return await _trialUseRepository.Where(t => t.TrialId == trialId, ignoreQueryFilters: true)
.Select(t => new TrialUserBasicInfo() { FullName = t.User.FullName, UserId = t.UserId, UserTypeId = t.User.UserTypeId, UserName = t.User.UserName })
.ToListAsync();
}
/// <summary>
/// Setting页面 获取项目参与人员列表
@@ -194,10 +194,10 @@ namespace IRaCIS.Core.Application.Services
var siteQueryable = _siteRepository.AsQueryable(true)
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.SiteName), t => t.SiteName.Contains(searchModel.SiteName)|| t.SiteNameCN.Contains(searchModel.SiteName))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.SiteName), t => t.SiteName.Contains(searchModel.SiteName) || t.SiteNameCN.Contains(searchModel.SiteName) || t.AliasName.Contains(searchModel.SiteName))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.AliasName), t => t.AliasName.Contains(searchModel.AliasName))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.City), t => t.City.Contains(searchModel.City))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Country), t => t.Country.Contains(searchModel.Country))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.City), t => t.City.Contains(searchModel.City))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Country), t => t.Country.Contains(searchModel.Country))
.ProjectTo<TrialSiteScreeningDTO>(_mapper.ConfigurationProvider, new { trialId = searchModel.TrialId , isEn_Us =_userInfo.IsEn_Us});
@@ -330,8 +330,8 @@ namespace IRaCIS.Core.Application.Services
var tag = await _readingCustomTagRepository.Where(x => x.VisitTaskId == indto.VisitTaskId && x.StudyId != null).Select(x => new
{
ShowOrder= 0,
RowIndex= 0m,
ShowOrder = 0,
RowIndex = 0m,
x.SeriesId,
x.StudyId,
x.InstanceId,
@@ -447,23 +447,23 @@ namespace IRaCIS.Core.Application.Services
var studyList = await _repository.Where<DicomStudy>(t => t.TrialId == indto.TrialId && t.SubjectVisitId == indto.SujectVisitId)
.Select(k => new VisitStudyDTO()
{
InstanceCount = k.InstanceCount,
Modalities = k.Modalities,
SeriesCount = k.SeriesCount,
StudyCode = k.StudyCode,
StudyId = k.Id,
{
InstanceCount = k.InstanceCount,
Modalities = k.Modalities,
SeriesCount = k.SeriesCount,
StudyCode = k.StudyCode,
StudyId = k.Id,
}).ToListAsync();
}).ToListAsync();
var studyIds = studyList.Select(t => t.StudyId).ToList();
var instanceList = await _repository.Where<DicomInstance>(t => studyIds.Contains(t.StudyId))
.Select(t => new { t.SeriesId, t.Id, t.InstanceNumber, t.Path, t.NumberOfFrames,t.WindowCenter,t.WindowWidth }).ToListAsync();
.Select(t => new { t.SeriesId, t.Id, t.InstanceNumber, t.Path, t.NumberOfFrames, t.WindowCenter, t.WindowWidth }).ToListAsync();
List<DicomSeriesDTO> seriesLists = await _repository.Where<DicomSeries>(s => studyIds.Contains(s.StudyId) /*&& s.IsReading*/)
.WhereIf(isManualGenerate==false, t => t.IsReading)
.WhereIf(isManualGenerate == false, t => t.IsReading)
.OrderBy(s => s.SeriesNumber).
ThenBy(s => s.SeriesTime)
.ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();
@@ -531,23 +531,35 @@ namespace IRaCIS.Core.Application.Services
foreach (var item in noDicomStudyList)
{
var nodicom = noDicomList.Where(x => x.Id == item.StudyId).First();
item.SeriesList = new List<DicomSeriesDTO>()
{
new DicomSeriesDTO (){
IsDicom=false,
Id=item.StudyId,
InstanceCount=await _noneDicomStudyFileRepository.Where(x=>x.NoneDicomStudyId==item.StudyId).CountAsync(),
Modality=item.Modalities,
StudyId=item.StudyId,
TrialId=nodicom.TrialId,
SiteId=nodicom.SiteId,
SubjectVisitId=nodicom.SubjectVisitId,
SubjectId=nodicom.SubjectId,
SeriesNumber=1,
NoneDicomFileFirstFile=await _noneDicomStudyFileRepository.Where(x=>x.NoneDicomStudyId==item.StudyId).Select(x=>x.Path).FirstOrDefaultAsync(),
}
};
var instanceCount = await _noneDicomStudyFileRepository.Where(x => x.NoneDicomStudyId == item.StudyId).CountAsync();
if (instanceCount == 0)
{
item.SeriesList = new List<DicomSeriesDTO>();
item.SeriesCount = 0;
}
else
{
item.SeriesList = new List<DicomSeriesDTO>()
{
new DicomSeriesDTO (){
IsDicom=false,
Id=item.StudyId,
InstanceCount=instanceCount,
Modality=item.Modalities,
StudyId=item.StudyId,
TrialId=nodicom.TrialId,
SiteId=nodicom.SiteId,
SubjectVisitId=nodicom.SubjectVisitId,
SubjectId=nodicom.SubjectId,
SeriesNumber=1,
NoneDicomFileFirstFile=await _noneDicomStudyFileRepository.Where(x=>x.NoneDicomStudyId==item.StudyId).Select(x=>x.Path).FirstOrDefaultAsync(),
}
};
}
}
@@ -35,7 +35,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<VisitStage, VisitStageDTO>();
CreateMap<Subject, SubjectQueryView>()
.ForMember(d => d.SiteName, u => u.MapFrom(s => s.TrialSite.Site.SiteName))
.ForMember(d => d.SiteName, u => u.MapFrom(s => s.TrialSite.TrialSiteAliasName))
.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))
@@ -88,8 +88,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<SubjectVisit, DicomTrialSiteSubjectInfo>().IncludeMembers(t=>t.Trial)
.ForMember(d => d.SiteName, u => u.MapFrom(s => s.Site.SiteName))
.ForMember(d => d.SiteCode, u => u.MapFrom(s => s.Site.SiteCode))
.ForMember(d => d.TrialSiteAliasName, u => u.MapFrom(s => s.TrialSite.TrialSiteAliasName))
.ForMember(d => d.SubjectVisitId, u => u.MapFrom(s => s.Id))
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode))
.ForMember(d => d.TrialCode, u => u.MapFrom(s => s.Trial.TrialCode))
@@ -354,6 +354,8 @@ namespace IRaCIS.Application.Contracts
public bool IsOncologyReading { get; set; }
public bool IsReadingPeriod { get; set; }
}
public class TrialCriterionReadingCategory
+225 -72
View File
@@ -1,4 +1,6 @@
using DocumentFormat.OpenXml.Office2010.Excel;
using Aliyun.OSS;
using Castle.DynamicProxy.Generators.Emitters.SimpleAST;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
@@ -12,8 +14,15 @@ using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MiniExcelLibs;
using Minio;
using Minio.DataModel.Args;
using NPOI.HPSF;
using NPOI.POIFS.Crypt;
using SharpCompress.Common;
using Spire.Doc;
using System.Linq.Expressions;
using System.Reflection.Metadata;
using System.Security.AccessControl;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
@@ -25,7 +34,7 @@ namespace IRaCIS.Application.Services
public class TestService : BaseService
{
public static int IntValue = 100;
public static int IntValue = 100;
private readonly IRepository<Dictionary> _dicRepository;
private readonly IRepository<Trial> _trialRepository;
@@ -40,7 +49,7 @@ namespace IRaCIS.Application.Services
private readonly ILogger<TestService> _logger;
public TestService(IRepository<Dictionary> dicRepository, IRepository<Trial> trialRepository,ILogger<TestService> logger
public TestService(IRepository<Dictionary> dicRepository, IRepository<Trial> trialRepository, ILogger<TestService> logger
, IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig, IOptionsMonitor<ServiceVerifyConfigOption> basicConfig, IRepository<VisitTask> visitTaskRepository, IDistributedLockProvider distributedLockProvider)
{
@@ -52,31 +61,56 @@ namespace IRaCIS.Application.Services
_dicRepository = dicRepository;
_trialRepository = trialRepository;
_distributedLockProvider= distributedLockProvider;
_distributedLockProvider = distributedLockProvider;
_logger= logger;
_logger = logger;
//_cache = cache;
}
[AllowAnonymous]
public async Task<IResponseOutput> TestDistributedLock( )
public async Task<IResponseOutput> TestEFcore8()
{
await _repository.Where<User>().Select(t => t.FullName).FirstNotNullAsync();
//var aa= _dicRepository._dbContext.Subject.Where(t => t.Id == Guid.Empty).ExecuteUpdate("FirstName","ddd");
await _repository.BatchUpdateAsync<Subject>(t => t.Id == Guid.Empty, u => new Subject() { FirstName = "fddd", LastName = "sss", UpdateTime = DateTime.Now });
await _repository.Where<Subject>().ExecuteUpdateAsync(t => t.SetProperty(t => t.UpdateTime, u => DateTime.Now));
return ResponseOutput.Ok();
}
// 设置 Ne
[AllowAnonymous]
public async Task<IResponseOutput> TestMinIO([FromServices] IOSSService oSSService)
{
await oSSService.UploadToOSSAsync("C:\\Users\\Administrator\\Desktop\\TrialSiteUserImportTemplate.xlsx", "myfolder");
await oSSService.DownLoadFromOSSAsync("/myfolder/TrialSiteUserImportTemplate.xlsx", "C:\\Users\\Administrator\\Desktop\\aws.xlsx");
return ResponseOutput.Ok();
}
[AllowAnonymous]
public async Task<IResponseOutput> TestDistributedLock()
{
await _repository.Where<User>().Select(t => t.FullName).FirstNotNullAsync();
Console.WriteLine($"我进来了当前值是:" + IntValue);
_logger.LogWarning($"我进来了当前值是:" + IntValue);
var @lock = _distributedLockProvider.CreateLock($"UserAccount");
using (await @lock.AcquireAsync())
using (await @lock.AcquireAsync())
{
await Task.Delay(4);
IntValue--;
_logger.LogWarning( IntValue.ToString());
_logger.LogWarning(IntValue.ToString());
Console.WriteLine(IntValue);
}
@@ -85,86 +119,126 @@ namespace IRaCIS.Application.Services
[AllowAnonymous]
public async Task<IResponseOutput> GetMemoryStoreData()
public async Task<IResponseOutput> InternationazitionInit()
{
var rows = await MiniExcel.QueryAsync<InternationalizationAddOrEdit>(@"C:\Users\Administrator\Desktop\i18n-new2.xlsx");
return ResponseOutput.Ok(new { StaticData.En_US_Dic , StaticData.Zh_CN_Dic });
rows = rows.Where(t => !string.IsNullOrEmpty(t.Code)).ToList();
foreach (var row in rows)
{
await _repository.InsertOrUpdateAsync<Internationalization, InternationalizationAddOrEdit>(row);
}
await _repository.SaveChangesAsync();
return ResponseOutput.Ok();
}
//[AllowAnonymous]
//public async Task<IResponseOutput> InternationazitionInit()
//{
// var rows = await MiniExcel.QueryAsync<InternationalizationAddOrEdit>(@"C:\Users\Administrator\Desktop\Export\vue.xlsx");
// foreach (var row in rows)
// {
// await _repository.InsertOrUpdateAsync<Internationalization, InternationalizationAddOrEdit>(row);
// }
// await _repository.SaveChangesAsync();
// return ResponseOutput.Ok();
//}
[AllowAnonymous]
[UnitOfWork]
public async Task<string> Get()
{
return "修改服务器时间自动发布测试--我又修改了";
//Expression<Func<VisitTask, bool>> visitTaskLambda = x => x.TrialId == Guid.Empty && x.SubjectId == Guid.Empty && x.TrialReadingCriterionId == Guid.Empty;
//var visitTaskIdQueryable = _visitTaskRepositoryy.Where(visitTaskLambda).Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)).Select(t => t.Id);
//await _visitTaskRepositoryy.BatchUpdateNoTrackingAsync(t => visitTaskIdQueryable.Contains(t.Id), u => new VisitTask()
//{
// IsFrontTaskNeedSignButNotSign = true
//});
//var a = ((Decimal)1.00).ToString().TrimEnd(new char[] { '.', '0' });
//var b = ((Decimal)1.01).ToString().TrimEnd(new char[] { '.', '0' });
//var c = ((Decimal)100).ToString().TrimEnd(new char[] { '.', '0' });
//var subject1 = Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391693");
//var subject2 = Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391694");
// var subjectList = new List<Guid>() { Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391693") ,
// Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391694") ,
// Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391695")
// };
//string[] citys = new string[] { "广州", "深圳", "上海", "北京" };
//foreach (var item in subjectList)
//{
// Console.WriteLine(await BNRFactory.Default.Create($"[CN:{item}][N:[CN:{item}]/0000000]"));
//}
//foreach (var item in subjectList)
//{
// Console.WriteLine(await BNRFactory.Default.Create($"[N:[CN:{item}]/0000000]"));
//}
//foreach (var item in subjectList)
//{
// Console.WriteLine(await BNRFactory.Default.Create($"[CN:{item}][redis:city/0000000]"));
//}
//var needAddVisitList = await _repository.Where<VisitTask>(t => t.TrialId == Guid.Empty).DistinctBy(t => t.VisitTaskNum).ToListAsync();
//await _repository.BatchUpdateAsync<VisitTask>(t => t.Id == Guid.Empty, u => new VisitTask()
//{
// SuggesteFinishedTime = u.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7),
// Code = u.Code + 1
//});
//var query = from item1 in _repository.Where<ReadingQuestionTrial>()
// join item2 in _repository.Where<ReadingQuestionTrial>() on item1.ValueType equals item2.ValueType
// select new
// {
// item1.ValueType,
// dd = item2.ValueType
// };
//var list2 = query.ToList();
//await Task.CompletedTask;
//var list = await _repository.Where<ClinicalDataTrialSet>(t => t.TrialId == Guid.Parse("40400000-3e2c-0016-239b-08da581f0e74")).ToListAsync();
////await _repository.BatchDeleteAsync<ClinicalDataTrialSet>(t => t.TrialId == Guid.Parse("40400000-3e2c-0016-239b-08da581f0e74"));
//await _repository.AddRangeAsync(list, true);
//await _repository.SaveChangesAsync();
//await _repository.BatchUpdateAsync<DataInspection>(t => t.TrialId == Guid.Parse("40400000-3e2c-0016-239b-08da581f0e74") && t.EntityName== "ClinicalDataTrialSet", t => new DataInspection() { CreateTime= DateTime.Now.AddMonths(-2) } );
//await _visitTaskRepositoryy.UpdatePartialFromQueryAsync( Guid.Parse("78360000-3E2C-0016-9B53-08DA6A002040"), c => new VisitTask() { UpdateTime = DateTime.Now });
//await _visitTaskRepositoryy.UpdatePartialFromQueryAsync( Guid.Parse("78360000-3E2C-0016-9B53-08DA6A002040"), c => new VisitTask() { UpdateTime = DateTime.Now.AddMinutes(1) });
//var a = _userInfo.IsTestUser;
//var list1 = await _repository.Where<Dictionary>().Select(t => t.TranslateValue(t.Value, t.ValueCN, true)).ToListAsync();
//var list2 = await _repository.Where<Dictionary>().Select(t => t.TranslateValue(t.Value, t.ValueCN, false)).ToListAsync();
return "测试自动发布--再次提交";
}
private static Dictionary<string, string> _replacePatterns = new Dictionary<string, string>()
{
{ "test", "Atlanta Knight" },
{ "GAME_TIME", "7:30pm" },
{ "GAME_NUMBER", "161" },
{ "DATE", "October 18 2018" },
};
private static string ReplaceFunc(string findStr)
{
if (_replacePatterns.ContainsKey(findStr))
{
return _replacePatterns[findStr];
}
return findStr;
}
[AllowAnonymous]
public async Task<List<Guid>> testwwwww([FromServices] IWebHostEnvironment env)
public async Task testwwwww([FromServices] IWebHostEnvironment env)
{
int count = 200;
var list=new List<Guid>();
for (int i = 0; i < count; i++)
{
Guid guid = NewId.NextGuid();
list.Add(guid);
}
return list;
await Task.CompletedTask;
}
[AllowAnonymous]
public async Task<object> GetEnvironmentName([FromServices] IWebHostEnvironment env)
{
var a = IdentifierHelper.CreateGuid("1.2.840.113619.2.416.3358551739363725609857319676326094825431.2.840.113619.2.80.2338912612.50499.1563432834.1.4.11.2.840.113619.2.80.2338912612.50499.1563432835.4b8340000-3e2c-0016-fbdd-08db883b137f");
var a = IdentifierHelper.CreateGuid("123456");
var k = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("123456"));
var c = MD5Helper.Md5("1.2.840.113619.2.416.3358551739363725609857319676326094825431.2.840.113619.2.80.2338912612.50499.1563432834.1.4.11.2.840.113619.2.80.2338912612.50499.1563432835.4b8340000-3e2c-0016-fbdd-08db883b137f");
var c = MD5Helper.Md5("123456");
//update DicomInstance set Path = '/IRaCISData/TrialData/' + cast(DicomInstance.TrialId as varchar) + '/' + DicomInstance.SiteId + '/' + DicomInstance.SubjectId + '/' + DicomInstance.SubjectVisitId + '/Dicom/' + DicomInstance.StudyId + '/' + DicomInstance.Id + '.dcm'
@@ -255,11 +329,7 @@ namespace IRaCIS.Application.Services
public string PostData(TestModel testModelList)
{
return String.Empty;
}
#region
/// <summary>
/// 维护临床数据 --一定要在同步表前同步数据才行
/// </summary>
@@ -299,6 +369,89 @@ namespace IRaCIS.Application.Services
}
/// <summary>
/// 维护OSS 影像数据
/// </summary>
/// <returns></returns>
[AllowAnonymous]
[UnitOfWork]
public async Task<IResponseOutput> OldLocalImageResizeJpg([FromServices] IOSSService oSSService, [FromServices] IRepository _repository, [FromServices] IWebHostEnvironment _hostEnvironment)
{
var aliConfig = oSSService.ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret);
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
var studyList = _repository.Where<DicomStudy>(t => t.SeriesList.Any(t => t.ImageResizePath.Length < 10)).Select(t => new { t.TrialId, t.SiteId, t.SubjectId, t.SubjectVisitId, t.Id }).ToList();
foreach (var studyitem in studyList)
{
var relativePath = $"{studyitem.TrialId}/{studyitem.SiteId}/{studyitem.SubjectId}/{studyitem.SubjectVisitId}/{StaticData.Folder.DicomFolder}/{studyitem.Id}/";
try
{
string nextMarker = null;
do
{
// 使用 prefix 模拟目录结构,设置 MaxKeys 和 NextMarker
var objectListing = _ossClient.ListObjects(new ListObjectsRequest(aliConfig.bucketName)
{
Prefix = relativePath,
MaxKeys = 1000,
Marker = nextMarker
});
var jpgInfoList = objectListing.ObjectSummaries
.Where(summary => summary.Key.EndsWith(".jpg"))
.Select(summary =>
{
string fileName = summary.Key.Split('/').Last(); // 提取文件夹名
return new
{
Key = summary.Key,
InstanceId = Guid.TryParse(
fileName.Split('.')[0],
out Guid instanceId)
? instanceId
: Guid.Empty
};
})
.Where(info => info.InstanceId != Guid.Empty)
.ToList();
foreach (var jpg in jpgInfoList)
{
var seriesId = _repository.Where<DicomInstance>(t => t.Id == jpg.InstanceId).Select(t => t.SeriesId).FirstOrDefault();
await _repository.BatchUpdateAsync<DicomSeries>(t => t.Id == seriesId, t => new DicomSeries() { ImageResizePath = "/" + jpg.Key });
}
// 设置 NextMarker 以获取下一页的数据
nextMarker = objectListing.NextMarker;
} while (!string.IsNullOrEmpty(nextMarker));
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
await _repository.SaveChangesAsync();
}
return ResponseOutput.Ok();
}
#endregion
}
public class TestModel
@@ -54,7 +54,7 @@ namespace IRaCIS.Core.Application.Triggers
t.TrialId = subject.TrialId;
t.SiteId = subject.SiteId;
t.IsEnrollmentConfirm = t.IsBaseLine ? triconfig.IsEnrollementQualificationConfirm : false;
t.PDState = t.IsBaseLine==false && triconfig.IsPDProgressView ? PDStateEnum.PDProgress : PDStateEnum.None;
t.PDState = t.IsBaseLine == false && triconfig.IsPDProgressView ? PDStateEnum.PDProgress : PDStateEnum.None;
t.Id = NewId.NextGuid();
});
@@ -65,6 +65,7 @@ namespace IRaCIS.Core.Application.Triggers
await _subjectVisitRepository.SaveChangesAsync();
#region f访视计划确认的时候处理 subject添加访视计划
////已添加受试者 都不存在该新增的计划名称 那么该项目所有受试者都增加一个访视记录
//if (!await _subjectVisitRepository.AnyAsync(t => t.VisitName == visitPlan.VisitName && t.TrialId == visitPlan.TrialId))
//{
@@ -0,0 +1,42 @@
using EntityFrameworkCore.Triggered;
using IP2Region.Net.Abstractions;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Triggers
{
public class UserLogTrigger : IBeforeSaveTrigger<UserLog>
{
public ISearcher _searcher;
public ILogger<UserLogTrigger> _logger;
public UserLogTrigger(ISearcher searcher,ILogger<UserLogTrigger> logger)
{
_searcher = searcher;
_logger= logger;
}
//国家|区域|省份|城市|ISP 缺省的地域信息默认是0
//0|0|0|内网IP|内网IP
// 中国|0|湖北省|武汉市|电信
public async Task BeforeSave(ITriggerContext<UserLog> context, CancellationToken cancellationToken)
{
var userLog = context.Entity;
if (context.ChangeType == ChangeType.Added)
{
var ipinfo = _searcher.Search(userLog.IP);
userLog.IPRegion = string.Join('|', ipinfo.Split('|').TakeLast(3));
}
}
}
}
@@ -52,6 +52,7 @@ namespace IRaCIS.Core.Application.Triggers
if (context.ChangeType == ChangeType.Modified && visitTask.ReadingTaskState==ReadingTaskState.HaveSigned && visitTask.ReadingTaskState != context.UnmodifiedEntity.ReadingTaskState && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI)
{
visitTask.PIAuditState = PIAuditState.PIAgree;
visitTask.FirstAuditUserId = _userInfo.Id;
}
if (context.ChangeType == ChangeType.Modified && visitTask.PIAuditState!=context.UnmodifiedEntity.PIAuditState && visitTask.PIAuditState==PIAuditState.PIAgree)
@@ -92,10 +92,10 @@ namespace IRaCIS.Core.Application.MediatR.CommandAndQueries
//[Required(ErrorMessage = "检查日期不能为空")]
[CanConvertToTime(ErrorMessage = "Does not conform to Stusy Date format")]
[CanConvertToTime(ErrorMessage = "Does not conform to Study Date format")]
[ImporterHeader(Name = "Stusy Date", AutoTrim = true)]
[ExcelColumnName("Stusy Date")]
[ImporterHeader(Name = "Study Date", AutoTrim = true)]
[ExcelColumnName("Study Date")]
public string StudyDate { get; set; } = string.Empty;
@@ -191,6 +191,8 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
dbSV.CheckState = CheckStateEnum.CVPassed;
dbSV.CheckUserId = _userInfo.Id;
dbSV.CheckPassedTime = DateTime.Now;
dbSV.CheckChallengeState = CheckChanllengeTypeEnum.Closed;
//---核对EDC数据,完全一致
dbSV.CheckResult = _localizer["ConsistencyVerification_EDCB"];
//---自动核查通过
+28 -4
View File
@@ -1811,10 +1811,34 @@ namespace IRaCIS.Core.Domain.Share
}
/// <summary>
/// 限制编辑
/// </summary>
public enum LimitEdit
/// <summary>
/// 显示限制
/// </summary>
public enum LimitShow
{
/// <summary>
/// 全都显示
/// </summary>
AllShow = 0,
/// <summary>
/// 基线显示
/// </summary>
BaseLineShow = 1,
/// <summary>
/// 随访显示
/// </summary>
FollowShow = 2,
}
/// <summary>
/// 限制编辑
/// </summary>
public enum LimitEdit
{
/// <summary>
@@ -33,16 +33,18 @@ namespace IRaCIS.Core.Domain.Models
public int State { get; set; }
public string Description { get; set; }
public string Description { get; set; } = string.Empty;
public string Code { get; set; }
public string Code { get; set; } = string.Empty;
public string Value { get; set; }
public string Value { get; set; } = string.Empty;
public string ValueCN { get; set; }
public string ValueCN { get; set; } = string.Empty;
public int InternationalizationType { get; set; }
public string FrontType { get; set; }=string.Empty;
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ namespace IRaCIS.Core.Domain.Models
///</summary>
[Table("TrialDocument")]
public class TrialDocument : Entity, IAuditUpdate, IAuditAdd
{
{
//需要确认的项目用户 通过TrialId 关联 用中间表过滤
@@ -41,7 +41,7 @@ namespace IRaCIS.Core.Domain.Models
[JsonIgnore]
public List<TrialEmailNoticeUser> TrialEmailNoticeUserList { get; set; } = new List<TrialEmailNoticeUser>();
[JsonIgnore]
public List<TrialEmailBlackUser> TrialEmailBlackUserList { get; set; } = new List<TrialEmailBlackUser>();
@@ -85,7 +85,9 @@ namespace IRaCIS.Core.Domain.Models
public bool IsSuccess { get; set; }
public string Note = string.Empty;
public string Note { get; set; } = string.Empty;
public string RecordPath { get; set; }=string.Empty;
}
+2
View File
@@ -47,6 +47,8 @@ namespace IRaCIS.Core.Domain.Models
[JsonIgnore]
public User OptUser { get; set; }
public string IPRegion { get; set; }
}
/// <summary>
@@ -181,6 +181,10 @@ namespace IRaCIS.Core.Domain.Models
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 数据来源
@@ -231,6 +231,11 @@ namespace IRaCIS.Core.Domain.Models
/// </summary>
public LimitEdit LimitEdit { get; set; } = LimitEdit.None;
/// <summary>
/// 限制显示
/// </summary>
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 自定义计算标记
/// </summary>
@@ -261,7 +266,11 @@ namespace IRaCIS.Core.Domain.Models
/// </summary>
public Guid? GroupId { get; set; }
[JsonIgnore]
//
[JsonIgnore]
[ForeignKey("GroupId")]
public ReadingQuestionTrial GroupInfo { get; set; }
@@ -284,8 +293,18 @@ namespace IRaCIS.Core.Domain.Models
[JsonIgnore]
public List<ReadingTableQuestionTrial> ReadingTableQuestionTrialList { get; set; }
[NotMapped]
public enum AssessmentResultType
{
//没有特殊标记
None=0,
//评估结果
AssessmentResult = 1,
}
[NotMapped]
public List<string> ParentTriggerValueList
{
get
@@ -74,7 +74,9 @@ namespace IRaCIS.Core.Domain.Models
public ReadingQuestionTrial ReadingQuestionTrial { get; set; }
[JsonIgnore]
[ForeignKey("ReadingQuestionCriterionTrialId")]
public ReadingQuestionCriterionTrial ReadingQuestionCriterionTrial { get; set; }
}
+4 -1
View File
@@ -183,7 +183,10 @@ public static class StaticData
public static class InternationalData
{
public const string Front = "Front";
}
/// <summary>
/// 匿名化配置 key
+42 -11
View File
@@ -69,18 +69,40 @@ namespace IRaCIS.Core.Infra.EFCore.Common
typeof(TrialSiteSurvey),
typeof(TrialSiteUser),
typeof(VisitStage),
typeof(TrialSite)
};
typeof(TrialSite),
};
}
}
// 修改为删除
private List<Type> UpdateIsDelete
{
get
{
return new List<Type>()
{
typeof(TrialDocument)
};
}
}
public string GetEntityAuditOpt(EntityEntry entityEntry)
public string GetEntityAuditOpt(EntityEntry entityEntry)
{
if (entityEntry.State == EntityState.Added)
{
return AuditOpt.Add;
}
else if (
UpdateIsDelete.Contains(entityEntry.Entity.GetType())
&& entityEntry.State == EntityState.Modified
&& (bool)entityEntry.Entity.GetType().GetProperty(nameof(ISoftDelete.IsDeleted)).GetValue(entityEntry.Entity)
)
{
return AuditOpt.Deleted;
}
else if (entityEntry.State == EntityState.Deleted ||
(entityEntry.State == EntityState.Modified
@@ -1272,6 +1294,8 @@ namespace IRaCIS.Core.Infra.EFCore.Common
var entity = item.Entity as QCChallenge;
var challengeState= await _dbContext.SubjectVisit.Where(x => x.Id == entity.SubjectVisitId).Select(x => x.ChallengeState).FirstOrDefaultAsync();
await InsertInspection<QCChallenge>(entity, type, x => new InspectionConvertDTO()
{
SubjectVisitId = x.SubjectVisitId,
@@ -1281,7 +1305,8 @@ namespace IRaCIS.Core.Infra.EFCore.Common
{
IsOverTime = entity.IsClosed ? entity.ClosedTime > entity.DeadlineTime : DateTime.Now > entity.DeadlineTime,
});
ChallengeState= challengeState,
});
}
// 质疑 对话
@@ -1394,19 +1419,25 @@ namespace IRaCIS.Core.Infra.EFCore.Common
var trialSiteId = entity.TrialSite?.Id;
await InsertInspection<TrialSiteSurvey>(item.Entity as TrialSiteSurvey, type, x => new InspectionConvertDTO()
var equipmentTypeList = await _dbContext.TrialSiteEquipmentSurvey.Where(x => x.TrialSiteSurveyId == entity.Id).Select(x => x.EquipmentType.ValueCN).ToListAsync();
var siteUserList = await _dbContext.TrialSiteUserSurvey.Where(x => x.TrialSiteSurveyId == entity.Id).Select(x => x.LastName + "/" + x.FirstName).ToListAsync();
await InsertInspection<TrialSiteSurvey>(item.Entity as TrialSiteSurvey, type, x => new InspectionConvertDTO()
{
ObjectRelationParentId = trialSiteId,
}, new
{
//TrialSiteCode = entity.TrialSite.TrialSiteCode,
//TrialSiteAliasName = entity.TrialSite.TrialSiteAliasName,
//Phone = entity.Phone,
//Email = entity.Email,
//TrialSiteCode = entity.TrialSite.TrialSiteCode,
//TrialSiteAliasName = entity.TrialSite.TrialSiteAliasName,
//Phone = entity.Phone,
//Email = entity.Email,
PreliminaryUser = entity.PreliminaryUser == null ? "" : entity.PreliminaryUser.FullName,
EquipmentTypeList=string.Join(",", equipmentTypeList),
SiteUserList= string.Join(",", siteUserList),
PreliminaryUser = entity.PreliminaryUser == null ? "" : entity.PreliminaryUser.FullName,
ReviewerUser = entity.ReviewerUser == null ? "" : entity.ReviewerUser.FullName,
});
@@ -10,7 +10,8 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto
{
public string Code { get; set; }
public string DateType { get; set; }
public string Identification { get; set; }
public string DateType { get; set; }
}
public class TypeNameDto
@@ -0,0 +1,120 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace IRaCIS.Core.Infra.EFCore
{
public static class DynamicRelationalExtensions
{
static MethodInfo UpdateMethodInfo =
typeof(RelationalQueryableExtensions).GetMethod(nameof(RelationalQueryableExtensions.ExecuteUpdate));
static MethodInfo UpdateAsyncMethodInfo =
typeof(RelationalQueryableExtensions).GetMethod(nameof(RelationalQueryableExtensions.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)
{
var dic = new Dictionary<string, object?>();
var obj = (TSource)Activator.CreateInstance(typeof(TSource));
Func<TSource, TSource> func = updateFactory.Compile();
TSource applyObj = func(obj);
var propList = ((MemberInitExpression)updateFactory.Body).Bindings.Select(mb => mb.Member.Name)
.Select(propName => typeof(TSource).GetProperty(propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)).ToList();
foreach (PropertyInfo prop in propList)
{
object value = prop.GetValue(applyObj);
dic.Add(prop.Name, value);
}
return dic;
}
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 })!;
}
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;
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;
}
static Expression ValueForType(Type desiredType, object? value)
{
if (value == null)
{
return Expression.Default(desiredType);
}
if (value.GetType() != desiredType)
{
return Expression.Convert(Expression.Constant(value), desiredType);
}
return Expression.Constant(value);
}
}
}
@@ -157,7 +157,7 @@ namespace IRaCIS.Core.Infra.EFCore
{
if (deleteFilter == null) throw new ArgumentNullException(nameof(deleteFilter));
return await _dbContext.Set<T>().IgnoreQueryFilters().Where(deleteFilter).BatchDeleteAsync() > 0;
return await _dbContext.Set<T>().IgnoreQueryFilters().Where(deleteFilter).ExecuteDeleteAsync() > 0;
}
@@ -166,34 +166,64 @@ namespace IRaCIS.Core.Infra.EFCore
{
if (where == null) throw new ArgumentNullException(nameof(where));
var bindings = ((MemberInitExpression)updateFactory.Body).Bindings.ToList();
var hasPropNameList = bindings.Select(t => t.Member.Name).ToList();
#region history 使
//var bindings = ((MemberInitExpression)updateFactory.Body).Bindings.ToList();
//var hasPropNameList = bindings.Select(t => t.Member.Name).ToList();
if (typeof(IAuditUpdate).IsAssignableFrom(typeof(T)))
//if (typeof(IAuditUpdate).IsAssignableFrom(typeof(T)))
//{
// if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateTime)))
// {
// bindings.Add(Expression.Bind(typeof(T).GetMember(nameof(IAuditUpdate.UpdateTime))[0], Expression.Constant(DateTime.Now)));
// }
// if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateUserId)))
// {
// bindings.Add(Expression.Bind(typeof(T).GetMember(nameof(IAuditUpdate.UpdateUserId))[0], Expression.Constant(updateUserId)));
// }
//}
//var member = Expression.MemberInit(Expression.New(typeof(T)), bindings);
//var factory = Expression.Lambda<Func<T, T>>(member, Expression.Parameter(typeof(T), "x"));
//return await _dbContext.Set<T>().IgnoreQueryFilters().Where(where).BatchUpdateAsync(factory).ConfigureAwait(false) > 0;
#endregion
#region efcore 7 & 8
{
var fieldValues = updateFactory.ExtractFieldValues();
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateTime)))
var hasPropNameList = ((MemberInitExpression)updateFactory.Body).Bindings.Select(t => t.Member.Name).ToList();
if (typeof(IAuditUpdate).IsAssignableFrom(typeof(T)))
{
bindings.Add(Expression.Bind(typeof(T).GetMember(nameof(IAuditUpdate.UpdateTime))[0], Expression.Constant(DateTime.Now)));
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateTime)))
{
fieldValues.Add(nameof(IAuditUpdate.UpdateTime), DateTime.Now);
}
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateUserId)))
{
fieldValues.Add(nameof(IAuditUpdate.UpdateUserId), updateUserId);
}
}
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateUserId)))
{
bindings.Add(Expression.Bind(typeof(T).GetMember(nameof(IAuditUpdate.UpdateUserId))[0], Expression.Constant(updateUserId)));
}
return await _dbContext.Set<T>().IgnoreQueryFilters().Where(where).ExecuteUpdateAsync(fieldValues).ConfigureAwait(false) > 0;
}
var member = Expression.MemberInit(Expression.New(typeof(T)), bindings);
var factory = Expression.Lambda<Func<T, T>>(member, Expression.Parameter(typeof(T), "x"));
return await _dbContext.Set<T>().IgnoreQueryFilters().Where(where).BatchUpdateAsync(factory).ConfigureAwait(false) > 0;
#endregion
@@ -1,17 +1,22 @@
using System;
using IRaCIS.Core.Infrastructure.Extention;
using System;
namespace IRaCIS.Core.Infrastructure
{
public class BusinessValidationFailedException : Exception
{
public ApiResponseCodeEnum Code { get; set; }
public BusinessValidationFailedException()
public BusinessValidationFailedException()
{
}
public BusinessValidationFailedException( string message) : base(message)
{
}
public BusinessValidationFailedException(string message, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed) : base(message)
{
Code = code;
}
}
}
@@ -24,11 +24,15 @@ namespace IRaCIS.Core.Infrastructure.Extention
ProgramException = 4,
//需要提示 ,需要提示 从Result 取数据 ( 0 可以继续处理提交 ,1 不能进行继续处理提交 ,2 刷新列表 )
NeedTips = 5,
NeedTips = 5,
/// <summary>
/// 关闭当前页面
/// </summary>
CloseCurrentWindows=6,
//在其他地方登陆,被迫下线
LoginInOtherPlace = -1,
//在其他地方登陆,被迫下线
LoginInOtherPlace = -1,
//没有带token访问(未登陆)
NoToken=10,
+2 -2
View File
@@ -90,7 +90,7 @@ clone:
disable: true #禁用默认克隆
server:
host: 123.56.94.154
host: 106.14.89.110
user: root
password:
from_secret: test_ssh_pwd
@@ -121,7 +121,7 @@ clone:
disable: true #禁用默认克隆
server:
host: 123.56.94.154
host: 106.14.89.110
user: root
password:
from_secret: test_ssh_pwd