Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing Details

IRC_NewDev
hang 2024-08-19 17:36:45 +08:00
commit 12ac7af11e
94 changed files with 1657 additions and 1220 deletions

View File

@ -4,6 +4,7 @@ using IRaCIS.Core.Infra.EFCore;
using Medallion.Threading;
using Medallion.Threading.SqlServer;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@ -15,11 +16,12 @@ namespace IRaCIS.Core.SCP
{
services.AddHttpContextAccessor();
services.AddScoped<IUserInfo, UserInfo>();
services.AddScoped<ISaveChangesInterceptor, AuditEntityInterceptor>();
//这个注入没有成功--注入是没问题的构造函数也只是支持参数就好错在注入的地方不能写DbContext
//Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量 这在概念上类似于ADO.NET Provider原生的连接池操作方式具有节省DbContext实例化成本的优点
services.AddDbContextPool<IRaCISDBContext>(options =>
services.AddDbContextPool<IRaCISDBContext>((sp, options) =>
{
// 在控制台
//public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); });
@ -35,6 +37,7 @@ namespace IRaCIS.Core.SCP
options.EnableSensitiveDataLogging();
options.AddInterceptors(new QueryWithNoLockDbCommandInterceptor());
options.AddInterceptors(sp.GetServices<ISaveChangesInterceptor>());
options.UseProjectables();

View File

@ -889,89 +889,6 @@ namespace IRaCIS.Core.API.Controllers
#region 废弃
/// <summary>
/// 下载多个医生的所有附件
/// </summary>
/// <param name="doctorIds"></param>
/// <returns></returns>
[Obsolete]
[HttpPost, Route("file/downloadDoctorAttachments")]
public async Task<IResponseOutput<UploadFileInfoDTO>> DownloadAttachment(Guid[] doctorIds)
{
var path = await _fileService.CreateDoctorsAllAttachmentZip(doctorIds);
return ResponseOutput.Ok(new UploadFileInfoDTO
{
FilePath = path,
FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7)
});
}
/// <summary>
/// 下载指定医生的指定附件
/// </summary>
/// <param name="doctorId">医生Id</param>
/// <param name="attachmentIds">要下载的附件Id</param>
/// <returns></returns>
[HttpPost, Route("file/downloadByAttachmentId/{doctorId}")]
[Obsolete]
public async Task<IResponseOutput<UploadFileInfoDTO>> DownloadAttachmentById(Guid doctorId, Guid[] attachmentIds)
{
var path = await _fileService.CreateZipPackageByAttachment(doctorId, attachmentIds);
return ResponseOutput.Ok(new UploadFileInfoDTO
{
FilePath = await _fileService.CreateZipPackageByAttachment(doctorId, attachmentIds),
FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7)
});
}
/// <summary>
/// 下载医生官方简历 首页 区分 中文和英文
/// </summary>
/// <param name="language"></param>
/// <param name="doctorIds"></param>
/// <returns></returns>
[HttpPost, Route("file/downloadOfficialCV/{language}")]
[Obsolete]
public async Task<IResponseOutput<UploadFileInfoDTO>> DownloadOfficialResume(int language, Guid[] doctorIds)
{
var path = await _fileService.CreateDoctorsAllAttachmentZip(doctorIds);
return ResponseOutput.Ok(new UploadFileInfoDTO
{
FilePath = await _fileService.CreateOfficialResumeZip(language, doctorIds),
FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7)
});
}
/// <summary>
/// 入组 项目下载简历
/// </summary>
/// <param name="language"></param>
/// <param name="trialId"></param>
/// <param name="doctorIdArray"></param>
/// <returns></returns>
[HttpPost, Route("enroll/downloadResume/{trialId:guid}/{language}")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[AllowAnonymous]
[Obsolete]
public async Task<IResponseOutput<string>> DownloadResume(int language, Guid trialId, Guid[] doctorIdArray)
{
var zipPath = await _fileService.CreateOfficialResumeZip(language, doctorIdArray);
return ResponseOutput.Ok(zipPath);
}
#endregion
}
#endregion

View File

@ -326,38 +326,6 @@
<param name="_attachmentrepository"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadAttachment(System.Guid[])">
<summary>
下载多个医生的所有附件
</summary>
<param name="doctorIds"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadAttachmentById(System.Guid,System.Guid[])">
<summary>
下载指定医生的指定附件
</summary>
<param name="doctorId">医生Id</param>
<param name="attachmentIds">要下载的附件Id</param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadOfficialResume(System.Int32,System.Guid[])">
<summary>
下载医生官方简历 首页 区分 中文和英文
</summary>
<param name="language"></param>
<param name="doctorIds"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadResume(System.Int32,System.Guid,System.Guid[])">
<summary>
入组 项目下载简历
</summary>
<param name="language"></param>
<param name="trialId"></param>
<param name="doctorIdArray"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.DownloadCommonFile(System.String,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument})">
<summary> 通用文件下载 </summary>
</member>

View File

@ -29,6 +29,10 @@ using IRaCIS.Core.Application.Service.ImageAndDoc;
using IP2Region.Net.Abstractions;
using IP2Region.Net.XDB;
using IRaCIS.Core.Application.BusinessFilter;
using Microsoft.AspNetCore.Http;
using IRaCIS.Core.Infrastructure.Extention;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Diagnostics;
#region 获取环境变量
@ -117,7 +121,7 @@ builder.Services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuratio
builder.Services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
builder.Services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
builder.Services.AddOptions().Configure<EncreptResponseOption>(_configuration.GetSection("EncrypteResponseConfig"));
builder.Services.AddOptions().Configure<SystemPacsConfig>(_configuration.GetSection("SystemPacsConfig"));
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
@ -164,6 +168,8 @@ builder.Services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
builder.Services.AddSingleton<ISearcher>(new Searcher(CachePolicy.Content, Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, "ip2region.xdb")));
//builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
//builder.Services.AddProblemDetails();
#region 历史废弃配置
//builder.Services.AddMemoryCache();
@ -190,6 +196,56 @@ var env = app.Environment;
// Configure the HTTP request pipeline.
#region 异常处理 全局业务异常已统一处理了,非业务错误会来到这里 400 -500状态码
//app.UseStatusCodePagesWithReExecute("/Error/{0}");
app.UseStatusCodePages(async context =>
{
var code = context.HttpContext.Response.StatusCode;
context.HttpContext.Response.ContentType = "application/json";
if (code < 500)
{
await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk($"Client error, actual request error status code({code})")));
}
else
{
//ResultFilter 里面的异常并不会到这里
await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject((ResponseOutput.NotOk($"Server error , actual request error status code({code})"))));
}
});
//app.UseExceptionHandler(o => { });
//这里没生效原因未知官方文档也是这种写法也用了GlobalExceptionHandler 尝试还是不行怀疑框架bug
//app.UseExceptionHandler(configure =>
//{
// configure.Run(async context =>
// {
// var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
//var ex = exceptionHandlerPathFeature?.Error;
//context.Response.ContentType = "application/json";
//if (ex != null)
//{
// var errorInfo = $"Exception: {ex.Message}[{ex.StackTrace}]" + (ex.InnerException != null ? $" InnerException: {ex.InnerException.Message}[{ex.InnerException.StackTrace}]" : "");
// await context.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk($"{ex?.Message}")));
// Log.Logger.Error(errorInfo);
//}
// });
//});
#endregion
//本地化
app.UseLocalization();
@ -198,12 +254,11 @@ 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");
@ -211,22 +266,24 @@ app.UseLogDashboard("/LogDashboard");
//hangfire
app.UseHangfireConfig(env);
#region 暂时废弃
//app.UseMiddleware<MultiDiskStaticFilesMiddleware>();
////限流 中间件
//app.UseIpRateLimiting();
//if (env.IsDevelopment())
//{
// app.UseDeveloperExceptionPage();
//}
//else
//{
// //app.UseHsts();
//}
#endregion
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
//app.UseHsts();
}
// 特殊异常处理 比如 404
app.UseStatusCodePagesWithReExecute("/Error/{0}");
SwaggerSetup.Configure(app, env);

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Builder;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Localization;
using System.Collections.Generic;
using System.Globalization;
@ -12,8 +13,9 @@ namespace IRaCIS.Core.API
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en-US"),
new CultureInfo("zh-CN")
new CultureInfo(StaticData.CultureInfo.en_US),
new CultureInfo(StaticData.CultureInfo.zh_CN)
};
var options = new RequestLocalizationOptions

View File

@ -7,6 +7,7 @@ using IRaCIS.Core.Infra.EFCore;
using Medallion.Threading;
using Medallion.Threading.SqlServer;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@ -21,12 +22,14 @@ namespace IRaCIS.Core.API
services.AddHttpContextAccessor();
services.AddScoped<IUserInfo, UserInfo>();
services.AddScoped<ISaveChangesInterceptor, AuditEntityInterceptor>();
// First, register a pooling context factory as a Singleton service, as usual:
//这个注入没有成功--注入是没问题的构造函数也只是支持参数就好错在注入的地方不能写DbContext
//Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量 这在概念上类似于ADO.NET Provider原生的连接池操作方式具有节省DbContext实例化成本的优点
services.AddDbContext<IRaCISDBContext>(options =>
services.AddDbContext<IRaCISDBContext>((sp, options) =>
{
// 在控制台
@ -43,6 +46,7 @@ namespace IRaCIS.Core.API
options.EnableSensitiveDataLogging();
options.AddInterceptors(new QueryWithNoLockDbCommandInterceptor());
options.AddInterceptors(sp.GetServices<ISaveChangesInterceptor>());
options.UseProjectables();

View File

@ -47,7 +47,11 @@
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
},
"SystemEmailSendConfig": {
"Port": 465,

View File

@ -49,8 +49,10 @@
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
},
"SystemEmailSendConfig": {

View File

@ -65,7 +65,10 @@
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
},
"SystemEmailSendConfig": {
@ -82,8 +85,10 @@
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗"
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "106.14.89.110"
}
}

View File

@ -63,7 +63,10 @@
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
},
"SystemEmailSendConfig": {

View File

@ -69,7 +69,10 @@
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
},
"SystemEmailSendConfig": {

View File

@ -62,6 +62,9 @@
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90,
"OpenLoginMFA": true
},

View File

@ -12,7 +12,7 @@
},
"ObjectStoreService": {
"ObjectStoreUse": "MinIO",
"ObjectStoreUse": "AliyunOSS",
"AliyunOSS": {
"regionId": "cn-shanghai",
@ -56,7 +56,10 @@
"ContinuousReadingTimeMin": 120,
"ReadingRestTimeMin": 10
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
"ChangePassWordDays": 90
},
"SystemEmailSendConfig": {
@ -72,7 +75,11 @@
"CompanyNameCN": "上海展影医疗科技有限公司",
"CompanyShortName": "Extensive Imaging",
"CompanyShortNameCN": "展影医疗"
},
"SystemPacsConfig": {
"Port": "11113",
"IP": "47.117.164.182"
}
}

View File

@ -8,6 +8,7 @@ using Panda.DynamicWebApi;
using Panda.DynamicWebApi.Attributes;
using System.Diagnostics.CodeAnalysis;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc;
namespace IRaCIS.Core.Application
{
@ -17,7 +18,8 @@ namespace IRaCIS.Core.Application
#region 非泛型版本
[Authorize, DynamicWebApi, UnifiedApiResultFilter]
[TypeFilter(typeof(UnifiedApiResultFilter))]
[Authorize, DynamicWebApi]
public class BaseService : IBaseService, IDynamicWebApi
{
public IMapper _mapper { get; set; }
@ -83,8 +85,8 @@ namespace IRaCIS.Core.Application
}
[Authorize, DynamicWebApi, UnifiedApiResultFilter]
[TypeFilter(typeof(UnifiedApiResultFilter))]
[Authorize, DynamicWebApi]
public class BaseServiceTest<T> : IBaseServiceTest<T>, IDynamicWebApi where T : Entity
{
public IMapper _mapper { get; set; }

View File

@ -0,0 +1,50 @@
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.BusinessFilter
{
/// <summary>
/// 不生效,不知道为啥
/// </summary>
public class GlobalExceptionHandler : IExceptionHandler
{
private readonly ILogger<GlobalExceptionHandler> _logger;
public GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger)
{
this._logger = logger;
}
public ValueTask<bool> TryHandleAsync(
HttpContext httpContext,
Exception exception,
CancellationToken cancellationToken)
{
httpContext.Response.ContentType = "application/json";
var ex = exception;
var errorInfo = $"Exception: {ex.Message}[{ex.StackTrace}]" + (ex.InnerException != null ? $" InnerException: {ex.InnerException.Message}[{ex.InnerException.StackTrace}]" : "");
httpContext.Response.WriteAsJsonAsync(ResponseOutput.NotOk($"{ex?.Message}"));
_logger.LogError(errorInfo);
// return true to signal that this exception is handled
return ValueTask.FromResult(false);
}
}
}

View File

@ -1,4 +1,5 @@
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
@ -11,13 +12,13 @@ namespace IRaCIS.Core.Application.Filter
{
private readonly ILogger<ProjectExceptionFilter> _logger;
public IStringLocalizer _localizer;
public IStringLocalizer _localizer;
public ProjectExceptionFilter(IStringLocalizer localizer, ILogger<ProjectExceptionFilter> logger)
public ProjectExceptionFilter(IStringLocalizer localizer, ILogger<ProjectExceptionFilter> logger)
{
_logger = logger;
_localizer = localizer;
}
_localizer = localizer;
}
public void OnException(ExceptionContext context)
{
//context.ExceptionHandled;//记录当前这个异常是否已经被处理过了
@ -26,7 +27,7 @@ namespace IRaCIS.Core.Application.Filter
{
if (context.Exception.GetType().Name == "DbUpdateConcurrencyException")
{
//---并发更新,当前不允许该操作
//---并发更新,当前不允许该操作
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ProjectException_ConcurrentUpdateNotAllowed"] + context.Exception.Message));
}
@ -34,28 +35,43 @@ namespace IRaCIS.Core.Application.Filter
{
var error = context.Exception as BusinessValidationFailedException;
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, error!.Code));
var info = string.Empty;
if (!string.IsNullOrWhiteSpace(error!.LocalizedKey) && StaticData.Log_Locoalize_Dic.ContainsKey(error!.LocalizedKey))
{
info = $"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}";
}
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, "", error!.Code, localizedInfo: info));
//warning 级别记录
//_logger.LogWarning($"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}");
}
else if(context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException))
else if (context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException))
{
context.Result = new JsonResult(ResponseOutput.NotOk( context.Exception.Message, ApiResponseCodeEnum.DataNotExist));
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, ApiResponseCodeEnum.DataNotExist));
}
else
{
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (context.Exception.InnerException is null ? (context.Exception.Message /*+ context.Exception.StackTrace*/)
: (context.Exception.InnerException?.Message /*+ context.Exception.InnerException?.StackTrace*/)), ApiResponseCodeEnum.ProgramException));
_logger.LogError(context.Exception.InnerException is null ? (context.Exception.Message + context.Exception.StackTrace) : (context.Exception.InnerException?.Message + context.Exception.InnerException?.StackTrace));
}
context.ExceptionHandled = true;//标记当前异常已经被处理过了
_logger.LogError(context.Exception.InnerException is null ? (context.Exception.Message + context.Exception.StackTrace) : (context.Exception.InnerException?.Message + context.Exception.InnerException?.StackTrace));
//throw new Exception("test-result-exceptioin");
}
else
{
//继续
}
context.ExceptionHandled = true;//标记当前异常已经被处理过了
}
}
}

View File

@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Share;
using Microsoft.Extensions.Logging;
namespace IRaCIS.Application.Services.BusinessFilter
{
@ -10,6 +11,12 @@ namespace IRaCIS.Application.Services.BusinessFilter
/// </summary>
public class UnifiedApiResultFilter : Attribute, IAsyncResultFilter
{
private readonly ILogger _logger;
public UnifiedApiResultFilter(ILogger<UnifiedApiResultFilter> logger)
{
_logger = logger;
}
/// <summary>
/// 异步版本
@ -31,12 +38,11 @@ namespace IRaCIS.Application.Services.BusinessFilter
var type = objectResult.Value?.GetType();
if ( type!=null&& type.IsGenericType&&(type.GetGenericTypeDefinition()==typeof(ValueTuple<,>)|| type.GetGenericTypeDefinition()==typeof(Tuple<,>)))
if (type != null && type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(ValueTuple<,>) || type.GetGenericTypeDefinition() == typeof(Tuple<,>)))
{
//报错
//var tuple = (object, object))objectResult.Value;
//var (val1, val2) = ((dynamic, dynamic))objectResult.Value;
//var apiResponse = ResponseOutput.Ok(val1, val2);
@ -56,16 +62,20 @@ namespace IRaCIS.Application.Services.BusinessFilter
objectResult.DeclaredType = apiResponse.GetType();
}
}
//如果不是200 是IResponseOutput 不处理
else if (statusCode != 200 && (objectResult.Value is IResponseOutput))
//如果是200 是IResponseOutput 记录下日志
else if (statusCode == 200 && (objectResult.Value is IResponseOutput))
{
var result = objectResult.Value as IResponseOutput;
//统一在这里记录国际化的日志信息
_logger.LogWarning($"{result.LocalizedInfo}");
}
else if(statusCode != 200&&!(objectResult.Value is IResponseOutput))
else if (statusCode != 200 && !(objectResult.Value is IResponseOutput))
{
//---程序错误,请联系开发人员。
//---程序错误,请联系开发人员。
var apiResponse = ResponseOutput.NotOk(StaticData.International("UnifiedAPI_ProgramError"));
objectResult.Value = apiResponse;

View File

@ -117,7 +117,7 @@ public static class ExcelExportHelper
var (physicalPath, fileNmae) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);
var (physicalPath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);
//模板路径
@ -157,7 +157,7 @@ public static class ExcelExportHelper
}
// 文件名称 从sheet里面取
fileNmae = workbook.GetSheetName(0);
//fileNmae = workbook.GetSheetName(0);
#endregion
@ -181,7 +181,7 @@ public static class ExcelExportHelper
return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
FileDownloadName = $"{exportFileNamePrefix}_{fileNmae/*.Substring(0, fileNmae.LastIndexOf('.'))*/}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
FileDownloadName = $"{(string.IsNullOrEmpty(exportFileNamePrefix) ? "" : exportFileNamePrefix+ "_") }{Path.GetFileNameWithoutExtension(fileName) }_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
};
#endregion
@ -328,7 +328,7 @@ public static class ExcelExportHelper
}
// 文件名称 从sheet里面取
fileName = workbook.GetSheetName(0);
//fileName = workbook.GetSheetName(0);
#endregion
#region MiniExcel

View File

@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json.Linq;
using System.Configuration;
using System.Globalization;
using System.Text.RegularExpressions;
namespace IRaCIS.Core.Application.Helper;
@ -128,65 +129,6 @@ public static class FileStoreHelper
#endregion
/// <summary>
///
/// </summary>
/// <param name="_hostEnvironment"></param>
/// <param name="_clinicalDataTrialSetRepository"></param>
/// <param name="id"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public static async Task<(string PhysicalPath, string FileName)> GetSystemClinicalPathAsync(IWebHostEnvironment _hostEnvironment, IRepository<ClinicalDataSystemSet> _clinicalDataTrialSetRepository, Guid id)
{
var systemClinicalData = await _clinicalDataTrialSetRepository.FirstOrDefaultAsync(t => t.Id == id);
if (systemClinicalData == null || systemClinicalData.Path == string.Empty)
{
//---数据库没有找到对应的数据模板文件,请联系系统运维人员。
throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileNotFound"));
}
var filePath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, systemClinicalData.Path);
if (!System.IO.File.Exists(filePath))
{
//---数据模板文件存储路径上未找对应文件,请联系系统运维人员。
throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileStoragePathInvalid"));
}
return (filePath, systemClinicalData.FileName);
}
/// <summary>
///
/// </summary>
/// <param name="_hostEnvironment"></param>
/// <param name="_clinicalDataTrialSetRepository"></param>
/// <param name="id"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public static async Task<(string PhysicalPath, string FileName)> GetTrialClinicalPathAsync(IWebHostEnvironment _hostEnvironment, IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository, Guid id)
{
var trialClinicalData = await _clinicalDataTrialSetRepository.FirstOrDefaultAsync(t => t.Id == id);
if (trialClinicalData == null|| trialClinicalData.Path==string.Empty)
{
//---数据库没有找到对应的数据模板文件,请联系系统运维人员。
throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileNotFound"));
}
var filePath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, trialClinicalData.Path);
if (!System.IO.File.Exists(filePath))
{
//---数据模板文件存储路径上未找对应文件,请联系系统运维人员。
throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileStoragePathInvalid"));
}
return (filePath, trialClinicalData.FileName);
}
//通过编码获取通用文档具体物理路径
@ -194,6 +136,7 @@ public static class FileStoreHelper
{
var doc = await _commonDocumentRepository.FirstOrDefaultAsync(t => t.Code == code);
var isEn_US = CultureInfo.CurrentCulture.Name!= "zh-CN";
if (doc == null)
{
//---数据库没有找到对应的数据模板文件,请联系系统运维人员。
@ -208,7 +151,7 @@ public static class FileStoreHelper
throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileStoragePathInvalid"));
}
return (filePath, doc.Name.Trim('/'));
return (filePath, isEn_US? doc.Name.Trim('/'): doc.NameCN.Trim('/'));
}
@ -235,44 +178,6 @@ public static class FileStoreHelper
return writeCount;
}
// 获取项目签名文档存放路径
public static (string PhysicalPath, string RelativePath) GetTrialSignDocPath(IWebHostEnvironment _hostEnvironment, Guid trialId, string fileName)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
//文件类型路径处理
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), StaticData.Folder.SignDocumentFolder);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{StaticData.Folder.SignDocumentFolder}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath);
}
// 获取系统签名文档存放路径
public static (string PhysicalPath, string RelativePath) GetSystemSignDocPath(IWebHostEnvironment _hostEnvironment, string fileName)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
//文件类型路径处理
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.SystemDataFolder, StaticData.Folder.SignDocumentFolder);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.SystemDataFolder}/{ StaticData.Folder.SignDocumentFolder}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath);
}
// 获取通用文档存放路径excel模板
@ -295,224 +200,6 @@ public static class FileStoreHelper
return (serverFilePath, relativePath);
}
//获取系统通知文档存放路径
public static (string PhysicalPath, string RelativePath) GetSystemNoticePath(IWebHostEnvironment _hostEnvironment, string fileName)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
//文件类型路径处理
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.SystemDataFolder, StaticData.Folder.NoticeAttachment);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.SystemDataFolder}/{StaticData.Folder.NoticeAttachment}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath);
}
// 获取一致性核查路径
public static (string PhysicalPath, string RelativePath) GetTrialCheckFilePath(IWebHostEnvironment _hostEnvironment, string fileName,Guid trialId)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
//上传根路径
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), StaticData.Folder.UploadEDCData);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
//存放核对表
var (trustedFileNameForFileStorage, realFileName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{StaticData.Folder.UploadEDCData}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath);
}
public static (string PhysicalPath, string RelativePath, string FileRealName) GetClinicalTemplatePath(IWebHostEnvironment _hostEnvironment, string fileName,Guid trialId)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, "ClinicalTemplate", trialId.ToString(), StaticData.Folder.TreatmenthistoryFolder);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/ClinicalTemplate/{trialId}/{StaticData.Folder.TreatmenthistoryFolder}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath, fileRealName);
}
public static (string PhysicalPath, string RelativePath, string FileRealName) GetReadClinicalDataPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteId, Guid subjectId, Guid readingId)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString(), StaticData.Folder.Reading, readingId.ToString());
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{StaticData.Folder.Reading}/{readingId}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath, fileRealName);
}
//获取临床数据存放路径
public static (string PhysicalPath, string RelativePath,string FileRealName) GetClinicalDataPath(IWebHostEnvironment _hostEnvironment, string fileName,Guid trialId,Guid siteId,Guid subjectId,Guid subjectVisitId)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(),siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.TreatmenthistoryFolder);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.TreatmenthistoryFolder}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath, fileRealName);
}
public static (string PhysicalPath, string RelativePath, string FileRealName) GetClinicalDataPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId , Guid subjectId)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), subjectId.ToString(), StaticData.Folder.TreatmenthistoryFolder);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{subjectId}/{StaticData.Folder.TreatmenthistoryFolder}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath, fileRealName);
}
/// <summary>
/// 上传截图
/// </summary>
/// <param name="_hostEnvironment"></param>
/// <param name="fileName"></param>
/// <param name="trialId"></param>
/// <param name="siteid"></param>
/// <param name="subjectId"></param>
/// <returns></returns>
public static (string PhysicalPath, string RelativePath, string FileRealName) GetUploadPrintscreenFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteid, Guid subjectId)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteid.ToString(), subjectId.ToString());
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteid}/{subjectId}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath, fileRealName);
}
/// <summary>
/// 通用获取文件路径
/// </summary>
/// <param name="_hostEnvironment"></param>
/// <param name="fileName"></param>
/// <param name="trialId"></param>
/// <param name="id"></param>
/// <param name="type"></param>
/// <returns></returns>
public static (string PhysicalPath, string RelativePath, string FileRealName) GetFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid id,string type)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), id.ToString(), type);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{id}/{type}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath, fileRealName);
}
public static (string PhysicalPath, string RelativePath, string FileRealName) GetMedicalReviewImage(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid taskMedicalReviewId)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), taskMedicalReviewId.ToString(), StaticData.Folder.MedicalReview);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{taskMedicalReviewId}/{StaticData.Folder.MedicalReview}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath, fileRealName);
}
//获取非dicom文件存放路径
public static (string PhysicalPath, string RelativePath, string FileRealName) GetNoneDicomFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.NoneDicomFolder);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.NoneDicomFolder}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath, fileRealName);
}
// 获取 入组确认 PD 进展发送邮件Word|PDF 存放路径
public static (string PhysicalPath, string RelativePath, string FileRealName) GetSubjectEnrollConfirmOrPDEmailPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid trialSiteId, Guid subjectId,bool isChangeToPdfFormat=false)
@ -629,49 +316,7 @@ public static class FileStoreHelper
// 获取医生通用文件存放路径
public static (string PhysicalPath, string RelativePath) GetDoctorOrdinaryFilePath(IWebHostEnvironment _hostEnvironment, string fileName,Guid doctorId,string attachmentType)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
//文件类型路径处理
var uploadFolderPath = Path.Combine(rootPath, "UploadFile", doctorId.ToString(), attachmentType);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.UploadFileFolder}/{doctorId}/{attachmentType}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath);
}
public static (string PhysicalPath, string RelativePath) GetNonDoctorFilePath(IWebHostEnvironment _hostEnvironment, string fileName, string attachmentType)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
//文件类型路径处理
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.UploadFileFolder, attachmentType);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.UploadFileFolder}/{attachmentType}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath);
}

View File

@ -9,7 +9,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static BeetleX.Redis.Commands.HSCAN;
using static IRaCIS.Core.Application.Service.Common.SystemMonitor;
namespace IRaCIS.Core.Application.Helper
@ -54,6 +53,9 @@ namespace IRaCIS.Core.Application.Helper
jsonObject[item.Code] = item.Value;
StaticData.En_US_Dic[item.Code] = item.Value;
//日志记录该信息方便自己人看, 返回给客户的是配置的
StaticData.Log_Locoalize_Dic[item.Code] = item.Description;
}
}
else
@ -72,7 +74,7 @@ namespace IRaCIS.Core.Application.Helper
}
}
public static async Task AddOrUpdateJsonKeyValueAsync(string key, string value, string valueCN)
public static async Task AddOrUpdateJsonKeyValueAsync(string key, string value, string valueCN,string description)
{
VerifyFolder();
@ -95,6 +97,9 @@ namespace IRaCIS.Core.Application.Helper
jsonObject[key] = value;
StaticData.En_US_Dic[key] = value;
//日志记录该信息方便自己人看, 返回给客户的是配置的
StaticData.Log_Locoalize_Dic[key] = description;
}
else
{
@ -118,7 +123,8 @@ namespace IRaCIS.Core.Application.Helper
{
t.Code,
t.Value,
t.ValueCN
t.ValueCN,
t.Description
}).ToListAsync();
//组织成json 文件
@ -132,6 +138,9 @@ namespace IRaCIS.Core.Application.Helper
{
StaticData.En_US_Dic[tojsonItem.Code] = tojsonItem.Value;
StaticData.Zh_CN_Dic[tojsonItem.Code] = tojsonItem.ValueCN;
//日志记录该信息方便自己人看, 返回给客户的是配置的
StaticData.Log_Locoalize_Dic[tojsonItem.Code] = tojsonItem.Description;
}
File.WriteAllText(usJsonPath, JsonConvert.SerializeObject(StaticData.En_US_Dic));

View File

@ -52,15 +52,19 @@ public static class SendEmailHelper
public static async Task<bool> TestEmailConfigAsync(SystemEmailSendConfig _systemEmailConfig)
{
using (var client = new MailKit.Net.Smtp.SmtpClient())
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)))
{
using (var client = new MailKit.Net.Smtp.SmtpClient())
{
await client.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto);
await client.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto, cts.Token);
await client.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode);
await client.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode, cts.Token);
await client.DisconnectAsync(true);
await client.DisconnectAsync(true);
}
}
return true;
}

View File

@ -0,0 +1,101 @@
using IRaCIS.Core.Domain.Share;
using NPOI.XWPF.UserModel;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xceed.Document.NET;
using Xceed.Words.NET;
namespace IRaCIS.Core.Application.Helper
{
/// <summary>
/// 利用DocX 库 处理word国际化模板
/// </summary>
public static class WordTempleteHelper
{
public static void DocX_GetInternationalTempleteStream(string filePath, Stream memoryStream)
{
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
using (DocX document = DocX.Load(filePath))
{
// 查找书签
var bookmarkEn_Start = document.Bookmarks.FirstOrDefault(b => b.Name == StaticData.CultureInfo.en_US_bookMark);
if (bookmarkEn_Start != null)
{
// 获取书签的起始位置
//int bookmarkCNStartPos = bookmarkCn_Start.Paragraph.StartIndex;
var bookmarkENStartPos = bookmarkEn_Start.Paragraph.StartIndex;
// 创建一个要删除段落的列表
List<Paragraph> paragraphsToRemove = new List<Paragraph>();
foreach (var item in document.Paragraphs)
{
//中文模板在前,英文在后,英文模板,就删除英文之前的,中文模板就删除英文之后的
if (isEn_US ? item.EndIndex < bookmarkENStartPos : item.StartIndex >= bookmarkENStartPos)
{
paragraphsToRemove.Add(item);
}
}
foreach (var paragraph in paragraphsToRemove)
{
document.RemoveParagraph(paragraph);
}
}
// 保存修改
document.SaveAs(memoryStream);
}
}
public static void Npoi_GetInternationalTempleteStream(string filePath, Stream memoryStream)
{
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
XWPFDocument doc = new XWPFDocument(fs);
// 查找包含指定书签的段落及其索引
var bookmarkParagraph = doc.Paragraphs
.FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == StaticData.CultureInfo.en_US_bookMark));
if (bookmarkParagraph != null)
{
int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph);
if (isEn_US)
{
// 从书签所在段落开始,删除之前的所有段落
for (int i = bookmarkIndex - 1; i >= 0; i--)
{
doc.RemoveBodyElement(i);
}
}
else
{
// 删除书签之后的所有段落
for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--)
{
doc.RemoveBodyElement(i);
}
}
}
doc.Write(memoryStream);
}
}
}
}

View File

@ -42,7 +42,7 @@
<ItemGroup>
<None Remove="IRaCIS.Core.Application.xml" />
<None Remove="Resources\en-US.json" />
<None Remove="Resources\zh-CN.json" />
<None Remove="Resources\zh_ch.json" />
<None Remove="Service\Allocation\TaskConsistentRuleService.cs~RF1603d47.TMP" />
<None Remove="Service\Reading\ReadingImageTask\ReadingImageTaskService.cs~RF2f9323.TMP" />
<None Remove="Service\Reading\ReadingImageTask\ReadingJudgeTaskService.cs~RF198afd23.TMP" />
@ -50,11 +50,6 @@
<ItemGroup>
<Content Include="Resources\zh-CN.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="Resources\en-US.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
@ -63,10 +58,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
<PackageReference Include="DocX" Version="3.0.1" />
<PackageReference Include="FreeSpire.Doc" Version="12.2.0" />
<PackageReference Include="Hangfire.Core" Version="1.8.12" />
<PackageReference Include="BeetleX.BNR" Version="1.0.1" />
<PackageReference Include="Hangfire.Core" Version="1.8.14" />
<PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
<PackageReference Include="EasyCaching.Redis" Version="1.9.2" />
<PackageReference Include="EasyCaching.InMemory" Version="1.9.2" />
@ -74,22 +69,22 @@
<PackageReference Include="ExcelDataReader.DataSet" Version="3.6.0" />
<PackageReference Include="DistributedLock.Redis" Version="1.0.3" />
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.4" />
<PackageReference Include="fo-dicom" Version="5.1.2" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.2" />
<PackageReference Include="fo-dicom.Codecs" Version="5.12.0" />
<PackageReference Include="fo-dicom" Version="5.1.3" />
<PackageReference Include="fo-dicom.Imaging.ImageSharp" Version="5.1.3" />
<PackageReference Include="fo-dicom.Codecs" Version="5.14.4" />
<PackageReference Include="IP2Region.Net" Version="2.0.2" />
<PackageReference Include="MailKit" Version="4.2.0" />
<PackageReference Include="MediatR" Version="12.2.0" />
<PackageReference Include="MimeKit" Version="4.2.0" />
<PackageReference Include="MiniExcel" Version="1.32.0" />
<PackageReference Include="Minio" Version="6.0.2" />
<PackageReference Include="Minio" Version="6.0.3" />
<PackageReference Include="MiniWord" Version="0.8.0" />
<PackageReference Include="My.Extensions.Localization.Json" Version="3.3.0">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="NPOI" Version="2.7.0" />
<PackageReference Include="NPOI" Version="2.7.1" />
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
<PackageReference Include="WinSCP" Version="6.3.3" />
</ItemGroup>

View File

@ -29,31 +29,16 @@
签名
</summary>
</member>
<member name="T:IRaCIS.Core.Application.BusinessFilter.GlobalExceptionHandler">
<summary>
不生效,不知道为啥
</summary>
</member>
<member name="T:IRaCIS.Core.Application.Filter.TrialResourceFilter">
<summary>
主要为了 处理项目结束 锁库,不允许操作
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Helper.FileStoreHelper.GetSystemClinicalPathAsync(Microsoft.AspNetCore.Hosting.IWebHostEnvironment,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ClinicalDataSystemSet},System.Guid)">
<summary>
</summary>
<param name="_hostEnvironment"></param>
<param name="_clinicalDataTrialSetRepository"></param>
<param name="id"></param>
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>
<member name="M:IRaCIS.Core.Application.Helper.FileStoreHelper.GetTrialClinicalPathAsync(Microsoft.AspNetCore.Hosting.IWebHostEnvironment,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ClinicalDataTrialSet},System.Guid)">
<summary>
</summary>
<param name="_hostEnvironment"></param>
<param name="_clinicalDataTrialSetRepository"></param>
<param name="id"></param>
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>
<member name="M:IRaCIS.Core.Application.Helper.FileStoreHelper.WriteFileAsync(System.IO.Stream,System.String)">
<summary>
写文件导到磁盘
@ -62,28 +47,6 @@
<param name="path">文件保存路径</param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Helper.FileStoreHelper.GetUploadPrintscreenFilePath(Microsoft.AspNetCore.Hosting.IWebHostEnvironment,System.String,System.Guid,System.Guid,System.Guid)">
<summary>
上传截图
</summary>
<param name="_hostEnvironment"></param>
<param name="fileName"></param>
<param name="trialId"></param>
<param name="siteid"></param>
<param name="subjectId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Helper.FileStoreHelper.GetFilePath(Microsoft.AspNetCore.Hosting.IWebHostEnvironment,System.String,System.Guid,System.Guid,System.String)">
<summary>
通用获取文件路径
</summary>
<param name="_hostEnvironment"></param>
<param name="fileName"></param>
<param name="trialId"></param>
<param name="id"></param>
<param name="type"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Helper.OSSService.UploadToOSSAsync(System.IO.Stream,System.String,System.String,System.Boolean)">
<summary>
oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
@ -117,6 +80,11 @@
<returns>解密后的字符串</returns>
</member>
<!-- Badly formed XML comment ignored for member "M:IRaCIS.Core.Application.Helper.RSAHelper.Encrypt(System.String,System.String)" -->
<member name="T:IRaCIS.Core.Application.Helper.WordTempleteHelper">
<summary>
利用DocX 库 处理word国际化模板
</summary>
</member>
<member name="T:IRaCIS.Core.Application.Service.TaskAllocationRuleService">
<summary>
分配规则
@ -543,9 +511,19 @@
<returns></returns>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.GetTrialList_Export(IRaCIS.Core.Application.Contracts.TrialToBeDoneQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument},IRaCIS.Application.Interfaces.IDictionaryService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
<summary>
项目列表导出---new
</summary>
<param name="inQuery"></param>
<param name="_commonDocumentRepository"></param>
<param name="_dictionaryService"></param>
<param name="_trialRepository"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.PMTrainingRecordList_Export(IRaCIS.Core.Application.Contracts.DocumentTrialUnionQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument},IRaCIS.Application.Interfaces.IDictionaryService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
<summary>
getDocumentConfirmList 培训记录导出
getDocumentConfirmList 培训记录导出--new
</summary>
<param name="inQuery"></param>
<param name="_commonDocumentRepository"></param>
@ -567,7 +545,7 @@
</member>
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.QCVisitList_Export(IRaCIS.Core.Application.Contracts.QCVisitSearchDTO,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument},IRaCIS.Application.Interfaces.IDictionaryService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
<summary>
影像质控导出
影像质控导出---new
</summary>
<param name="inQuery"></param>
<param name="_commonDocumentRepository"></param>
@ -9910,7 +9888,7 @@
<param name="trialId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.TrialDicomAEService.TestSCPServerConnect(System.Guid)">
<member name="M:IRaCIS.Core.Application.Service.TrialDicomAEService.TestSCPServerConnect(IRaCIS.Core.Application.ViewModel.TestAECommand)">
<summary>
测试scp server 是否可以连接
</summary>
@ -15368,6 +15346,13 @@
<param name="outEnrollTime"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Application.Services.TestService.DeleteConsistentDate(System.Guid)">
<summary>
清理一致性分析任务
</summary>
<param name="trialReadingCriterionId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Application.Services.TestService.ModifyClinicalDataTable">
<summary>
维护临床数据 --一定要在同步表前同步数据才行

View File

@ -107,7 +107,7 @@ namespace IRaCIS.Core.Application.ViewModel
public class DoctorSelfConsistentSubjectView: ConsistentCommonView
{
public string FirstGlobalVisitName { get; set; } = string.Empty;
public string? BlindSubjectCode { get; set; }
public List<VisitTaskSimpleDTO> VisitTaskList { get; set; }

View File

@ -211,7 +211,9 @@ namespace IRaCIS.Core.Application.ViewModel
{
public bool? IsSelfAnalysis { get; set; }
public bool IsReReadingOrBackInfluenceAnalysis { get; set; }
public int ConsistentClinicalDataCount { get; set; } = 0;
public bool IsReReadingOrBackInfluenceAnalysis { get; set; }
}

View File

@ -20,6 +20,7 @@ using IRaCIS.Core.Infrastructure.Extention;
using System;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using NPOI.SS.Formula.Functions;
using IRaCIS.Core.Application.Service.Reading.Dto;
namespace IRaCIS.Core.Application.Service
{
@ -32,6 +33,8 @@ namespace IRaCIS.Core.Application.Service
private readonly IRepository<TaskConsistentRule> _taskConsistentRuleRepository;
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IRepository<ReadingConsistentClinicalData> _readingConsistentClinicalDataRepository;
private readonly IReadingClinicalDataService _readingClinicalDataService;
private readonly IRepository<SubjectUser> _subjectUserRepository;
private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<Enroll> _enrollRepository;
@ -44,11 +47,16 @@ namespace IRaCIS.Core.Application.Service
private readonly IVisitTaskHelpeService _visitTaskCommonService;
public TaskConsistentRuleService(IRepository<VisitTask> visitTaskRepository, IRepository<Enroll> enrollRepository, IRepository<TaskConsistentRule> taskConsistentRuleRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<Subject> subjectRepository, IDistributedLockProvider distributedLockProvider,
public TaskConsistentRuleService(IRepository<VisitTask> visitTaskRepository,
IRepository<ReadingConsistentClinicalData> readingConsistentClinicalDataRepository,
IReadingClinicalDataService readingClinicalDataService,
IRepository<Enroll> enrollRepository, IRepository<TaskConsistentRule> taskConsistentRuleRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<Subject> subjectRepository, IDistributedLockProvider distributedLockProvider,
IRepository<Trial> trialRepository, IRepository<TrialSite> trialSiteRepository, IRepository<TrialVirtualSiteCodeUpdate> trialVirtualSiteCodeUpdateRepository, IVisitTaskHelpeService visitTaskCommonService)
{
_taskConsistentRuleRepository = taskConsistentRuleRepository;
_visitTaskRepository = visitTaskRepository;
this._readingConsistentClinicalDataRepository = readingConsistentClinicalDataRepository;
this._readingClinicalDataService = readingClinicalDataService;
_subjectUserRepository = subjectUserRepository;
_subjectRepository = subjectRepository;
_enrollRepository = enrollRepository;
@ -117,6 +125,20 @@ namespace IRaCIS.Core.Application.Service
var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) };
var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);
#region 统计一致性分析临床数据数量
foreach (var item in pageList.CurrentPageData)
{
item.ConsistentClinicalDataCount = (await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
{
SubjectId = item.SubjectId,
TrialId = item.TrialId,
SelectIsSign = false,
IsGetAllConsistencyAnalysis = false,
VisitTaskId = item.Id,
})).Count();
}
#endregion
var trialTaskConfig = _repository.Where<Trial>(t => t.Id == queryVisitTask.TrialId).Select(t => new { IsHaveDoubleReadCriterion = t.TrialReadingCriterionList.Any(t => t.IsSigned && t.IsConfirm && t.ReadingType == ReadingMethod.Double), t.VitrualSiteCode }).FirstOrDefault();
@ -253,6 +275,7 @@ namespace IRaCIS.Core.Application.Service
TaskName = lastTask.TaskName + "_Global",
TaskBlindName = lastTask.TaskBlindName + "_Global",
TrialReadingCriterionId = trialReadingCriterionId,
VisitTaskNum= lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]
};
var afterGlobal = _visitTaskRepository.Where(t => t.SubjectId == lastTask.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum > lastTask.VisitTaskNum).ProjectTo<VisitTaskSimpleDTO>(_mapper.ConfigurationProvider).FirstOrDefault();
@ -496,7 +519,9 @@ namespace IRaCIS.Core.Application.Service
TrialReadingCriterionId = trialReadingCriterionId,
BlindSubjectCode = blindSubjectCode,
BlindTrialSiteCode = filterObj.BlindTrialSiteCode
BlindTrialSiteCode = filterObj.BlindTrialSiteCode,
VisitTaskNum = lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]
};
}
@ -599,6 +624,8 @@ namespace IRaCIS.Core.Application.Service
IsReReadingOrBackInfluenceAnalysis = t.IsReReadingOrBackInfluenceAnalysis,
FirstGlobalVisitName= t.ReadModuleList.Where(c=>c.TrialReadingCriterionId== trialReadingCriterionId && c.ModuleType== ModuleTypeEnum.Global).OrderBy(k=>k.SubjectVisit.VisitNum).Select(u=>u.SubjectVisit.VisitName).FirstOrDefault(),
BlindSubjectCode = t.SubjectVisitTaskList.Where(t => t.IsAnalysisCreate && t.TrialReadingCriterionId == trialReadingCriterionId).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault(),
IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.DoctorUserId == doctorUserId && c.IsSelfAnalysis == true && c.TrialReadingCriterionId == trialReadingCriterionId),
@ -711,7 +738,7 @@ namespace IRaCIS.Core.Application.Service
IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.IsSelfAnalysis == false && c.TrialReadingCriterionId == trialReadingCriterionId),
DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed).Select(t => new UserSimpleInfo()
DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed && t.ArmEnum <= Arm.DoubleReadingArm2).Select(t => new UserSimpleInfo()
{
UserId = t.Id,
FullName = t.DoctorUser.FullName,

View File

@ -1420,14 +1420,16 @@ namespace IRaCIS.Core.Application.Service
//判断是否存在传输方式为Pdf得临床数据
var exsitPDF = await _trialClinicalDataSetRepository.AnyAsync(t => t.TrialId == trialId &&
t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == readingCriterionId)
&& t.ClinicalUploadType == ClinicalUploadType.PDF);
var taskState = exsitPDF ? TaskState.NotEffect : TaskState.Effect;
var clinicalDataList = _readingClinicalDataRepository.Where(t => t.SubjectId == subjectId && t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF).Include(t => t.ReadingClinicalDataPDFList).Include(t => t.ClinicalDataTrialSet).ToList();
var firsttask = generateTaskCommand.GenerataConsistentTaskList[0];
var clinicalDataList = _readingClinicalDataRepository.Where(t => t.SubjectId == subjectId
&& t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == firsttask.TrialReadingCriterionId)
&& t.ClinicalDataTrialSet.ClinicalDataLevel!= ClinicalLevel.Study
&& t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF)
// crc受试者和访视的临床数据没上传 一致性分析的时候也不用显示
.Where(x=>x.ClinicalDataTrialSet.UploadRole == UploadRole.PM||x.FileCount>0)
.Include(t => t.ReadingClinicalDataPDFList).Include(t => t.ClinicalDataTrialSet).ToList();
foreach (var clinicalData in clinicalDataList)
{
var consistnentClinicalData = _mapper.Map<ReadingConsistentClinicalData>(clinicalData);
@ -1438,6 +1440,7 @@ namespace IRaCIS.Core.Application.Service
{
consistnentClinicalData.IsSign = false;
consistnentClinicalData.IsBlind = false;
consistnentClinicalData.IsComplete = true;
consistnentClinicalData.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded;
consistnentClinicalData.ClinicalDataTrialSet = null;
}
@ -1453,6 +1456,15 @@ namespace IRaCIS.Core.Application.Service
foreach (var task in generateTaskCommand.GenerataConsistentTaskList)
{
var exsitPDF = await _readingClinicalDataRepository.AnyAsync(t => t.TrialId == trialId &&
t.SubjectId== task.SubjectId&&
t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == readingCriterionId)
&& t.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.Study
&& t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF);
var taskState = exsitPDF ? TaskState.NotEffect : TaskState.Effect;
var consistentTask = new VisitTask()
{
TrialId = task.TrialId,

View File

@ -290,7 +290,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
{
foreach (var command in cancelCommand.CancelList.Where(t => t.IsCancelAssign))
{
if (await _visitTaskRepository.AnyAsync(t => t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState != ReadingTaskState.WaitReading))
if (await _visitTaskRepository.AnyAsync(t => t.TaskState==TaskState.Effect && t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState != ReadingTaskState.WaitReading))
{
//---当前医生已开始做该Subject 该标准的任务,不允许取消分配
throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorConfigNotFound"]);
@ -786,7 +786,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate))
.WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
.WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate)
.WhereIf(queryVisitTask.BeginSignTime != null, t => t.SignTime > queryVisitTask.BeginSignTime)
.WhereIf(queryVisitTask.BeginSignTime != null, t => t.SignTime > queryVisitTask.BeginSignTime)
.WhereIf(queryVisitTask.EndSignTime != null, t => t.SignTime < queryVisitTask.EndSignTime)
.ProjectTo<ReadingTaskView>(_mapper.ConfigurationProvider);

View File

@ -104,7 +104,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<SubjectUser, SubjectUserDTO>().IncludeBase<SubjectUser, SubjectUserView>()
.ForMember(o => o.IsHaveReading, t => t.MapFrom(u => u.Subject.SubjectVisitTaskList.Any(t => t.ReadingTaskState != ReadingTaskState.WaitReading && t.TrialReadingCriterionId==u.TrialReadingCriterionId && t.DoctorUserId==u.DoctorUserId)));
.ForMember(o => o.IsHaveReading, t => t.MapFrom(u => u.Subject.SubjectVisitTaskList.Any(t => t.ReadingTaskState != ReadingTaskState.WaitReading && t.TrialReadingCriterionId==u.TrialReadingCriterionId && t.DoctorUserId==u.DoctorUserId && t.TaskState == TaskState.Effect)));
CreateMap<SubjectVisit, VisitGenerataTaskDTO>();

View File

@ -41,7 +41,7 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(string.IsNullOrEmpty(queryCommonDocument.Name), t => t.Name.Contains(queryCommonDocument.Name))
.ProjectTo<CommonDocumentView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken, userId = _userInfo.Id });
return await commonDocumentQueryable.ToPagedListAsync(queryCommonDocument.PageIndex, queryCommonDocument.PageSize, String.IsNullOrEmpty(queryCommonDocument.SortField) ? nameof(CommonDocument.Code) : queryCommonDocument.SortField, queryCommonDocument.Asc); ;
return await commonDocumentQueryable.ToPagedListAsync(queryCommonDocument);
}
@ -119,7 +119,7 @@ namespace IRaCIS.Core.Application.Service
var filePath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, dbbeforeEntity.Path);
if (File.Exists(filePath))
if (File.Exists(filePath) && dbbeforeEntity.Path!=addOrEditCommonDocument.Path)
{
File.Delete(filePath);
}

View File

@ -76,8 +76,7 @@ namespace IRaCIS.Core.Application.ViewModel
public string ValueCN { get; set; } = string.Empty;
public string Module { get; set; } = string.Empty;
//关联版本历史记录表Id
public Guid? PublishLogId { get; set; }
}
public class BatchAddInternationalizationDto : BatchInternationalizationDto

View File

@ -16,6 +16,7 @@ using MiniExcelLibs;
using MiniExcelLibs.OpenXml;
using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.SS.Formula.Functions;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
@ -181,6 +182,132 @@ namespace IRaCIS.Core.Application.Service.Common
}
/// <summary>
/// 项目列表导出---new
/// </summary>
/// <param name="inQuery"></param>
/// <param name="_commonDocumentRepository"></param>
/// <param name="_dictionaryService"></param>
/// <param name="_trialRepository"></param>
/// <returns></returns>
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> GetTrialList_Export(TrialToBeDoneQuery inQuery,
[FromServices] IRepository<CommonDocument> _commonDocumentRepository,
[FromServices] IDictionaryService _dictionaryService,
[FromServices] IRepository<Trial> _trialRepository
)
{
var isPM = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM;
var isCRC = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator;
var isIQC = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC;
var isMIM = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM;
var isSPMOrCPM = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM;
var isIR = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer;
var query = _trialRepository.AsQueryable().IgnoreQueryFilters()
.WhereIf(inQuery.SponsorId != null, o => o.SponsorId == inQuery.SponsorId)
.WhereIf(!string.IsNullOrEmpty(inQuery.Code), o => o.TrialCode.Contains(inQuery.Code))
.WhereIf(!string.IsNullOrEmpty(inQuery.ResearchProgramNo), o => o.ResearchProgramNo.Contains(inQuery.ResearchProgramNo))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.ExperimentName), o => o.ExperimentName.Contains(inQuery.ExperimentName))
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.Admin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.OP, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id && t.IsDeleted == false) && t.IsDeleted == false)
.WhereIf(inQuery.CriterionType != null, o => o.TrialReadingCriterionList.Any(t => t.CriterionType == inQuery.CriterionType && t.IsSigned && t.IsConfirm))
.WhereIf(!string.IsNullOrEmpty(inQuery.PM_EMail), o => o.TrialUserList.Any(t => t.User.EMail.Contains(inQuery.PM_EMail) && (t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM)))
.Select(t => new TrialToBeDoneDto()
{
TrialId = t.Id,
ResearchProgramNo = t.ResearchProgramNo,
ExperimentName = t.ExperimentName,
TrialCode = t.TrialCode,
CreateTime = t.CreateTime,
Sponsor = _userInfo.IsEn_Us ? t.Sponsor.SponsorName : t.Sponsor.SponsorNameCN,
TrialStatusStr = t.TrialStatusStr,
ExpetiedTaskCount = isPM ? t.VisitTaskList.Where(t => t.IsUrgent).Count() : 0,
ReReadingApprovalCount = isPM ? t.VisitTaskReReadingList.Where(t => t.OriginalReReadingTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed).Count() : 0,
PendingReconciliationCount = isPM ? t.SubjectVisitList.Where(t => t.CheckState == CheckStateEnum.ToCheck).Count() : 0,
PendingResponseCount = isPM ? t.SubjectVisitList.Where(u => u.CheckState == CheckStateEnum.CVIng &&
u.CheckChallengeDialogList.OrderByDescending(t => t.CreateTime).First().UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Count() : 0,
SPM_ReReadingApprovalCount = isSPMOrCPM ? t.VisitTaskReReadingList.Where(t => t.OriginalReReadingTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed).Count() : 0,
SPM_ReviewerSelectApprovalCount = isSPMOrCPM ? t.EnrollList.Where(u => u.EnrollStatus == EnrollStatus.HasCommittedToCRO).Count() : 0,
MIM_UrgentCount = isMIM ? t.TaskMedicalReviewList.Where(t => t.IsClosedDialog == false && t.VisitTask.TaskState == TaskState.Effect && t.IsInvalid == false && t.MedicalManagerUserId == _userInfo.Id)
.Where(u => u.VisitTask.IsUrgent &&
u.AuditState != MedicalReviewAuditState.HaveSigned).Count() : 0,
MIM_PendingResponseCount = isMIM ? t.TaskMedicalReviewList.Where(t => t.IsClosedDialog == false && t.VisitTask.TaskState == TaskState.Effect && t.IsInvalid == false && t.MedicalManagerUserId == _userInfo.Id)
.Where(u => u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IndependentReviewer && u.AuditState == MedicalReviewAuditState.Auditing).Count() : 0,
MIM_PendingReviewCount = isMIM ? t.TaskMedicalReviewList.Where(t => t.IsClosedDialog == false && t.VisitTask.TaskState == TaskState.Effect && t.IsInvalid == false && t.MedicalManagerUserId == _userInfo.Id)
.Where(u => u.AuditState != MedicalReviewAuditState.HaveSigned && u.LatestReplyUser.UserTypeEnum != UserTypeEnum.IndependentReviewer).Count() : 0,
CRC_UrgentCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id) && t.IsUrgent).Count() : 0,
CRC_CheckQuestionCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id))
.Where(u => u.CheckState == CheckStateEnum.CVIng && u.CheckChallengeState == CheckChanllengeTypeEnum.PMWaitCRCReply).Count() : 0,
CRC_QCQuestionCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id)).SelectMany(c => c.QCChallengeList)
.Where(u => u.IsClosed == false && (u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IQC || u.LatestReplyUserId == null)).Count() : 0,
//待审核 审核中 加急的数量
IQC_UrgentCount = isIQC ? t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.Id && t.QCProcessEnum != TrialQCProcess.NotAudit && t.IsUrgent).Count() : 0,
//审核未完成
IQC_AuditToBeDealedCount = isIQC ? t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.Id && t.QCProcessEnum != TrialQCProcess.NotAudit).Count() : 0,
//质疑待处理
IQC_QuestionToBeDealedCount = isIQC ? t.SubjectVisitList.SelectMany(c => c.QCChallengeList)
.Where(u => u.CreateUserId == _userInfo.Id && u.IsClosed == false && u.LatestReplyUser.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Count() : 0,
//待领取
IQC_ToBeClaimedCount = isIQC ? t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.AuditState != AuditStateEnum.QCPassed)
.Where(u => u.CurrentActionUserId == null && (u.PreliminaryAuditUserId == null || (u.PreliminaryAuditUserId != _userInfo.Id && u.ReviewAuditUserId == null))).Count() : 0,
IR_ReadingCriterionList = isIR ? t.TrialReadingCriterionList.Where(t => t.IsConfirm && t.IsSigned).OrderBy(t => t.CriterionName).Select(t => t.CriterionName).ToList() : null,
IR_PMEmailList = isIR ? t.TrialUserList.Where(t => t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM).OrderBy(t => t.User.EMail).Select(t => t.User.EMail).ToList() : null,
IR_TotalReadCount = isIR ? t.VisitTaskList.Where(t => t.DoctorUserId == _userInfo.Id && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned).Count() : 0,
IR_UnReadCount = isIR ? t.VisitTaskList
.Where(c => c.DoctorUserId == _userInfo.Id && c.ReadingTaskState != ReadingTaskState.HaveSigned && c.TaskState == TaskState.Effect && c.TrialReadingCriterion.IsSigned)
// 前序 不存在 未一致性核查未通过的
.Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum))
//前序 不存在 未生成任务的访视
.Where(t => t.TrialReadingCriterion.IsAutoCreate == false ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true)
.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)).Count() : 0,
IR_UrgentCount = isIR ? t.VisitTaskList.Where(t => t.SourceSubjectVisit.IsUrgent).Count() : 0,
});
var list = query.ToList();
var exportInfo = new ExcelExportInfo();
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
exportInfo.IsEn_US = _userInfo.IsEn_Us;
exportInfo.ClientZoneId = _userInfo.TimeZoneId;
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialToBeDoneDto));
}
#endregion
@ -190,7 +317,7 @@ namespace IRaCIS.Core.Application.Service.Common
#region 导表查询
/// <summary>
/// getDocumentConfirmList 培训记录导出
/// getDocumentConfirmList 培训记录导出--new
/// </summary>
/// <param name="inQuery"></param>
/// <param name="_commonDocumentRepository"></param>
@ -357,7 +484,7 @@ namespace IRaCIS.Core.Application.Service.Common
}
/// <summary>
/// 影像质控导出
/// 影像质控导出---new
/// </summary>
/// <param name="inQuery"></param>
/// <param name="_commonDocumentRepository"></param>
@ -376,9 +503,9 @@ namespace IRaCIS.Core.Application.Service.Common
{
var svExpression = QCCommon.GetSubjectVisitFilter(inQuery.VisitPlanArray);
var query = _subjectVisitRepository.Where(x => x.TrialId == inQuery.TrialId)
.WhereIf(inQuery.VisitId != null, t => t.Id == inQuery.VisitId)
.WhereIf(inQuery.CurrentActionUserId != null, t => t.CurrentActionUserId == inQuery.CurrentActionUserId)
.WhereIf(inQuery.ChallengeState != null, t => t.ChallengeState == inQuery.ChallengeState)
.WhereIf(inQuery.VisitId != null, t => t.Id == inQuery.VisitId)
.WhereIf(inQuery.CurrentActionUserId != null, t => t.CurrentActionUserId == inQuery.CurrentActionUserId)
.WhereIf(inQuery.ChallengeState != null, t => t.ChallengeState == inQuery.ChallengeState)
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.SubjectId != null, t => t.Subject.Id == inQuery.SubjectId)
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectInfo), t => /*t.Subject.FirstName.Contains(subjectInfo) || t.Subject.LastName.Contains(subjectInfo) ||*/ t.Subject.Code.Contains(inQuery.SubjectInfo))
@ -489,9 +616,9 @@ namespace IRaCIS.Core.Application.Service.Common
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
// CRC 只负责他管理site的受试者
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.ProjectTo<SubjectExportDTO>(_mapper.ConfigurationProvider)
.WhereIf(inQuery.IsMissingImages == true, t => t.MissingSubmmitCount> 0)
.WhereIf(inQuery.IsMissingImages == true, t => t.MissingSubmmitCount > 0)
.WhereIf(inQuery.IsMissingImages == false, t => t.MissingSubmmitCount == 0)
;
@ -915,10 +1042,10 @@ namespace IRaCIS.Core.Application.Service.Common
[FromServices] IRepository<Trial> _trialRepository)
{
var list = await _repository.Where<VisitTask>(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false)
//.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null)
//.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.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum)
.WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
@ -1314,7 +1441,7 @@ namespace IRaCIS.Core.Application.Service.Common
list.Add(new ExportDocumentDes() { Code = StaticData.Export.PCWG3Point1DetailedOfEvaluatedLesion_Export, ExportCatogory = ExportCatogory.DetailedOfEvaluatedLesion });
}
var result = _repository.Where<CommonDocument>(t => list.Select(c => c.Code).Contains(t.Code)).Select(c => new ExportDocumentDes() { Code = c.Code, FileName = c.Name }).ToList();
var result = _repository.Where<CommonDocument>(t => list.Select(c => c.Code).Contains(t.Code)).Select(c => new ExportDocumentDes() { Code = c.Code, FileName = _userInfo.IsEn_Us ? c.Name : c.NameCN }).ToList();
foreach (var item in list)
{
@ -1325,63 +1452,154 @@ namespace IRaCIS.Core.Application.Service.Common
public List<T> DealJudgeMark<T>(ArbitrationRule arbitrationRule, IEnumerable<T> list) where T : OverallTumorEvaluationExport
{
//处理裁判标记
var resultList = list.Where(t => t.ReadingCategory != ReadingCategory.Judge).ToList();
//处理访视任务的裁判标记
var resultExceptJudgeList = list.Where(t => t.ReadingCategory != ReadingCategory.Judge).ToList();
var judegeList = list.Where(t => t.ReadingCategory == ReadingCategory.Judge).ToList();
if (arbitrationRule == ArbitrationRule.Visit)
{
foreach (var item in resultList)
foreach (var item in resultExceptJudgeList)
{
item.IsGenerateJudge = list.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode
item.IsGenerateJudge = judegeList.FirstOrDefault(t => t.SubjectCode == item.SubjectCode
&& (t.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Judge]) == item.VisitTaskNum)?.JudgeArmEnum == item.ArmEnum ? true : false;
}
//如果没有产生裁判默认选择R1
//找到没有裁判的访视任务
var notJudgeList = resultExceptJudgeList.GroupBy(t => new { t.SubjectCode, t.VisitTaskNum }).Where(g => g.All(t => t.IsGenerateJudge == false)).Select(g => new { g.Key.SubjectCode, g.Key.VisitTaskNum }).ToList();
foreach (var item in resultExceptJudgeList)
{
if (notJudgeList.Any(t => t.SubjectCode == item.SubjectCode && t.VisitTaskNum == item.VisitTaskNum) && item.ArmEnum == Arm.DoubleReadingArm1)
{
item.IsGenerateJudge = true;
}
}
}
if (arbitrationRule == ArbitrationRule.Reading)
{
//先确定裁判选定的是谁
foreach (var item in resultList)
//处理访视裁判标记
foreach (var visitItem in resultExceptJudgeList.Where(t => t.ReadingCategory == ReadingCategory.Visit))
{
//以最后一次裁判为准 找到最大的裁判的裁判选择的Arm,相同就设置裁判标记
item.IsGenerateJudge = list.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode && t.VisitTaskNum > item.VisitTaskNum
).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault()?.JudgeArmEnum == item.ArmEnum ? true : false;
//默认设置为false 只处理为true 和 空的情况
visitItem.IsGenerateJudge = false;
}
//全局裁判了,选择了那个全局,那么对应全局下面的访视 设置裁判标记
foreach (var item in resultList.Where(t => t.ReadingCategory == ReadingCategory.Visit))
{
if (judegeList.Count > 0)
{
var selectJudegeGlobalList = resultList.Where(t => t.ReadingCategory == ReadingCategory.Global && t.IsGenerateJudge == true).ToList();
var maxFinishedJudge = judegeList.Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned).FirstOrDefault();
//全局修改了答案,那么给访视上赋值全局的结果 并且取的是最后的全局
var existGlobalAnswer = selectJudegeGlobalList.Where(t => t.SubjectCode == item.SubjectCode).SelectMany(t => t.GlobalTaskAnswerList).Where(t => t.VisitTaskId == item.Id)
.OrderByDescending(t => t.GlobalTaskVisitNum).FirstOrDefault()?.Answer;
var maxNotFinishedJudge = judegeList.Where(t => t.ReadingTaskState != ReadingTaskState.HaveSigned).FirstOrDefault();
item.OverallTumorEvaluationResult = string.IsNullOrEmpty(existGlobalAnswer) ? item.OverallTumorEvaluationResult : existGlobalAnswer;
if (maxFinishedJudge == null && maxNotFinishedJudge != null)
{
//仅有一个未完成的全局裁判那么都是null
if (visitItem.VisitTaskNum < maxNotFinishedJudge.VisitTaskNum)
{
visitItem.IsGenerateJudge = null;
}
}
else if (maxFinishedJudge != null && maxNotFinishedJudge == null)
{
//全局裁判都完成了,那么以最后一次裁判选择的为准
item.IsGenerateJudge = true;
}
if (visitItem.ArmEnum == maxFinishedJudge.JudgeArmEnum && visitItem.VisitTaskNum < maxFinishedJudge.VisitTaskNum)
{
visitItem.IsGenerateJudge = true;
}
else if (visitItem.ArmEnum == Arm.DoubleReadingArm1)
{
visitItem.IsGenerateJudge = true;
}
}
else
{
//两个都不为null 肯定是不同的裁判
//在完成裁判之后的,和未完成裁判之前的
if (/*visitItem.VisitTaskNum < maxNotFinishedJudge.VisitTaskNum &&*/ visitItem.VisitTaskNum > maxFinishedJudge.VisitTaskNum)
{
visitItem.IsGenerateJudge = null;
}
else if (visitItem.ArmEnum == maxFinishedJudge.JudgeArmEnum && visitItem.VisitTaskNum < maxFinishedJudge.VisitTaskNum)
{
visitItem.IsGenerateJudge = true;
}
//else if (visitItem.ArmEnum == Arm.DoubleReadingArm1)
//{
// visitItem.IsGenerateJudge = true;
//}
}
}
else
{
//不存在裁判 将R1设置
if (visitItem.ArmEnum == Arm.DoubleReadingArm1)
{
visitItem.IsGenerateJudge = true;
}
}
#region 全局的维度考虑
}
//// 该阅片人 subject 已完成的最大的全局(全局都是已完成的任务,裁判可能完成了,可能没完成)
//var subjectMaxGlobal = resultExceptJudgeList.Where(t => t.ReadingCategory == ReadingCategory.Global && t.SubjectCode == item.SubjectCode && t.ArmEnum == item.ArmEnum).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault();
//如果没有产生裁判默认选择R1
////没有全局
//if (subjectMaxGlobal == null)
//{
// //这个时候肯定没有裁判 默认选择R1
//找到没有裁判的访视任务
var notJudgeList = resultList.GroupBy(t => new { t.SubjectCode, t.VisitTaskNum }).Where(g => g.All(t => t.IsGenerateJudge == false)).Select(g => new { g.Key.SubjectCode, g.Key.VisitTaskNum }).ToList();
// if (item.ArmEnum == Arm.DoubleReadingArm1)
// {
// item.IsGenerateJudge = true;
// }
foreach (var item in resultList)
{
if (notJudgeList.Any(t => t.SubjectCode == item.SubjectCode && t.VisitTaskNum == item.VisitTaskNum) && item.ArmEnum == Arm.DoubleReadingArm1)
{
item.IsGenerateJudge = true;
//}
////有全局
//else
//{
// //判断当前受试者已完成的最大的全局是否有裁判
// var existSubjectMaxGlobalJudge = judegeList.Where(t => t.SubjectCode == item.SubjectCode && t.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Judge] == subjectMaxGlobal.VisitTaskNum).FirstOrDefault();
// //最大的全局没有裁判(有一个做完了,有一个没做,或者都做完了,没产生裁判)
// if (existSubjectMaxGlobalJudge == null)
// {
// //找到最大的全局裁判
// var maxJudgedGlobal= judegeList.Where(t => t.SubjectCode == item.SubjectCode ).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault();
// }
// else
// {
// //将该裁判选择的全局的阅片人之前的裁判标记都设置为是
// //是否是裁判选择的
// if (item.ArmEnum == existSubjectMaxGlobalJudge.JudgeArmEnum)
// {
// //是否是裁判选择之前的
// if (item.VisitTaskNum < existSubjectMaxGlobalJudge.VisitTaskNum)
// {
// item.IsGenerateJudge = true;
// }
// }
// }
//}
#endregion
}
}
return resultList;
return resultExceptJudgeList;
}
@ -1413,8 +1631,10 @@ namespace IRaCIS.Core.Application.Service.Common
throw new Exception(_localizer["ExcelExport_UnsupportedExport"]);
}
var list = await _repository.Where<VisitTask>(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned)
var list = await _repository.Where<VisitTask>(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect)
//访视和全局查询已签名完成的,裁判可以是未签名,未完成的
.Where(t => (t.ReadingTaskState == ReadingTaskState.HaveSigned && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global)) || (t.ReadingCategory == ReadingCategory.Judge))
//.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
//.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
//.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
@ -1541,10 +1761,6 @@ namespace IRaCIS.Core.Application.Service.Common
var query = _repository.Where<VisitTask>(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned)
//.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
//.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
//.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId)

View File

@ -81,7 +81,9 @@ namespace IRaCIS.Core.Application.Service
{
var mapItem = _mapper.Map<Internationalization>(item);
mapItem.InternationalizationType = 0;
mapItem.State = 1;
// 0 是预翻译 1是已确认 2是后端废弃
mapItem.State = 0;
await _internationalizationRepository.AddAsync(mapItem);
}
@ -182,7 +184,7 @@ namespace IRaCIS.Core.Application.Service
if (addOrEditInternationalization.InternationalizationType == 1)
{
await InternationalizationHelper.AddOrUpdateJsonKeyValueAsync(entity.Code, addOrEditInternationalization.Value, addOrEditInternationalization.ValueCN);
await InternationalizationHelper.AddOrUpdateJsonKeyValueAsync(entity.Code, addOrEditInternationalization.Value, addOrEditInternationalization.ValueCN,addOrEditInternationalization.Description);
}
else
{

View File

@ -322,7 +322,7 @@ namespace IRaCIS.Application.Services
};
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc);
await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.ReviewerLogin, messageToSend, emailConfigFunc);
//此时不知道用户
var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress);

View File

@ -25,7 +25,7 @@ namespace IRaCIS.Core.Application.Contracts
Task<List<TrialUserDto>> GetTrialUserSelect(Guid trialId);
PageOutput<DocumentUnionWithUserStatView> GetTrialSystemDocumentList(DocumentTrialUnionQuery querySystemDocument);
Task<PageOutput<DocumentUnionWithUserStatView>> GetTrialSystemDocumentList(DocumentTrialUnionQuery querySystemDocument);
List<TrialUserUnionDocumentView> GetTrialUserDocumentList(Guid trialId);
}
}

View File

@ -26,8 +26,8 @@ namespace IRaCIS.Core.Application.Services
private readonly IRepository<TrialDocument> _trialDocumentRepository;
private readonly IRepository<TrialDocConfirmedUser> _trialDocUserTypeConfirmedUserRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly ISystemDocumentService _systemDocumentService;
private readonly IRepository<SystemDocConfirmedUser> _systemDocConfirmedUserRepository;
private readonly ISystemDocumentService _systemDocumentService;
private readonly IRepository<SystemDocConfirmedUser> _systemDocConfirmedUserRepository;
private readonly IRepository<SystemDocument> _systemDocumentRepository;
private readonly IRepository<TrialCriterionAdditionalAssessmentType> _trialCriterionAdditionalAssessmentTypeRepository;
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository;
@ -36,8 +36,8 @@ namespace IRaCIS.Core.Application.Services
public TrialDocumentService(IRepository<TrialDocument> trialDocumentRepository,
IRepository<TrialDocConfirmedUser> trialDocUserTypeConfirmedUserRepository,
IRepository<Trial> trialRepository,
ISystemDocumentService systemDocumentService,
IRepository<SystemDocConfirmedUser> systemDocConfirmedUserRepository,
ISystemDocumentService systemDocumentService,
IRepository<SystemDocConfirmedUser> systemDocConfirmedUserRepository,
IRepository<TrialCriterionAdditionalAssessmentType> trialCriterionAdditionalAssessmentTypeRepository,
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository
, IRepository<SystemDocument> systemDocumentRepository)
@ -45,8 +45,8 @@ namespace IRaCIS.Core.Application.Services
_trialDocumentRepository = trialDocumentRepository;
this._trialDocUserTypeConfirmedUserRepository = trialDocUserTypeConfirmedUserRepository;
this._trialRepository = trialRepository;
this._systemDocumentService = systemDocumentService;
this._systemDocConfirmedUserRepository = systemDocConfirmedUserRepository;
this._systemDocumentService = systemDocumentService;
this._systemDocConfirmedUserRepository = systemDocConfirmedUserRepository;
_systemDocumentRepository = systemDocumentRepository;
_readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
_trialCriterionAdditionalAssessmentTypeRepository = trialCriterionAdditionalAssessmentTypeRepository;
@ -64,7 +64,7 @@ namespace IRaCIS.Core.Application.Services
var trialDocumentQueryable = _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == queryTrialDocument.TrialId)
.WhereIf(!string.IsNullOrEmpty(queryTrialDocument.Name), t => t.Name.Contains(queryTrialDocument.Name))
.WhereIf(queryTrialDocument.FileTypeId != null, t => t.FileTypeId == queryTrialDocument.FileTypeId)
.WhereIf(queryTrialDocument.UserTypeId != null, t => t.NeedConfirmedUserTypeList.Any(t=>t.NeedConfirmUserTypeId== queryTrialDocument.UserTypeId) )
.WhereIf(queryTrialDocument.UserTypeId != null, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == queryTrialDocument.UserTypeId))
.WhereIf(queryTrialDocument.IsDeleted != null, t => t.IsDeleted == queryTrialDocument.IsDeleted)
.ProjectTo<TrialDocumentView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken, isEn_Us = _userInfo.IsEn_Us });
@ -75,17 +75,17 @@ namespace IRaCIS.Core.Application.Services
public async Task<PageOutput<TrialSignDocView>> GetTrialSignDocumentList(TrialDocQuery querySystemDocument)
{
var trialDocQueryable = from trialDoc in _trialDocumentRepository.AsQueryable(true)
.WhereIf(querySystemDocument.TrialId!=null,t=>t.TrialId==querySystemDocument.TrialId)
.Where(t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId) )
.WhereIf(querySystemDocument.TrialId != null, t => t.TrialId == querySystemDocument.TrialId)
.Where(t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
join trialUser in _repository.Where<TrialUser>(t=>t.UserId==_userInfo.Id) on trialDoc.TrialId equals trialUser.TrialId
join trialUser in _repository.Where<TrialUser>(t => t.UserId == _userInfo.Id) on trialDoc.TrialId equals trialUser.TrialId
join confirm in _repository.Where<TrialDocConfirmedUser>() on
new { trialUser.UserId, TrialDocumentId = trialDoc.Id } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
from confirm in cc.DefaultIfEmpty()
select new TrialSignDocView()
{
TrialCode=trialDoc.Trial.TrialCode,
TrialCode = trialDoc.Trial.TrialCode,
ResearchProgramNo = trialDoc.Trial.ResearchProgramNo,
ExperimentName = trialDoc.Trial.ExperimentName,
Id = trialDoc.Id,
@ -116,7 +116,7 @@ namespace IRaCIS.Core.Application.Services
.WhereIf(querySystemDocument.IsSigned == false, t => t.ConfirmTime == null);
return await trialDocQueryable.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);
return await trialDocQueryable.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);
}
@ -142,19 +142,19 @@ namespace IRaCIS.Core.Application.Services
PageSize = 1,
})).Data;
}
else
else
{
result = await _systemDocumentService.getWaitSignSysDocList(new SystemDocumentQuery()
{
PageIndex=1,
PageIndex = 1,
IsSigned = false,
PageSize=1,
Asc=false,
SortField="UpdateTime",
});
PageSize = 1,
Asc = false,
SortField = "UpdateTime",
});
}
}
if (result.CurrentPageData.Count > 0)
{
@ -823,7 +823,7 @@ namespace IRaCIS.Core.Application.Services
/// <returns></returns>
[HttpPost]
[Obsolete]
public PageOutput<DocumentUnionWithUserStatView> GetTrialSystemDocumentList(DocumentTrialUnionQuery querySystemDocument)
public async Task<PageOutput<DocumentUnionWithUserStatView>> GetTrialSystemDocumentList(DocumentTrialUnionQuery querySystemDocument)
{
var systemDocumentQueryable = _repository
.WhereIf<SystemDocument>(!_userInfo.IsAdmin, t => t.IsDeleted == false)
@ -867,7 +867,7 @@ namespace IRaCIS.Core.Application.Services
.WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name))
.WhereIf(querySystemDocument.FileTypeId != null, t => t.FileTypeId == querySystemDocument.FileTypeId);
return unionQuery.ToPagedList(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);
return await unionQuery.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);
}
#endregion

View File

@ -1272,6 +1272,8 @@ namespace IRaCIS.Core.Application.Service
public async Task<PageOutput<TrialSelectEmailNoticeConfigView>> GetSysEmailNoticeConfigList(EmailNoticeConfigQuery queryEmailNoticeConfig)
{
var emailNoticeConfigQueryable = _emailNoticeConfigRepository
.WhereIf(queryEmailNoticeConfig.SystemLevel == null, t => t.SystemLevel == SysEmailLevel.not_sys)
.WhereIf(queryEmailNoticeConfig.SystemLevel != null, t => t.SystemLevel == queryEmailNoticeConfig.SystemLevel)
.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)
@ -1477,7 +1479,7 @@ namespace IRaCIS.Core.Application.Service
{
//---发件人配置错误,请核对服务器地址或者授权码是否填写有误
throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidSenderEmailConfig"] + ex.Message);
throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidSenderEmailConfig"]);
}

View File

@ -66,7 +66,7 @@ namespace IRaCIS.Core.Application.Service
{
GroupId=gropId,
LimitEdit=LimitEdit.OnlyBaseLine,
DictionaryCode="YesOrNoOrNa",
DictionaryCode="YesOrNoOrNE",
IsJudgeQuestion=false,
IsShowInDicom=false,
GlobalReadingShowType=GlobalReadingShowType.NotShow,

View File

@ -3,6 +3,7 @@ using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Service.Inspection.DTO;
using IRaCIS.Core.Application.Service.Inspection.Interface;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using Panda.DynamicWebApi.Attributes;
@ -58,8 +59,11 @@ namespace IRaCIS.Core.Application.Service.Inspection
join usertype in _repository.GetQueryable<UserType>().IgnoreQueryFilters() on leftuser.UserTypeId equals usertype.Id into usertypetemp
from leftusertype in usertypetemp.DefaultIfEmpty()
//join trialCriterion in _repository.GetQueryable<ReadingQuestionCriterionTrial>().IgnoreQueryFilters() on data.TrialReadingCriterionId equals trialCriterion.Id into criterion
//from leftCriterion in criterion.DefaultIfEmpty()
join visttask in _repository.GetQueryable<VisitTask>().IgnoreQueryFilters() on data.VisitTaskId equals visttask.Id into visttasktemp
from leftvisttask in visttasktemp.DefaultIfEmpty()
//join trialCriterion in _repository.GetQueryable<ReadingQuestionCriterionTrial>().IgnoreQueryFilters() on data.TrialReadingCriterionId equals trialCriterion.Id into criterion
//from leftCriterion in criterion.DefaultIfEmpty()
//join moduleTyped in _repository.GetQueryable<Dictionary>().Where(x => x.Code == "ModuleType") on 1 equals 1
//join moduleTypec in _repository.GetQueryable<Dictionary>() on new { ParentId = moduleTyped.Id, ModuleType = data.ModuleType } equals new { ParentId = moduleTypec.ParentId.Value, ModuleType = moduleTypec.Value } into moduleTypectemp
@ -131,7 +135,7 @@ namespace IRaCIS.Core.Application.Service.Inspection
ExperimentName = leftrial.ExperimentName,
SubjectCode = leftsubject.Code,
SubjectCode = leftvisttask.BlindSubjectCode.IsNullOrEmpty()? leftsubject.Code: leftvisttask.BlindSubjectCode,
SiteCode = lefttrialSite.TrialSiteCode,
ResearchProgramNo = leftrial.ResearchProgramNo,

View File

@ -36,6 +36,7 @@ namespace IRaCIS.Application.Contracts
public class SiteSelectionDTO
{
public Guid Id { get; set; }
public string SiteName { get; set; } = String.Empty;
public string SiteNameCN { get; set; } = String.Empty;

View File

@ -39,7 +39,7 @@ namespace IRaCIS.Application.Contracts
public Guid Id { get; set; }
public string UserName { get; set; } = string.Empty;
public string RealName { get; set; } = string.Empty;
public int Sex { get; set; } // 1-男 2-女
public int? Sex { get; set; } // 1-男 2-女
/// <summary>
/// LastLoginIP
@ -131,7 +131,7 @@ namespace IRaCIS.Application.Contracts
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public int Sex { get; set; } // 1-男 2-女
public int? Sex { get; set; } // 1-男 2-女
public int Status { get; set; } = 1; // 0-已删除 1-正常

View File

@ -16,9 +16,9 @@ using EasyCaching.Core;
using IRaCIS.Core.Application.Contracts;
using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO;
using IRaCIS.Core.Application.Auth;
using BeetleX.Redis.Commands;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Application.Helper;
using IP2Region.Net.Abstractions;
namespace IRaCIS.Application.Services
{
@ -38,6 +38,7 @@ namespace IRaCIS.Application.Services
private readonly IReadingImageTaskService _readingImageTaskService;
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
private readonly SystemEmailSendConfig _systemEmailConfig;
public ISearcher _searcher;
public UserService(IRepository<User> userRepository,
@ -45,6 +46,7 @@ namespace IRaCIS.Application.Services
IRepository<VerificationCode> verificationCodeRepository,
IRepository<Doctor> doctorRepository,
IEasyCachingProvider cache,
ISearcher searcher,
IReadingImageTaskService readingImageTaskService,
IRepository<TrialUser> userTrialRepository,
IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig,
@ -58,6 +60,7 @@ namespace IRaCIS.Application.Services
this._userPassWordLogRepository = userPassWordLogRepository;
_verifyConfig = verifyConfig;
_cache = cache;
this._searcher = searcher;
this._readingImageTaskService = readingImageTaskService;
_userRepository = userRepository;
_mailVerificationService = mailVerificationService;
@ -794,7 +797,7 @@ namespace IRaCIS.Application.Services
}
//超过90天没修改密码
if (loginUser.LastChangePassWordTime != null && DateTime.Now.AddDays(-90) > loginUser.LastChangePassWordTime.Value)
if (_verifyConfig.CurrentValue.IsNeedChangePassWord&& loginUser.LastChangePassWordTime != null && DateTime.Now.AddDays(-_verifyConfig.CurrentValue.ChangePassWordDays) > loginUser.LastChangePassWordTime.Value)
{
loginUser.LoginState = 1;
}
@ -803,12 +806,14 @@ namespace IRaCIS.Application.Services
//登录成功 清除缓存
_cache.Set(cacheKey, 0, TimeSpan.FromMinutes(lockoutMinutes));
var ipinfo = _searcher.Search(_userInfo.IP);
var iPRegion = string.Join('|', ipinfo.Split('|').TakeLast(3));
if (loginUser.LastLoginIP != string.Empty)
{
// 与上一次IP不一致
if (loginUser.LastLoginIP != _userInfo.IP)
if (loginUser.LastLoginIP != iPRegion)
{
loginUser.LoginState = 2;
}
@ -829,10 +834,10 @@ namespace IRaCIS.Application.Services
});
}
await _userRepository.BatchUpdateNoTrackingAsync(x => x.Id == loginUser.Id, x => new User()
{
LastLoginIP = _userInfo.IP,
LastLoginIP = iPRegion,
LastLoginTime = DateTime.Now
});

View File

@ -119,12 +119,12 @@ namespace IRaCIS.Core.Application.Contracts
if (userTypeSelectEnum == UserTypeSelectEnum.InnerUser)
{
userTypeEnums = new List<UserTypeEnum>() { UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA ,UserTypeEnum.MW,UserTypeEnum.MC};
userTypeEnums = new List<UserTypeEnum>() { UserTypeEnum.ClinicalResearchCoordinator, UserTypeEnum.ProjectManager, UserTypeEnum.CRA, UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA ,UserTypeEnum.MW,UserTypeEnum.MC};
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin)
{
userTypeEnums.Add(UserTypeEnum.ProjectManager);
}
//if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin)
//{
// userTypeEnums.Add(UserTypeEnum.ProjectManager);
//}
}
if (userTypeSelectEnum == UserTypeSelectEnum.SiteSurvey)

View File

@ -131,7 +131,7 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.ExperimentName, c => c.MapFrom(t => t.Trial.ExperimentName))
.ForMember(d => d.TrialCode, c => c.MapFrom(t => t.Trial.TrialCode))
.ForMember(d => d.SubjectCode, c => c.MapFrom(t => t.Subject.Code))
.ForMember(d => d.TrialSiteCode, c => c.MapFrom(t => t.TrialSite.TrialSiteCode))
.ForMember(d => d.TrialSiteCode, c => c.MapFrom(t => t.VisitTask.IsAnalysisCreate? t.VisitTask.BlindTrialSiteCode: t.TrialSite.TrialSiteCode))
.ForMember(d => d.SubjectVisitName, c => c.MapFrom(t => t.SubjectVisit.VisitName))
.ForMember(d => d.FeedBackUserName, c => c.MapFrom(t => t.CreateUser.UserName))
.ForMember(d => d.FeedBackFullName, c => c.MapFrom(t => t.CreateUser.FullName))

View File

@ -157,6 +157,8 @@ namespace IRaCIS.Core.Application.Contracts
public bool IsHaveVisitClinicalData { get; set; } = false;
public bool IsPacsConnectConfiged { get; set; }
}
@ -201,15 +203,15 @@ namespace IRaCIS.Core.Application.Contracts
{
//关闭 未关闭
[DictionaryTranslateAttribute("CheckIsClosedEnum")]
public ChallengeStateEnum CheckIsClosedEnum { get; set; }
public ChallengeStateEnum ChallengeState { get; set; }
//强行要分为两个字段 有无质疑
[DictionaryTranslateAttribute("YesOrNo")]
public bool IsChallengeClosed => (int)CheckIsClosedEnum > 0;
public bool IsHaveChallenge => (int)ChallengeState > 0;
//临床数据收集
public string ClinicalDataCollect => $"{DicomStudyCount},{NoneDicomStudyCount}{(IsBaseLine? (ClinicalInformationTransmissionEnum>0 &&IsHaveClinicalData ? "w/" : "w/o") :"" )}";
public string ClinicalDataCollect => $"{DicomStudyCount},{NoneDicomStudyCount}{(IsBaseLine? (ClinicalInformationTransmissionEnum>0 && IsHaveClinicalData ? ",w/" : ",w/o") :"" )}";
public int? DicomStudyCount { get; set; }
public int? NoneDicomStudyCount { get; set; }
@ -266,7 +268,7 @@ namespace IRaCIS.Core.Application.Contracts
public string CurrentActionUserName { get; set; }
public string HistoryAuditUserName => string.Join(' ', PreliminaryAuditUserName, ReviewAuditUserName);
}
public class QCChanllengeExportDto
@ -325,7 +327,7 @@ namespace IRaCIS.Core.Application.Contracts
//public bool IsUrgent { get; set; }
//public DateTime? ReUploadedTime { get; set; }
public DateTime? ReUploadedTime { get; set; }
//public RequestBackStateEnum RequestBackState { get; set; }
@ -676,6 +678,8 @@ namespace IRaCIS.Core.Application.Contracts
{
public string? TalkContent { get; set; } = String.Empty;
public string BlindName { get; set; } = String.Empty;
[DictionaryTranslateAttribute("YesOrNo")]
public bool IsUrgent { get; set; }
public DateTime? CheckPassedTime { get; set; }
@ -831,11 +835,12 @@ namespace IRaCIS.Core.Application.Contracts
public AuditAdvice AuditAdviceEnum { get; set; }
//审核结论
[DictionaryTranslateAttribute("IsPass")]
public bool IsHaveQuestion { get; set; }
[DictionaryTranslateAttribute("IsPass")]
public bool? IsHaveQuestionView => AuditState == MedicalReviewAuditState.WaitAudit ? null : IsHaveQuestion;
//public UserSimpleInfo DoctorUser { get; set; }
//public UserSimpleInfo MedicalManagerUser { get; set; }
@ -932,6 +937,9 @@ namespace IRaCIS.Core.Application.Contracts
public string SubjectCode { get; set; } = String.Empty;
public Guid Id { get; set; }
public Guid DoctorUserId { get; set; }
public string TaskName { get; set; }
public string TaskBlindName { get; set; }
@ -944,6 +952,8 @@ namespace IRaCIS.Core.Application.Contracts
public Arm ArmEnum { get; set; }
public string UserName { get; set; }
public ReadingTaskState ReadingTaskState { get; set; }
public ReadingCategory ReadingCategory { get; set; }
[DictionaryTranslateAttribute("ExistDisease", CriterionType.RECIST1Point1, nameof(OverallTumorEvaluationExport.IsBaseline), "true")]
@ -958,15 +968,17 @@ namespace IRaCIS.Core.Application.Contracts
public Arm? JudgeArmEnum { get; set; }
//public Guid? JudgeResultTaskId { get; set; }
//根据裁判的任务结果 设置访视任务的这个字段 该字段表示 裁判认同该任务的结果
[DictionaryTranslateAttribute("YesOrNo")]
public bool IsGenerateJudge { get; set; }
public bool? IsGenerateJudge { get; set; }
[JsonIgnore]
//[JsonIgnore]
public List<GlobalAnswerInfo> GlobalTaskAnswerList { get; set; }
//public List<GlobalAnswerInfo> GlobalTaskAnswerList { get; set; }
}

View File

@ -547,6 +547,7 @@ namespace IRaCIS.Core.Application.Image.QA
config.IsHaveStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.IsConfirm && x.TrialId == visit.TrialId && x.ClinicalDataLevel == ClinicalLevel.Study);
config.IsPacsConnectConfiged= await _subjectVisitRepository.Where(t=>t.Id==subjectVisitId).AnyAsync(t=>t.Trial.IsPACSConnect && t.Subject.TrialSite.TrialSiteDicomAEList.Any());
return (list, config);
}

View File

@ -103,8 +103,10 @@ namespace IRaCIS.Core.Application.Contracts
.OrderByDescending(x=>x.LanguageType)
.ThenBy(t=>t.ShowOrder)
.ProjectTo<QCQuestionConfigureView>(_mapper.ConfigurationProvider);
return await QCQuestionQueryable.ToPagedListAsync(queryQCQuestionConfigure.PageIndex, queryQCQuestionConfigure.PageSize, new string[2] { "LanguageType desc", "ShowOrder asc" });
var defalutSortArray = new string[] { nameof(QCQuestionConfigureView.LanguageType) + " desc", nameof(QCQuestionConfigureView.ShowOrder) };
return await QCQuestionQueryable.ToPagedListAsync(queryQCQuestionConfigure.PageIndex, queryQCQuestionConfigure.PageSize, new string[2] { "LanguageType desc", "ShowOrder asc" });
}
public async Task<IResponseOutput> AddOrUpdateQCQuestionConfigure(QCQuestionAddOrEdit addOrEditQCQuestionConfigure)

View File

@ -54,9 +54,9 @@ namespace IRaCIS.Core.Application.Contracts
var trialQCQuestionQueryable = _trialQcQuestionRepository.Where(t => t.TrialId == queryTrialQCQuestionConfigure.TrialId)
.WhereIf(!string.IsNullOrWhiteSpace(queryTrialQCQuestionConfigure.QuestionName), t => t.QuestionName.Contains(queryTrialQCQuestionConfigure.QuestionName))
.WhereIf(!string.IsNullOrWhiteSpace(queryTrialQCQuestionConfigure.Type), t => t.Type.Contains(queryTrialQCQuestionConfigure.Type))
.WhereIf(queryTrialQCQuestionConfigure.IsEnable != null, t => t.IsEnable == queryTrialQCQuestionConfigure.IsEnable)
.WhereIf(queryTrialQCQuestionConfigure.IsRequired != null, t => t.IsRequired == queryTrialQCQuestionConfigure.IsRequired)
.WhereIf(queryTrialQCQuestionConfigure.LanguageType != null, t => t.LanguageType == queryTrialQCQuestionConfigure.LanguageType)
.WhereIf(queryTrialQCQuestionConfigure.IsEnable != null, t => t.IsEnable == queryTrialQCQuestionConfigure.IsEnable)
.WhereIf(queryTrialQCQuestionConfigure.IsRequired != null, t => t.IsRequired == queryTrialQCQuestionConfigure.IsRequired)
.WhereIf(queryTrialQCQuestionConfigure.LanguageType != null, t => t.LanguageType == queryTrialQCQuestionConfigure.LanguageType)
.ProjectTo<TrialQCQuestionConfigureView>(_mapper.ConfigurationProvider);

View File

@ -25,7 +25,8 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.QCProcessEnum, u => u.MapFrom(s => s.Trial.QCProcessEnum))
.ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.Subject.Code))
.ForMember(d => d.SubmitUserName, u => u.MapFrom(s => s.SubmitUser.FullName))
.ForMember(d => d.ClinicalInformationTransmissionEnum, u => u.MapFrom(s => s.Trial.ClinicalInformationTransmissionEnum))
.ForMember(d => d.IsHaveClinicalData, u => u.MapFrom(t => t.IsBaseLine ? t.PreviousHistoryList.Any() || t.PreviousOtherList.Any()
|| t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count > 0)
|| t.PreviousSurgeryList.Any() : false))
@ -116,7 +117,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("\n\n", 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()))
@ -154,7 +155,7 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.VisitTask.Subject.MedicalNo))
.ForMember(o => o.DoctorUserName, t => t.MapFrom(u => u.VisitTask.DoctorUser.UserName))
.ForMember(o => o.MedicalManagerUserName, t => t.MapFrom(u => u.MedicalManagerUser.UserName))
.ForMember(o => o.QuestionContent, t => t.MapFrom(u=> string.Join('|', u.ReadingMedicalReviewDialogList.Where(t => t.IsHaveQuestion).Select(t=>t.Questioning))) );
.ForMember(o => o.QuestionContent, t => t.MapFrom(u=> string.Join("\n\n", u.ReadingMedicalReviewDialogList.Where(t => t.IsHaveQuestion).Select(t=>t.Questioning))) );
CreateMap<VisitTask, TaskMedicalReviewExportDto>()
.ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName))
@ -191,15 +192,14 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.OverallTumorEvaluationResult, t => t.MapFrom(u =>
criterionType == CriterionType.RECIST1Point1 ?( u.SourceSubjectVisit.IsBaseLine==true ? u.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == QuestionType.ExistDisease).FirstOrDefault()!.Answer:
u.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).FirstOrDefault()!.Answer)
u.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).Select(t=>t.IsGlobalChange?t.GlobalChangeAnswer:t.Answer).FirstOrDefault())
: criterionType == CriterionType.PCWG3 ? u.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation).FirstOrDefault()!.Answer : String.Empty
))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.Subject.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.Subject.Code))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
.ForMember(o => o.GlobalTaskAnswerList, t => t.MapFrom(u => u.GlobalVisitResultList.Where(t=>t.GlobalAnswerType== GlobalAnswerType.Question)
.Select(c=>new GlobalAnswerInfo() { GlobalTaskVisitNum=c.VisitTask.VisitTaskNum,VisitTaskId=c.TaskId ,Answer=c.Answer})))
//.ForMember(o => o.GlobalTaskAnswerList, t => t.MapFrom(u => u.GlobalVisitResultList.Where(t=>t.GlobalAnswerType== GlobalAnswerType.Question).Select(c=>new GlobalAnswerInfo() { GlobalTaskVisitNum=c.VisitTask.VisitTaskNum,VisitTaskId=c.TaskId ,Answer=c.Answer})))
;

View File

@ -442,9 +442,9 @@ namespace IRaCIS.Core.Application.Service
join subjectCriteriaEvaluationVisitFilter in _subjectCriteriaEvaluationVisitFilterRepository
.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.ImageDeterminationResultState != null, t => t.ImageDeterminationResultState == inQuery.ImageDeterminationResultState)
.WhereIf(inQuery.ImageFilterState != null, t => t.ImageFilterState == inQuery.ImageFilterState)
.WhereIf(inQuery.IsGeneratedTask != null, t => t.IsGeneratedTask == inQuery.IsGeneratedTask)
.WhereIf(inQuery.ImageDeterminationResultState != null, t => t.ImageDeterminationResultState == inQuery.ImageDeterminationResultState)
.WhereIf(inQuery.ImageFilterState != null, t => t.ImageFilterState == inQuery.ImageFilterState)
.WhereIf(inQuery.IsGeneratedTask != null, t => t.IsGeneratedTask == inQuery.IsGeneratedTask)
on subjectVisit.Id equals subjectCriteriaEvaluationVisitFilter.SubjectVisitId
//into d from subjectCriteriaEvaluationVisitFilter in d.DefaultIfEmpty()
@ -687,7 +687,7 @@ namespace IRaCIS.Core.Application.Service
var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == command.SubjectVisitId);
//仅仅影响该标准自己的任务
Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == command.TrialId && t.SubjectId == command.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated
Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == command.TrialId && t.SubjectId == command.SubjectId && t.TaskState == TaskState.Effect /*&& t.TaskAllocationState == TaskAllocationState.Allocated*/
&& t.TrialReadingCriterionId == command.TrialReadingCriterionId;
//有序

View File

@ -637,8 +637,9 @@ namespace IRaCIS.Core.Application.Service
ModuleName=x.ModuleName,
});
var defalutSortArray = new string[] { nameof(GetCRCConfirmListOutDto.SubjectCode) + " desc", nameof(GetCRCConfirmListOutDto.LatestScanDate) };
var result = await query.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, new string[2] { "SubjectCode asc", "LatestScanDate asc" });
var result = await query.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, new string[2] { "SubjectCode asc", "LatestScanDate asc" });
var formList = await _clinicalFormRepository.Where(x => x.TrialId == inDto.TrialId)
.Where(x => x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC)

View File

@ -12,7 +12,6 @@ using System.Linq.Dynamic.Core;
using Microsoft.Extensions.Logging;
using IRaCIS.Core.Infrastructure.Extention;
using System.Linq;
using BeetleX.Redis.Commands;
using NPOI.SS.Formula.Functions;
namespace IRaCIS.Application.Services
@ -394,7 +393,7 @@ namespace IRaCIS.Application.Services
//如果先生成了任务再签名subject级别 PM 临床数据,那么会导致其他标准的任务签名状态无法得到维护
if (await _repository.AnyAsync<ClinicalDataTrialSet>(t => t.Id == data.ClinicalDataTrialSetId && t.UploadRole == UploadRole.PM && t.ClinicalDataLevel == ClinicalLevel.Subject))
if (await _repository.AnyAsync<ClinicalDataTrialSet>(t => t.Id == data.ClinicalDataTrialSetId && t.UploadRole == UploadRole.PM && (t.ClinicalDataLevel == ClinicalLevel.Subject|| t.ClinicalDataLevel == ClinicalLevel.SubjectVisit)))
{
var needDealTrialReadingCriterionIdList = _repository.Where<ClinicalDataTrialSet>(t => t.Id == data.ClinicalDataTrialSetId)
.SelectMany(t => t.TrialClinicalDataSetCriteriaList)
@ -431,9 +430,6 @@ namespace IRaCIS.Application.Services
// data.IsComplete = inDto.IsComplete;
// data.IsSign = true;
// data.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned;
// var result = await _readingClinicalDataRepository.SaveChangesAsync();
@ -479,6 +475,7 @@ namespace IRaCIS.Application.Services
var needSignCount = 0;
var haveSignedCount = _readingClinicalDataRepository.Where(t => t.TrialId == trialId && t.IsSign && t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count();
ReadModule readModule = null;
if (isVisit)
{
@ -514,7 +511,7 @@ namespace IRaCIS.Application.Services
else
{
//判断是影像学 还是肿瘤学阅片
var readModule = await _readModuleRepository.Where(t => t.Id == readingId).FirstNotNullAsync();
readModule = await _readModuleRepository.Where(t => t.Id == readingId).FirstNotNullAsync();
//CRC 阅片期自定义结构化录入是否签名
bool crcReadModuleSign = true;
@ -576,7 +573,7 @@ namespace IRaCIS.Application.Services
Expression<Func<VisitTask, bool>> visitTaskLambda = x => x.TrialId == trialId && x.SubjectId == subjectId && x.TrialReadingCriterionId == trialReadingCritrialId;
if (isVisit)
if (isVisit ||(isVisit==false && readModule.ReadingSetType == ReadingSetType.ImageReading))
{
//访视类型的任务 不影响肿瘤学任务的临床数据状态
visitTaskLambda = visitTaskLambda.And(x => x.ArmEnum != Arm.TumorArm);
@ -730,11 +727,14 @@ namespace IRaCIS.Application.Services
public async Task<(List<GetReadingClinicalDataListOutDto>, object)> GetReadingOrTaskClinicalDataList(GetReadingOrTaskClinicalDataListInDto inDto)
{
var readingNameOrTaskBlindName = string.Empty;
var subjectCode = string.Empty;
if (inDto.ReadingId == null)
{
var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId);
readingNameOrTaskBlindName = visitTask.TaskBlindName;
var visitTask = await _visitTaskRepository.AsQueryable().Include(x=>x.Subject)
.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId);
subjectCode=visitTask.BlindSubjectCode.IsNullOrEmpty() ? visitTask.Subject.Code : visitTask.BlindSubjectCode;
readingNameOrTaskBlindName = visitTask.TaskBlindName;
}
inDto.SelectIsSign = false;
var result = await GetClinicalDataList(inDto);
@ -777,7 +777,7 @@ namespace IRaCIS.Application.Services
return (result, new
{
SubjectCode = await _subjectRepository.Where(x => x.Id == inDto.SubjectId).Select(x => x.Code).FirstOrDefaultAsync(),
SubjectCode = subjectCode,
ReadingNameOrTaskBlindName = readingNameOrTaskBlindName,
});
}
@ -906,7 +906,7 @@ namespace IRaCIS.Application.Services
.WhereIf(inDto.SelectIsSign, x => x.IsSign == true)
.Where(x => x.ReadingId == inDto.ReadingId)
.WhereIf(inDto.TrialReadingCriterionId != null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId))
.Where(x => x.ClinicalDataTrialSet.ClinicalUploadType != ClinicalUploadType.PDF)
.Where(x => x.ClinicalDataTrialSet.ClinicalUploadType != ClinicalUploadType.PDF||x.ClinicalDataTrialSet.ClinicalDataLevel== ClinicalLevel.Study)
.Select(x => new GetReadingClinicalDataListOutDto()
{
ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
@ -1185,8 +1185,8 @@ namespace IRaCIS.Application.Services
}).ToList();
entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded;
entity.IsBlind = null;
entity.IsComplete = null;
entity.IsBlind = false;
entity.IsComplete = true;
entity.FileCount = entity.ReadingClinicalDataPDFList.Count;
await _readingConsistentClinicalDataRepository.AddAsync(entity, true);
var success = await _readingConsistentClinicalDataRepository.SaveChangesAsync();
@ -1215,8 +1215,8 @@ namespace IRaCIS.Application.Services
if (indto.AddFileList.Count > 0 || indto.AddFileList.Count > 0)
{
entity.IsComplete = null;
entity.IsBlind = null;
entity.IsComplete = true;
entity.IsBlind = false;
}
await _readingConsistentClinicalDataPDFRepository.AddRangeAsync(addFileList);
@ -1227,6 +1227,7 @@ namespace IRaCIS.Application.Services
entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded;
entity.IsSign = false;
entity.FileCount = fileCount;
entity.CreateTime=DateTime.Now;
var success = await _readingConsistentClinicalDataRepository.SaveChangesAsync();
return ResponseOutput.Ok(entity.Id);
@ -1267,13 +1268,26 @@ namespace IRaCIS.Application.Services
[HttpPost]
public async Task<IResponseOutput> SetTaskValid(SetTaskValidInDto inDto)
{
var visittask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var visittask = await _visitTaskRepository.AsQueryable().Include(x=>x.TrialReadingCriterion).Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var readingId = visittask.SouceReadModuleId==null? visittask.SourceSubjectVisitId: visittask.SouceReadModuleId;
if (await _readingConsistentClinicalDataRepository.AnyAsync(x => x.ReadingId == readingId && x.IsSign == false))
if (await _readingConsistentClinicalDataRepository.AnyAsync(x => x.ReadingId == readingId
&& x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == visittask.TrialReadingCriterionId) && x.IsSign == false))
{
return ResponseOutput.NotOk(_localizer["ReadingClinicalData_HaveUnsignedClinicalData"]);
}
if(visittask.TrialReadingCriterion.IsReadingTaskViewInOrder== ReadingOrder.InOrder)
{
if(await _visitTaskRepository.Where(x=>x.SubjectId== visittask.SubjectId
&&x.TrialReadingCriterionId== visittask.TrialReadingCriterionId
&&x.VisitTaskNum< visittask.VisitTaskNum&&x.IsAnalysisCreate==visittask.IsAnalysisCreate
&&x.IsSelfAnalysis==visittask.IsSelfAnalysis&&x.ArmEnum==visittask.ArmEnum&&x.TaskState==TaskState.NotEffect).AnyAsync()
)
{
return ResponseOutput.NotOk(_localizer["ReadingClinicalData_NeedSetBeforeTaskEffect"]);
}
}
await _visitTaskRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
{

View File

@ -31,5 +31,6 @@ namespace IRaCIS.Core.Application.Contracts
Task DealVisiTaskClinicalDataSignedAsync(Guid trialId, Guid subjectId, Guid readingId, bool isVisit, Guid trialReadingCritrialId);
Task<IResponseOutput> SignConsistencyAnalysisReadingClinicalData(SignConsistencyAnalysisReadingClinicalDataInDto inDto);
}
}

View File

@ -65,7 +65,9 @@ namespace IRaCIS.Core.Application.Service
.WhereIf(inDto.LanguageType != null, x => x.LanguageType == inDto.LanguageType!.Value)
.ProjectTo<ReadingMedicineSystemQuestionView>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder);
return await query.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, new string[2] { "LanguageType desc", "ShowOrder asc" });
var defalutSortArray = new string[] { nameof(ReadingMedicineSystemQuestionView.LanguageType) + " desc", nameof(ReadingMedicineSystemQuestionView.ShowOrder) };
return await query.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, new string[2] { "LanguageType desc", "ShowOrder asc" });
}
/// <summary>

View File

@ -34,6 +34,23 @@ namespace IRaCIS.Application.Services
await VerifyTaskIsSign(inDto.GlobalTaskId);
await this.SubmitTaskChangeState(inDto.GlobalTaskId);
var globalAnswerList = await _readingGlobalTaskInfoRepository.Where(x =>
x.QuestionId!=null &&x.Answer!=string.Empty&& x.Answer != null &&
x.GlobalTaskId == inDto.GlobalTaskId).ToListAsync();
foreach (var item in globalAnswerList)
{
await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.TaskId && x.ReadingQuestionTrialId == item.QuestionId
&& x.Answer != item.Answer
, x => new ReadingTaskQuestionAnswer()
{
GlobalChangeAnswer = item.Answer,
IsGlobalChange = true,
});
}
await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
return ResponseOutput.Ok(true);
}
@ -60,24 +77,15 @@ namespace IRaCIS.Application.Services
if (criterionType == CriterionType.PCWG3)
{
await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == answer.QuestionId
&& x.Answer != answer.Answer && answer.Answer != string.Empty && answer.Answer != null
, x => new ReadingTaskQuestionAnswer()
{
&& x.Answer != answer.Answer && answer.Answer != string.Empty && answer.Answer != null
, x => new ReadingTaskQuestionAnswer()
{
Answer= answer.Answer,
GlobalChangeAnswer = answer.Answer,
IsGlobalChange = true,
});
}
else
{
await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == answer.QuestionId
&& x.Answer != answer.Answer && answer.Answer != string.Empty && answer.Answer != null
, x => new ReadingTaskQuestionAnswer()
{
GlobalChangeAnswer = answer.Answer,
IsGlobalChange = true,
});
});
}
}
}

View File

@ -2968,7 +2968,7 @@ namespace IRaCIS.Application.Services
task.SubjectCode = await _subjectRepository.Where(x => x.Id == task.SubjectId).Select(x => x.Code).FirstNotNullAsync();
}
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == task.VisitTaskId && x.FirstReadingTime == null, x => new VisitTask()
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == task.VisitTaskId&&x.TaskState==TaskState.Effect&&x.ReadingTaskState!=ReadingTaskState.HaveSigned && x.FirstReadingTime == null, x => new VisitTask()
{
FirstReadingTime = DateTime.Now,
});

View File

@ -19,7 +19,6 @@ namespace IRaCIS.Core.Application.ViewModel
public DateTime? LatestTestTime { get; set; }
public bool IsTestOK { get; set; }
//public bool IsPACSConnect { get; set; }
@ -61,6 +60,15 @@ namespace IRaCIS.Core.Application.ViewModel
public bool IsPACSConnect { get; set; }
public bool? IsTestOK { get; set; }
}
public class TestAECommand
{
public string CalledAE { get; set; } = string.Empty;
public string IP { get; set; } = string.Empty;
public int Port { get; set; }
}

View File

@ -2,6 +2,7 @@
using System.ComponentModel.DataAnnotations;
using System.Web;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.Application.Contracts
@ -289,6 +290,7 @@ namespace IRaCIS.Core.Application.Contracts
public string Sponsor { get; set; }
[DictionaryTranslateAttribute("TrialStatusEnum")]
public string TrialStatusStr { get; set; }
#region PM

View File

@ -321,7 +321,7 @@ namespace IRaCIS.Application.Contracts
public class TrialUserScreeningDTO : TrialUserAddCommand
{
public int Sex { get; set; } // 1-男 2-女
public int? Sex { get; set; } // 1-男 2-女
public string Phone { get; set; } = string.Empty;
public string EMail { get; set; } = string.Empty;

View File

@ -22,6 +22,7 @@ using IRaCIS.Core.Domain.Models;
using IRaCIS.Application.Contracts;
using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors;
using Newtonsoft.Json;
using Microsoft.Extensions.Options;
namespace IRaCIS.Core.Application
{
@ -1347,7 +1348,7 @@ namespace IRaCIS.Core.Application
{
var codeList = await _repository.Where<TrialBodyPart>(t => t.TrialId == incommand.TrialId)
.WhereIf(incommand.Id!=null,t=>t.Id!=incommand.Id)
.WhereIf(incommand.Id != null, t => t.Id != incommand.Id)
.Select(t => t.Code).ToListAsync();
@ -1384,5 +1385,12 @@ namespace IRaCIS.Core.Application
return JsonConvert.DeserializeObject<TrialExtraConfig>(extralConfig) ?? new TrialExtraConfig();
}
public async Task<TrialPacsInfo> GetTrialPacsConfigInfo(Guid trialId, [FromServices] IOptionsMonitor<SystemPacsConfig> optionsMonitor)
{
var trialCode = await _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialCode).FirstOrDefaultAsync();
return new TrialPacsInfo() { Ip=optionsMonitor.CurrentValue.IP,Port=optionsMonitor.CurrentValue.Port,TrialCalledAE=$"EI{trialCode}" };
}
}
}

View File

@ -12,6 +12,7 @@ using FellowOakDicom.Network.Client;
using FellowOakDicom.Network;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Domain.Share;
using DocumentFormat.OpenXml.InkML;
namespace IRaCIS.Core.Application.Service
{
/// <summary>
@ -84,6 +85,14 @@ namespace IRaCIS.Core.Application.Service
VerifyMsg = _localizer["TrialDicomAE_RepeatCalledAE"]
};
var verifyExp3 = new EntityVerifyExp<TrialDicomAE>()
{
VerifyExp = u => u.TrialId == addOrEditDicomAE.TrialId,
//"AE名称不能与其他项目相同"
VerifyMsg = "该项目只允许添加一条dicom AE记录前端对接有bug时出现"
};
//var verifyExp2 = new EntityVerifyExp<TrialDicomAE>()
//{
// VerifyExp = u => u.TrialId == addOrEditDicomAE.TrialId,
@ -98,7 +107,7 @@ namespace IRaCIS.Core.Application.Service
if (addOrEditDicomAE.IsPACSConnect)
{
// 在此处拷贝automapper 映射
var entity = await _dicomAERepository.InsertOrUpdateAsync(addOrEditDicomAE, true, verifyExp1, verifyExp2);
var entity = await _dicomAERepository.InsertOrUpdateAsync(addOrEditDicomAE, true, verifyExp3, verifyExp1, verifyExp2);
return ResponseOutput.Ok(entity.Id.ToString());
}
@ -123,42 +132,33 @@ namespace IRaCIS.Core.Application.Service
/// 测试scp server 是否可以连接
/// </summary>
/// <returns></returns>
[HttpGet("{dicomAEId:guid}")]
public async Task<bool> TestSCPServerConnect(Guid dicomAEId)
[HttpPost]
public async Task<bool> TestSCPServerConnect(TestAECommand inCommand)
{
var find = await _dicomAERepository.FirstOrDefaultAsync(t => t.Id == dicomAEId);
if (find == null)
try
{
var client = DicomClientFactory.Create(inCommand.IP, inCommand.Port, false, "test-callingAE", inCommand.CalledAE);
return false;
client.NegotiateAsyncOps();
await client.AddRequestAsync(new DicomCEchoRequest());
// 创建一个超时任务设置超时时间为1秒
var timeoutTask = Task.Delay(TimeSpan.FromSeconds(3));
// 发送 DICOM 请求
var sendTask = client.SendAsync();
// 等待任务完成,若超时任务先完成则抛出超时异常
if (await Task.WhenAny(sendTask, timeoutTask) == timeoutTask)
{
throw new TimeoutException("DICOM 请求超时。");
}
return true;
}
else
catch (Exception ex)
{
find.LatestTestTime = DateTime.Now;
try
{
var client = DicomClientFactory.Create(find.IP, find.Port, false, "test-callingAE", find.CalledAE);
client.NegotiateAsyncOps();
await client.AddRequestAsync(new DicomCEchoRequest());
await client.SendAsync();
find.IsTestOK = true;
await _dicomAERepository.SaveChangesAsync();
return true;
}
catch (Exception ex)
{
find.IsTestOK = false;
await _dicomAERepository.SaveChangesAsync();
return false;
}
return false;
}

View File

@ -121,8 +121,9 @@ namespace IRaCIS.Application.Services
{
var trialType = _trialRepository.Where(t => t.Id == trialUserQuery.TrialId).Select(t => t.TrialType).FirstOrDefault();
var userTypeEnums = new List<UserTypeEnum>() { UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA, UserTypeEnum.MW };
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin)
var userTypeEnums = new List<UserTypeEnum>() { UserTypeEnum.ClinicalResearchCoordinator, UserTypeEnum.CRA, UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA, UserTypeEnum.MW, UserTypeEnum.MC };
//if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin)
{
userTypeEnums.Add(UserTypeEnum.ProjectManager);
}
@ -138,7 +139,7 @@ namespace IRaCIS.Application.Services
.WhereIf(trialType == TrialType.NoneOfficial, t => t.IsTestUser == true || (t.IsTestUser == false && t.IsZhiZhun))
.Where(t=>userTypeEnums.Contains(t.UserTypeEnum))
.WhereIf(!string.IsNullOrWhiteSpace(trialUserQuery.UserRealName), t => (t.FullName).Contains(trialUserQuery.UserRealName))

View File

@ -51,8 +51,7 @@ namespace IRaCIS.Core.Application.Service
{
var verifyExp1 = new EntityVerifyExp<TrialSiteDicomAE>()
{
VerifyExp = u => u.IP == addOrEditTrialSiteDicomAE.IP && u.Port == addOrEditTrialSiteDicomAE.Port
&& u.CallingAE == addOrEditTrialSiteDicomAE.CallingAE && u.TrialId == addOrEditTrialSiteDicomAE.TrialId
VerifyExp = u => u.CallingAE == addOrEditTrialSiteDicomAE.CallingAE && u.TrialId == addOrEditTrialSiteDicomAE.TrialId
&& u.TrialSiteId == addOrEditTrialSiteDicomAE.TrialSiteId,
//"不允许添加相同的记录"

View File

@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure;
namespace IRaCIS.Application.Services
{

View File

@ -1,4 +1,5 @@
using Aliyun.OSS;
using DocumentFormat.OpenXml.Wordprocessing;
using IP2Region.Net.XDB;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
@ -18,12 +19,15 @@ using Microsoft.Extensions.Options;
using MiniExcelLibs;
using Minio;
using Minio.DataModel.Args;
using NPOI.XWPF.UserModel;
using SharpCompress.Common;
using Spire.Doc;
using System.Linq.Expressions;
using System.Reflection.Metadata;
using System.Text;
using System.Text.RegularExpressions;
using Xceed.Document.NET;
using Xceed.Words.NET;
namespace IRaCIS.Application.Services
@ -65,6 +69,30 @@ namespace IRaCIS.Application.Services
//_cache = cache;
}
/// <summary>
/// 清理一致性分析任务
/// </summary>
/// <param name="trialReadingCriterionId"></param>
/// <returns></returns>
public async Task<IResponseOutput> DeleteConsistentDate(Guid trialReadingCriterionId)
{
var consistentSubjectIdList = _repository.Where<VisitTask>(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == true).Select(t => t.SubjectId).ToList();
await _repository.BatchDeleteAsync<TaskConsistentRule>(t => t.TrialReadingCriterionId == trialReadingCriterionId);
await _repository.BatchDeleteAsync<VisitTask>(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == true);
await _repository.BatchDeleteAsync<ReadingConsistentClinicalDataPDF>(t => consistentSubjectIdList.Contains(t.ReadingConsistentClinicalData.SubjectId));
await _repository.BatchDeleteAsync<ReadingConsistentClinicalData>(t => consistentSubjectIdList.Contains(t.SubjectId));
await _repository.SaveChangesAsync();
return ResponseOutput.Ok();
}
public async Task<IResponseOutput> TestEFcore8()
@ -113,7 +141,7 @@ namespace IRaCIS.Application.Services
public async Task<IResponseOutput> TestMinIO([FromServices] IOSSService oSSService)
{
var str= await oSSService.GetSignedUrl("/01000000-c0a8-0242-1c98-08dc7ebcd37d/Read/01000000-c0a8-0242-1c98-08dc7ebcd37d/Visit/1716872544006_1716872544003.png");
var str = await oSSService.GetSignedUrl("/01000000-c0a8-0242-1c98-08dc7ebcd37d/Read/01000000-c0a8-0242-1c98-08dc7ebcd37d/Visit/1716872544006_1716872544003.png");
//await oSSService.UploadToOSSAsync("C:\\Users\\Administrator\\Desktop\\TrialSiteUserImportTemplate.xlsx", "myfolder");
@ -170,6 +198,9 @@ namespace IRaCIS.Application.Services
[UnitOfWork]
public async Task<string> Get()
{
await _repository.Where<ReadingConsistentClinicalData>(t => t.SubjectId == Guid.Empty).Include(t => t.ReadingClinicalDataPDFList).ExecuteDeleteAsync();
// Generate RSA keys
var keyPair = RSAHelper.GenerateRSAKeyPair(2048);
@ -187,11 +218,11 @@ namespace IRaCIS.Application.Services
Console.WriteLine("\nOriginal Data: " + dataToEncrypt);
// Encrypt the data
var encryptedData = RSAHelper.Encrypt( publicKey, dataToEncrypt);
var encryptedData = RSAHelper.Encrypt(publicKey, dataToEncrypt);
Console.WriteLine("\nEncrypted Data: " + encryptedData);
// Decrypt the data
string decryptedData = RSAHelper.Decrypt( privateKey, encryptedData);
string decryptedData = RSAHelper.Decrypt(privateKey, encryptedData);
Console.WriteLine("\nDecrypted Data: " + decryptedData);
@ -201,12 +232,111 @@ namespace IRaCIS.Application.Services
[AllowAnonymous]
public async Task<string> testEmail([FromServices] IWebHostEnvironment env ,string email)
public async Task<string> testDoc([FromServices] IWebHostEnvironment env, string email)
{
#region DocX 测试
//using (DocX document = DocX.Load("C:\\Users\\hang\\Desktop\\test.docx"))
//{
// // 查找书签
// var bookmarkCn_Start = document.Bookmarks.FirstOrDefault(b => b.Name == "zh_cn");
// var bookmarkEn_Start = document.Bookmarks.FirstOrDefault(b => b.Name == "en_us");
var hiddenEmail = EmailMaskHelper.MaskEmail(email);
// if (bookmarkCn_Start != null && bookmarkEn_Start != null)
// {
// // 获取书签的起始位置
// int bookmarkCNStartPos = bookmarkCn_Start.Paragraph.StartIndex;
return hiddenEmail;
// var bookmarkENStartPos = bookmarkEn_Start.Paragraph.StartIndex;
// // // 创建一个要删除段落的列表
// List<Paragraph> paragraphsToRemove = new List<Paragraph>();
// foreach (var item in document.Paragraphs)
// {
// //中文模板在前,英文在后,英文模板,就删除英文之前的,中文模板就删除英文之后的
// //_userInfo.IsEn_Us? item.EndIndex< bookmarkENStartPos :item.StartIndex>= bookmarkENStartPos
// if (item.StartIndex>= bookmarkENStartPos)
// {
// paragraphsToRemove.Add(item);
// }
// }
// foreach (var paragraph in paragraphsToRemove)
// {
// document.RemoveParagraph(paragraph);
// }
// }
// // 保存修改
// document.SaveAs("C:\\Users\\hang\\Desktop\\test1.docx");
//}
#endregion
using (FileStream fs = new FileStream("C:\\Users\\hang\\Desktop\\test.docx", FileMode.Open, FileAccess.Read))
{
XWPFDocument doc = new XWPFDocument(fs);
// 查找包含指定书签的段落及其索引
var bookmarkParagraph = doc.Paragraphs
.FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == "en_us"));
if (bookmarkParagraph != null)
{
int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph);
// 删除书签之后的所有段落
for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--)
{
doc.RemoveBodyElement(i);
}
}
else
{
throw new BusinessValidationFailedException("word 模板没有英文书签");
}
// 创建一个要删除段落的列表
//XWPFParagraph bookmarkParagraph = null;
//foreach (var paragraph in doc.Paragraphs)
//{
// foreach (var bookmark in paragraph.GetCTP().GetBookmarkStartList())
// {
// if (bookmark.name == "en_us")
// {
// bookmarkParagraph = paragraph;
// break;
// }
// }
//}
//// 从书签所在段落开始,删除之前的所有段落
//for (int i = bookmarkIndex - 1; i >= 0; i--)
//{
// doc.RemoveBodyElement(i);
//}
using (FileStream outStream = new FileStream("C:\\Users\\hang\\Desktop\\test1.docx", FileMode.Create, FileAccess.Write))
{
doc.Write(outStream);
}
}
return "hiddenEmail";
}

View File

@ -64,6 +64,15 @@ namespace IRaCIS.Core.Domain.Share
}
public class TrialPacsInfo
{
public int Port { get; set; }
public string Ip { get; set; }
public string TrialCalledAE { get; set; }
}
public class SiteSurveyModifyFiled
{
public string NeedModifyFiled { get; set; }

View File

@ -17,4 +17,52 @@ namespace IRaCIS.Core.Domain.Models
abstract TKey Id { get; set; }
}
#region 减少实体属性,增加基类
public abstract class BaseAuditAddEntity : Entity, IAuditAdd
{
public Guid CreateUserId { get; set; }
public DateTime CreateTime { get; set; }
}
public abstract class BaseFullAuditEntity : Entity, IAuditUpdate, IAuditAdd
{
public Guid CreateUserId { get; set; }
public DateTime CreateTime { get; set; }
public Guid UpdateUserId { get; set; }
public DateTime UpdateTime { get; set; }
}
public abstract class BaseFullAuditDeleteEntity : Entity, IAuditUpdate, IAuditAdd, ISoftDelete
{
public Guid? DeleteUserId { get; set; }
public bool IsDeleted { get; set; }
public DateTime? DeletedTime { get; set; }
public Guid CreateUserId { get; set; }
public DateTime CreateTime { get; set; }
public Guid UpdateUserId { get; set; }
public DateTime UpdateTime { get; set; }
}
public abstract class BaseAuditAddEntityWithUserName : Entity, IAuditAddWithUserName
{
public string CreateUser { get; set; }
public Guid CreateUserId { get; set; }
public DateTime CreateTime { get; set; }
}
public abstract class BaseAuditUpdateEntity : Entity, IAuditUpdate
{
public Guid UpdateUserId { get; set; }
public DateTime UpdateTime { get; set; }
}
#endregion
}

View File

@ -19,7 +19,9 @@ namespace IRaCIS.Core.Domain.Models
public interface IAuditAddWithUserName : IAuditAdd<Guid>
{
string CreateUser { get; set; }
public string CreateUser { get; set; }
}
}

View File

@ -5,7 +5,6 @@ namespace IRaCIS.Core.Domain.Models
public interface IAuditUpdate<TKey> where TKey : struct
{
public TKey UpdateUserId { get; set; }
//string UpdateUserName { get; set; }
public DateTime UpdateTime { get; set; }
}
@ -13,4 +12,9 @@ namespace IRaCIS.Core.Domain.Models
{
}
}

View File

@ -2,16 +2,18 @@
namespace IRaCIS.Core.Domain.Models
{
public interface ISoftDelete
public interface ISoftDelete<TKey> where TKey : struct
{
bool IsDeleted { get; set; }
public TKey? DeleteUserId { get; set; }
public bool IsDeleted { get; set; }
public DateTime? DeletedTime { get; set; }
public Guid? DeleteUserId { get; set; }
}
public interface ISoftDelete : ISoftDelete<Guid>
{
}
}

View File

@ -9,82 +9,30 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IRaCIS.Core.Domain.Models
{
///<summary>
///CommonDocument
///</summary>
[Table("CommonDocument")]
public class CommonDocument : Entity, IAuditUpdate, IAuditAdd,ISoftDelete
{
///<summary>
///CommonDocument
///</summary>
[Table("CommonDocument")]
public class CommonDocument : BaseFullAuditDeleteEntity
{
public string Code { get; set; } = String.Empty;
[Required]
public string Code { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
[Required]
public string Name { get; set; } = String.Empty;
public string NameCN { get; set; } = string.Empty;
public string NameCN { get; set; } = string.Empty;
/// <summary>
/// Path
/// </summary>
[Required]
public string Path { get; set; } = String.Empty;
/// <summary>
/// CreateTime
/// </summary>
[Required]
public DateTime CreateTime { get; set; }
/// <summary>
/// CreateUserId
/// </summary>
[Required]
public Guid CreateUserId { get; set; }
/// <summary>
/// UpdateTime
/// </summary>
[Required]
public DateTime UpdateTime { get; set; }
/// <summary>
/// UpdateUserId
/// </summary>
[Required]
public Guid UpdateUserId { get; set; }
/// <summary>
/// Description
/// </summary>
[Required]
public string Description { get; set; } = String.Empty;
/// <summary>
/// IsDeleted
/// </summary>
[Required]
public bool IsDeleted { get; set; }
public DateTime? DeletedTime { get; set; }
public Guid? DeleteUserId { get; set; }
public string Path { get; set; } = String.Empty;
public CriterionType? CriterionTypeEnum { get; set; }
public CommonDocumentFileType FileTypeEnum { get; set; }
public EmailBusinessScenario BusinessScenarioEnum { get; set; }
public string Description { get; set; } = String.Empty;
public CriterionType? CriterionTypeEnum { get; set; }
public CommonDocumentFileType FileTypeEnum { get; set; }
public EmailBusinessScenario BusinessScenarioEnum { get; set; }
//[Required]
//public Guid FileTypeId { get; set; }
//public Guid ModuleTypeId { get; set; }
}
//public Dictionary FileType { get; set; }
//public Dictionary ModuleType { get; set; }
}
}
}

View File

@ -29,7 +29,9 @@ namespace IRaCIS.Core.Domain.Models
public Guid UpdateUserId { get; set; }
/// <summary>
/// 0 1 2 预翻译 已确认 废除
/// </summary>
public int State { get; set; }

View File

@ -10,6 +10,7 @@
<ItemGroup>
<ProjectReference Include="..\IRaCIS.Core.Domain.Share\IRaCIS.Core.Domain.Share.csproj" />
<ProjectReference Include="..\IRaCIS.Core.Infrastructure\IRaCIS.Core.Infrastructure.csproj" />
</ItemGroup>

View File

@ -45,7 +45,7 @@ namespace IRaCIS.Core.Domain.Models
public DateTime? LatestTestTime { get; set; }
public bool IsTestOK { get; set; }
public bool? IsTestOK { get; set; }
}

View File

@ -36,7 +36,7 @@ namespace IRaCIS.Core.Domain.Models
public string Phone { get; set; } = string.Empty;
public string EMail { get; set; } = string.Empty;
public int Sex { get; set; }
public int? Sex { get; set; }
public UserStateEnum Status { get; set; } = UserStateEnum.Enable;
public DateTime? LastLoginTime { get; set; }

View File

@ -54,12 +54,12 @@ namespace IRaCIS.Core.Domain.Models
/// <summary>
/// 是否盲化
/// </summary>
public bool? IsBlind { get; set; }
public bool? IsBlind { get; set; } = false;
/// <summary>
/// 是否完整
/// </summary>
public bool? IsComplete { get; set; }
public bool? IsComplete { get; set; } = true;
/// <summary>
/// 创建人

View File

@ -36,6 +36,17 @@ namespace IRaCIS.Core.Domain.Share
/// </summary>
public int ReadingRestTimeMin { get; set; }
/// <summary>
/// 是否需要修改密码
/// </summary>
public bool IsNeedChangePassWord { get; set; }
/// <summary>
/// 修改密码的天数
/// </summary>
public int ChangePassWordDays { get; set; }
}
public class SystemEmailSendConfig
@ -67,6 +78,15 @@ namespace IRaCIS.Core.Domain.Share
}
public class SystemPacsConfig
{
public int Port { get; set; }
public string IP { get; set; }
}
public class EncreptResponseOption
{
public bool IsEnable { get; set; }

View File

@ -158,7 +158,8 @@ namespace IRaCIS.Core.Infra.EFCore.Common
t.IsTrialBasicLogicConfirmed,
t.IsTrialProcessConfirmed,
t.IsTrialUrgentConfirmed,
t.IsConfigureEmail
t.IsConfigureEmail,
t.IsTrialPACSConfirmed,
}).FirstOrDefaultAsync();
switch (_userInfo.RequestUrl)
{
@ -172,6 +173,9 @@ namespace IRaCIS.Core.Infra.EFCore.Common
case "configTrialBasicInfo/ConfigTrialUrgentInfoConfirm":
extraIdentification = $"/{oldentity.IsTrialUrgentConfirmed.ToString()}";
break;
case "configTrialBasicInfo/ConfigTrialPACSInfoConfirm":
extraIdentification = $"/{oldentity.IsTrialPACSConfirmed.ToString()}";
break;
case "TrialEmailNoticeConfig/setTrialEmail":
@ -328,6 +332,34 @@ namespace IRaCIS.Core.Infra.EFCore.Common
});
}
// PACS直连
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialSiteDicomAE)))
{
var type = GetEntityAuditOpt(item);
var entity = item.Entity as TrialSiteDicomAE;
await InsertInspection<TrialSiteDicomAE>(entity, type, x => new InspectionConvertDTO()
{
ObjectRelationParentId=entity.TrialSiteId,
});
}
// PACS直连
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialDicomAE)))
{
var type = GetEntityAuditOpt(item);
var entity = item.Entity as TrialDicomAE;
await InsertInspection<TrialDicomAE>(entity, type, x => new InspectionConvertDTO()
{
});
}
//系统标准问题
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingQuestionSystem)))
{
@ -2314,6 +2346,27 @@ namespace IRaCIS.Core.Infra.EFCore.Common
}, new { FileCountViewStr = config?.ClinicalDataLevel == ClinicalLevel.Subject && config?.ClinicalUploadType == ClinicalUploadType.Table ? "NA" : entity.FileCount.ToString() });
}
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingConsistentClinicalData)))
{
var type = GetEntityAuditOpt(item);
var entity = item.Entity as ReadingConsistentClinicalData;
var config = await _dbContext.ClinicalDataTrialSet.FindAsync(entity.ClinicalDataTrialSetId);
await InsertInspection<ReadingConsistentClinicalData>(item.Entity as ReadingConsistentClinicalData, type, x => new InspectionConvertDTO()
{
IsDistinctionInterface = type == AuditOpt.Update ? true : false,
SubjectVisitId = x.IsVisit ? x.ReadingId : null,
ObjectRelationParentId = entity.ClinicalDataTrialSetId,
//ObjectRelationParentId2 = x.IsVisit == false?x.ReadingId:null
}, new { FileCountViewStr = config?.ClinicalDataLevel == ClinicalLevel.Subject && config?.ClinicalUploadType == ClinicalUploadType.Table ? "NA" : entity.FileCount.ToString() });
}
//阅片期计划
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingPeriodSet)))
{
@ -2870,7 +2923,6 @@ namespace IRaCIS.Core.Infra.EFCore.Common
{
Unit = (ValueUnit)int.Parse(x.Code),
UnitName = x.Value.ToString(),
}).ToList();
//获取表格问题名称 组合成数组

View File

@ -21,6 +21,7 @@ using Microsoft.Identity.Client;
using EntityFramework.Exceptions.Common;
using System.Data;
using IRaCIS.Core.Infrastructure;
using System.Reflection.Metadata;
namespace IRaCIS.Core.Infra.EFCore
{
@ -49,7 +50,7 @@ namespace IRaCIS.Core.Infra.EFCore
public class IRaCISDBContext : DbContext
{
private IUserInfo _userInfo;
private IUserInfo _userInfo;
private readonly ILogger<IRaCISDBContext> _logger;
@ -57,7 +58,7 @@ namespace IRaCIS.Core.Infra.EFCore
) : base(options)
{
_userInfo= userInfo;
_userInfo = userInfo;
_logger = logger;
}
@ -72,7 +73,7 @@ namespace IRaCIS.Core.Infra.EFCore
});
modelBuilder.Entity<ReadingQuestionTrial>().HasQueryFilter(p => p.IsAdditional==false);
modelBuilder.Entity<ReadingQuestionTrial>().HasQueryFilter(p => p.IsAdditional == false);
modelBuilder.Entity<User>().HasMany(t => t.VisitTaskList).WithOne(t => t.DoctorUser).HasForeignKey(t => t.DoctorUserId).IsRequired(false);
@ -98,11 +99,12 @@ namespace IRaCIS.Core.Infra.EFCore
modelBuilder.Entity<VisitTask>().HasMany(t => t.TaskInfluenceList).WithOne(s => s.OriginalTask).HasForeignKey(t => t.OriginalTaskId);
modelBuilder.Entity<VisitTask>().HasMany(t => t.GlobalVisitResultList).WithOne(s => s.GlobalVisitTask).HasForeignKey(t => t.GlobalTaskId);
modelBuilder.Entity<VisitTask>().HasMany(t => t.GlobalVisitResultList).WithOne(s => s.GlobalVisitTask).HasForeignKey(t => t.GlobalTaskId);
modelBuilder.Entity<Dictionary>().HasMany(t => t.ChildList).WithOne(t => t.Parent);
modelBuilder.Entity<SubjectUser>().HasMany(t => t.EarlierSubjectUserList).WithOne(t => t.OrignalSubjectUser);
modelBuilder.Entity<VisitTask>().HasQueryFilter(b => b.Subject.IsDeleted == false);
//遍历实体模型手动配置
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(q => q.GetInterface(typeof(IEntityTypeConfiguration<>).FullName) != null);
@ -239,18 +241,18 @@ namespace IRaCIS.Core.Infra.EFCore
public virtual DbSet<CriterionNidusSystem> CriterionNidusSystem { get; set; }
public virtual DbSet<CriterionNidusTrial> CriterionNidusTrial { get; set; }
public virtual DbSet<CriterionNidusTrial> CriterionNidusTrial { get; set; }
public virtual DbSet<ReadingTrialCriterionDictionary> ReadingTrialCriterionDictionary { get; set; }
public virtual DbSet<ReadingTrialCriterionDictionary> ReadingTrialCriterionDictionary { get; set; }
public virtual DbSet<ReadingTableQuestionTrial> ReadingTableQuestionTrial { get; set; }
public virtual DbSet<ReadingTableQuestionTrial> ReadingTableQuestionTrial { get; set; }
public virtual DbSet<TumorAssessment_RECIST1Point1BM> TumorAssessment_RECIST1Point1BM { get; set; }
public virtual DbSet<TumorAssessment_RECIST1Point1> TumorAssessment_RECIST1Point1 { get; set; }
public virtual DbSet<TumorAssessment_IRECIST1Point1> TumorAssessment_IRECIST1Point1 { get; set; }
public virtual DbSet<TrialClinicalDataSetCriterion> TrialClinicalDataSetCriterion { get; set; }
public virtual DbSet<TrialCriterionAdditionalAssessmentType> TrialCriterionAdditionalAssessmentType { get; set; }
@ -319,7 +321,7 @@ namespace IRaCIS.Core.Infra.EFCore
#region Trial
public virtual DbSet<Trial> Trial { get; set; }
public virtual DbSet<TrialDictionary> TrialDictionary { get; set; }
public virtual DbSet<TrialStatusDetail> TrialDetail { get; set; }
public virtual DbSet<TrialUser> UserTrial { get; set; }
@ -333,9 +335,9 @@ namespace IRaCIS.Core.Infra.EFCore
public virtual DbSet<User> User { get; set; }
public virtual DbSet<UserPassWordLog> UserPassWordLog { get; set; }
public virtual DbSet<UserPassWordLog> UserPassWordLog { get; set; }
public virtual DbSet<TrialSiteUserSurvey> TrialSiteUserSurvey { get; set; }
public virtual DbSet<TrialSiteUserSurvey> TrialSiteUserSurvey { get; set; }
public virtual DbSet<TrialSiteEquipmentSurvey> TrialSiteEquipmentSurvey { get; set; }
public virtual DbSet<TrialSiteSurvey> TrialSiteSurvey { get; set; }
@ -391,8 +393,8 @@ namespace IRaCIS.Core.Infra.EFCore
public virtual DbSet<ClinicalTableAnswer> ClinicalTableAnswer { get; set; }
public virtual DbSet<ReadModuleCriterionFrom> ReadModuleCriterionFrom { get; set; }
public virtual DbSet<ClinicalForm> ClinicalForm { get; set; }
public virtual DbSet<ReadModuleCriterionFrom> ReadModuleCriterionFrom { get; set; }
public virtual DbSet<ClinicalForm> ClinicalForm { get; set; }
#endregion
@ -448,8 +450,8 @@ namespace IRaCIS.Core.Infra.EFCore
public virtual DbSet<ShortcutKey> ShortcutKey { get; set; }
public virtual DbSet<UserWLTemplate> UserWLTemplate { get; set; }
public virtual DbSet<EmailNoticeConfig> EmailNoticeConfig { get; set; }
public virtual DbSet<UserWLTemplate> UserWLTemplate { get; set; }
public virtual DbSet<EmailNoticeConfig> EmailNoticeConfig { get; set; }
public virtual DbSet<SystemBasicData> SystemBasicData { get; set; }
public virtual DbSet<TrialSign> TrialSign { get; set; }
@ -498,7 +500,7 @@ namespace IRaCIS.Core.Infra.EFCore
public virtual DbSet<TrialDicomAE> TrialDicomAE { get; set; }
public virtual DbSet<TrialSiteDicomAE> TrialSiteDicomAE { get; set; }
public virtual DbSet<TrialSiteDicomAE> TrialSiteDicomAE { get; set; }
public virtual DbSet<SCPImageUpload> SCPImageUpload { get; set; }
@ -509,7 +511,6 @@ namespace IRaCIS.Core.Infra.EFCore
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{
// 采用触发器的方式 设置 CreateUserId CreateTime UpdateTime UpdateUserId 稽查实体里面没有这四个字段的值 因为先后顺序的原因
SetCommonEntityAuditInfo();
await AddAudit();
try
@ -519,7 +520,7 @@ namespace IRaCIS.Core.Infra.EFCore
}
catch (UniqueConstraintException ex)
{
_logger.LogError(ex.InnerException is null? ex.Message :ex.InnerException?.Message);
_logger.LogError(ex.InnerException is null ? ex.Message : ex.InnerException?.Message);
throw new DBSaveFailedException("该唯一键已经存在于数据库中。");
@ -567,7 +568,7 @@ namespace IRaCIS.Core.Infra.EFCore
}
}
public async Task AddAudit()
@ -589,91 +590,13 @@ namespace IRaCIS.Core.Infra.EFCore
await auditingData.InsertAddEntitys(entities);
}
}
/// <summary>
/// 重写savechange方式 统一增加审计信息 CreateUserId CreateTime UpdateTime Update UserId
/// </summary>
private void SetCommonEntityAuditInfo()
{
ChangeTracker.DetectChanges(); // Important!
// 获取所有更改,删除,新增的实体,但排除审计实体(避免死循环)
var entities = ChangeTracker.Entries()
.Where(u => (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added)).Where(x => !typeof(DataInspection).IsAssignableFrom(x.Entity.GetType())).ToList();
foreach (var t in entities)
{
switch (t.State)
{
case EntityState.Deleted:
break;
case EntityState.Modified:
if (t.Entity is IAuditUpdate updateEntity1)
{
updateEntity1.UpdateTime = DateTime.Now;
updateEntity1.UpdateUserId = _userInfo.Id;
}
if (t.Entity is ISoftDelete softDelete)
{
if (softDelete.IsDeleted)
{
softDelete.DeleteUserId = _userInfo.Id;
softDelete.DeletedTime = DateTime.Now;
}
else
{
softDelete.DeletedTime = null;
}
}
break;
//添加的时候,更新审计字段也赋值
case EntityState.Added:
if (t.Entity is IAuditAdd addEntity)
{
if (addEntity.CreateTime == default(DateTime))
{
addEntity.CreateTime = DateTime.Now;
}
addEntity.CreateUserId = _userInfo.Id;
}
if (t.Entity is IAuditUpdate updateEntity)
{
updateEntity.UpdateTime = DateTime.Now;
updateEntity.UpdateUserId = _userInfo.Id;
}
if (t.Entity is IAuditAddWithUserName addEntity3)
{
if (addEntity3.CreateTime == default(DateTime))
{
addEntity3.CreateTime = DateTime.Now;
}
addEntity3.CreateUserId = _userInfo.Id;
addEntity3.CreateUser = _userInfo.RealName;
}
break;
}
}
}
public virtual DbSet<TaskAllocationRule> TaskAllocationRule { get; set; }
public virtual DbSet<VisitTask> VisitTask { get; set; }

View File

@ -0,0 +1,103 @@
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace IRaCIS.Core.Infra.EFCore;
public class AuditEntityInterceptor(IUserInfo _userInfo) : SaveChangesInterceptor
{
public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
{
AuditEntities(eventData.Context);
return base.SavingChanges(eventData, result);
}
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData,
InterceptionResult<int> result, CancellationToken cancellationToken = default)
{
AuditEntities(eventData.Context);
return base.SavingChangesAsync(eventData, result, cancellationToken);
}
public void AuditEntities(DbContext? context)
{
if (context == null) return;
// 获取所有更改,删除,新增的实体,但排除审计实体(避免死循环)
foreach (var entry in context.ChangeTracker.Entries().Where(u => (u.State == EntityState.Modified || u.State == EntityState.Added))
.Where(x => !typeof(DataInspection).IsAssignableFrom(x.Entity.GetType())).ToList())
{
switch (entry.State)
{
case EntityState.Deleted:
break;
case EntityState.Modified:
if (entry.Entity is IAuditUpdate updateEntity1)
{
updateEntity1.UpdateTime = DateTime.Now;
updateEntity1.UpdateUserId = _userInfo.Id;
}
if (entry.Entity is ISoftDelete softDelete)
{
if (softDelete.IsDeleted)
{
softDelete.DeleteUserId = _userInfo.Id;
softDelete.DeletedTime = DateTime.Now;
}
else
{
softDelete.DeletedTime = null;
}
}
break;
//添加的时候,更新审计字段也赋值
case EntityState.Added:
if (entry.Entity is IAuditAdd addEntity)
{
if (addEntity.CreateTime == default(DateTime))
{
addEntity.CreateTime = DateTime.Now;
}
addEntity.CreateUserId = _userInfo.Id;
}
if (entry.Entity is IAuditUpdate updateEntity)
{
updateEntity.UpdateTime = DateTime.Now;
updateEntity.UpdateUserId = _userInfo.Id;
}
if (entry.Entity is IAuditAddWithUserName addEntity3)
{
if (addEntity3.CreateTime == default(DateTime))
{
addEntity3.CreateTime = DateTime.Now;
}
addEntity3.CreateUserId = _userInfo.Id;
addEntity3.CreateUser = _userInfo.RealName;
}
break;
}
}
}
}

View File

@ -11,6 +11,8 @@
<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
<PackageReference Include="SharpCompress" Version="0.37.2" />

View File

@ -1,4 +1,5 @@
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.Extensions.Localization;
using System;
namespace IRaCIS.Core.Infrastructure
@ -8,15 +9,24 @@ namespace IRaCIS.Core.Infrastructure
public ApiResponseCodeEnum Code { get; set; }
public BusinessValidationFailedException()
public string LocalizedKey { get; set; }=string.Empty;
public BusinessValidationFailedException()
{
}
public BusinessValidationFailedException(LocalizedString message, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed) : base(message)
{
Code = code;
LocalizedKey=message.Name;
}
public BusinessValidationFailedException(string message, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed) : base(message)
{
Code = code;
Code = code;
}
}
}
}

View File

@ -5,44 +5,86 @@ using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
using System.Collections.Generic;
using System;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace IRaCIS.Core.Infrastructure.Extention
{
public static class QueryablePageListExtensions
{
//单字段排序
public static PageOutput<T> ToPagedList<T>(this IQueryable<T> source, int pageIndex, int pageSize, string defaultSortFiled = "Id", bool isAsc = true)
//单字段排序 异步 (或者默认排序字段是空,多字段排序,传递了,就以传递的单字段为准)
public static async Task<PageOutput<T>> ToPagedListAsync<T>(this IQueryable<T> source, PageInput pageInput, bool isMultiSortFiled = false, string[] sortArray = default, CancellationToken cancellationToken = default)
{
if (pageIndex <= 0)
if (isMultiSortFiled && sortArray == default)
{
pageIndex = 1;
throw new InvalidOperationException("The sort field must be specified");
}
if (pageSize <= 0)
if (pageInput.PageIndex <= 0)
{
pageSize = 10;
pageInput.PageIndex = 1;
}
var count = source.Count();
if (pageInput.PageSize <= 0)
{
pageInput.PageSize = 10;
}
var count = await source.CountAsync(cancellationToken).ConfigureAwait(false);
if (count == 0)
{
return new PageOutput<T>() { CurrentPageData = new T[0] };
}
var propName=string.Empty;
var propName = string.IsNullOrWhiteSpace(defaultSortFiled) ? "Id" : defaultSortFiled;
if (string.IsNullOrWhiteSpace(pageInput.SortField))
{
//没有指定优先以Id排序否则从属性里面随便取出来一个排序
var propertyNameList = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(t => t.CanWrite).Select(t => t.Name).OrderBy(t => t).ToList();
source = isAsc ? source.OrderBy(propName) : source.OrderBy(propName + " desc");
if (propertyNameList.Count == 0)
{
throw new InvalidOperationException("no default sort field.");
}
else
{
propName= propertyNameList.Contains("Id") ? "Id" : propertyNameList.FirstOrDefault();
}
}
else
{
//有值,以前段传输的为主
propName = pageInput.SortField;
}
source = source.Skip((pageIndex - 1) * pageSize);
if (!isMultiSortFiled)
{
source = pageInput.Asc ? source.OrderBy(propName) : source.OrderBy(propName + " desc");
var items = source
.Take(pageSize)
.ToArray();
}
else
{
var sortString = string.Join(',', sortArray);
source = source.OrderBy(sortString);
}
source = source.Skip((pageInput.PageIndex - 1) * pageInput.PageSize);
var items = await source
.Take(pageInput.PageSize)
.ToArrayAsync(cancellationToken)
.ConfigureAwait(false);
var pagedList = new PageOutput<T>()
{
PageIndex = pageIndex,
PageSize = pageSize,
PageIndex = pageInput.PageIndex,
PageSize = pageInput.PageSize,
TotalCount = count,
CurrentPageData = items
};
@ -50,8 +92,10 @@ namespace IRaCIS.Core.Infrastructure.Extention
return pagedList;
}
//单字段排序 异步
public static async Task<PageOutput<T>> ToPagedListAsync<T>(this IQueryable<T> source, int pageNumber, int pageSize, string defaultSortFiled = "Id", bool isAsc = true, bool isMultiSortFiled = false, string[] sortArray = default, CancellationToken cancellationToken = default)
public static async Task<PageOutput<T>> ToPagedListAsync<T>(this IQueryable<T> source, int pageNumber, int pageSize, string defaultSortFiled = "Id", bool isAsc = true, bool isMultiSortFiled = false, string[] sortArray = default)
{
if (isMultiSortFiled && sortArray == default)
@ -68,7 +112,7 @@ namespace IRaCIS.Core.Infrastructure.Extention
pageSize = 10;
}
var count = await source.CountAsync(cancellationToken).ConfigureAwait(false);
var count = await source.CountAsync().ConfigureAwait(false);
if (count == 0)
{
@ -90,7 +134,7 @@ namespace IRaCIS.Core.Infrastructure.Extention
source = source.Skip((pageNumber - 1) * pageSize);
var items = await source
.Take(pageSize)
.ToArrayAsync(cancellationToken)
.ToArrayAsync()
.ConfigureAwait(false);
var pagedList = new PageOutput<T>()
@ -105,85 +149,11 @@ namespace IRaCIS.Core.Infrastructure.Extention
}
public static PageOutput<T> ToPagedList<T>(this IList<T> source, int pageIndex, int pageSize, string defaultSortFiled = "Id", bool isAsc = true)
{
if (pageIndex <= 0)
{
pageIndex = 1;
}
if (pageSize <= 0)
{
pageSize = 10;
}
var count = source.Count();
if (count == 0)
{
return new PageOutput<T>() { CurrentPageData = new List<T>() };
}
var propName = string.IsNullOrWhiteSpace(defaultSortFiled) ? "Id" : defaultSortFiled;
IQueryable<T> sourceQuery = isAsc ? source.AsQueryable().OrderBy(propName) : source.AsQueryable().OrderBy(propName + " desc");
sourceQuery = sourceQuery.Skip((pageIndex - 1) * pageSize);
var items = sourceQuery
.Take(pageSize)
.ToArray();
var pagedList = new PageOutput<T>()
{
PageIndex = pageIndex,
PageSize = pageSize,
TotalCount = count,
CurrentPageData = items
};
return pagedList;
}
//多字段排序 ["a asc", "b desc", "c asc"]
public static PageOutput<T> ToPagedList<T>(this IQueryable<T> source, int pageIndex, int pageSize, string[] sortArray)
{
if (pageIndex <= 0)
{
pageIndex = 1;
}
if (pageSize <= 0)
{
pageSize = 10;
}
var count = source.Count();
if (count == 0)
{
return new PageOutput<T>() { CurrentPageData = new T[0] };
}
var sortString = string.Join(',', sortArray);
source.OrderBy(sortString);
source = source.Skip((pageIndex - 1) * pageSize);
var items = source
.Take(pageSize)
.ToArray();
var pagedList = new PageOutput<T>()
{
PageIndex = pageIndex,
PageSize = pageSize,
TotalCount = count,
CurrentPageData = items
};
return pagedList;
}
//多字段排序异步 ["a asc", "b desc", "c asc"]
public static async Task<PageOutput<T>> ToPagedListAsync<T>(this IQueryable<T> source, int pageNumber, int pageSize, string[] sortArray, CancellationToken cancellationToken = default)
public static async Task<PageOutput<T>> ToPagedListAsync<T>(this IQueryable<T> source, int pageNumber, int pageSize, string[] sortArray)
{
if (pageNumber <= 0)
{
@ -194,7 +164,7 @@ namespace IRaCIS.Core.Infrastructure.Extention
pageSize = 10;
}
var count = await source.CountAsync(cancellationToken).ConfigureAwait(false);
var count = await source.CountAsync().ConfigureAwait(false);
if (count == 0)
{
@ -212,7 +182,7 @@ namespace IRaCIS.Core.Infrastructure.Extention
source = source.Skip((pageNumber - 1) * pageSize);
var items = await source
.Take(pageSize)
.ToArrayAsync(cancellationToken)
.ToArrayAsync()
.ConfigureAwait(false);
var pagedList = new PageOutput<T>()
@ -227,6 +197,127 @@ namespace IRaCIS.Core.Infrastructure.Extention
}
#region 同步方法废弃
////单字段排序
//public static PageOutput<T> ToPagedList<T>(this IQueryable<T> source, int pageIndex, int pageSize, string defaultSortFiled = "Id", bool isAsc = true)
//{
// if (pageIndex <= 0)
// {
// pageIndex = 1;
// }
// if (pageSize <= 0)
// {
// pageSize = 10;
// }
// var count = source.Count();
// if (count == 0)
// {
// return new PageOutput<T>() { CurrentPageData = new T[0] };
// }
// var propName = string.IsNullOrWhiteSpace(defaultSortFiled) ? "Id" : defaultSortFiled;
// source = isAsc ? source.OrderBy(propName) : source.OrderBy(propName + " desc");
// source = source.Skip((pageIndex - 1) * pageSize);
// var items = source
// .Take(pageSize)
// .ToArray();
// var pagedList = new PageOutput<T>()
// {
// PageIndex = pageIndex,
// PageSize = pageSize,
// TotalCount = count,
// CurrentPageData = items
// };
// return pagedList;
//}
//public static PageOutput<T> ToPagedList<T>(this IList<T> source, int pageIndex, int pageSize, string defaultSortFiled = "Id", bool isAsc = true)
//{
// if (pageIndex <= 0)
// {
// pageIndex = 1;
// }
// if (pageSize <= 0)
// {
// pageSize = 10;
// }
// var count = source.Count();
// if (count == 0)
// {
// return new PageOutput<T>() { CurrentPageData = new List<T>() };
// }
// var propName = string.IsNullOrWhiteSpace(defaultSortFiled) ? "Id" : defaultSortFiled;
// IQueryable<T> sourceQuery = isAsc ? source.AsQueryable().OrderBy(propName) : source.AsQueryable().OrderBy(propName + " desc");
// sourceQuery = sourceQuery.Skip((pageIndex - 1) * pageSize);
// var items = sourceQuery
// .Take(pageSize)
// .ToArray();
// var pagedList = new PageOutput<T>()
// {
// PageIndex = pageIndex,
// PageSize = pageSize,
// TotalCount = count,
// CurrentPageData = items
// };
// return pagedList;
//}
////多字段排序 ["a asc", "b desc", "c asc"]
//public static PageOutput<T> ToPagedList<T>(this IQueryable<T> source, int pageIndex, int pageSize, string[] sortArray)
//{
// if (pageIndex <= 0)
// {
// pageIndex = 1;
// }
// if (pageSize <= 0)
// {
// pageSize = 10;
// }
// var count = source.Count();
// if (count == 0)
// {
// return new PageOutput<T>() { CurrentPageData = new T[0] };
// }
// var sortString = string.Join(',', sortArray);
// source.OrderBy(sortString);
// source = source.Skip((pageIndex - 1) * pageSize);
// var items = source
// .Take(pageSize)
// .ToArray();
// var pagedList = new PageOutput<T>()
// {
// PageIndex = pageIndex,
// PageSize = pageSize,
// TotalCount = count,
// CurrentPageData = items
// };
// return pagedList;
//}
#endregion
}
}

View File

@ -16,6 +16,11 @@
/// 消息
/// </summary>
string ErrorMessage { get; }
public string LocalizedInfo { get; set; }
}
/// <summary>
@ -30,13 +35,4 @@
T Data { get; set; }
}
//public interface IResponseOutput<T,T2> : IResponseOutput
//{
// /// <summary>
// /// 返回数据
// /// </summary>
// T Data { get; }
// T2 OtherInfo { get; }
//}
}

View File

@ -1,4 +1,8 @@
using Newtonsoft.Json;
using IRaCIS.Core.Domain.Share;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace IRaCIS.Core.Infrastructure.Extention
{
@ -7,10 +11,10 @@ namespace IRaCIS.Core.Infrastructure.Extention
/// </summary>
public class ResponseOutput<T> : IResponseOutput<T>
{
/// <summary>
/// 是否成功标记
/// </summary>
public bool IsSuccess { get; private set; }
/// <summary>
/// 是否成功标记
/// </summary>
public bool IsSuccess { get; private set; }
public ApiResponseCodeEnum Code { get; set; } = ApiResponseCodeEnum.OK;
@ -25,34 +29,20 @@ namespace IRaCIS.Core.Infrastructure.Extention
/// 数据 兼顾以前 Json序列化的时候返回属性名为“Result”
/// </summary>
[JsonProperty("Result")]
public T Data { get; set; }
public T Data { get; set; }
[JsonProperty("OtherInfo")]
public object OtherData { get; set; }
public string LocalizedInfo { get; set; }
/// <summary>
/// 成功
/// </summary>
/// <param name="data">数据</param>
/// <param name="msg">消息</param>
//public ResponseOutput<T> Ok(T data, string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.OK)
//{
// IsSuccess = true;
// Code = code;
// Data = data;
// ErrorMessage = msg;
// return this;
//}
public ResponseOutput<T> Ok(T data, object otherData, string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.OK)
public ResponseOutput<T> Ok(T data, object otherData, string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.OK)
{
IsSuccess = true;
Code = code;
Data = data;
OtherData=otherData;
OtherData = otherData;
ErrorMessage = msg;
return this;
@ -64,12 +54,13 @@ namespace IRaCIS.Core.Infrastructure.Extention
/// <param name="msg">提示消息</param>
/// <param name="data">数据</param>
/// <returns></returns>
public ResponseOutput<T> NotOk(string msg = "", T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.OK)
public ResponseOutput<T> NotOk(string msg = "", T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.OK, string localizedInfo = "")
{
IsSuccess = false;
Code = code;
Code = code;
ErrorMessage = msg;
Data = data;
LocalizedInfo = localizedInfo;
return this;
}
@ -77,33 +68,6 @@ namespace IRaCIS.Core.Infrastructure.Extention
}
//public class ResponseOutput<T, T2> : IResponseOutput<T, T2>
//{
// [JsonProperty("Result")]
// public T Data { get; private set; }
// public T2 OtherInfo { get; private set; }
// public bool IsSuccess { get; private set; }
// public ApiResponseCodeEnum Code { get; set; }
// public string ErrorMessage { get; private set; }
// public ResponseOutput<T, T2> Ok(T data, T2 otherInfo, string msg = "")
// {
// IsSuccess = true;
// Data = data;
// OtherInfo = otherInfo;
// ErrorMessage = msg;
// return this;
// }
//}
/// <summary>
/// 响应数据静态输出 为了代码简洁 不用每处都New
/// </summary>
@ -111,23 +75,6 @@ namespace IRaCIS.Core.Infrastructure.Extention
{
//public static IResponseOutput<T, T2> Ok<T, T2>(T data, T2 otherInfo, string msg = "")
//{
// return new ResponseOutput<T, T2>().Ok(data, otherInfo);
//}
/// <summary>
/// 成功 -----适合查询
/// </summary>
/// <param name="data">数据</param>
/// <param name="msg">消息</param>
/// <returns></returns>
//public static IResponseOutput<T> Ok<T>(T data = default, string msg = "")
//{
// return new ResponseOutput<T>().Ok(data, msg);
//}
public static IResponseOutput<T> Ok<T>(T data = default, object otherData = default, string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.OK)
{
return new ResponseOutput<T>().Ok(data, otherData, msg, code);
@ -147,15 +94,11 @@ namespace IRaCIS.Core.Infrastructure.Extention
/// <param name="msg">消息</param>
/// <param name="data">数据</param>
/// <returns></returns>
public static IResponseOutput<T> NotOk<T>(string msg = "", T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed)
public static IResponseOutput<T> NotOk<T>(string msg = "", T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed, string localizedInfo = "")
{
return new ResponseOutput<T>().NotOk(msg, data, code);
return new ResponseOutput<T>().NotOk(msg, data, code, localizedInfo);
}
//public static IResponseOutput<T> NotOk<T>( T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed)
//{
// return new ResponseOutput<T>().NotOk("", data, code);
//}
/// <summary>
/// 失败
@ -164,7 +107,22 @@ namespace IRaCIS.Core.Infrastructure.Extention
/// <returns></returns>
public static IResponseOutput<string> NotOk(string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed)
{
return new ResponseOutput<string>().NotOk(msg,code:code);
return new ResponseOutput<string>().NotOk(msg, code: code);
}
public static IResponseOutput<string> NotOk(LocalizedString msg, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed)
{
var key = msg.Name;
var info = string.Empty;
if (!string.IsNullOrWhiteSpace(key) && StaticData.Log_Locoalize_Dic.ContainsKey(key))
{
info = $"[{key}]:{StaticData.Log_Locoalize_Dic[key]}";
}
return new ResponseOutput<string>().NotOk(msg, code: code, localizedInfo: info);
}
public static IResponseOutput<string> DBNotExistIfNUll(object businessObject)
@ -172,7 +130,7 @@ namespace IRaCIS.Core.Infrastructure.Extention
return new ResponseOutput<string>().NotOk($"The business object{businessObject.GetType().Name} does not exist in the database, or was deleted by someone else, or an incorrect parameter query caused");
}
/// <summary>
/// 根据布尔值返回结果 --适合删除
/// </summary>
@ -190,7 +148,7 @@ namespace IRaCIS.Core.Infrastructure.Extention
/// <returns></returns>
public static IResponseOutput<T> Result<T>(bool success, T data = default)
{
return success ? Ok<T>(data) : NotOk<T>("Saved failed",data);
return success ? Ok<T>(data) : NotOk<T>("Saved failed", data);
}
///// <summary>

View File

@ -12,11 +12,21 @@ public static class StaticData
public static Dictionary<string, string> Zh_CN_Dic = new Dictionary<string, string>();
public static Dictionary<string, string> Log_Locoalize_Dic = new Dictionary<string, string>();
public static readonly string En_US_Json = "en-US.json";
public static readonly string Zh_CN_Json = "zh-CN.json";
public static class CultureInfo
{
public static readonly string zh_CN = "zh-CN";
public static readonly string en_US = "en-US";
public static readonly string en_US_bookMark = "en_us";
}
/// <summary>
/// 获取国际化
/// </summary>
@ -208,6 +218,8 @@ public static class StaticData
/// </summary>
public static class Export
{
public const string TrialList_Export = "TrialList_Export";
public const string TrialTrainingRecordList_Export = "TrialTrainingRecordList_Export";
public const string TrialSiteUserList_Export = "TrialSiteUserList_Export";

View File

@ -77,11 +77,6 @@
<AutoGen>True</AutoGen>
<DependentUpon>IRaCIS.Core.Dto.tt</DependentUpon>
</Compile>
<Compile Update="TT_Template\IRaCIS.Core.Entity.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>IRaCIS.Core.Entity.tt</DependentUpon>
</Compile>
<Compile Update="TT_Template\IRaCIS.Core.IRepository.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
@ -102,12 +97,18 @@
<AutoGen>True</AutoGen>
<DependentUpon>IRaCIS.Core.Services.tt</DependentUpon>
</Compile>
<Compile Update="TT_Template\IRaCIS.Core.Entity.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>IRaCIS.Core.Entity.tt</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Folder Include="TT_Template\Dto_New\" />
<Folder Include="TT_Template\IServices_New\" />
<Folder Include="TT_Template\Models_New\" />
<Folder Include="TT_Template\Repositories_New\" />
<Folder Include="TT_Template\Services_New\" />
</ItemGroup>

View File

@ -72,11 +72,9 @@ namespace IRaCIS.Core.Application.Service
var <#=char.ToLower(tableName[0]) + tableName.Substring(1)#>Queryable =
_<#=char.ToLower(tableName[0]) + tableName.Substring(1)#>Repository
.ProjectTo<<#=tableName#>View>(_mapper.ConfigurationProvider);
.ProjectTo<<#=tableName#>View>(_mapper.ConfigurationProvider);
var pageList= await <#=char.ToLower(tableName[0]) + tableName.Substring(1)#>Queryable
.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(<#=tableName#>View.Id) : inQuery.SortField,
inQuery.Asc);
var pageList= await <#=char.ToLower(tableName[0]) + tableName.Substring(1)#>Queryable.ToPagedListAsync(<#=tableName#>Query);
return pageList;
}

View File

@ -42,30 +42,34 @@ using IRaCIS.Core.Domain.Share;
using System.Collections.Generic;
namespace IRaCIS.Core.Application.ViewModel
{
/// <summary> <#=tableName#>View 列表视图模型 </summary>
public class <#=tableName#>View
<# var excludedColumns = new[] { "CreateUserId", "UpdateUserId", "CreateTime", "UpdateTime" };#>
/// <summary> <#=tableName#>View 列表视图 </summary>
public class <#=tableName#>View:<#=tableName#>AddOrEdit
{
<# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){#>
<# if (excludedColumns.Contains(column.ColumnName)){ #>
public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; }
<# }#>
<# }#>
}
///<summary><#=tableName#>Query 列表查询参数模型</summary>
///<summary><#=tableName#>Query 列表查询参数</summary>
public class <#=tableName#>Query
{
<# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){#><# if(column.CSharpType=="string"){#>
///<summary> <#= column.Remark == "" ? column.ColumnName : column.Remark.Replace("\r\n","") #></summary>
public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; }
<# }#>
<# }#>
<# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){#><# if(column.CSharpType=="string"){#>
public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; }
<# }#>
<# }#>
}
///<summary> <#=tableName#>AddOrEdit 列表查询参数模型</summary>
///<summary> <#=tableName#>AddOrEdit 添加编辑</summary>
public class <#=tableName#>AddOrEdit
{
<# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){#>
<# if (!excludedColumns.Contains(column.ColumnName)){ #>
public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; }
<#}#>
<# }#>
}

View File

@ -1,3 +1,3 @@


View File

@ -1,4 +1,4 @@
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Core.dll" #>
<#@ assembly name="System.Data.dll" #>
@ -27,13 +27,13 @@
<# foreach (var item in DbHelper.GetDbTablesNew(config.ConnectionString, config.DbDatabase,config.TableName))
{
var tableName=item.ToString();
manager.StartBlock(tableName+".cs",OutputPath1);//文件名
manager.StartBlock(tableName+".cs",OutputPath1);//文件名
#>
//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 <#=DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")#>
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 <#=DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")#>
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
using System;
using IRaCIS.Core.Domain.Share;
using System.ComponentModel.DataAnnotations;
@ -44,19 +44,15 @@ namespace IRaCIS.Core.Domain.Models
///<#=tableName#>
///</summary>
[Table("<#=tableName#>")]
public class <#=tableName#> : Entity, IAuditUpdate, IAuditAdd
public class <#=tableName#> : BaseFullAuditEntity
{
<# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){#>
/// <summary>
/// <#= column.Remark == "" ? column.ColumnName : column.Remark.Replace("\r\n"," ") #>
/// </summary>
<#
if(column.IsPrimaryKey)
{#>[Key]
<#}#><# if(!column.IsNullable) {#>[Required]
<# }#>public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; }
<#}#>
<# var excludedColumns = new[] { "CreateUserId", "Id", "UpdateUserId", "CreateTime", "UpdateTime", "DeleteUserId", "IsDeleted", "DeletedTime" };#>
<# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){ #>
<# if (!excludedColumns.Contains(column.ColumnName)){ #>
/// <summary> <#= column.Remark == "" ? column.ColumnName : column.Remark.Replace("\r\n"," ") #> </summary>
public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; }
<#}#>
<#}#>
}
public virtual DbSet<<#=tableName#>> <#=tableName#> { get; set; }

View File

@ -19,7 +19,7 @@ steps:
- name: build-uat-irc
commands:
- cd /opt/1panel/xc-deploy/Uat_IRC/devops-build-publish/Uat-To-Uat
- sh pull-build-uat-irc-image.sh v${DRONE_BUILD_NUMBER}
- sh uat-branch-latest-build-image-publish.sh v${DRONE_BUILD_NUMBER}
trigger:
branch: