diff --git a/IRC.Core.SCP/IRC.Core.SCP.csproj b/IRC.Core.SCP/IRC.Core.SCP.csproj
index 61afafb4e..768c65fef 100644
--- a/IRC.Core.SCP/IRC.Core.SCP.csproj
+++ b/IRC.Core.SCP/IRC.Core.SCP.csproj
@@ -10,25 +10,25 @@
-
-
+
+
-
+
-
+
true
-
+
-
+
diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj
index 1a7f28ec4..34d17bbd7 100644
--- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj
+++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj
@@ -62,25 +62,23 @@
-
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
-
-
-
+
+
+
-
+
diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs
index 99903e9f7..1df9a24b5 100644
--- a/IRaCIS.Core.API/Progranm.cs
+++ b/IRaCIS.Core.API/Progranm.cs
@@ -144,14 +144,24 @@ builder.Services.AddMasaMinimalAPIs(options =>
options.RouteHandlerBuilder= t=> {
t.RequireAuthorization()
.AddEndpointFilter()
- .AddEndpointFilter()
+ //.AddEndpointFilter()
.AddEndpointFilter()
- .WithGroupName("Institution");
+ .WithGroupName("Institution").DisableAntiforgery();
};
+ options.MapHttpMethodsForUnmatched = new string[] { "Post" };
options.DisableTrimMethodPrefix = true; //禁用去除方法前缀
options.DisableAutoMapRoute = false;//可通过配置true禁用全局自动路由映射或者删除此配置以启用全局自动路由映射
});
+//// 添加反伪造服务
+//builder.Services.AddAntiforgery(options =>
+//{
+// // 可选:设置自定义的头部名称以支持 AJAX 请求等
+// options.HeaderName = "X-XSRF-TOKEN";
+//});
+
+//builder.Services.AddAntiforgery();
+
#endregion
var app = builder.Build();
@@ -160,7 +170,6 @@ var env = app.Environment;
#region 配置中间件
-
app.UseMiddleware();
#region 异常处理 全局业务异常已统一处理了,非业务错误会来到这里 400 -500状态码
@@ -235,6 +244,13 @@ app.UseRouting();
app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseAuthentication();
app.UseAuthorization();
+
+
+//Map MinimalAPI routes
+app.MapMasaMinimalAPIs();
+
+//// 这里添加反伪造中间件
+//app.UseAntiforgery();
app.MapControllers();
app.MapHub("/UploadHub");
@@ -244,8 +260,7 @@ app.MapHealthChecks("/health");
#endregion
-//Map MinimalAPI routes
-app.MapMasaMinimalAPIs();
+
// Serilog
SerilogExtension.AddSerilogSetup(enviromentName, app.Services);
diff --git a/IRaCIS.Core.API/_ServiceExtensions/ServiceCollectionSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/ServiceCollectionSetup.cs
index 6eb538635..7541ecf25 100644
--- a/IRaCIS.Core.API/_ServiceExtensions/ServiceCollectionSetup.cs
+++ b/IRaCIS.Core.API/_ServiceExtensions/ServiceCollectionSetup.cs
@@ -1,4 +1,3 @@
-using Autofac;
using IP2Region.Net.Abstractions;
using IP2Region.Net.XDB;
using IRaCIS.Core.Application.BackGroundJob;
@@ -96,42 +95,42 @@ public static class ServiceCollectionSetup
}
#region Autofac
-public class AutofacModuleSetup : Autofac.Module
-{
- protected override void Load(ContainerBuilder containerBuilder)
- {
+//public class AutofacModuleSetup : Autofac.Module
+//{
+// protected override void Load(ContainerBuilder containerBuilder)
+// {
- #region byzhouhang 20210917 ˴ע᷺Ͳִ ԼDomain Infra.EFcore յIJִӿڶ ִļ
+// #region byzhouhang 20210917 ˴ע᷺Ͳִ ԼDomain Infra.EFcore յIJִӿڶ ִļ
- containerBuilder.RegisterGeneric(typeof(Repository<>))
- .As(typeof(IRepository<>)).InstancePerLifetimeScope();//ע᷺Ͳִ
+// containerBuilder.RegisterGeneric(typeof(Repository<>))
+// .As(typeof(IRepository<>)).InstancePerLifetimeScope();//ע᷺Ͳִ
- containerBuilder.RegisterType().As().InstancePerLifetimeScope();
+// containerBuilder.RegisterType().As().InstancePerLifetimeScope();
- #endregion
+// #endregion
- #region ָҲautofac ʵȡ https://www.cnblogs.com/xwhqwer/p/15320838.html
+// #region ָҲautofac ʵȡ https://www.cnblogs.com/xwhqwer/p/15320838.html
- //ȡпͲʹע
- containerBuilder.RegisterAssemblyTypes(typeof(BaseService).Assembly)
- .Where(type => typeof(IDynamicWebApi).IsAssignableFrom(type))
- .PropertiesAutowired();
+// //ȡпͲʹע
+// containerBuilder.RegisterAssemblyTypes(typeof(BaseService).Assembly)
+// .Where(type => typeof(IDynamicWebApi).IsAssignableFrom(type))
+// .PropertiesAutowired();
- #endregion
+// #endregion
- Assembly application = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "IRaCIS.Core.Application.dll");
- containerBuilder.RegisterAssemblyTypes(application).Where(t => t.FullName.Contains("Service"))
- .PropertiesAutowired().AsImplementedInterfaces();
+// Assembly application = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "IRaCIS.Core.Application.dll");
+// containerBuilder.RegisterAssemblyTypes(application).Where(t => t.FullName.Contains("Service"))
+// .PropertiesAutowired().AsImplementedInterfaces();
- //containerBuilder.RegisterType().As().SingleInstance();
- //containerBuilder.RegisterType().As().InstancePerLifetimeScope();
+// //containerBuilder.RegisterType().As().SingleInstance();
+// //containerBuilder.RegisterType().As().InstancePerLifetimeScope();
- //עhangfire ע
- containerBuilder.RegisterType().As().InstancePerDependency();
+// //עhangfire ע
+// containerBuilder.RegisterType().As().InstancePerDependency();
- }
-}
+// }
+//}
#endregion
diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json
index 457e2223f..85d1b7163 100644
--- a/IRaCIS.Core.API/appsettings.Test_IRC.json
+++ b/IRaCIS.Core.API/appsettings.Test_IRC.json
@@ -72,7 +72,9 @@
"ReadingRestTimeMin": 10,
"IsNeedChangePassWord": true,
- "ChangePassWordDays": 90
+ "ChangePassWordDays": 90,
+
+ "ThirdPdfUrl": "http://106.14.89.110:30088/api/v1/convert/file/pdf"
},
"SystemEmailSendConfig": {
diff --git a/IRaCIS.Core.Application/BusinessFilter/MinimalAPI/ModelValidationEndpointFilter.cs b/IRaCIS.Core.Application/BusinessFilter/MinimalAPI/Todo/ModelValidationEndpointFilter.cs
similarity index 100%
rename from IRaCIS.Core.Application/BusinessFilter/MinimalAPI/ModelValidationEndpointFilter.cs
rename to IRaCIS.Core.Application/BusinessFilter/MinimalAPI/Todo/ModelValidationEndpointFilter.cs
diff --git a/IRaCIS.Core.Application/BusinessFilter/MinimalAPI/TrialGlobalLimitEndpointFilter.cs b/IRaCIS.Core.Application/BusinessFilter/MinimalAPI/Todo/TrialGlobalLimitEndpointFilter.cs
similarity index 100%
rename from IRaCIS.Core.Application/BusinessFilter/MinimalAPI/TrialGlobalLimitEndpointFilter.cs
rename to IRaCIS.Core.Application/BusinessFilter/MinimalAPI/Todo/TrialGlobalLimitEndpointFilter.cs
diff --git a/IRaCIS.Core.Application/BusinessFilter/_Config/_AppSettings.cs b/IRaCIS.Core.Application/BusinessFilter/_Config/_AppSettings.cs
index 885c65dd1..c89c9a803 100644
--- a/IRaCIS.Core.Application/BusinessFilter/_Config/_AppSettings.cs
+++ b/IRaCIS.Core.Application/BusinessFilter/_Config/_AppSettings.cs
@@ -34,6 +34,8 @@ public class ServiceVerifyConfigOption
[Description("修改密码的天数")]
public int ChangePassWordDays { get; set; }
+ public string ThirdPdfUrl { get; set; }
+
}
public class SystemEmailSendConfig
diff --git a/IRaCIS.Core.Application/Helper/FileConvertHelper.cs b/IRaCIS.Core.Application/Helper/FileConvertHelper.cs
index 5b34f64f3..9034db877 100644
--- a/IRaCIS.Core.Application/Helper/FileConvertHelper.cs
+++ b/IRaCIS.Core.Application/Helper/FileConvertHelper.cs
@@ -1,11 +1,18 @@
-using System.Diagnostics;
+using Microsoft.Extensions.Configuration;
+using RestSharp;
+using SharpCompress.Common;
+using System.Diagnostics;
namespace IRaCIS.Core.Application.Helper;
public class FileConvertHelper
{
-
+ ///
+ /// 镜像里面打入libreoffice 的方案
+ ///
+ ///
+ ///
static public void ConvertWordToPdf(string inputWordFilePath, string outputPdfDir)
{
// 设置 libreoffice 命令行参数
@@ -30,4 +37,88 @@ public class FileConvertHelper
}
+ ///
+ /// 返回文件字节数组
+ /// File.WriteAllBytes(outputFilePath, response.RawBytes); 直接将字节数组写入到本地某个路径
+ /// var stream = new MemoryStream(response.RawBytes); 直接变为内存流,给其他程序用也可以
+ ///
+ ///
+ static public async Task ThirdStirling_PDFWordToPdfAsync(string filePath)
+ {
+
+ var apiUrl = GetApiUrl();
+
+ var client = new RestClient(apiUrl);
+
+ var request = new RestRequest(apiUrl, Method.Post);
+
+ request.AddHeader("accept", "*/*");
+
+ // 直接上传文件,无需生成字节数组
+ request.AddFile("fileInput", filePath);
+
+ return await GetPDFByteArrayAsync(client, request);
+ }
+
+ static public async Task ThirdStirling_PDFWordToPdfAsync(byte[] fileBytes, string fileName)
+ {
+
+ var apiUrl = GetApiUrl();
+ var client = new RestClient(apiUrl);
+
+ var request = new RestRequest(apiUrl, Method.Post);
+
+ request.AddHeader("accept", "*/*");
+
+ // 添加文件流到请求
+ request.AddFile("fileInput", fileBytes, fileName);
+
+ return await GetPDFByteArrayAsync(client, request);
+ }
+
+ static private async Task GetPDFByteArrayAsync(RestClient client, RestRequest request)
+ {
+ try
+ {
+
+
+
+ // 发送请求并获取响应
+ var response = await client.ExecuteAsync(request);
+
+ // 检查请求是否成功
+ if (response.IsSuccessful)
+ {
+ return response.RawBytes ?? new byte[] { };
+ }
+ else
+ {
+ Console.WriteLine($"上传失败,错误代码: {response.StatusCode}, 错误消息: {response.ErrorMessage}");
+
+ return Array.Empty();
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("发生异常: " + ex.Message);
+
+ return Array.Empty();
+ }
+ }
+
+ static private string GetApiUrl()
+ {
+
+ var enviromentName = Environment.GetEnvironmentVariables()["ASPNETCORE_ENVIRONMENT"]?.ToString();
+
+ var configuration = new ConfigurationBuilder().AddJsonFile($"appsettings.{enviromentName}.json", false, false).Build();
+
+ // 手动绑定配置
+ var appSettings = new ServiceVerifyConfigOption();
+ configuration.GetSection("BasicSystemConfig").Bind(appSettings);
+
+ return appSettings.ThirdPdfUrl;
+ }
+
+
}
diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj
index 9c039cd04..99a2cfcf6 100644
--- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj
+++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj
@@ -48,9 +48,9 @@
-
+
-
+
@@ -60,13 +60,13 @@
-
+
-
+
@@ -74,10 +74,10 @@
-
+
-
+
diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
index 42c3ff56b..aed7723bb 100644
--- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
+++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
@@ -2273,6 +2273,20 @@
+
+
+ minimal api 测试
+ 学习参考文档:http://fanrk.cn/%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3/MinimalApi/MinimalApi.html
+ 组件参考文档:https://docs.masastack.com/framework/building-blocks/minimal-apis#section-69828ff0
+
+
+
+
+ minimal api 测试
+ 学习参考文档:http://fanrk.cn/%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3/MinimalApi/MinimalApi.html
+ 组件参考文档:https://docs.masastack.com/framework/building-blocks/minimal-apis#section-69828ff0
+
+
验证CRC 是否已提交 已提交 就不允许进行任何操作,如果是IQC 那么还验证是否是当前任务领取人
@@ -12683,20 +12697,6 @@
-
-
- minimal api 测试
- 学习参考文档:http://fanrk.cn/%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3/MinimalApi/MinimalApi.html
- 组件参考文档:https://docs.masastack.com/framework/building-blocks/minimal-apis#section-69828ff0
-
-
-
-
- minimal api 测试
- 学习参考文档:http://fanrk.cn/%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3/MinimalApi/MinimalApi.html
- 组件参考文档:https://docs.masastack.com/framework/building-blocks/minimal-apis#section-69828ff0
-
-
清理一致性分析任务
@@ -12762,6 +12762,21 @@
+
+
+ 镜像里面打入libreoffice 的方案
+
+
+
+
+
+
+ 返回文件字节数组
+ File.WriteAllBytes(outputFilePath, response.RawBytes); 直接将字节数组写入到本地某个路径
+ var stream = new MemoryStream(response.RawBytes); 直接变为内存流,给其他程序用也可以
+
+
+
写文件导到磁盘
@@ -12916,12 +12931,17 @@
加急阅片 IR 申请重阅 或者PM 申请重阅
+
+
+ 加急阅片 IR 申请重阅 或者PM 申请重阅
+
+
用户提交 发送邮件 通知SPM 或者PM
-
+
用户提交 发送邮件 通知SPM 或者PM
@@ -12931,7 +12951,7 @@
调研表初审通过,进行复审发送邮件
-
+
调研表初审通过,进行复审发送邮件
@@ -12941,7 +12961,7 @@
调研表驳回发送邮件 之前已有,需要迁移过来
-
+
调研表驳回发送邮件 之前已有,需要迁移过来
@@ -13042,17 +13062,17 @@
影像质控
-
+
QC 影像质疑待处理
-
+
CRC 影像质疑
-
+
影像质控
diff --git a/IRaCIS.Core.Application/MassTransit/Consumer/SiteSurverEmailConsumer.cs b/IRaCIS.Core.Application/MassTransit/Consumer/SiteSurverEmailConsumer.cs
index 0f3fdf4f9..385240394 100644
--- a/IRaCIS.Core.Application/MassTransit/Consumer/SiteSurverEmailConsumer.cs
+++ b/IRaCIS.Core.Application/MassTransit/Consumer/SiteSurverEmailConsumer.cs
@@ -30,6 +30,7 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer;
public class UserSiteSurveySubmitedEventConsumer(
IRepository _trialRepository,
IRepository _trialSiteRepository,
+ IRepository _trialUserRepository,
IRepository _trialSiteSurveyRepository,
IRepository _emailNoticeConfigrepository,
IOptionsMonitor 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(
///
public class SiteSurveySPMSubmitedEventConsumer(
IRepository _trialRepository,
+ IRepository _trialUserRepository,
IRepository _trialSiteRepository,
IRepository _trialSiteSurveyRepository,
IRepository _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(
/// 调研表驳回发送邮件 之前已有,需要迁移过来
///
public class SiteSurverRejectedEventConsumer(
- IRepository _userRepository,
+ IRepository _trialUserRepository,
IRepository _trialRepository,
IRepository _trialSiteRepository,
IRepository _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();
diff --git a/IRaCIS.Core.Application/MassTransit/Consumer/TestConsumer.cs b/IRaCIS.Core.Application/MassTransit/Consumer/TestConsumer.cs
index ac559acc0..d87654fbd 100644
--- a/IRaCIS.Core.Application/MassTransit/Consumer/TestConsumer.cs
+++ b/IRaCIS.Core.Application/MassTransit/Consumer/TestConsumer.cs
@@ -1,14 +1,18 @@
-using IRaCIS.Core.Domain;
+using IRaCIS.Core.Application.Helper;
+using IRaCIS.Core.Domain;
using IRaCIS.Core.Domain.Share;
using MassTransit;
using MassTransit.Mediator;
using MassTransit.Scheduling;
using Medallion.Threading;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Options;
+using RestSharp;
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -71,11 +75,76 @@ public class TestMasstransitService : BaseService
////发布后,不会立即进入消费者,消费者是另外的线程执行
//await _mediatorScoped.Publish(new MasstransiTestCommand { value = "message at " + DateTime.Now.ToString() });
- await _recurringMessageScheduler.ScheduleRecurringPublish(new QCImageQuestionSchedule() { CronExpression = "0/3 * * * * ? " }, new MasstransiTestCommand { value = "message at " + DateTime.Now.ToString() });
+ await _recurringMessageScheduler.ScheduleRecurringPublish(new QCImageQuestionRecurringSchedule() { CronExpression = "0/3 * * * * ? " }, new MasstransiTestCommand { value = "message at " + DateTime.Now.ToString() });
//await _scheduler.SchedulePublish(DateTime.Now.AddSeconds(10), new MasstransiTestCommand() { value = "message at " + DateTime.Now.ToString() });
return ResponseOutput.Ok();
}
+
+ public async Task TestWordToPdf()
+ {
+
+ var dd = await FileConvertHelper.ThirdStirling_PDFWordToPdfAsync(@"C:\Users\hang\Desktop\test.docx");
+
+ string outputFilePath = @"C:\Users\hang\Desktop\test-byte4-output.pdf"; // 保存路径
+ File.WriteAllBytes(outputFilePath, dd); // 将响应字节数组写入文件
+
+
+
+ //var envName = Environment.GetEnvironmentVariables()["ASPNETCORE_ENVIRONMENT"]?.ToString();
+
+ //// API 地址
+ //string apiUrl = "http://106.14.89.110:30088/api/v1/convert/file/pdf";
+
+ //// 模拟文件路径,假设你有一个内存流的文件,不指定实际文件
+ //string filePath = @"C:\Users\hang\Desktop\test.docx"; // 本地文件路径或者你可以直接使用流
+
+ //var fileBytes = File.ReadAllBytes(@"C:\Users\hang\Desktop\test.docx");
+
+
+ //try
+ //{
+ // // 创建 RestClient
+ // var client = new RestClient(apiUrl);
+
+ // // 创建 RestRequest,使用 POST 方法
+ // var request = new RestRequest(apiUrl, Method.Post);
+ // request.AddHeader("accept", "*/*");
+
+ // //new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(filePath), out var contentType);
+
+ // // 直接上传文件,无需生成字节数组
+ // //request.AddFile("fileInput", filePath, contentType);
+
+ // // 添加文件流到请求
+ // request.AddFile("fileInput", fileBytes, "test-byte.docx");
+
+ // // 发送请求并获取响应
+ // var response = await client.ExecuteAsync(request);
+
+ // // 检查请求是否成功
+ // if (response.IsSuccessful)
+ // {
+ // // 保存接收到的文件到本地
+ // string outputFilePath = @"C:\Users\hang\Desktop\test-byte3-output.pdf"; // 保存路径
+ // File.WriteAllBytes(outputFilePath, response.RawBytes); // 将响应字节数组写入文件
+
+ // //如果要文件流,就这样
+ // //var stream = new MemoryStream(response.RawBytes);
+
+ // }
+ // else
+ // {
+ // Console.WriteLine($"上传失败,错误代码: {response.StatusCode}, 错误消息: {response.ErrorMessage}");
+ // }
+ //}
+ //catch (Exception ex)
+ //{
+ // Console.WriteLine("发生异常: " + ex.Message);
+ //}
+
+ return ResponseOutput.Ok();
+ }
}
diff --git a/IRaCIS.Core.Application/MassTransit/Recurring/RecurringEmailConsumer.cs b/IRaCIS.Core.Application/MassTransit/Recurring/RecurringEmailConsumer.cs
index 265cd453c..90c1b79c1 100644
--- a/IRaCIS.Core.Application/MassTransit/Recurring/RecurringEmailConsumer.cs
+++ b/IRaCIS.Core.Application/MassTransit/Recurring/RecurringEmailConsumer.cs
@@ -11,9 +11,9 @@ namespace IRaCIS.Core.Application.MassTransit.Consumer;
-public class QCImageQuestionScheduleConsumer : IConsumer
+public class QCImageQuestionScheduleConsumer : IConsumer
{
- public Task Consume(ConsumeContext context)
+ public Task Consume(ConsumeContext context)
{
Console.WriteLine(DateTime.Now);
diff --git a/IRaCIS.Core.Application/MassTransit/Recurring/RecurringEvent.cs b/IRaCIS.Core.Application/MassTransit/Recurring/Schedule/RecurringEvent.cs
similarity index 100%
rename from IRaCIS.Core.Application/MassTransit/Recurring/RecurringEvent.cs
rename to IRaCIS.Core.Application/MassTransit/Recurring/Schedule/RecurringEvent.cs
diff --git a/IRaCIS.Core.Application/MassTransit/Recurring/RecurringSchedule.cs b/IRaCIS.Core.Application/MassTransit/Recurring/Schedule/RecurringSchedule.cs
similarity index 85%
rename from IRaCIS.Core.Application/MassTransit/Recurring/RecurringSchedule.cs
rename to IRaCIS.Core.Application/MassTransit/Recurring/Schedule/RecurringSchedule.cs
index cc7481c25..41cef4508 100644
--- a/IRaCIS.Core.Application/MassTransit/Recurring/RecurringSchedule.cs
+++ b/IRaCIS.Core.Application/MassTransit/Recurring/Schedule/RecurringSchedule.cs
@@ -32,7 +32,7 @@ public abstract class IRCRecurringSchedule :
///
/// QC 影像质疑待处理
///
-public class QCImageQuestionSchedule : IRCRecurringSchedule
+public class QCImageQuestionRecurringSchedule : IRCRecurringSchedule
{
}
@@ -40,7 +40,7 @@ public class QCImageQuestionSchedule : IRCRecurringSchedule
///
/// CRC 影像质疑
///
-public class CRCImageQuestionSchedule : IRCRecurringSchedule
+public class CRCImageQuestionRecurringSchedule : IRCRecurringSchedule
{
}
@@ -48,7 +48,7 @@ public class CRCImageQuestionSchedule : IRCRecurringSchedule
///
/// 影像质控
///
-public class ImageQCSchedule : IRCRecurringSchedule
+public class ImageQCRecurringSchedule : IRCRecurringSchedule
{
}
diff --git a/IRaCIS.Core.Application/Service/MinimalApiService/FileToPDFService.cs b/IRaCIS.Core.Application/Service/MinimalApiService/FileToPDFService.cs
new file mode 100644
index 000000000..9e4570b79
--- /dev/null
+++ b/IRaCIS.Core.Application/Service/MinimalApiService/FileToPDFService.cs
@@ -0,0 +1,132 @@
+using IRaCIS.Core.Application.Helper;
+using MassTransit;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.StaticFiles;
+using RestSharp;
+using SharpCompress.Common;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IRaCIS.Core.Application.Service.MinimalApiService
+{
+ [ApiExplorerSettings(GroupName = "Institution")]
+ public class FileToPDFService(IWebHostEnvironment _hostEnvironment) : ServiceBase
+ {
+
+ [AllowAnonymous]
+ [RoutePattern(HttpMethod = "Post")]
+ public async Task UploadFileAsync([FromForm] IFormFile file)
+ {
+ var tempFileName = NewId.NextGuid() + file.FileName;
+ var tempPDFName = Path.GetFileNameWithoutExtension(tempFileName) + ".pdf";
+
+
+ // 获取wwwroot目录
+ var wwwRootPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "temp");
+
+ // 检查wwwroot/temp目录是否存在,不存在则创建
+ if (!Directory.Exists(wwwRootPath))
+ {
+ Directory.CreateDirectory(wwwRootPath);
+ }
+
+ // 文件保存路径
+ var pdfFilePath = Path.Combine(wwwRootPath, tempPDFName);
+ var tempFilePath = Path.Combine(wwwRootPath, tempFileName);
+
+
+ using var stream = File.OpenWrite(tempFilePath);
+ await file.CopyToAsync(stream);
+
+ FileConvertHelper.ConvertWordToPdf(tempFilePath, Path.GetDirectoryName(pdfFilePath));
+
+ var fileBytes = await File.ReadAllBytesAsync(pdfFilePath);
+
+ // 清理临时上传的文件和pdf
+ if (File.Exists(pdfFilePath))
+ {
+ File.Delete(pdfFilePath);
+ }
+ if (File.Exists(tempFilePath))
+ {
+ File.Delete(tempFilePath);
+ }
+
+ new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(tempPDFName), out var contentType);
+
+ return Results.File(fileBytes, contentType);
+
+ }
+
+
+ public async Task GetPDFFileAsync(string fileUrl)
+ {
+ var tempFileName = NewId.NextGuid() + Path.GetFileName(fileUrl);
+ var tempPDFName = Path.GetFileNameWithoutExtension(tempFileName) + ".pdf";
+
+
+ // 获取wwwroot目录
+ var wwwRootPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "temp");
+
+ // 检查wwwroot/temp目录是否存在,不存在则创建
+ if (!Directory.Exists(wwwRootPath))
+ {
+ Directory.CreateDirectory(wwwRootPath);
+ }
+
+ // 文件保存路径
+ var pdfFilePath = Path.Combine(wwwRootPath, tempPDFName);
+ var tempFilePath = Path.Combine(wwwRootPath, tempFileName);
+
+
+ //请求url获取文件
+ var client = new RestClient(fileUrl);
+
+ var request = new RestRequest(fileUrl, Method.Get);
+
+ var response = await client.ExecuteAsync(request);
+
+ // 检查响应是否成功
+ if (response.IsSuccessful)
+ {
+ // 将响应内容写入到本地文件
+ await File.WriteAllBytesAsync(tempFilePath, response.RawBytes);
+
+ FileConvertHelper.ConvertWordToPdf(tempFilePath, Path.GetDirectoryName(pdfFilePath));
+
+ var fileBytes = await File.ReadAllBytesAsync(pdfFilePath);
+
+ // 清理临时上传的文件和pdf
+ if (File.Exists(pdfFilePath))
+ {
+ File.Delete(pdfFilePath);
+ }
+ if (File.Exists(tempFilePath))
+ {
+ File.Delete(tempFilePath);
+ }
+
+ new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(tempPDFName), out var contentType);
+
+ return Results.File(fileBytes, contentType);
+ }
+ else
+ {
+ Console.WriteLine($"下载文件失败: {response.ErrorMessage}");
+
+ return Results.Problem("下载文件失败", statusCode: StatusCodes.Status500InternalServerError);
+
+ }
+
+
+ }
+
+ }
+}
diff --git a/IRaCIS.Core.Application/Service/MinimalApiService/TestMinimalApiService.cs b/IRaCIS.Core.Application/Service/MinimalApiService/TestMinimalApiService.cs
new file mode 100644
index 000000000..5b0678790
--- /dev/null
+++ b/IRaCIS.Core.Application/Service/MinimalApiService/TestMinimalApiService.cs
@@ -0,0 +1,57 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IRaCIS.Core.Application.Service.MinimalApiService
+{
+ ///
+ /// minimal api 测试
+ /// 学习参考文档:http://fanrk.cn/%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3/MinimalApi/MinimalApi.html
+ /// 组件参考文档:https://docs.masastack.com/framework/building-blocks/minimal-apis#section-69828ff0
+ ///
+ [ApiExplorerSettings(GroupName = "Institution")]
+
+ public class TestMinimalApiService(IUserInfo _userInfo) : ServiceBase
+ {
+
+
+
+ public Task> GetProjectList1Async()
+ {
+ var list = new List()
+ {
+ "Auth",
+ "DCC",
+ "PM"
+ };
+ return Task.FromResult(list);
+ }
+
+ [AllowAnonymous]
+ public IResponseOutput GetTest()
+ {
+
+ //throw new BusinessValidationFailedException("手动抛出的异常");
+
+ return ResponseOutput.Ok(_userInfo.IP);
+ }
+
+ public IResponseOutput GetTestI18n()
+ {
+ var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
+
+ //CultureInfo.CurrentCulture = new CultureInfo(StaticData.CultureInfo.en_US);
+ //CultureInfo.CurrentUICulture = new CultureInfo(StaticData.CultureInfo.en_US);
+
+ return ResponseOutput.Ok(I18n.T("TaskAllocation_DoctorConfigExists"));
+ }
+
+ }
+
+}
diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs
index f3955893b..c764d0838 100644
--- a/IRaCIS.Core.Application/TestService.cs
+++ b/IRaCIS.Core.Application/TestService.cs
@@ -33,49 +33,6 @@ using System.Text;
namespace IRaCIS.Core.Application.Service
{
- ///
- /// minimal api 测试
- /// 学习参考文档:http://fanrk.cn/%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3/MinimalApi/MinimalApi.html
- /// 组件参考文档:https://docs.masastack.com/framework/building-blocks/minimal-apis#section-69828ff0
- ///
- [ApiExplorerSettings(GroupName = "Institution")]
-
- public class TestMinimalApiService(IUserInfo _userInfo) : ServiceBase
- {
-
-
-
- public Task> GetProjectList1Async()
- {
- var list = new List()
- {
- "Auth",
- "DCC",
- "PM"
- };
- return Task.FromResult(list);
- }
-
- [AllowAnonymous]
- public IResponseOutput GetTest()
- {
-
- //throw new BusinessValidationFailedException("手动抛出的异常");
-
- return ResponseOutput.Ok(_userInfo.IP);
- }
-
- public IResponseOutput GetTestI18n()
- {
- var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
-
- //CultureInfo.CurrentCulture = new CultureInfo(StaticData.CultureInfo.en_US);
- //CultureInfo.CurrentUICulture = new CultureInfo(StaticData.CultureInfo.en_US);
-
- return ResponseOutput.Ok(I18n.T("TaskAllocation_DoctorConfigExists"));
- }
-
- }
diff --git a/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj b/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj
index 85d943c69..509c67d57 100644
--- a/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj
+++ b/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj b/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj
index 684798ebc..383747676 100644
--- a/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj
+++ b/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj
@@ -25,17 +25,17 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/IRaCIS.Core.Infra.EFCore/Interceptor/AddDomainExt.cs b/IRaCIS.Core.Infra.EFCore/Interceptor/AddDomainExt.cs
index 30c5e53a6..df891c547 100644
--- a/IRaCIS.Core.Infra.EFCore/Interceptor/AddDomainExt.cs
+++ b/IRaCIS.Core.Infra.EFCore/Interceptor/AddDomainExt.cs
@@ -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 });
}
diff --git a/IRaCIS.Core.Infra.EFCore/Interceptor/DispatchDomainEventsInterceptor.cs b/IRaCIS.Core.Infra.EFCore/Interceptor/DispatchDomainEventsInterceptor.cs
index 871ed9b45..609a938cd 100644
--- a/IRaCIS.Core.Infra.EFCore/Interceptor/DispatchDomainEventsInterceptor.cs
+++ b/IRaCIS.Core.Infra.EFCore/Interceptor/DispatchDomainEventsInterceptor.cs
@@ -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);
}
}
diff --git a/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj b/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj
index a59275bf9..cac011aba 100644
--- a/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj
+++ b/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj
@@ -12,13 +12,13 @@
-
+
-
+
-
+
diff --git a/IRaCIS.Core.Test/IRaCIS.Core.Test.csproj b/IRaCIS.Core.Test/IRaCIS.Core.Test.csproj
index 54bd36e5d..ee616207e 100644
--- a/IRaCIS.Core.Test/IRaCIS.Core.Test.csproj
+++ b/IRaCIS.Core.Test/IRaCIS.Core.Test.csproj
@@ -50,10 +50,10 @@
-
-
-
-
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive