diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs index 193586589..1ddc35683 100644 --- a/IRaCIS.Core.API/Controllers/ExtraController.cs +++ b/IRaCIS.Core.API/Controllers/ExtraController.cs @@ -213,44 +213,49 @@ namespace IRaCIS.Api.Controllers if (Enum.TryParse(serviceOption.ObjectStoreUse, out var parsedEnum) && parsedEnum == ObjectStoreUse.AliyunOSS) { + var ossOptions = serviceOption.AliyunOSS; - IClientProfile profile = DefaultProfile.GetProfile(ossOptions.RegionId, ossOptions.AccessKeyId, ossOptions.AccessKeySecret); - DefaultAcsClient client = new DefaultAcsClient(profile); + return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO ,AliyunOSS= serviceOption.AliyunOSS }); + + #region 临时token 屏蔽 + //IClientProfile profile = DefaultProfile.GetProfile(ossOptions.RegionId, ossOptions.AccessKeyId, ossOptions.AccessKeySecret); + //DefaultAcsClient client = new DefaultAcsClient(profile); - // 创建一个STS请求 - AssumeRoleRequest request = new AssumeRoleRequest - { - RoleArn = ossOptions.RoleArn, // 角色ARN,需要替换为你的角色ARN - RoleSessionName = $"session-name-{NewId.NextGuid()}", // 角色会话名称,可自定义 - DurationSeconds = 900, // 令牌有效期(单位:秒),这里设置为1小时 - }; + //// 创建一个STS请求 + //AssumeRoleRequest request = new AssumeRoleRequest + //{ + // RoleArn = ossOptions.RoleArn, // 角色ARN,需要替换为你的角色ARN + // RoleSessionName = $"session-name-{NewId.NextGuid()}", // 角色会话名称,可自定义 + // DurationSeconds = 900, // 令牌有效期(单位:秒),这里设置为1小时 + //}; - AssumeRoleResponse response = client.GetAcsResponse(request); + //AssumeRoleResponse response = client.GetAcsResponse(request); - // 返回STS令牌信息给前端 - var stsToken = new ObjectStoreDTO() - { - ObjectStoreUse=serviceOption.ObjectStoreUse, - AliyunOSS=new AliyunOSSTempToken() - { - AccessKeyId = response.Credentials.AccessKeyId, - AccessKeySecret = response.Credentials.AccessKeySecret, - SecurityToken = response.Credentials.SecurityToken, - Expiration = response.Credentials.Expiration, + //// 返回STS令牌信息给前端 + //var stsToken = new ObjectStoreDTO() + //{ + // ObjectStoreUse = serviceOption.ObjectStoreUse, + // AliyunOSS = new AliyunOSSTempToken() + // { + // AccessKeyId = response.Credentials.AccessKeyId, + // AccessKeySecret = response.Credentials.AccessKeySecret, + // SecurityToken = response.Credentials.SecurityToken, + // Expiration = response.Credentials.Expiration, - Region = ossOptions.Region, - BucketName = ossOptions.BucketName, - ViewEndpoint = ossOptions.ViewEndpoint, + // Region = ossOptions.Region, + // BucketName = ossOptions.BucketName, + // ViewEndpoint = ossOptions.ViewEndpoint, - }, - MinIO=serviceOption.MinIO - } - ; + // }, + // MinIO = serviceOption.MinIO + //}; + //return ResponseOutput.Ok(stsToken); + + #endregion - return ResponseOutput.Ok(stsToken); } else if(Enum.TryParse(serviceOption.ObjectStoreUse, out var parsedValue) && parsedValue == ObjectStoreUse.MinIO) { @@ -269,14 +274,14 @@ namespace IRaCIS.Api.Controllers var ossOptions = options.CurrentValue; - IClientProfile profile = DefaultProfile.GetProfile(ossOptions.RegionId, ossOptions.AccessKeyId, ossOptions.AccessKeySecret); + IClientProfile profile = DefaultProfile.GetProfile(ossOptions.regionId, ossOptions.accessKeyId, ossOptions.accessKeySecret); DefaultAcsClient client = new DefaultAcsClient(profile); // 创建一个STS请求 AssumeRoleRequest request = new AssumeRoleRequest { - RoleArn = ossOptions.RoleArn, // 角色ARN,需要替换为你的角色ARN + RoleArn = ossOptions.roleArn, // 角色ARN,需要替换为你的角色ARN RoleSessionName = $"session-name-{NewId.NextGuid()}", // 角色会话名称,可自定义 DurationSeconds = 900, // 令牌有效期(单位:秒),这里设置为1小时 }; @@ -292,9 +297,9 @@ namespace IRaCIS.Api.Controllers SecurityToken = response.Credentials.SecurityToken, Expiration = response.Credentials.Expiration, - Region = ossOptions.Region , - BucketName = ossOptions.BucketName , - ViewEndpoint = ossOptions.ViewEndpoint , + Region = ossOptions.region , + BucketName = ossOptions.bucketName , + ViewEndpoint = ossOptions.viewEndpoint , }; diff --git a/IRaCIS.Core.API/Program.cs b/IRaCIS.Core.API/Program.cs index ad2c3f425..3878accd3 100644 --- a/IRaCIS.Core.API/Program.cs +++ b/IRaCIS.Core.API/Program.cs @@ -13,6 +13,7 @@ using System.IO; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Application.Helper; +using System.Runtime.InteropServices; namespace IRaCIS.Core.API { @@ -55,12 +56,29 @@ namespace IRaCIS.Core.API //// Serilog SerilogExtension.AddSerilogSetup(enviromentName, host.Services); + Log.Logger.Warning($"ǰ{enviromentName}"); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Log.Logger.Warning($"ǰƽ̨windows"); + } + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Log.Logger.Warning($"ǰƽ̨linux"); + } + else + { + Log.Logger.Warning($"ǰƽ̨OSX or FreeBSD"); + } + NewId.SetProcessIdProvider(new CurrentProcessIdProvider()); - + + host.Run(); + } catch (Exception e) diff --git a/IRaCIS.Core.API/appsettings.Development.json b/IRaCIS.Core.API/appsettings.Development.json index 96aa3b8e8..1563831a3 100644 --- a/IRaCIS.Core.API/appsettings.Development.json +++ b/IRaCIS.Core.API/appsettings.Development.json @@ -17,23 +17,23 @@ "ObjectStoreUse": "AliyunOSS", "AliyunOSS": { - "RegionId": "cn-shanghai", - "Endpoint": "https://oss-cn-shanghai.aliyuncs.com", - "AccessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", - "AccessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", - "BucketName": "zy-irc-test-store", - "RoleArn": "acs:ram::1899121822495495:role/oss-upload", - "ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", - "Region": "oss-cn-shanghai" + "regionId": "cn-shanghai", + "endpoint": "https://oss-cn-shanghai.aliyuncs.com", + "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", + "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", + "bucketName": "zy-irc-test-store", + "roleArn": "acs:ram::1899121822495495:role/oss-upload", + "viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", + "region": "oss-cn-shanghai" }, "MinIO": { - "Endpoint": "http://192.168.3.68", - "Port": "8001", - "UseSSL": false, - "AccessKey": "IDFkwEpWej0b4DtiuThL", - "SecretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h", - "BucketName": "test" + "endpoint": "http://192.168.3.68", + "port": "8001", + "useSSL": false, + "accessKey": "IDFkwEpWej0b4DtiuThL", + "secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h", + "bucketName": "test" } }, diff --git a/IRaCIS.Core.API/appsettings.Uat_IRC.json b/IRaCIS.Core.API/appsettings.Uat_IRC.json index 570b586c7..f5ccb5824 100644 --- a/IRaCIS.Core.API/appsettings.Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.Uat_IRC.json @@ -22,6 +22,31 @@ "Region": "oss-cn-shanghai" }, + "ObjectStoreService": { + + "ObjectStoreUse": "AliyunOSS", + + "AliyunOSS": { + "regionId": "cn-shanghai", + "endpoint": "https://oss-cn-shanghai.aliyuncs.com", + "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", + "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", + "bucketName": "zy-irc-uat-store", + "roleArn": "acs:ram::1899121822495495:role/oss-upload", + "viewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com", + "region": "oss-cn-shanghai" + }, + + "MinIO": { + "endpoint": "http://192.168.3.68", + "port": "8001", + "useSSL": false, + "accessKey": "IDFkwEpWej0b4DtiuThL", + "secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h", + "bucketName": "test" + } + }, + "BasicSystemConfig": { "OpenUserComplexPassword": true, diff --git a/IRaCIS.Core.Application/Helper/FileConvertHelper.cs b/IRaCIS.Core.Application/Helper/FileConvertHelper.cs new file mode 100644 index 000000000..fa6aa2324 --- /dev/null +++ b/IRaCIS.Core.Application/Helper/FileConvertHelper.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Application.Helper +{ + public class FileConvertHelper + { + + + static public void ConvertWordToPdf(string inputWordFilePath, string outputPdfDir) + { + // 设置 libreoffice 命令行参数 + string arguments = $"--headless --invisible --convert-to pdf \"{inputWordFilePath}\" --outdir \"{outputPdfDir}\""; + + // 启动 libreoffice 进程 + using (Process process = new Process()) + { + process.StartInfo.FileName = "libreoffice"; + process.StartInfo.Arguments = arguments; + process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + process.StartInfo.RedirectStandardOutput = true; + process.StartInfo.RedirectStandardError = true; + process.StartInfo.UseShellExecute = false; + process.StartInfo.CreateNoWindow = true; + + process.Start(); + + // 等待进程结束 + process.WaitForExit(); + } + } + + + } +} diff --git a/IRaCIS.Core.Application/Helper/OSSService.cs b/IRaCIS.Core.Application/Helper/OSSService.cs index c83ec5fc4..66ecfbbec 100644 --- a/IRaCIS.Core.Application/Helper/OSSService.cs +++ b/IRaCIS.Core.Application/Helper/OSSService.cs @@ -18,27 +18,27 @@ namespace IRaCIS.Core.Application.Helper { public class MinIOOptions { - public string Endpoint { get; set; } - public string Port { get; set; } - public bool UseSSL { get; set; } - public string AccessKey { get; set; } - public string SecretKey { get; set; } - public string BucketName { get; set; } + public string endpoint { get; set; } + public string port { get; set; } + public bool useSSL { get; set; } + public string accessKey { get; set; } + public string secretKey { get; set; } + public string bucketName { get; set; } } public class AliyunOSSOptions { - public string RegionId { get; set; } - public string AccessKeyId { get; set; } - public string AccessKeySecret { get; set; } - public string EndPoint { get; set; } - public string BucketName { get; set; } + public string regionId { get; set; } + public string accessKeyId { get; set; } + public string accessKeySecret { get; set; } + public string endPoint { get; set; } + public string bucketName { get; set; } - public string RoleArn { get; set; } + public string roleArn { get; set; } - public string Region { get; set; } + public string region { get; set; } - public string ViewEndpoint { get; set; } + public string viewEndpoint { get; set; } } @@ -53,7 +53,8 @@ namespace IRaCIS.Core.Application.Helper public class ObjectStoreDTO { public string ObjectStoreUse { get; set; } - public AliyunOSSTempToken AliyunOSS { get; set; } + + public AliyunOSSOptions AliyunOSS { get; set; } public MinIOOptions MinIO { get; set; } @@ -109,7 +110,7 @@ namespace IRaCIS.Core.Application.Helper _OSSConfig = ossOptions; - _ossClient = new OssClient(_OSSConfig.EndPoint, _OSSConfig.AccessKeyId, _OSSConfig.AccessKeySecret); + _ossClient = new OssClient(_OSSConfig.endPoint, _OSSConfig.accessKeyId, _OSSConfig.accessKeySecret); } @@ -137,7 +138,7 @@ namespace IRaCIS.Core.Application.Helper memoryStream.Seek(0, SeekOrigin.Begin); // 上传文件 - var result = _ossClient.PutObject(_OSSConfig.BucketName, ossRelativePath, memoryStream); + var result = _ossClient.PutObject(_OSSConfig.bucketName, ossRelativePath, memoryStream); } @@ -167,7 +168,7 @@ namespace IRaCIS.Core.Application.Helper try { // 上传文件 - var result = _ossClient.PutObject(_OSSConfig.BucketName, ossRelativePath, localFilePath); + var result = _ossClient.PutObject(_OSSConfig.bucketName, ossRelativePath, localFilePath); return ossRelativePath; } @@ -182,7 +183,7 @@ namespace IRaCIS.Core.Application.Helper { try { - var result = _ossClient.GetObject(_OSSConfig.BucketName, ossRelativePath); + var result = _ossClient.GetObject(_OSSConfig.bucketName, ossRelativePath); // 将下载的文件流保存到本地文件 using (var fs = File.OpenWrite(localFilePath)) diff --git a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs index 91d9e117e..9a250344c 100644 --- a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs +++ b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs @@ -23,6 +23,9 @@ using System.Linq; using Spire.Doc; using Microsoft.AspNetCore.Http; using System; +using System.Runtime.InteropServices; +using SharpCompress.Common; +using SkiaSharp; namespace IRaCIS.Core.Application.Service { @@ -58,7 +61,7 @@ namespace IRaCIS.Core.Application.Service IRepository subjectVisitRepository, IRepository trialEmailBlackUserRepository, IRepository emailNoticeConfigRepository -, IEmailSendService emailSendService +, IEmailSendService emailSendService ) { _trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository; @@ -634,7 +637,7 @@ namespace IRaCIS.Core.Application.Service FileStream = File.OpenRead(phyPath), }); - + await SendEmailHelper.SendEmailAsync(sendEmailConfig); return string.Empty; @@ -662,13 +665,31 @@ namespace IRaCIS.Core.Application.Service MemoryStream wordMemoryStream = new MemoryStream(); - Document document = new Document(); MiniSoftware.MiniWord.SaveAsByTemplate(wordMemoryStream, path, value); - document.LoadFromStream(wordMemoryStream, FileFormat.Docx); - document.SaveToFile(serverFilePath, FileFormat.PDF); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Document document = new Document(); + + document.LoadFromStream(wordMemoryStream, FileFormat.Docx); + + document.SaveToFile(serverFilePath, FileFormat.PDF); + } + else + { + var wordStoreServerPath = Path.Combine(Path.GetDirectoryName(serverFilePath), Path.GetFileNameWithoutExtension(serverFilePath)+".docx"); + + using (FileStream fileStream = new FileStream(wordStoreServerPath, FileMode.Create, FileAccess.Write)) + { + wordMemoryStream.WriteTo(fileStream); + } + FileConvertHelper.ConvertWordToPdf(wordStoreServerPath, Path.GetDirectoryName(serverFilePath)); + + File.Delete(wordStoreServerPath); + } + } @@ -686,17 +707,39 @@ namespace IRaCIS.Core.Application.Service { - MemoryStream memoryStream = new MemoryStream(); + MemoryStream wordMemoryStream = new MemoryStream(); MemoryStream pdfMemoryStream = new MemoryStream(); - MiniSoftware.MiniWord.SaveAsByTemplate(memoryStream, path, value); - Document document = new Document(); + MiniSoftware.MiniWord.SaveAsByTemplate(wordMemoryStream, path, value); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Document document = new Document(); + document.LoadFromStream(wordMemoryStream, FileFormat.Docx); + document.SaveToStream(pdfMemoryStream, FileFormat.PDF); + + } + else + { + var wordStoreServerPath = Path.Combine(Path.GetDirectoryName(serverFilePath), Path.GetFileNameWithoutExtension(serverFilePath) + ".docx"); + + using (FileStream fileStream = new FileStream(wordStoreServerPath, FileMode.Create, FileAccess.Write)) + { + wordMemoryStream.WriteTo(fileStream); + } + FileConvertHelper.ConvertWordToPdf(wordStoreServerPath, Path.GetDirectoryName(serverFilePath)); + + File.Delete(wordStoreServerPath); + + using (FileStream fileStream = new FileStream(serverFilePath, FileMode.Open, FileAccess.Read)) + { + fileStream.CopyTo(pdfMemoryStream); + } + + } - document.LoadFromStream(memoryStream, FileFormat.Docx); - document.SaveToStream(pdfMemoryStream, FileFormat.PDF); pdfMemoryStream.Seek(0, SeekOrigin.Begin); - sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig() { FileName = $"{taskInfo.SubjectCode}_{Path.GetFileNameWithoutExtension(_userInfo.IsEn_Us ? trialEmailConfig.AttachName : trialEmailConfig.AttachNameCN)}.pdf", diff --git a/IRaCIS.Core.Application/Service/Institution/HospitalService.cs b/IRaCIS.Core.Application/Service/Institution/HospitalService.cs index 2707fb556..6ce0a8f22 100644 --- a/IRaCIS.Core.Application/Service/Institution/HospitalService.cs +++ b/IRaCIS.Core.Application/Service/Institution/HospitalService.cs @@ -60,10 +60,7 @@ namespace IRaCIS.Application.Services //---该医院下已经注册有医生,不可以删除。 return ResponseOutput.NotOk(_localizer["Hospital_HasDoctors"]); } - //if (_userRepository.Find().Any(t => t.OrganizationId == hospitalId)) - //{ - // return ResponseOutput.NotOk("该医院下存在用户,暂时无法删除。"); - //} + var success = await _hospitalRepository.BatchDeleteNoTrackingAsync(x => x.Id == hospitalId); diff --git a/IRaCIS.Core.Application/Service/Institution/SiteService.cs b/IRaCIS.Core.Application/Service/Institution/SiteService.cs index b65b2379f..4a78b453a 100644 --- a/IRaCIS.Core.Application/Service/Institution/SiteService.cs +++ b/IRaCIS.Core.Application/Service/Institution/SiteService.cs @@ -31,8 +31,8 @@ namespace IRaCIS.Application.Services .WhereIf(!string.IsNullOrWhiteSpace(searchModel.AliasName), t => t.AliasName.Contains(searchModel.AliasName)) .WhereIf(!string.IsNullOrWhiteSpace(searchModel.City), t => t.City.Contains(searchModel.City)) .WhereIf(!string.IsNullOrWhiteSpace(searchModel.Country), t => t.Country.Contains(searchModel.Country)) - .WhereIf(!string.IsNullOrWhiteSpace(searchModel.Province), t => t.Country.Contains(searchModel.Province)) - .ProjectTo(_mapper.ConfigurationProvider); + .WhereIf(!string.IsNullOrWhiteSpace(searchModel.Province), t => t.Province.Contains(searchModel.Province)) + .ProjectTo(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }); return await siteQueryable.ToPagedListAsync(searchModel.PageIndex, searchModel.PageSize, string.IsNullOrWhiteSpace(searchModel.SortField) ? "SiteName" : searchModel.SortField, searchModel.Asc); @@ -76,11 +76,6 @@ namespace IRaCIS.Application.Services } - - - - - } /// 删除研究中心 diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs index fcf08c590..41ffe590f 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs @@ -109,7 +109,7 @@ namespace IRaCIS.Core.Application.Service CreateMap() - .ForMember(d => d.HospitalName, u => u.MapFrom(s => s.Hospital.HospitalName)); + .ForMember(d => d.HospitalName, u => u.MapFrom(s => isEn_Us? s.Hospital.HospitalName:s.Hospital.HospitalNameCN)); //trial site 选择列表 subjectVisit pannel 模式添加的时候 diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index 582fba034..8128b08df 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -69,8 +69,8 @@ namespace IRaCIS.Application.Services var minIO = options.CurrentValue.MinIO; - var minioClient = new MinioClient().WithEndpoint($"{minIO.Endpoint}:{minIO.Port}") - .WithCredentials(minIO.AccessKey,minIO.SecretKey) + var minioClient = new MinioClient().WithEndpoint($"{minIO.endpoint}:{minIO.port}") + .WithCredentials(minIO.accessKey,minIO.secretKey) .Build(); diff --git a/IRaCIS.Core.Domain/Institution/Site.cs b/IRaCIS.Core.Domain/Institution/Site.cs index feeeaa044..7bfbbbf7c 100644 --- a/IRaCIS.Core.Domain/Institution/Site.cs +++ b/IRaCIS.Core.Domain/Institution/Site.cs @@ -8,6 +8,7 @@ namespace IRaCIS.Core.Domain.Models public partial class Site : Entity, IAuditUpdate, IAuditAdd { [JsonIgnore] + [ForeignKey("HospitalId")] public Hospital Hospital { get; set; } public string SiteName { get; set; } = string.Empty; public string SiteNameCN{ get; set; } = string.Empty;