Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
commit
9b91472186
|
@ -315,7 +315,7 @@ namespace IRaCIS.Core.SCP.Service
|
|||
_SCPStudyIdList.Add(scpStudyId);
|
||||
}
|
||||
|
||||
var series = await _seriesRepository.FindAsync(seriesId);
|
||||
var series = await _seriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
|
||||
|
||||
//没有缩略图
|
||||
if (series != null && string.IsNullOrEmpty(series.ImageResizePath))
|
||||
|
|
|
@ -75,9 +75,9 @@ namespace IRaCIS.Core.SCP.Service
|
|||
//using (@lock.Acquire())
|
||||
{
|
||||
var findPatient = await _patientRepository.FirstOrDefaultAsync(t => t.PatientIdStr == patientIdStr && t.TrialSiteId==trialSiteId );
|
||||
var findStudy = await _studyRepository.FindAsync(studyId);
|
||||
var findSerice = await _seriesRepository.FindAsync(seriesId);
|
||||
var findInstance = await _instanceRepository.FindAsync(instanceId);
|
||||
var findStudy = await _studyRepository.FirstOrDefaultAsync(t=>t.Id== studyId);
|
||||
var findSerice = await _seriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
|
||||
var findInstance = await _instanceRepository.FirstOrDefaultAsync(t => t.Id == instanceId);
|
||||
|
||||
DateTime? studyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.StudyDate).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.StudyTime).TimeOfDay);
|
||||
|
||||
|
@ -307,7 +307,7 @@ namespace IRaCIS.Core.SCP.Service
|
|||
await _instanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == instanceId, u => new SCPInstance() { Path = fileRelativePath,FileSize=fileSize });
|
||||
}
|
||||
|
||||
//await _studyRepository.SaveChangesAsync();
|
||||
await _studyRepository.SaveChangesAsync();
|
||||
|
||||
return findStudy.Id;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
<PackageReference Include="LogDashboard" Version="1.4.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
|
||||
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="2.1.2" />
|
||||
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.9.0" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -340,13 +340,10 @@
|
|||
序列化,反序列化的时候,处理时间 时区转换
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.NullToEmptyStringResolver.CreateProperties(System.Type,Newtonsoft.Json.MemberSerialization)">
|
||||
<member name="T:IRaCIS.Core.API.NullToEmptyStringResolver">
|
||||
<summary>
|
||||
创建属性
|
||||
LowerCamelCaseJsonAttribute 可以设置类小写返回给前端
|
||||
</summary>
|
||||
<param name="type">类型</param>
|
||||
<param name="memberSerialization">序列化成员</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
|
||||
<summary>
|
||||
|
|
|
@ -80,6 +80,7 @@ builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
|
|||
|
||||
//健康检查
|
||||
builder.Services.AddHealthChecks();
|
||||
builder.Services.AddSerilog();
|
||||
//本地化
|
||||
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");
|
||||
|
||||
|
@ -95,8 +96,11 @@ builder.Services.AddControllers(options =>
|
|||
})
|
||||
.AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化 处理
|
||||
|
||||
//动态WebApi + UnifiedApiResultFilter 省掉控制器代码
|
||||
// Panda动态WebApi + UnifiedApiResultFilter + 省掉控制器代码
|
||||
builder.Services.AddDynamicWebApiSetup();
|
||||
//MinimalAPI
|
||||
builder.Services.AddMasaMinimalAPIs();
|
||||
|
||||
//AutoMapper
|
||||
builder.Services.AddAutoMapperSetup();
|
||||
//EF ORM QueryWithNoLock
|
||||
|
@ -126,32 +130,8 @@ builder.Services.AddDicomSetup();
|
|||
// 实时应用
|
||||
builder.Services.AddSignalR();
|
||||
|
||||
//MinimalAPI
|
||||
builder.Services.AddMasaMinimalAPIs(options =>
|
||||
{
|
||||
options.Prefix = "";//自定义前缀 默认是api
|
||||
options.Version = ""; //默认是V1
|
||||
options.AutoAppendId = false; //路由是否自动附加参数Id 默认是true
|
||||
options.PluralizeServiceName = false; //服务名称是否启用复数
|
||||
|
||||
//options.Assemblies = new List<Assembly>() { typeof(UserSiteSurveySubmitedEventConsumer).Assembly };
|
||||
|
||||
options.GetPrefixes = new List<string> { "Get", "Select", "Find" };
|
||||
options.PostPrefixes = new List<string> { "Post", "Add", "Create", "List" };
|
||||
options.PutPrefixes = new List<string> { "Put", "Update" };
|
||||
options.DeletePrefixes = new List<string> { "Delete", "Remove" };
|
||||
|
||||
options.RouteHandlerBuilder= t=> {
|
||||
t.RequireAuthorization()
|
||||
.AddEndpointFilter<LimitUserRequestAuthorizationEndpointFilter>()
|
||||
//.AddEndpointFilter<ModelValidationEndpointFilter>()
|
||||
.AddEndpointFilter<UnifiedApiResultEndpointFilter>()
|
||||
.WithGroupName("Institution").DisableAntiforgery();
|
||||
};
|
||||
options.MapHttpMethodsForUnmatched = new string[] { "Post" };
|
||||
options.DisableTrimMethodPrefix = true; //禁用去除方法前缀
|
||||
options.DisableAutoMapRoute = false;//可通过配置true禁用全局自动路由映射或者删除此配置以启用全局自动路由映射
|
||||
});
|
||||
|
||||
//// 添加反伪造服务
|
||||
//builder.Services.AddAntiforgery(options =>
|
||||
|
@ -218,7 +198,7 @@ app.UseExceptionHandler(o => { });
|
|||
app.UseIRacisHostStaticFileStore(env);
|
||||
|
||||
//本地化
|
||||
await app.UseLocalization(app.Services);
|
||||
await app.UseLocalization(app.Services);
|
||||
|
||||
app.UseForwardedHeaders();
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
using IRaCIS.Core.API._PipelineExtensions.Serilog;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Serilog;
|
||||
using System.Linq;
|
||||
|
||||
namespace IRaCIS.Core.API
|
||||
{
|
||||
|
@ -17,8 +20,66 @@ namespace IRaCIS.Core.API
|
|||
app.UseSerilogRequestLogging(opts
|
||||
=>
|
||||
{
|
||||
opts.MessageTemplate = "{TokenUserRealName} {TokenUserTypeShortName} {ClientIp} {LocalIP} {Host} {Protocol} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
|
||||
opts.EnrichDiagnosticContext = SerilogHelper.EnrichFromRequest;
|
||||
|
||||
opts.MessageTemplate = "{FullName} {UserType} {UserIp} {Host} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";
|
||||
|
||||
opts.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
|
||||
{
|
||||
|
||||
var request = httpContext.Request;
|
||||
|
||||
// Set all the common properties available for every request
|
||||
diagnosticContext.Set("Host", request.Host.Value);
|
||||
|
||||
|
||||
// Only set it if available. You're not sending sensitive data in a querystring right?!
|
||||
if (request.QueryString.HasValue)
|
||||
{
|
||||
diagnosticContext.Set("QueryString", request.QueryString.Value);
|
||||
}
|
||||
|
||||
diagnosticContext.Set("FullName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.RealName)?.Value);
|
||||
|
||||
diagnosticContext.Set("UserType", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value);
|
||||
|
||||
var clientIp = httpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault() ??
|
||||
httpContext.Connection.RemoteIpAddress?.ToString();
|
||||
|
||||
if (clientIp.StartsWith("::ffff:"))
|
||||
{
|
||||
clientIp = clientIp.Substring(7); // 移除前缀
|
||||
}
|
||||
|
||||
diagnosticContext.Set("UserIp", clientIp);
|
||||
|
||||
#region 非必要不记录
|
||||
//diagnosticContext.Set("Protocol", request.Protocol);
|
||||
//diagnosticContext.Set("Scheme", request.Scheme);
|
||||
//// Retrieve the IEndpointFeature selected for the request
|
||||
//var endpoint = httpContext.GetEndpoint();
|
||||
//if (endpoint is object) // endpoint != null
|
||||
//{
|
||||
// diagnosticContext.Set("EndpointName", endpoint.DisplayName);
|
||||
//}
|
||||
// Set the content-type of the Response at this point
|
||||
//diagnosticContext.Set("ContentType", httpContext.Response.ContentType);
|
||||
#endregion
|
||||
|
||||
|
||||
#region old 未用
|
||||
//这种获取的Ip不准 配置服务才行
|
||||
//diagnosticContext.Set("RequestIP", httpContext.Connection.RemoteIpAddress.ToString());
|
||||
|
||||
//这种方式可以,但是serilog提供了 就不用了
|
||||
//diagnosticContext.Set("TestIP", httpContext.GetUserIp());
|
||||
|
||||
//这种方式不行 读取的body为空字符串 必须在中间件中读取
|
||||
//diagnosticContext.Set("RequestBody", await ReadRequestBody(httpContext.Request));
|
||||
//diagnosticContext.Set("RequestBody", RequestPayload);
|
||||
#endregion
|
||||
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
using IRaCIS.Core.Domain.Share;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Serilog;
|
||||
|
||||
namespace IRaCIS.Core.API
|
||||
{
|
||||
public class SerilogHelper
|
||||
{
|
||||
//public static string RequestPayload = "";
|
||||
|
||||
public static void EnrichFromRequest(IDiagnosticContext diagnosticContext, HttpContext httpContext)
|
||||
{
|
||||
var request = httpContext.Request;
|
||||
|
||||
// Set all the common properties available for every request
|
||||
diagnosticContext.Set("Host", request.Host);
|
||||
|
||||
diagnosticContext.Set("Protocol", request.Protocol);
|
||||
diagnosticContext.Set("Scheme", request.Scheme);
|
||||
|
||||
#region old 未用
|
||||
//这种获取的Ip不准 配置服务才行
|
||||
//diagnosticContext.Set("RequestIP", httpContext.Connection.RemoteIpAddress.ToString());
|
||||
|
||||
//这种方式可以,但是serilog提供了 就不用了
|
||||
//diagnosticContext.Set("TestIP", httpContext.GetUserIp());
|
||||
|
||||
//这种方式不行 读取的body为空字符串 必须在中间件中读取
|
||||
//diagnosticContext.Set("RequestBody", await ReadRequestBody(httpContext.Request));
|
||||
//diagnosticContext.Set("RequestBody", RequestPayload);
|
||||
#endregion
|
||||
|
||||
// Only set it if available. You're not sending sensitive data in a querystring right?!
|
||||
if (request.QueryString.HasValue)
|
||||
{
|
||||
diagnosticContext.Set("QueryString", request.QueryString.Value);
|
||||
}
|
||||
|
||||
// Set the content-type of the Response at this point
|
||||
diagnosticContext.Set("ContentType", httpContext.Response.ContentType);
|
||||
|
||||
diagnosticContext.Set("TokenUserRealName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.RealName)?.Value);
|
||||
|
||||
diagnosticContext.Set("TokenUserTypeShortName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value);
|
||||
|
||||
// Retrieve the IEndpointFeature selected for the request
|
||||
var endpoint = httpContext.GetEndpoint();
|
||||
if (endpoint is object) // endpoint != null
|
||||
{
|
||||
diagnosticContext.Set("EndpointName", endpoint.DisplayName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,9 +1,13 @@
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using IRaCIS.Core.Application.Service.BusinessFilter;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Panda.DynamicWebApi;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace IRaCIS.Core.API
|
||||
{
|
||||
public static class DynamicWebApiSetup
|
||||
public static class WebApiSetup
|
||||
{
|
||||
//20210910 避免冗余的控制器层代码编写,仅仅包了一层前后台定义的格式 这里采用动态webAPi+IResultFilter 替代大部分情况
|
||||
public static void AddDynamicWebApiSetup(this IServiceCollection services)
|
||||
|
@ -20,5 +24,37 @@ namespace IRaCIS.Core.API
|
|||
|
||||
});
|
||||
}
|
||||
|
||||
public static void AddMasaMinimalAPiSetUp(this IServiceCollection services)
|
||||
{
|
||||
services.AddMasaMinimalAPIs(options =>
|
||||
{
|
||||
options.Prefix = "";//自定义前缀 默认是api
|
||||
options.Version = ""; //默认是V1
|
||||
options.AutoAppendId = false; //路由是否自动附加参数Id 默认是true
|
||||
options.PluralizeServiceName = false; //服务名称是否启用复数
|
||||
|
||||
//options.Assemblies = new List<Assembly>() { typeof(UserSiteSurveySubmitedEventConsumer).Assembly };
|
||||
|
||||
options.GetPrefixes = new List<string> { "Get", "Select", "Find" };
|
||||
options.PostPrefixes = new List<string> { "Post", "Add", "Create", "List" };
|
||||
options.PutPrefixes = new List<string> { "Put", "Update" };
|
||||
options.DeletePrefixes = new List<string> { "Delete", "Remove" };
|
||||
|
||||
options.RouteHandlerBuilder = t => {
|
||||
t.RequireAuthorization()
|
||||
.AddEndpointFilter<LimitUserRequestAuthorizationEndpointFilter>()
|
||||
//.AddEndpointFilter<ModelValidationEndpointFilter>()
|
||||
.AddEndpointFilter<UnifiedApiResultEndpointFilter>()
|
||||
.WithGroupName("Institution").DisableAntiforgery();
|
||||
};
|
||||
options.MapHttpMethodsForUnmatched = new string[] { "Post" };
|
||||
options.DisableTrimMethodPrefix = true; //禁用去除方法前缀
|
||||
options.DisableAutoMapRoute = false;//可通过配置true禁用全局自动路由映射或者删除此配置以启用全局自动路由映射
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@ namespace IRaCIS.Core.API
|
|||
//迁移的时候,不生成外键
|
||||
options.ReplaceService<IMigrationsSqlGenerator, NoForeignKeyMigrationsSqlGenerator>();
|
||||
|
||||
|
||||
options.UseLoggerFactory(logFactory);
|
||||
|
||||
options.UseExceptionProcessor();
|
||||
|
@ -63,10 +62,6 @@ namespace IRaCIS.Core.API
|
|||
|
||||
options.UseProjectables();
|
||||
|
||||
//options.AddInterceptors(new AuditingInterceptor(configuration.GetSection("ConnectionStrings:RemoteNew").Value));
|
||||
|
||||
//options.UseTriggers(triggerOptions => triggerOptions.AddTrigger<SubjectVisitImageDateTrigger>());
|
||||
|
||||
//options.UseTriggers(triggerOptions => triggerOptions.AddAssemblyTriggers(typeof(SubjectVisitTrigger).Assembly));
|
||||
|
||||
|
||||
|
@ -84,13 +79,7 @@ namespace IRaCIS.Core.API
|
|||
|
||||
triggerOptions.AddTrigger<UserLogTrigger>();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
// Register an additional context factory as a Scoped service, which gets a pooled context from the Singleton factory we registered above,
|
||||
|
|
|
@ -14,7 +14,6 @@ namespace IRaCIS.Core.API
|
|||
public static void AddMassTransitSetup(this IServiceCollection services)
|
||||
{
|
||||
|
||||
|
||||
#region MassTransit
|
||||
//masstransit组件 也支持MediatR 中介者模式,但是支持分布式,考虑后续,所以在次替代MediatR
|
||||
//参考链接:https://masstransit.io/documentation/concepts/mediator#scoped-mediator
|
||||
|
|
|
@ -124,4 +124,75 @@ namespace IRaCIS.Core.API
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region 废弃
|
||||
|
||||
public class MyDateTimeConverter : JsonConverter<DateTime>
|
||||
{
|
||||
public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
return reader.ReadAsDateTime().Value;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
|
||||
{
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
string dateFormat;
|
||||
if (!isEn_US)
|
||||
{
|
||||
// Chinese date format
|
||||
dateFormat = "yyyy-MM-dd HH:mm:ss";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default or English date format
|
||||
dateFormat = "MM/dd/yyyy HH:mm:ss";
|
||||
}
|
||||
|
||||
writer.WriteValue(value.ToString(dateFormat));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class MyNullableDateTimeConverter : JsonConverter<DateTime?>
|
||||
{
|
||||
public override DateTime? ReadJson(JsonReader reader, Type objectType, DateTime? existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
var val = reader.ReadAsDateTime();
|
||||
return val;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, DateTime? value, JsonSerializer serializer)
|
||||
{
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
string dateFormat;
|
||||
if (!isEn_US)
|
||||
{
|
||||
// Chinese date format
|
||||
dateFormat = "yyyy-MM-dd HH:mm:ss";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default or English date format
|
||||
dateFormat = "MM/dd/yyyy HH:mm:ss";
|
||||
}
|
||||
|
||||
if (value.HasValue)
|
||||
{
|
||||
writer.WriteValue(value.Value.ToString(dateFormat));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteValue(default(DateTime?));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
using IRaCIS.Core.Domain.Share;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace IRaCIS.Core.API
|
||||
{
|
||||
|
||||
|
||||
//public class CustomContractResolver : DefaultContractResolver
|
||||
//{
|
||||
// protected override JsonContract CreateContract(Type objectType)
|
||||
// {
|
||||
// var contract = base.CreateContract(objectType);
|
||||
|
||||
// // 检查类是否有 LowercaseJsonAttribute 标记
|
||||
// if (objectType.GetCustomAttribute<LowerCamelCaseJsonAttribute>() != null)
|
||||
// {
|
||||
// contract.NamingStrategy = new IRCCamelCaseNamingStrategy();
|
||||
// }
|
||||
|
||||
// return contract;
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
#region 废弃
|
||||
|
||||
public class MyDateTimeConverter : JsonConverter<DateTime>
|
||||
{
|
||||
public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
return reader.ReadAsDateTime().Value;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
|
||||
{
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
string dateFormat;
|
||||
if (!isEn_US)
|
||||
{
|
||||
// Chinese date format
|
||||
dateFormat = "yyyy-MM-dd HH:mm:ss";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default or English date format
|
||||
dateFormat = "MM/dd/yyyy HH:mm:ss";
|
||||
}
|
||||
|
||||
writer.WriteValue(value.ToString(dateFormat));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class MyNullableDateTimeConverter : JsonConverter<DateTime?>
|
||||
{
|
||||
public override DateTime? ReadJson(JsonReader reader, Type objectType, DateTime? existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
var val = reader.ReadAsDateTime();
|
||||
return val;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, DateTime? value, JsonSerializer serializer)
|
||||
{
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
string dateFormat;
|
||||
if (!isEn_US)
|
||||
{
|
||||
// Chinese date format
|
||||
dateFormat = "yyyy-MM-dd HH:mm:ss";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default or English date format
|
||||
dateFormat = "MM/dd/yyyy HH:mm:ss";
|
||||
}
|
||||
|
||||
if (value.HasValue)
|
||||
{
|
||||
writer.WriteValue(value.Value.ToString(dateFormat));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteValue(default(DateTime?));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
|
@ -22,13 +22,6 @@ namespace IRaCIS.Core.API
|
|||
builder.AddNewtonsoftJson(options =>
|
||||
{
|
||||
|
||||
//大驼峰
|
||||
//options.SerializerSettings.ContractResolver = new DefaultContractResolver();
|
||||
//小驼峰
|
||||
//options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
||||
|
||||
|
||||
|
||||
// 忽略循环引用
|
||||
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
||||
|
||||
|
@ -40,10 +33,18 @@ namespace IRaCIS.Core.API
|
|||
|
||||
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
|
||||
|
||||
#region 废弃
|
||||
//大驼峰
|
||||
//options.SerializerSettings.ContractResolver = new DefaultContractResolver();
|
||||
//小驼峰
|
||||
//options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
||||
|
||||
|
||||
|
||||
//二者只能取其一
|
||||
//options.SerializerSettings.Converters.Add(new MyDateTimeConverter());
|
||||
//options.SerializerSettings.Converters.Add(new MyNullableDateTimeConverter());
|
||||
#endregion
|
||||
|
||||
//必须放在后面
|
||||
options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService<JSONTimeZoneConverter>());
|
||||
|
@ -55,6 +56,7 @@ namespace IRaCIS.Core.API
|
|||
{
|
||||
o.SuppressModelStateInvalidFilter = true; //自己写验证
|
||||
|
||||
#region 废弃验证
|
||||
////这里是自定义验证结果和返回状态码 因为这里是在[ApiController]控制器层校验,动态webApi的不会校验 所以需要单独写一个Filter
|
||||
//o.InvalidModelStateResponseFactory = (context) =>
|
||||
//{
|
||||
|
@ -65,7 +67,7 @@ namespace IRaCIS.Core.API
|
|||
|
||||
//return new JsonResult(ResponseOutput.NotOk("The inputs supplied to the API are invalid. " + JsonConvert.SerializeObject( error)));
|
||||
//};
|
||||
|
||||
#endregion
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -8,27 +8,11 @@ using System.Reflection;
|
|||
|
||||
namespace IRaCIS.Core.API
|
||||
{
|
||||
/// <summary>
|
||||
/// LowerCamelCaseJsonAttribute 可以设置类小写返回给前端
|
||||
/// </summary>
|
||||
public class NullToEmptyStringResolver : DefaultContractResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建属性
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
/// <param name="memberSerialization">序列化成员</param>
|
||||
/// <returns></returns>
|
||||
//protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
|
||||
//{
|
||||
// IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
|
||||
|
||||
|
||||
// foreach (var jsonProperty in properties)
|
||||
// {
|
||||
// jsonProperty.DefaultValue = new NullToEmptyStringValueProvider(jsonProperty);
|
||||
// }
|
||||
|
||||
// return properties;
|
||||
|
||||
//}
|
||||
|
||||
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
|
||||
{
|
||||
|
@ -65,4 +49,37 @@ namespace IRaCIS.Core.API
|
|||
|
||||
|
||||
}
|
||||
public class NullToEmptyStringValueProvider : IValueProvider
|
||||
{
|
||||
PropertyInfo _MemberInfo;
|
||||
public NullToEmptyStringValueProvider(PropertyInfo memberInfo)
|
||||
{
|
||||
_MemberInfo = memberInfo;
|
||||
}
|
||||
public object GetValue(object target)
|
||||
{
|
||||
object result = _MemberInfo.GetValue(target);
|
||||
if (_MemberInfo.PropertyType == typeof(string) && result == null) result = "";
|
||||
else if (_MemberInfo.PropertyType == typeof(String[]) && result == null) result = new string[] { };
|
||||
//else if (_MemberInfo.PropertyType == typeof(Nullable<Int32>) && result == null) result = 0;
|
||||
//else if (_MemberInfo.PropertyType == typeof(Nullable<Decimal>) && result == null) result = 0.00M;
|
||||
|
||||
return result;
|
||||
}
|
||||
public void SetValue(object target, object value)
|
||||
{
|
||||
|
||||
if (_MemberInfo.PropertyType == typeof(string))
|
||||
{
|
||||
//去掉前后空格
|
||||
_MemberInfo.SetValue(target, value == null ? string.Empty : value.ToString() == string.Empty ? value : value/*.ToString().Trim()*/);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
_MemberInfo.SetValue(target, value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace IRaCIS.Core.API
|
||||
{
|
||||
|
||||
public class NullToEmptyStringValueProvider : IValueProvider
|
||||
{
|
||||
PropertyInfo _MemberInfo;
|
||||
public NullToEmptyStringValueProvider(PropertyInfo memberInfo)
|
||||
{
|
||||
_MemberInfo = memberInfo;
|
||||
}
|
||||
public object GetValue(object target)
|
||||
{
|
||||
object result = _MemberInfo.GetValue(target);
|
||||
if (_MemberInfo.PropertyType == typeof(string) && result == null) result = "";
|
||||
else if (_MemberInfo.PropertyType == typeof(String[]) && result == null) result = new string[] { };
|
||||
//else if (_MemberInfo.PropertyType == typeof(Nullable<Int32>) && result == null) result = 0;
|
||||
else if (_MemberInfo.PropertyType == typeof(Nullable<Decimal>) && result == null) result = 0.00M;
|
||||
|
||||
return result;
|
||||
}
|
||||
public void SetValue(object target, object value)
|
||||
{
|
||||
|
||||
if (_MemberInfo.PropertyType == typeof(string))
|
||||
{
|
||||
//去掉前后空格
|
||||
_MemberInfo.SetValue(target, value == null ? string.Empty : value.ToString() == string.Empty ? value : value/*.ToString().Trim()*/);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
_MemberInfo.SetValue(target, value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Serilog;
|
||||
using Serilog.Configuration;
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
|
||||
namespace IRaCIS.Core.API
|
||||
{
|
||||
public static class EnricherExtensions
|
||||
{
|
||||
public static LoggerConfiguration WithHttpContextInfo(this LoggerEnrichmentConfiguration enrich, IServiceProvider serviceProvider)
|
||||
{
|
||||
if (enrich == null)
|
||||
throw new ArgumentNullException(nameof(enrich));
|
||||
|
||||
return enrich.With(new HttpContextEnricher(serviceProvider));
|
||||
}
|
||||
public static LoggerConfiguration WithHttpContextInfo(this LoggerEnrichmentConfiguration enrich, IServiceProvider serviceProvider, Action<LogEvent, ILogEventPropertyFactory, HttpContext> enrichAction)
|
||||
{
|
||||
if (enrich == null)
|
||||
throw new ArgumentNullException(nameof(enrich));
|
||||
|
||||
return enrich.With(new HttpContextEnricher(serviceProvider, enrichAction));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
using IRaCIS.Core.Domain.Share;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.API
|
||||
{
|
||||
public class HttpContextEnricher : ILogEventEnricher
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly Action<LogEvent, ILogEventPropertyFactory, HttpContext> _enrichAction;
|
||||
|
||||
public HttpContextEnricher(IServiceProvider serviceProvider) : this(serviceProvider, null)
|
||||
{ }
|
||||
|
||||
public HttpContextEnricher(IServiceProvider serviceProvider, Action<LogEvent, ILogEventPropertyFactory, HttpContext> enrichAction)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
if (enrichAction == null)
|
||||
{
|
||||
_enrichAction = (logEvent, propertyFactory, httpContext) =>
|
||||
{
|
||||
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestIP", httpContext.Connection.RemoteIpAddress.ToString()));
|
||||
|
||||
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("LocalIP", httpContext.Connection.LocalIpAddress.MapToIPv4().ToString()));
|
||||
|
||||
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("TokenUserRealName", httpContext?.User?.FindFirst(ClaimAttributes.RealName)?.Value));
|
||||
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("TokenUserType", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value));
|
||||
|
||||
|
||||
//这样读取没用
|
||||
//logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestBody", await ReadRequestBody(httpContext.Request)));
|
||||
//logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestIP", IPHelper.GetIP(httpContext.Request) ));
|
||||
//logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Referer", httpContext.Request.Headers["Referer"].ToString()));
|
||||
//logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("request_path", httpContext.Request.Path));
|
||||
//logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("request_method", httpContext.Request.Method));
|
||||
//if (httpContext.Response.HasStarted)
|
||||
//{
|
||||
// logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("response_status", httpContext.Response.StatusCode));
|
||||
//}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
_enrichAction = enrichAction;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
|
||||
{
|
||||
var httpContext = _serviceProvider.GetService<IHttpContextAccessor>()?.HttpContext;
|
||||
if (null != httpContext)
|
||||
{
|
||||
_enrichAction.Invoke(logEvent, propertyFactory, httpContext);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> ReadRequestBody(HttpRequest request)
|
||||
{
|
||||
// Ensure the request's body can be read multiple times (for the next middlewares in the pipeline).
|
||||
request.EnableBuffering();
|
||||
|
||||
using var streamReader = new StreamReader(request.Body, leaveOpen: true);
|
||||
var requestBody = await streamReader.ReadToEndAsync();
|
||||
|
||||
// Reset the request's body stream position for next middleware in the pipeline.
|
||||
request.Body.Position = 0;
|
||||
return requestBody == null ? String.Empty : requestBody.Trim();
|
||||
}
|
||||
|
||||
private async Task<string> ReadResponseBody(HttpResponse response)
|
||||
{
|
||||
response.Body.Seek(0, SeekOrigin.Begin);
|
||||
string responseBody = await new StreamReader(response.Body).ReadToEndAsync();
|
||||
response.Body.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
return $"{responseBody}";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
using Serilog;
|
||||
using DocumentFormat.OpenXml.Bibliography;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using Serilog.Formatting.Compact;
|
||||
|
||||
//using Serilog.Sinks.Email;
|
||||
using System;
|
||||
|
||||
|
@ -16,18 +19,34 @@ namespace IRaCIS.Core.API
|
|||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
||||
// Filter out ASP.NET Core infrastructre logs that are Information and below 日志太多了 一个请求 记录好几条
|
||||
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
|
||||
.MinimumLevel.Override("Microsoft.AspNetCore.Hosting", LogEventLevel.Warning)
|
||||
.MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Warning)
|
||||
.MinimumLevel.Override("Microsoft.AspNetCore.Routing", LogEventLevel.Warning)
|
||||
.MinimumLevel.Override("Hangfire", LogEventLevel.Warning)
|
||||
.MinimumLevel.Override("System.Net.Http.HttpClient.HttpReports", LogEventLevel.Warning)
|
||||
.Enrich.WithClientIp()
|
||||
//如果有反向代理并不会获取到用户的真实IP
|
||||
//.Enrich.WithClientIp()
|
||||
//.Enrich.WithRequestHeader("User-Agent")
|
||||
.Enrich.FromLogContext()
|
||||
.Filter.ByExcluding(logEvent => logEvent.Properties.ContainsKey("RequestPath") && logEvent.Properties["RequestPath"].ToString().Contains("/health"))
|
||||
|
||||
//控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型
|
||||
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning,
|
||||
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}")
|
||||
//https://github.com/serilog/serilog-formatting-compact
|
||||
|
||||
.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day,
|
||||
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}");
|
||||
.WriteTo.Console()
|
||||
.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day);
|
||||
//// 控制台输出 JSON 格式
|
||||
//.WriteTo.Console(formatter: new CompactJsonFormatter(), LogEventLevel.Warning),
|
||||
//// 文件输出 JSON 格式
|
||||
//.WriteTo.File(new CompactJsonFormatter(), $"{AppContext.BaseDirectory}Serilogs/.json", rollingInterval: RollingInterval.Day);
|
||||
|
||||
////控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型
|
||||
//.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning,
|
||||
// outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {ClientIp} {SourceContext:l} || {Message} || {Exception} ||end {NewLine}")
|
||||
|
||||
//.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day,
|
||||
// outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {ClientIp} {SourceContext:l} || {Message} || {Exception} ||end {NewLine}");
|
||||
|
||||
|
||||
Log.Logger = config.CreateLogger();
|
||||
|
||||
//.WriteTo.MSSqlServer("Data Source=DESKTOP-4TU9A6M;Initial Catalog=CoreFrame;User ID=sa;Password=123456", "logs", autoCreateSqlTable: true, restrictedToMinimumLevel: LogEventLevel.Information)//从左至右四个参数分别是数据库连接字符串、表名、如果表不存在是否创建、最低等级。Serilog会默认创建一些列。
|
||||
|
||||
|
@ -46,7 +65,7 @@ namespace IRaCIS.Core.API
|
|||
//}
|
||||
|
||||
//扩展方法 获取上下文的ip 用户名 用户类型
|
||||
Log.Logger = config.Enrich.WithHttpContextInfo(serviceProvider).CreateLogger();
|
||||
//Log.Logger = config.Enrich.WithHttpContextInfo(serviceProvider).CreateLogger();
|
||||
}
|
||||
|
||||
}
|
|
@ -57,6 +57,7 @@ public class ProjectExceptionFilter(ILogger<ProjectExceptionFilter> _logger, ISt
|
|||
|
||||
_logger.LogError(errorInfo);
|
||||
|
||||
//_logger.LogError(exception, exception.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1164,6 +1164,13 @@
|
|||
添加/更新 医生基本信息 BasicInfo
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.DoctorService.AddOrUpdateDoctorBasicInfoAndEmployment(IRaCIS.Application.Contracts.BasicInfoAndEmploymentDto)">
|
||||
<summary>
|
||||
新增修改 医生基本信息和工作
|
||||
</summary>
|
||||
<param name="indto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.DoctorService.GetBasicInfo(System.Guid)">
|
||||
<summary>
|
||||
详情、编辑-获取 医生基本信息 BasicInfo
|
||||
|
@ -12941,7 +12948,7 @@
|
|||
用户提交 发送邮件 通知SPM 或者PM
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.MassTransit.Consumer.UserSiteSurveySubmitedEventConsumer.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSite},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteSurvey},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeConfig},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig})">
|
||||
<member name="M:IRaCIS.Core.Application.MassTransit.Consumer.UserSiteSurveySubmitedEventConsumer.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSite},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteSurvey},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeConfig},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig})">
|
||||
<summary>
|
||||
用户提交 发送邮件 通知SPM 或者PM
|
||||
</summary>
|
||||
|
@ -12951,7 +12958,7 @@
|
|||
调研表初审通过,进行复审发送邮件
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.MassTransit.Consumer.SiteSurveySPMSubmitedEventConsumer.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSite},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteSurvey},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeConfig},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig})">
|
||||
<member name="M:IRaCIS.Core.Application.MassTransit.Consumer.SiteSurveySPMSubmitedEventConsumer.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSite},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteSurvey},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeConfig},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig})">
|
||||
<summary>
|
||||
调研表初审通过,进行复审发送邮件
|
||||
</summary>
|
||||
|
@ -12961,14 +12968,19 @@
|
|||
调研表驳回发送邮件 之前已有,需要迁移过来
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.MassTransit.Consumer.SiteSurverRejectedEventConsumer.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.User},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSite},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteSurvey},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeConfig},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig})">
|
||||
<member name="M:IRaCIS.Core.Application.MassTransit.Consumer.SiteSurverRejectedEventConsumer.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSite},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSiteSurvey},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeConfig},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig})">
|
||||
<summary>
|
||||
调研表驳回发送邮件 之前已有,需要迁移过来
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Core.Application.MassTransit.Consumer.CRCSubmitedAndQCToAuditEventConsumer">
|
||||
<summary>
|
||||
CRC 提交了 通知QC进行质控
|
||||
CRC 提交了 通知QC进行质控 Code005,006
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.MassTransit.Consumer.CRCSubmitedAndQCToAuditEventConsumer.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.User},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialUser},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Dictionary},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.EmailNoticeConfig},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.SystemEmailSendConfig})">
|
||||
<summary>
|
||||
CRC 提交了 通知QC进行质控 Code005,006
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Core.Application.MassTransit.Consumer.CRCRepliedQCChallengeEventConsumer">
|
||||
|
@ -16799,6 +16811,36 @@
|
|||
入组 Selection 列表查询参数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Application.Contracts.DoctorBasicInfo.WorkPartTime">
|
||||
<summary>
|
||||
工作兼职
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Application.Contracts.DoctorBasicInfo.WorkPartTimeEn">
|
||||
<summary>
|
||||
工作兼职En
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Application.Contracts.BasicInfoAndEmploymentDto.WorkPartTime">
|
||||
<summary>
|
||||
工作兼职
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Application.Contracts.BasicInfoAndEmploymentDto.WorkPartTimeEn">
|
||||
<summary>
|
||||
工作兼职En
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Application.Contracts.EmploymentInfo.WorkPartTime">
|
||||
<summary>
|
||||
工作兼职
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Application.Contracts.EmploymentInfo.WorkPartTimeEn">
|
||||
<summary>
|
||||
工作兼职En
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Application.Contracts.AddDoctorCriterionFileDto.FileName">
|
||||
<summary>
|
||||
文件名称
|
||||
|
|
|
@ -12,6 +12,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -96,13 +97,14 @@ public class UrgentMedicalReviewAddedEventConsumer(
|
|||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
|
||||
var subjectName = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectName, taskInfo.TaskBlindName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
criterion.CriterionName, // 阅片标准 {2}
|
||||
taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode, // 受试者 {3}
|
||||
subjectName, // 受试者 {3}
|
||||
taskInfo.TaskBlindName, // 访视 {4}
|
||||
dictionValue[0], // 任务类型 {5}
|
||||
//dictionValue[1], // 阅片人是否同意 {6}
|
||||
|
@ -196,13 +198,14 @@ public class UrgentIRRepliedMedicalReviewConsumer(
|
|||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
|
||||
var subjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
criterion.CriterionName, // 阅片标准 {2}
|
||||
taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode, // 受试者 {3}
|
||||
subjectCode, // 受试者 {3}
|
||||
taskInfo.TaskBlindName, // 访视 {4}
|
||||
dictionValue[0], // 任务类型 {5}
|
||||
dictionValue[1], // 阅片人是否同意 {6}
|
||||
|
@ -309,12 +312,13 @@ public class UrgentMIMRepliedMedicalReviewConsumer(
|
|||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
|
||||
var subjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode, // 受试者 {2}
|
||||
subjectCode, // 受试者 {2}
|
||||
taskInfo.TaskBlindName, // 访视 {3}
|
||||
criterion.CriterionName, // 阅片标准 {4}
|
||||
dictionValue[0], // 任务类型 {5}
|
||||
|
@ -357,7 +361,7 @@ public class UrgentIRApplyedReReadingConsumer(
|
|||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||
public async Task Consume(ConsumeContext<UrgentApplyedReReading> context)
|
||||
{
|
||||
Console.WriteLine("发送(024,25) 【加急医学反馈】邮件!!!");
|
||||
Console.WriteLine("发送(024,025) 【加急医学反馈】邮件!!!");
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
var visitTaskId = context.Message.VisitTaskId;
|
||||
|
@ -407,12 +411,13 @@ public class UrgentIRApplyedReReadingConsumer(
|
|||
|
||||
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
{
|
||||
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
|
||||
var subjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode;
|
||||
var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
||||
var htmlBodyStr = string.Format(
|
||||
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
userinfo.FullName, // 用户名 {0}
|
||||
trialInfo.ExperimentName, // 项目 {1}
|
||||
taskInfo.BlindSubjectCode.IsNullOrEmpty() ? taskInfo.Subject.Code : taskInfo.BlindSubjectCode, // 受试者 {2}
|
||||
subjectCode, // 受试者 {2}
|
||||
taskInfo.TaskBlindName, // 访视 {3}
|
||||
dictionValue[0], // 任务类型 {4}
|
||||
doctorInfo.FullName, // 阅片人 {5}
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
|||
public class UserSiteSurveySubmitedEventConsumer(
|
||||
IRepository<Trial> _trialRepository,
|
||||
IRepository<TrialSite> _trialSiteRepository,
|
||||
IRepository<TrialUser> _trialUserRepository,
|
||||
IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
|
||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig
|
||||
|
@ -46,7 +47,7 @@ public class UserSiteSurveySubmitedEventConsumer(
|
|||
|
||||
var trialId = siteSurveyInfo.TrialId;
|
||||
|
||||
var trialUserList = await _trialSiteSurveyRepository.Where(t => t.TrialId == siteSurveyInfo.TrialId).SelectMany(t => t.Trial.TrialUserList)
|
||||
var trialUserList = await _trialUserRepository.Where(t => t.TrialId == siteSurveyInfo.TrialId)
|
||||
.Where(t => t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM || t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM)
|
||||
.Select(t => new { t.User.FullName, t.User.EMail, t.User.UserTypeEnum }).ToListAsync();
|
||||
|
||||
|
@ -124,6 +125,7 @@ public class UserSiteSurveySubmitedEventConsumer(
|
|||
/// </summary>
|
||||
public class SiteSurveySPMSubmitedEventConsumer(
|
||||
IRepository<Trial> _trialRepository,
|
||||
IRepository<TrialUser> _trialUserRepository,
|
||||
IRepository<TrialSite> _trialSiteRepository,
|
||||
IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
|
||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
||||
|
@ -143,8 +145,7 @@ public class SiteSurveySPMSubmitedEventConsumer(
|
|||
|
||||
var messageToSend = new MimeMessage();
|
||||
|
||||
var trialUserList = _trialRepository.Where(t => t.Id == trialId)
|
||||
.SelectMany(t => t.TrialUserList)
|
||||
var trialUserList = _trialUserRepository.Where(t => t.TrialId == trialId)
|
||||
.Where(t => t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM || t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM)
|
||||
.Select(t => new { t.User.EMail, t.User.FullName, t.User.UserTypeEnum }).ToList();
|
||||
|
||||
|
@ -199,7 +200,7 @@ public class SiteSurveySPMSubmitedEventConsumer(
|
|||
/// 调研表驳回发送邮件 之前已有,需要迁移过来
|
||||
/// </summary>
|
||||
public class SiteSurverRejectedEventConsumer(
|
||||
IRepository<User> _userRepository,
|
||||
IRepository<TrialUser> _trialUserRepository,
|
||||
IRepository<Trial> _trialRepository,
|
||||
IRepository<TrialSite> _trialSiteRepository,
|
||||
IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
|
||||
|
@ -232,8 +233,7 @@ public class SiteSurverRejectedEventConsumer(
|
|||
|
||||
//name = user.FullName;
|
||||
|
||||
var sPMOrCPMList = _trialRepository.Where(t => t.Id == trialId)
|
||||
.SelectMany(t => t.TrialUserList)
|
||||
var sPMOrCPMList = _trialUserRepository.Where(t => t.TrialId == trialId)
|
||||
.Where(t => t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM)
|
||||
.Select(t => new { t.User.EMail, t.User.FullName, t.User.UserTypeEnum }).ToList();
|
||||
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
using IRaCIS.Core.Application.MassTransit.Command;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Domain;
|
||||
using IRaCIS.Core.Domain.BaseModel;
|
||||
using IRaCIS.Core.Infra.EFCore.Common;
|
||||
using MassTransit;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MimeKit;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -12,13 +17,93 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
|||
|
||||
|
||||
/// <summary>
|
||||
/// CRC 提交了 通知QC进行质控
|
||||
/// CRC 提交了 通知QC进行质控 Code005,006
|
||||
/// </summary>
|
||||
public class CRCSubmitedAndQCToAuditEventConsumer : IConsumer<CRCSubmitedAndQCToAuditEvent>
|
||||
public class CRCSubmitedAndQCToAuditEventConsumer(
|
||||
IRepository<User> _userRepository,
|
||||
IRepository<TrialUser> _trialUseRepository,
|
||||
IRepository<SubjectVisit> _subjectVisitRepository,
|
||||
IRepository<Trial> _trialRepository,
|
||||
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
||||
IRepository<VisitTask> _visitTaskRepository,
|
||||
IRepository<Dictionary> _dictionaryRepository,
|
||||
IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
|
||||
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<CRCSubmitedAndQCToAuditEvent>
|
||||
{
|
||||
public Task Consume(ConsumeContext<CRCSubmitedAndQCToAuditEvent> context)
|
||||
private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
|
||||
public async Task Consume(ConsumeContext<CRCSubmitedAndQCToAuditEvent> context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
//Console.WriteLine("发送(005,006) 【加急项目所有IQC待领取质控任务】邮件!!!");
|
||||
//var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
//var subjectVisitId = context.Message.SubjectVisitId;
|
||||
|
||||
//var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Include(x=>x.Subject).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//var trialUser = await _trialUseRepository.Where(x => x.TrialId == subjectVisit.TrialId).Include(x => x.User).Select(x => x.User).ToListAsync();
|
||||
|
||||
//var userinfoList = trialUser.Where(x => x.UserTypeEnum == UserTypeEnum.IQC).ToList();
|
||||
|
||||
|
||||
//var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == subjectVisit.TrialId);
|
||||
|
||||
//foreach (var userinfo in userinfoList)
|
||||
//{
|
||||
// var messageToSend = new MimeMessage();
|
||||
// //发件地址
|
||||
// messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
|
||||
// messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.EMail));
|
||||
|
||||
|
||||
// var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
|
||||
|
||||
|
||||
// var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
|
||||
// {
|
||||
|
||||
// DictionaryRepository = _dictionaryRepository,
|
||||
// IsEn_US = isEn_US,
|
||||
// DictionaryList = new List<DictionaryDto>()
|
||||
// {
|
||||
// new DictionaryDto (){DictionaryCode= "ReadingCategory",EnumValue=subjectVisit.AuditState.GetEnumInt(), }, //审核状态
|
||||
|
||||
// }
|
||||
// });
|
||||
|
||||
// Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
|
||||
// {
|
||||
// var subjectCode = subjectVisit.Subject.Code;
|
||||
// var topicStr = string.Format(input.topicStr, trialInfo.ResearchProgramNo, subjectCode, taskInfo.TaskBlindName);
|
||||
// var htmlBodyStr = string.Format(
|
||||
// CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
|
||||
// userinfo.FullName, // 用户名 {0}
|
||||
// trialInfo.ExperimentName, // 项目 {1}
|
||||
// subjectCode, // 受试者 {2}
|
||||
// subjectVisit.VisitName, // 访视 {3}
|
||||
// dictionValue[0], // 审核状态 {4}
|
||||
// _systemEmailConfig.SiteUrl // 链接 {5}
|
||||
|
||||
|
||||
|
||||
|
||||
// );
|
||||
|
||||
// return (topicStr, htmlBodyStr);
|
||||
// };
|
||||
|
||||
// await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository,
|
||||
|
||||
// context.Message.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed ? EmailBusinessScenario.ReReadFromPMApproval : EmailBusinessScenario.ReReadFromIRApproval,
|
||||
|
||||
// messageToSend, emailConfigFunc);
|
||||
|
||||
// await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -298,9 +298,50 @@ namespace IRaCIS.Application.Contracts
|
|||
public string WeChat { get; set; } = String.Empty;
|
||||
public int Nation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工作兼职
|
||||
/// </summary>
|
||||
public string WorkPartTime { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 工作兼职En
|
||||
/// </summary>
|
||||
public string WorkPartTimeEn { get; set; } = string.Empty;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class BasicInfoAndEmploymentDto: DoctorBasicInfoCommand
|
||||
{
|
||||
//部门
|
||||
public Guid? DepartmentId { get; set; } = Guid.Empty;
|
||||
public string DepartmentOther { get; set; } = string.Empty;
|
||||
public string DepartmentOtherCN { get; set; } = string.Empty;
|
||||
//职称
|
||||
public Guid? RankId { get; set; } = Guid.Empty;
|
||||
public string RankOther { get; set; } = string.Empty;
|
||||
public string RankOtherCN { get; set; } = string.Empty;
|
||||
//职位 主席 副主席
|
||||
public Guid? PositionId { get; set; } = Guid.Empty;
|
||||
public string PositionOther { get; set; } = string.Empty;
|
||||
public string PositionOtherCN { get; set; } = string.Empty;
|
||||
|
||||
public Guid? HospitalId { get; set; } = Guid.Empty;
|
||||
|
||||
public Guid? PhysicianId { get; set; }
|
||||
public string Physician { get; set; } = string.Empty;
|
||||
public string PhysicianCN { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 工作兼职
|
||||
/// </summary>
|
||||
public string WorkPartTime { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 工作兼职En
|
||||
/// </summary>
|
||||
public string WorkPartTimeEn { get; set; } = string.Empty;
|
||||
}
|
||||
public class DoctorBasicInfoCommand : DoctorBasicInfo
|
||||
{
|
||||
|
||||
|
@ -493,6 +534,16 @@ namespace IRaCIS.Application.Contracts
|
|||
public string Physician { get; set; } = string.Empty;
|
||||
public string PhysicianCN { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 工作兼职
|
||||
/// </summary>
|
||||
public string WorkPartTime { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 工作兼职En
|
||||
/// </summary>
|
||||
public string WorkPartTimeEn { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -112,6 +112,19 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增修改 医生基本信息和工作
|
||||
/// </summary>
|
||||
/// <param name="indto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput<DoctorBasicInfoCommand>> AddOrUpdateDoctorBasicInfoAndEmployment(BasicInfoAndEmploymentDto indto)
|
||||
{
|
||||
return await AddOrUpdateDoctorBasicInfo(indto);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///详情、编辑-获取 医生基本信息 BasicInfo
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
}
|
||||
|
||||
[HttpDelete, Route("{doctorId:guid}")]
|
||||
[HttpDelete, Route("{id:guid}")]
|
||||
public async Task<IResponseOutput> DeleteEducationInfo(Guid id)
|
||||
{
|
||||
var success = await _educationRepository.BatchDeleteNoTrackingAsync(o => o.Id == id);
|
||||
|
|
|
@ -782,7 +782,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
var criterionIdInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == trialReadingCriterionId).FirstNotNullAsync();
|
||||
|
||||
|
||||
var groupIds = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialReadingCriterionId && x.Type == ReadingQestionType.Table || x.Type == ReadingQestionType.BasicTable).Select(x => x.GroupId).Distinct().ToListAsync();
|
||||
var groupIds = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialReadingCriterionId &&( x.Type == ReadingQestionType.Table || x.Type == ReadingQestionType.BasicTable)).Select(x => x.GroupId).Distinct().ToListAsync();
|
||||
|
||||
var questionIds = await _readingQuestionTrialRepository
|
||||
.Where(x => x.IsShowInDicom)
|
||||
|
|
|
@ -14,12 +14,11 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
|||
public class ReadingCalculateService(IEnumerable<ICriterionCalculateService> _criterionServices,
|
||||
IRepository<VisitTask> _visitTaskRepository,
|
||||
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
||||
ICriterionCalculateService _useCriterion,
|
||||
IStringLocalizer _localizer, IUserInfo _userInfo
|
||||
IStringLocalizer _localizer, IUserInfo _userInfo
|
||||
|
||||
) : BaseService, IReadingCalculateService
|
||||
{
|
||||
|
||||
private ICriterionCalculateService _useCriterion;
|
||||
/// <summary>
|
||||
/// 标准和服务对应
|
||||
/// </summary>
|
||||
|
|
|
@ -33,12 +33,6 @@ using System.Text;
|
|||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[ApiExplorerSettings(GroupName = "Institution")]
|
||||
public class TestService(IRepository<Dictionary> _dicRepository,
|
||||
IRepository<Trial> _trialRepository,
|
||||
|
|
|
@ -172,6 +172,16 @@ public class Doctor : BaseFullAuditEntity
|
|||
|
||||
public string WeChat { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// ¹¤×÷¼æÖ°
|
||||
/// </summary>
|
||||
public string WorkPartTime { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// ¹¤×÷¼æÖ°En
|
||||
/// </summary>
|
||||
public string WorkPartTimeEn { get; set; } = string.Empty;
|
||||
|
||||
[NotMapped]
|
||||
public string FullName => LastName + " / " + FirstName;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ public class CRCSubmitedAndQCToAuditEvent : DomainEvent
|
|||
{
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
|
||||
public bool IsPd { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@ public static class DBContext_Ext
|
|||
|
||||
var originState = entry.Property(p => p.State).OriginalValue;
|
||||
|
||||
//状态从待提交 变为CRC提交 (驳回也会变为已提交,所以必须设置前置状态是待提交)
|
||||
if (trialSiteSurvey.State == TrialSiteSurveyEnum.CRCSubmitted && originState == TrialSiteSurveyEnum.ToSubmit)
|
||||
//状态从待提交 变为CRC提交||SPM 提交 (驳回也会变为已提交,所以必须设置前置状态是待提交)
|
||||
if ((trialSiteSurvey.State == TrialSiteSurveyEnum.CRCSubmitted || trialSiteSurvey.State == TrialSiteSurveyEnum.SPMApproved) && originState == TrialSiteSurveyEnum.ToSubmit)
|
||||
{
|
||||
trialSiteSurvey.AddDomainEvent(new UserSiteSurveySubmitedEvent() { TrialSiteSurveyId = trialSiteSurvey.Id });
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ public static class DBContext_Ext
|
|||
originAuditState == AuditStateEnum.None && subjectVisit.AuditState == AuditStateEnum.ToAudit
|
||||
)
|
||||
{
|
||||
subjectVisit.AddDomainEvent(new CRCSubmitedAndQCToAuditEvent() { SubjectVisitId = subjectVisit.Id });
|
||||
subjectVisit.AddDomainEvent(new CRCSubmitedAndQCToAuditEvent() { SubjectVisitId = subjectVisit.Id,IsPd= subjectVisit.PDState == PDStateEnum.PDProgress });
|
||||
}
|
||||
|
||||
//一致性核查通知PM发送邮件
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace IRaCIS.Core.Infra.EFCore.Interceptor
|
|||
// 发件箱模式参考: https://dev.to/antonmartyniuk/use-masstransit-to-implement-outbox-pattern-with-ef-core-and-mongodb-oep#:~:text=MongoDB%20replica%20set%20is%20required%20for%20both%20publisher%20and%20consumer
|
||||
// 1、IPublishEndpoint 才会将事件存储到发件箱表中, 高级IBus接口时 - 消息不会存储在发件箱中,必须有savechanges 才会一起提交保存到数据库中
|
||||
// 2、进入消息代理之前,发布事件在OutboxState OutboxMessage, 进入消费者以后(已经删除OutboxState OutboxMessage),消费失败,需要修改代码重新发布,然后之前消费事件的重新处理,错误处理参考:https://www.youtube.com/watch?v=3TMKUu7c4lc
|
||||
public class DispatchDomainEventsInterceptor(IMediator _mediator, IMessageScheduler _scheduler/*, IPublishEndpoint _publishEndpoint*/) : SaveChangesInterceptor
|
||||
public class DispatchDomainEventsInterceptor(/*IMediator _mediator,*/ IMessageScheduler _scheduler, IPublishEndpoint _publishEndpoint) : SaveChangesInterceptor
|
||||
{
|
||||
|
||||
//领域事件通常与数据变更密切相关。如果在 SaveChanges 之前发布事件,有可能事件发布时的数据状态还没有被持久化到数据库。这可能导致事件消费者看到的是一个不一致的状态
|
||||
|
@ -64,7 +64,7 @@ namespace IRaCIS.Core.Infra.EFCore.Interceptor
|
|||
await _scheduler.SchedulePublish(DateTime.Now.AddSeconds((int)domainEvent.DelaySeconds!), (object)domainEvent);
|
||||
}
|
||||
|
||||
await _mediator.Publish(domainEvent.GetType(), domainEvent);
|
||||
await _publishEndpoint.Publish(domainEvent.GetType(), domainEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
17873
IRaCIS.Core.Infra.EFCore/Migrations/20241021053401_DoctorInfo.Designer.cs
generated
Normal file
17873
IRaCIS.Core.Infra.EFCore/Migrations/20241021053401_DoctorInfo.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,42 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class DoctorInfo : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "WorkPartTime",
|
||||
table: "Doctor",
|
||||
type: "nvarchar(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "WorkPartTimeEn",
|
||||
table: "Doctor",
|
||||
type: "nvarchar(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "WorkPartTime",
|
||||
table: "Doctor");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "WorkPartTimeEn",
|
||||
table: "Doctor");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.8")
|
||||
.HasAnnotation("ProductVersion", "8.0.10")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
@ -1539,6 +1539,16 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<string>("WorkPartTime")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<string>("WorkPartTimeEn")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreateUserId");
|
||||
|
|
Loading…
Reference in New Issue