From 5be941663bcd53a9f62ce7c0089399778a7a5414 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 9 Nov 2023 16:56:55 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E8=B0=83=E7=A0=94=E5=AF=BC=E5=85=A5=E5=92=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/UploadDownLoadController.cs | 104 ++++++++++++++++++ .../Service/Management/UserTypeService.cs | 4 +- .../Interface/ITrialSiteSurveyService.cs | 2 + .../SiteSurvey/TrialSiteSurveyService.cs | 1 + IRaCIS.Core.Domain.Share/User/UserType.cs | 7 +- 5 files changed, 111 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs index 93ad59670..a1dd8d861 100644 --- a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs +++ b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs @@ -946,6 +946,110 @@ namespace IRaCIS.Core.API.Controllers _userInfo = userInfo; } + [HttpPost, Route("TrialSiteSurvey/UploadTrialSiteSurveyUser")] + [DisableFormValueModelBinding] + [UnitOfWork] + public async Task UploadTrialSiteSurveyUser(Guid trialId, string baseUrl, string routeUrl, + [FromServices] IRepository _trialSiteRepository, + [FromServices] IRepository _usertypeRepository, + [FromServices] ITrialSiteSurveyService _trialSiteSurveyService) + { + var (serverFilePath, relativePath, fileName) = (string.Empty, string.Empty, string.Empty); + await FileUploadAsync(async (realFileName) => + { + fileName = realFileName; + + if (!fileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase)) + { + // 请用提供格式的模板excel上传需要处理的数据 + throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_TemplateUploadData")); + } + + (serverFilePath, relativePath) = FileStoreHelper.GetOtherFileUploadPath(_hostEnvironment, StaticData.Folder.TempFile, fileName); + + //FileStoreHelper.UploadOOS(serverFilePath, "testc/test", true); + + return serverFilePath; + }); + + //去掉空白行 + var excelList = MiniExcel.Query(serverFilePath).ToList() + .Where(t => !(string.IsNullOrWhiteSpace(t.TrialSiteCode) && string.IsNullOrWhiteSpace(t.FirstName) && string.IsNullOrWhiteSpace(t.LastName) && string.IsNullOrWhiteSpace(t.Email) + && string.IsNullOrWhiteSpace(t.Phone) && string.IsNullOrWhiteSpace(t.UserTypeStr) && string.IsNullOrWhiteSpace(t.OrganizationName))).ToList(); + + if (excelList.Any(t => string.IsNullOrWhiteSpace(t.TrialSiteCode) || string.IsNullOrWhiteSpace(t.FirstName) || string.IsNullOrWhiteSpace(t.LastName) || string.IsNullOrWhiteSpace(t.Email) || string.IsNullOrWhiteSpace(t.UserTypeStr))) + { + //请确保Excel中 每一行的 中心编号,姓名,邮箱,用户类型数据记录完整再进行上传 + throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_EnsureCompleteData")); + } + + var siteCodeList = excelList.Select(t => t.TrialSiteCode.Trim().ToUpper()).Distinct().ToList(); + + if (_trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode.ToUpper())).Count() != siteCodeList.Count) + { + //在项目中未找到该Excel中部分或全部中心 + throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidCenters")); + } + + if (excelList.GroupBy(t => new { t.TrialSiteCode, t.UserTypeStr, t.Email }).Any(g => g.Count() > 1)) + { + // 同一邮箱,同一用户类型,只能生成一个账户,请核查Excel数据 + + throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_CheckDuplicateAccounts")); + } + + if (excelList.Any(t => !t.Email.Contains("@"))) + { + //有邮箱不符合邮箱格式,请核查Excel数据 + throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidEmail")); + } + var generateUserTypeList = new List() { "CRC", "CRA" }; + + if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper()))) + { + //用户类型仅能为 CRC,SR,CRA 请核查Excel数据 + throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidUserType")); + } + if (excelList.Count == 0) + { + throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_NoValiddata")); + } + //处理好 用户类型 和用户类型枚举 + var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator ).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList(); + var siteList = _trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode)).Select(t => new { t.TrialSiteCode, t.SiteId }).ToList(); + + foreach (var item in excelList) + { + switch (item.UserTypeStr.ToUpper()) + { + case "CRC": + + item.UserTypeId = sysUserTypeList.FirstOrDefault(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).UserTypeId; + item.UserTypeEnum = UserTypeEnum.ClinicalResearchCoordinator; + break; + + case "CRA": + item.UserTypeId = sysUserTypeList.FirstOrDefault(t => t.UserTypeEnum == UserTypeEnum.CRA).UserTypeId; + item.UserTypeEnum = UserTypeEnum.CRA; + break; + + + + } + + item.SiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.ToUpper() == item.TrialSiteCode.ToUpper()).SiteId; + } + + + + await _trialSiteSurveyService.ImportGenerateAccountAndJoinTrialAsync(trialId, baseUrl, routeUrl, excelList.ToList()); + + return ResponseOutput.Ok(); + + + } + + /// 通用文件下载 [AllowAnonymous] [HttpGet("CommonDocument/DownloadCommonDoc")] diff --git a/IRaCIS.Core.Application/Service/Management/UserTypeService.cs b/IRaCIS.Core.Application/Service/Management/UserTypeService.cs index 1e55c1dd3..c3553372b 100644 --- a/IRaCIS.Core.Application/Service/Management/UserTypeService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserTypeService.cs @@ -113,13 +113,13 @@ namespace IRaCIS.Core.Application.Contracts if (userTypeSelectEnum == UserTypeSelectEnum.ExternalUser) { - userTypeEnums = new List() { UserTypeEnum.CPM, UserTypeEnum.SPM, UserTypeEnum.CPM, UserTypeEnum.SMM, UserTypeEnum.CMM, UserTypeEnum.EA }; + userTypeEnums = new List() { UserTypeEnum.CPM, UserTypeEnum.SPM, UserTypeEnum.CPM, UserTypeEnum.SMM, UserTypeEnum.CMM, UserTypeEnum.EA , UserTypeEnum.MC }; } if (userTypeSelectEnum == UserTypeSelectEnum.InnerUser) { - userTypeEnums = new List() { UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA ,UserTypeEnum.MW}; + userTypeEnums = new List() { UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA ,UserTypeEnum.MW,UserTypeEnum.MC}; if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin) { diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/Interface/ITrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/Interface/ITrialSiteSurveyService.cs index 6bc2fc3ec..526f29ca7 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/Interface/ITrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/Interface/ITrialSiteSurveyService.cs @@ -20,5 +20,7 @@ namespace IRaCIS.Core.Application.Contracts //Task TrialSurveyLock(Guid trialSiteSurveyId, bool isLock); //IResponseOutput TrialSurveySubmmit(Guid trialId, Guid trialSiteSurveyId); Task VerifySendCode(LoginDto userInfo, [FromServices] ITokenService _tokenService); + + Task ImportGenerateAccountAndJoinTrialAsync(Guid trialId, string baseUrl, string routeUrl, List list); } } \ No newline at end of file diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 1e6b9451c..a2253fa03 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -1013,5 +1013,6 @@ namespace IRaCIS.Core.Application.Contracts } + } } diff --git a/IRaCIS.Core.Domain.Share/User/UserType.cs b/IRaCIS.Core.Domain.Share/User/UserType.cs index d38149bdd..29d582894 100644 --- a/IRaCIS.Core.Domain.Share/User/UserType.cs +++ b/IRaCIS.Core.Domain.Share/User/UserType.cs @@ -15,11 +15,6 @@ IQC = 3, - ////简历管理人员 - //ResumeManager=4, - ////简历运维人员 - //ReviewerCoordinator = 5, - ReviewerCoordinator = 4, // 大屏展示 @@ -58,6 +53,8 @@ AIR=21, + MC=30, + //医生用户类型暂不处理 ShareImage = 125, From 2fe19dbf0e3885a5bbdb8a983be5dc97c521d9bb Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 10 Nov 2023 09:57:22 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E5=8C=BB=E5=AD=A6=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E6=A1=86=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/TaskMedicalReviewService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs index 770d89a9e..56a5ac007 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs @@ -295,7 +295,7 @@ namespace IRaCIS.Core.Application.Service [HttpGet("{trialId:guid}")] public async Task> GetMIMUserList(Guid trialId) { - var query = _trialUserRepository.Where(t => t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MIM && t.TrialId == trialId).Select(t => t.User).ProjectTo(_mapper.ConfigurationProvider); + var query = _trialUserRepository.Where(t => (t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MIM || t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MC) && t.TrialId == trialId).Select(t => t.User).ProjectTo(_mapper.ConfigurationProvider); return await query.ToListAsync(); } From c7b956344f98b4f462b277f63c1d49cbe424bbcf Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 10 Nov 2023 14:12:40 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=BB=93=E6=9E=9C=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/PersonalWorkstation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs index 11415ad04..b5f9171df 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs @@ -715,7 +715,7 @@ namespace IRaCIS.Core.Application //待审核通过,统计从已领取到QC提交之间的 已领取 待审核 审核中 (审核完成 领取人就会清理 所以只用查询当前领取人是自己的就好了) ToBeReviewedCount = t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.Id).Count() - }).Where(x => x.UrgentCount > 0); + }).Where(x => x.ToBeClaimedCount+x.ToBeReviewedCount > 0); var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ImageQualityToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc); From a118cbeb1e47a7fe8b5ac4c7ce11b66946fc43d0 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 10 Nov 2023 15:52:44 +0800 Subject: [PATCH 4/9] =?UTF-8?q?CRC=20=20=E5=BD=B1=E5=83=8F=E8=B4=A8?= =?UTF-8?q?=E7=96=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/PersonalWorkstation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs index b5f9171df..7a60a159a 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs @@ -529,7 +529,7 @@ namespace IRaCIS.Core.Application ToBeDealedCount = t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id)) .SelectMany(c => c.QCChallengeList) - .Where(u => u.IsClosed == false && u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IQC).Count(), + .Where(u => u.IsClosed == false && (u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IQC || u.LatestReplyUserId==null)).Count(), }).Where(x => x.ToBeDealedCount > 0); ; From 82212aac162c44654c1c516443e1c165037b01b6 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 10 Nov 2023 17:18:49 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=9F=E8=AE=A103=20-?= =?UTF-8?q?=E9=9C=80=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/PersonalWorkstation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs index 7a60a159a..3be1a7df3 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs @@ -655,7 +655,7 @@ namespace IRaCIS.Core.Application TrialCode = t.TrialCode, UrgentCount = t.SubjectVisitList .Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id)) - .Where(u => u.SubmitState == SubmitStateEnum.ToSubmit && u.IsUrgent).Count(), + .Where(u => u.SubmitState == SubmitStateEnum.ToSubmit && (u.IsEnrollmentConfirm ||u.PDState==PDStateEnum.PDProgress || u.Trial.IsUrgent ||u.Subject.IsUrgent)/*u.IsUrgent*/).Count(), ToBeDealedCount = t.SubjectVisitList From 1aaf5e10f4a502ad53ea1f7dcb9fcca123c1d049 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 13 Nov 2023 14:05:02 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/IRaCIS.Core.Application.xml | 7 +++++++ .../Service/TrialSiteUser/PersonalWorkstation.cs | 2 +- .../Service/TrialSiteUser/TrialService.cs | 2 +- IRaCIS.Core.Domain.Share/User/UserType.cs | 6 ++++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index e134eefbf..cce22df5d 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -10371,6 +10371,13 @@ + + + 批量删除项目QC问题 + + + + 批量添加 QC 问题 diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs index 3be1a7df3..f8c9eb00c 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs @@ -1108,7 +1108,7 @@ namespace IRaCIS.Core.Application .WhereIf(!string.IsNullOrEmpty(inQuery.Code), o => o.TrialCode.Contains(inQuery.Code)) .WhereIf(!string.IsNullOrEmpty(inQuery.ResearchProgramNo), o => o.ResearchProgramNo.Contains(inQuery.ResearchProgramNo)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.ExperimentName), o => o.ExperimentName.Contains(inQuery.ExperimentName)) - .WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id && t.IsDeleted == false) && t.IsDeleted == false) + .WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.Admin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.OP, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id && t.IsDeleted == false) && t.IsDeleted == false) .Select(t => new TrialToBeDoneDto() { TrialId = t.Id, diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs index d165c1cc4..22674f8ad 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs @@ -103,7 +103,7 @@ namespace IRaCIS.Application.Services public async Task> GetTrialSelect() { return await _trialRepository.AsQueryable().IgnoreQueryFilters() - .WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id) && t.IsDeleted == false) + .WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.Admin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.OP, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id) && t.IsDeleted == false) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); } diff --git a/IRaCIS.Core.Domain.Share/User/UserType.cs b/IRaCIS.Core.Domain.Share/User/UserType.cs index 29d582894..3e99ed0ff 100644 --- a/IRaCIS.Core.Domain.Share/User/UserType.cs +++ b/IRaCIS.Core.Domain.Share/User/UserType.cs @@ -53,8 +53,14 @@ AIR=21, + ZYSS=26, + + ZYBS=27, + MC=30, + OP=31, + //医生用户类型暂不处理 ShareImage = 125, From 5834ac7f37b1e4296d07a5589dd800ea7b5ba109 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 14 Nov 2023 10:11:37 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AF=BC=E8=A1=A8bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Helper/ExcelExportHelper.cs | 4 ++-- IRaCIS.Core.Application/Service/Common/ExcelExportService.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs b/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs index a7ea86977..04746abc0 100644 --- a/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs +++ b/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs @@ -146,7 +146,7 @@ public static class ExcelExportHelper } var memoryStream2 = new MemoryStream(); - workbook.Write(memoryStream2); + workbook.Write(memoryStream2,true); memoryStream2.Seek(0, SeekOrigin.Begin); @@ -316,7 +316,7 @@ public static class ExcelExportHelper } var memoryStream2 = new MemoryStream(); - workbook.Write(memoryStream2); + workbook.Write(memoryStream2,true); memoryStream2.Seek(0, SeekOrigin.Begin); diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index 3d377fd1b..a40c0b71a 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -491,7 +491,7 @@ namespace IRaCIS.Core.Application.Service.Common } var memoryStream2 = new MemoryStream(); - wb.Write(memoryStream2); + wb.Write(memoryStream2,true); memoryStream2.Seek(0, SeekOrigin.Begin); return new FileStreamResult(memoryStream2, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") From 2ce78f333bcd9dd603afa12d96e31d087cc97022 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 16 Nov 2023 09:15:14 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Domain.Share/User/UserType.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/IRaCIS.Core.Domain.Share/User/UserType.cs b/IRaCIS.Core.Domain.Share/User/UserType.cs index 3e99ed0ff..fb583c742 100644 --- a/IRaCIS.Core.Domain.Share/User/UserType.cs +++ b/IRaCIS.Core.Domain.Share/User/UserType.cs @@ -35,6 +35,7 @@ CPM=12, IndependentReviewer=13, + // 医学影像经理 MIM = 14, From 55b72a91565f55fe02aecbd96d6ae06ceb6053b1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 17 Nov 2023 17:55:19 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E5=AF=B9=E6=8E=A5MinIO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ExtraController.cs | 60 +++++++++++++++- IRaCIS.Core.API/Startup.cs | 3 +- IRaCIS.Core.API/appsettings.Development.json | 25 +++++++ IRaCIS.Core.Application/Helper/OSSService.cs | 72 ++++++++++++++----- .../IRaCIS.Core.Application.csproj | 1 + IRaCIS.Core.Application/TestService.cs | 21 +++++- 6 files changed, 161 insertions(+), 21 deletions(-) diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs index 5d43d4a61..193586589 100644 --- a/IRaCIS.Core.API/Controllers/ExtraController.cs +++ b/IRaCIS.Core.API/Controllers/ExtraController.cs @@ -206,9 +206,65 @@ namespace IRaCIS.Api.Controllers return ResponseOutput.Ok("/showdicom?studyId=f7b67793-8155-0223-2f15-118f2642efb8&type=Share&token=" + token); } + [HttpGet("user/GetObjectStoreToken")] + public IResponseOutput GetObjectStoreToken([FromServices] IOptionsMonitor options) + { + var serviceOption = options.CurrentValue; - [HttpGet("user/GenerateSTS")] - public IResponseOutput GenerateSTS([FromServices]IOptionsMonitor options ) + 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); + + + // 创建一个STS请求 + AssumeRoleRequest request = new AssumeRoleRequest + { + RoleArn = ossOptions.RoleArn, // 角色ARN,需要替换为你的角色ARN + RoleSessionName = $"session-name-{NewId.NextGuid()}", // 角色会话名称,可自定义 + DurationSeconds = 900, // 令牌有效期(单位:秒),这里设置为1小时 + }; + + + 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, + + Region = ossOptions.Region, + BucketName = ossOptions.BucketName, + ViewEndpoint = ossOptions.ViewEndpoint, + + }, + MinIO=serviceOption.MinIO + } + ; + + return ResponseOutput.Ok(stsToken); + } + else if(Enum.TryParse(serviceOption.ObjectStoreUse, out var parsedValue) && parsedValue == ObjectStoreUse.MinIO) + { + return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse=serviceOption.ObjectStoreUse,MinIO=serviceOption.MinIO}); + } + else + { + return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO }); + } + + } + + [HttpGet("user/GenerateSTS")] + public IResponseOutput GenerateSTS([FromServices]IOptionsMonitor options ) { var ossOptions = options.CurrentValue; diff --git a/IRaCIS.Core.API/Startup.cs b/IRaCIS.Core.API/Startup.cs index dcd24c696..3e071a8bc 100644 --- a/IRaCIS.Core.API/Startup.cs +++ b/IRaCIS.Core.API/Startup.cs @@ -93,7 +93,8 @@ namespace IRaCIS.Core.API services.AddOptions().Configure( _configuration.GetSection("SystemEmailSendConfig")); services.AddOptions().Configure(_configuration.GetSection("BasicSystemConfig")); - services.AddOptions().Configure(_configuration.GetSection("AliyunOSS")); + services.AddOptions().Configure(_configuration.GetSection("AliyunOSS")); + services.AddOptions().Configure(_configuration.GetSection("ObjectStoreService")); //̬WebApi + UnifiedApiResultFilter ʡ diff --git a/IRaCIS.Core.API/appsettings.Development.json b/IRaCIS.Core.API/appsettings.Development.json index 868d9187d..c4b06e481 100644 --- a/IRaCIS.Core.API/appsettings.Development.json +++ b/IRaCIS.Core.API/appsettings.Development.json @@ -12,6 +12,31 @@ }, + "ObjectStoreService": { + + "ObjectStoreUse": "AliyunOSS", + + "AliyunOSS": { + "RegionId": "cn-shanghai", + "Endpoint": "https://oss-cn-shanghai.aliyuncs.com", + "AccessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", + "AccessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", + "BucketName": "zyypacs", + "RoleArn": "acs:ram::1899121822495495:role/oss-upload", + "ViewEndpoint": "https://zyypacs.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" + } + }, + "AliyunOSS": { "RegionId": "cn-shanghai", "Endpoint": "https://oss-cn-shanghai.aliyuncs.com", diff --git a/IRaCIS.Core.Application/Helper/OSSService.cs b/IRaCIS.Core.Application/Helper/OSSService.cs index ff0a024fa..b4c5b5286 100644 --- a/IRaCIS.Core.Application/Helper/OSSService.cs +++ b/IRaCIS.Core.Application/Helper/OSSService.cs @@ -14,8 +14,17 @@ using System.Threading.Tasks; 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 class AliyunOssOptions + public class AliyunOSSOptions { public string RegionId { get; set; } public string AccessKeyId { get; set; } @@ -23,15 +32,56 @@ namespace IRaCIS.Core.Application.Helper 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 ViewEndpoint { get; set; } + } + + public class ObjectStoreServiceOptions + { + public string ObjectStoreUse { get; set; } + public AliyunOSSOptions AliyunOSS { get; set; } + public MinIOOptions MinIO { get; set; } } + public class ObjectStoreDTO + { + public string ObjectStoreUse { get; set; } + public AliyunOSSTempToken AliyunOSS { get; set; } + + public MinIOOptions MinIO { get; set; } + + } + + public class AliyunOSSTempToken + { + public string AccessKeyId { get; set; } + public string AccessKeySecret { get; set; } + public string SecurityToken { get; set; } + public string Expiration { get; set; } + + public string Region { get; set; } + public string BucketName { get; set; } + public string ViewEndpoint { get; set; } + } + + + + public enum ObjectStoreUse + { + AliyunOSS = 0, + MinIO = 1, + AWS = 2, + } + + + + + public interface IOSSService { @@ -41,29 +91,17 @@ namespace IRaCIS.Core.Application.Helper public class OSSService : IOSSService { - public AliyunOssOptions _OSSConfig { get; set; } + public AliyunOSSOptions _OSSConfig { get; set; } public OssClient _ossClient { get; set; } - public OSSService(IOptionsMonitor options) + public OSSService(IOptionsMonitor options) { var ossOptions = options.CurrentValue; - _OSSConfig= ossOptions; - - //_OSSConfig = new AliyunOssOptions() - //{ - // RegionId = ossOptions.RegionId, - // AccessKeyId = ossOptions.AccessKeyId, - // AccessKeySecret = ossOptions.AccessKeySecret, - // EndPoint = ossOptions.EndPoint, - // BucketName = ossOptions.BucketName, - // RoleArn = ossOptions.RoleArn, - // Region = ossOptions.Region, - // ViewEndpoint = ossOptions.ViewEndpoint - //}; + _OSSConfig = ossOptions; _ossClient = new OssClient(_OSSConfig.EndPoint, _OSSConfig.AccessKeyId, _OSSConfig.AccessKeySecret); diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index e717885ba..8153511fb 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -89,6 +89,7 @@ + true diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index 158e1a40b..582fba034 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -1,4 +1,6 @@ -using BeetleX.BNR; +using BeetleX; +using BeetleX.BNR; +using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Service; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Share; @@ -12,6 +14,8 @@ using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MiniExcelLibs; +using Minio; +using NPOI.POIFS.Crypt; using System.Linq.Expressions; using System.Reflection.Metadata; using System.Security.Cryptography; @@ -58,7 +62,22 @@ namespace IRaCIS.Application.Services //_cache = cache; } + [AllowAnonymous] + public async Task TestMinIO([FromServices] IOptionsMonitor options) + { + var minIO = options.CurrentValue.MinIO; + + + var minioClient = new MinioClient().WithEndpoint($"{minIO.Endpoint}:{minIO.Port}") + .WithCredentials(minIO.AccessKey,minIO.SecretKey) + .Build(); + + + + + return ResponseOutput.Ok(options); + } [AllowAnonymous] public async Task TestDistributedLock( )