From ed2b53192ba50b916b4b6fe1282d08a35bdc7c9c Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 6 Apr 2022 08:58:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E6=98=8E=E8=8A=82=E5=89=8D=E5=AF=BC?= =?UTF-8?q?=E8=A1=A8=E9=A2=84=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- .../Controllers/DownLoadController.cs | 2 + IRaCIS.Core.API/Startup.cs | 6 +- .../BusinessFilter/NotDefault.cs | 25 ++++ .../IRaCIS.Core.Application.csproj | 39 +++--- .../Service/QC/QCOperationService.cs | 59 ++++++++- .../DTO/TrialSiteUserSurveyViewModel.cs | 2 - .../TrialSiteUser/DTO/UserTrialViewModel.cs | 70 ++++++++-- .../TrialSiteUser/TrialExternalUserService.cs | 16 ++- .../TrialSiteUser/TrialMaintenanceService.cs | 120 +++++++++--------- .../Service/TrialSiteUser/TrialSiteService.cs | 86 ++++++++++++- .../Service/TrialSiteUser/_MapConfig.cs | 17 ++- .../ConsistencyVerificationRequest.cs | 62 +++++++++ .../User/TrialExternalEnum.cs | 8 ++ 14 files changed, 405 insertions(+), 110 deletions(-) diff --git a/.gitignore b/.gitignore index 9491a2fda..490c28f8c 100644 --- a/.gitignore +++ b/.gitignore @@ -360,4 +360,5 @@ MigrationBackup/ .ionide/ # Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file +FodyWeavers.xsd +/UploadFile/Check diff --git a/IRaCIS.Core.API/Controllers/DownLoadController.cs b/IRaCIS.Core.API/Controllers/DownLoadController.cs index a2884d90c..e6b51bbce 100644 --- a/IRaCIS.Core.API/Controllers/DownLoadController.cs +++ b/IRaCIS.Core.API/Controllers/DownLoadController.cs @@ -79,6 +79,8 @@ namespace IRaCIS.Core.API.Controllers } new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(filePath), out var contentType); + + return File(System.IO.File.OpenRead(filePath), contentType ?? "application/octet-stream", doc.Name); diff --git a/IRaCIS.Core.API/Startup.cs b/IRaCIS.Core.API/Startup.cs index 7c6350140..abe8502bd 100644 --- a/IRaCIS.Core.API/Startup.cs +++ b/IRaCIS.Core.API/Startup.cs @@ -17,6 +17,8 @@ using IRaCIS.Core.Infra.EFCore; using System.Globalization; using Microsoft.AspNetCore.Localization; using Localization; +using Magicodes.ExporterAndImporter.Core.Filters; +using IRaCIS.Core.Application.MediatR.CommandAndQueries; namespace IRaCIS.Core.API { @@ -125,7 +127,9 @@ namespace IRaCIS.Core.API //DicomӰȾͼƬ ƽ̨ services.AddDicomSetup(); - + + //services.AddSingleton(); + } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/IRaCIS.Core.Application/BusinessFilter/NotDefault.cs b/IRaCIS.Core.Application/BusinessFilter/NotDefault.cs index 6c644b315..b67f35b5c 100644 --- a/IRaCIS.Core.Application/BusinessFilter/NotDefault.cs +++ b/IRaCIS.Core.Application/BusinessFilter/NotDefault.cs @@ -50,4 +50,29 @@ return true; } } + + + public class CanConvertToTimeAttribute : ValidationAttribute + { + public const string DefaultErrorMessage = "The {0} field is is not a valid DateTime value"; + public CanConvertToTimeAttribute() : base(DefaultErrorMessage) { } + + public override bool IsValid(object? value) + { + if (value is null) + { + return false; + } + + if (DateTime.TryParse(value.ToString(), out _) == true) + { + return true; + } + else + { + return false; + } + } + } + } diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index 55bd3da97..22b0fd495 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -60,36 +60,37 @@ - - - + + + - + - - - - + + + + + - - - + + + - - - - + + + + - - - + + + - + diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs index e527c06df..ca39d9b2a 100644 --- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs @@ -17,6 +17,9 @@ using IRaCIS.Core.Infra.EFCore; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Authorization; using WinSCP; +using Magicodes.ExporterAndImporter.Excel; +using Newtonsoft.Json; +using Magicodes.ExporterAndImporter.Csv; namespace IRaCIS.Core.Application.Image.QA { @@ -569,15 +572,59 @@ namespace IRaCIS.Core.Application.Image.QA var etcCheckList = new List(); - if (fileName.EndsWith(".csv")) + + + #region MiniExcel 需要自己验证数据格式规范 + + //if (fileName.EndsWith(".csv")) + //{ + // //因为csv 需要加配置文件 不然都是null + // etcCheckList = MiniExcel.Query(filePath, null, configuration: config).ToList(); + //} + //else if (fileName.EndsWith(".xlsx")) + //{ + // + + + // etcCheckList = MiniExcel.Query(filePath).ToList(); + //} + + #endregion + + //Magicodes 支持自定义特性验证 + if (fileName.EndsWith(".xlsx")) { + var Importer = new ExcelImporter(); + + var import = await Importer.Import(File.OpenRead(filePath)); + + if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString()); + + if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors)); + + if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors)); + + etcCheckList = import.Data.ToList(); + } + else if (fileName.EndsWith(".csv")) + { + //因为csv 需要加配置文件 不然都是null - etcCheckList = MiniExcel.Query(filePath, null, configuration: config).ToList(); - } - else if (fileName.EndsWith(".xlsx")) - { - etcCheckList = MiniExcel.Query(filePath).ToList(); + etcCheckList = MiniExcel.Query(filePath, null, configuration: config).ToList(); + + //var Importer = new CsvImporter(); + + //var import = await Importer.Import(File.OpenRead(filePath)); + + //if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString()); + + //if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors)); + + //if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors)); + + //etcCheckList = import.Data.ToList(); } + //ExcelReaderFactory 需要自己验证数据 并且从固定列取数据 else { //为了支持 xls 引入新的组件库 diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteUserSurveyViewModel.cs b/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteUserSurveyViewModel.cs index 5b6e67358..a4fa5be1b 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteUserSurveyViewModel.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteUserSurveyViewModel.cs @@ -50,8 +50,6 @@ namespace IRaCIS.Core.Application.Contracts public Guid? SystemUserId { get; set; } - - } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs index 40554eccf..09a14a85f 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs @@ -3,6 +3,8 @@ using IRaCIS.Core.Infrastructure.Extention; using IRaCIS.Core.Domain.Share; using Magicodes.ExporterAndImporter.Core; using MiniExcelLibs.Attributes; +using Newtonsoft.Json; +using IRaCIS.Core.Application.Contracts; namespace IRaCIS.Application.Contracts { @@ -12,14 +14,19 @@ namespace IRaCIS.Application.Contracts public class UserTrialDTO : UserTrialCommand { + [JsonIgnore] + public string State => IsDeleted ? "退出" : "加入"; public bool IsDeleted { get; set; } + + [ExcelFormat("yyyy-mm-dd hh:mm:ss")] public DateTime? DeletedTime { get; set; } public Guid? SiteId { get; set; } public string Phone { get; set; } = String.Empty; public DateTime UpdateTime { get; set; } + [ExcelFormat("yyyy-mm-dd hh:mm:ss")] public DateTime CreateTime { get; set; } @@ -38,25 +45,34 @@ namespace IRaCIS.Application.Contracts public class TrialMaintenanceDTO : UserTrialCommand { - //[ValueMapping(text: "退出", true)] - //[ValueMapping(text: "加入", false)] - [ExcelFormat("yyyy-mm-dd hh:mm:ss")] - public bool IsDeleted { get; set; } - + //For MiniExcel ExcelFormat public string State => IsDeleted ? "退出" : "加入"; - //[ExporterHeader(Format = "yyyy-mm-dd hh:mm:ss")] + + [ValueMapping(text: "退出", true)] + [ValueMapping(text: "加入", false)] + public bool IsDeleted { get; set; } + + [ExporterHeader(Format = "yyyy-mm-DD hh:mm:ss")] [ExcelFormat("yyyy-mm-dd hh:mm:ss")] public DateTime? DeletedTime { get; set; } + + [ExporterHeader(Format = "yyyy-mm-DD")] [ExcelFormat("yyyy-mm-dd")] public DateTime? RemoveTime { get; set; } - [ExcelFormat("yyyy-mm-dd ")] + + [ExporterHeader(Format = "yyyy-mm-DD")] + [ExcelFormat("yyyy-mm-DD")] public DateTime? JoinTime { get; set; } - [ExcelFormat("yyyy-mm-dd hh:mm:ss")] + + [ExporterHeader(Format = "yyyy-mm-DD hh:mm:ss")] + [ExcelFormat("yyyy-mm-DD hh:mm:ss")] public DateTime CreateTime { get; set; } + + public string Phone { get; set; } = String.Empty; public string EMail { get; set; } = string.Empty; @@ -78,7 +94,7 @@ namespace IRaCIS.Application.Contracts } - public class TrialUserExportDTO: TrialSelectDTO + public class TrialUserExportDTO : TrialSelectDTO { public DateTime CurrentTime { get; set; } = DateTime.Now; @@ -86,6 +102,34 @@ namespace IRaCIS.Application.Contracts } + public class TrialSiteUserExportDto : TrialSelectDTO + { + public DateTime CurrentTime { get; set; } = DateTime.Now; + + public List TrialSiteUserList { get; set; } = new List(); + } + public class SiteUserExportDTO : UserTrialDTO + { + public string TrialSiteCode { get; set; } = String.Empty; + public string TrialSiteAliasName { get; set; } = String.Empty; + } + + public class TrialSiteUserSummaryExportDto : TrialSelectDTO + { + public DateTime CurrentTime { get; set; } = DateTime.Now; + + public List TrialSiteUserList { get; set; } = new List(); + + } + + public class TrialSiteUserSummaryDto: TrialSiteUserSurveyView + { + public string TrialSiteCode { get; set; } = String.Empty; + public string TrialSiteAliasName { get; set; } = String.Empty; + } + + + public class SiteCRCCommand : UserTrialCommand { public Guid SiteId { get; set; } @@ -164,7 +208,7 @@ namespace IRaCIS.Application.Contracts public List UserNameList { get; set; } = new List(); } - + @@ -175,7 +219,7 @@ namespace IRaCIS.Application.Contracts public string UserRealName { get; set; } = string.Empty; //public string UserType { get; set; } = string.Empty; - public Guid? UserTypeId { get; set; } + public Guid? UserTypeId { get; set; } public string UserName { get; set; } = string.Empty; @@ -197,7 +241,7 @@ namespace IRaCIS.Application.Contracts } - + public class TrialUserQuery : PageInput { @@ -253,7 +297,7 @@ namespace IRaCIS.Application.Contracts [NotDefault] public Guid Id { get; set; } - public Guid TrialId { get; set; } + public Guid TrialId { get; set; } public bool IsDeleted { get; set; } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialExternalUserService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialExternalUserService.cs index a632e7bd0..112ef6ca8 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialExternalUserService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialExternalUserService.cs @@ -241,16 +241,22 @@ namespace IRaCIS.Core.Application.Service 您好,展影医疗作为 实验方案号:{trialInfo.ResearchProgramNo} 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢! -
- -
+ + + + 查看并确认 + "; - - messageToSend.Body = builder.ToMessageBody(); + //< form action = '#' method = 'post' > + + // < button type = 'submit' style = 'margin-left:60px;font-size:14px;text-decoration: none;display: inline-block;height: 40px;width: 140px;background: #00D1B2;color:#fff;border-radius: 5px;line-height: 40px;text-align: center;border:none;margin-bottom: 100px;cursor: pointer' > 查看并确认 + + // + messageToSend.Body = builder.ToMessageBody(); using (var smtp = new MailKit.Net.Smtp.SmtpClient()) { diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs index b7c71efbf..4357b97e7 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs @@ -26,6 +26,67 @@ namespace IRaCIS.Application.Services _trialRepository = trialRepository; } + + [HttpGet] + [AllowAnonymous] + public async Task TrialUserListExport(Guid trialId, [FromServices] IRepository _commonDocumentRepository) + { + + var doc = _commonDocumentRepository.AsQueryable(true).FirstOrDefault(t => t.Code == "TrialUserList_Export"); + + if (doc == null) + { + throw new Exception("当前code 没要找到对应的导出模板文件"); + } + + var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).FullName; + + var filePath = Path.Combine(rootPath, doc.Path.Trim('/')); + + if (!System.IO.File.Exists(filePath)) + { + throw new Exception("服务器本地不存在该路径文件"); + } + + + var exportInfo = await _trialRepository.Where(t => t.Id == trialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); + + + //模板路径 + var tplPath = filePath; + + + #region MiniExcel + + var memoryStream = new MemoryStream(); + + MiniExcel.SaveAsByTemplate(memoryStream, tplPath, exportInfo); + + memoryStream.Seek(0, SeekOrigin.Begin); + + return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + { + FileDownloadName = $"{doc.Name}_{DateTime.Now.ToString("yyyy-MM-dd:hh:mm:ss")}.xlsx" + }; + + #endregion + + + #region Magicodes 模板规则不一样 + + ////创建Excel导出对象 + //IExportFileByTemplate exporter = new ExcelExporter(); + + ////根据模板导出 + //var result = await exporter.ExportBytesByTemplate(exportInfo, tplPath); + + + //return new XlsxFileResult(bytes: result, fileDownloadName: $"{doc.Name}_{DateTime.Now.ToString("yyyy-MM-dd:hh:mm:ss")}.xlsx"); + #endregion + + + } + /// /// Setting页面 获取项目参与人员列表 /// @@ -49,65 +110,6 @@ namespace IRaCIS.Application.Services } - [HttpGet] - [AllowAnonymous] - public async Task TrialUserListExport(Guid trialId, [FromServices] IRepository _commonDocumentRepository) - { - - var doc = _commonDocumentRepository.AsQueryable(true).FirstOrDefault(t => t.Code == "Test"); - - if (doc == null) - { - throw new Exception("当前code 没要找到对应的文件"); - } - - var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).FullName; - - var filePath = Path.Combine(rootPath, doc.Path.Trim('/')); - - if (!System.IO.File.Exists(filePath)) - { - throw new Exception("服务器本地不存在该路径文件"); - } - - - var exportInfo = await _trialRepository.Where(t => t.Id == trialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); - - - //模板路径 - var tplPath = filePath; - - #region MiniExcel - - var memoryStream = new MemoryStream(); - - MiniExcel.SaveAsByTemplate(memoryStream, tplPath, exportInfo); - - memoryStream.Seek(0, SeekOrigin.Begin); - return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") - { - FileDownloadName = $"{doc.Name}_{DateTime.Now.ToString("yyyy-MM-dd:hh:mm:ss")}.xlsx" - }; - - #endregion - - - #region Magicodes - - //创建Excel导出对象 - IExportFileByTemplate exporter = new ExcelExporter(); - - //根据模板导出 - var result = await exporter.ExportBytesByTemplate(exportInfo, tplPath); - - - return new XlsxFileResult(bytes: result, fileDownloadName: $"{doc.Name}_{DateTime.Now.ToString("yyyy-MM-dd:hh:mm:ss")}.xlsx"); - #endregion - - - - - } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteService.cs index f2da007d1..170b87445 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteService.cs @@ -7,6 +7,8 @@ using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Interfaces; +using Microsoft.AspNetCore.Authorization; +using MiniExcelLibs; namespace IRaCIS.Core.Application.Services { @@ -16,15 +18,95 @@ namespace IRaCIS.Core.Application.Services private readonly IRepository _trialSiteRepository; private readonly IRepository _trialSiteUserRepository; private readonly IRepository _siteRepository; + private readonly IRepository _trialRepository; public TrialMaintenanceService(IRepository trialSiteRepository, IRepository trialSiteUserRepository - , IRepository siteRepository) + , IRepository siteRepository, IRepository trialRepository) { _trialSiteRepository = trialSiteRepository; _trialSiteUserRepository = trialSiteUserRepository; - this._siteRepository = siteRepository; + _siteRepository = siteRepository; + _trialRepository = trialRepository; } + + + [HttpGet, Route("{trialId:guid}/{isSiteUserNotAll:bool}")] + [AllowAnonymous] + public async Task TrialSiteUserListExport(Guid trialId, bool isAllSiteUser, + [FromServices] IRepository _commonDocumentRepository, + [FromServices] IRepository _trialSiteSurveyRepository, + [FromServices] IRepository _trialSiteUserSurveyRepository + ) + { + var code = isAllSiteUser ? "TrialSiteUserSummary_Export" : "TrialSiteUserList_Export"; + + var doc = _commonDocumentRepository.AsQueryable(true).FirstOrDefault(t => t.Code == code); + + if (doc == null) + { + throw new Exception("当前code 没要找到对应的导出模板文件"); + } + + var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).FullName; + + var filePath = Path.Combine(rootPath, doc.Path.Trim('/')); + + if (!System.IO.File.Exists(filePath)) + { + throw new Exception("服务器本地不存在该路径文件"); + } + + object exportInfo = default; + + if (isAllSiteUser == false) + { + exportInfo = await _trialRepository.Where(t => t.Id == trialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); + + } + else + { + + var data = await _trialRepository.Where(t => t.Id == trialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); + + var groupSelectIdQuery = + _trialSiteSurveyRepository.Where(t => t.TrialId == trialId && t.IsAbandon == false) + .GroupBy(t => t.SiteId) + .Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First()); + + + var query = _trialSiteUserSurveyRepository + .Where(t => groupSelectIdQuery.Contains(t.TrialSiteSurveyId)) + .ProjectTo(_mapper.ConfigurationProvider); + + data.TrialSiteUserList = await query.ToListAsync(); + + exportInfo = data; + } + + + + //模板路径 + var tplPath = filePath; + + #region MiniExcel + + var memoryStream = new MemoryStream(); + + MiniExcel.SaveAsByTemplate(memoryStream, tplPath, exportInfo); + + memoryStream.Seek(0, SeekOrigin.Begin); + + return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + { + FileDownloadName = $"{doc.Name}_{DateTime.Now.ToString("yyyy-MM-dd:hh:mm:ss")}.xlsx" + }; + + #endregion + + } + + /// Pannel 进去 SiteTab [HttpPost] public async Task> GetSiteCRCList(SiteCrcQueryDTO param) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs index 2dfbe8615..6b812ef27 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs @@ -201,9 +201,22 @@ namespace IRaCIS.Core.Application.Service CreateMap(); + + + + CreateMap(); + CreateMap().IncludeMembers(t=>t.User) + .ForMember(t => t.TrialSiteCode, u => u.MapFrom(c => c.TrialSite.TrialSiteCode)) + .ForMember(t => t.TrialSiteAliasName, u => u.MapFrom(c => c.TrialSite.TrialSiteAliasName)) + .ForMember(t => t.UserRealName, u => u.MapFrom(c => c.User.LastName + " / " + c.User.FirstName)) + .ForMember(t => t.UserType, u => u.MapFrom(c => c.User.UserTypeRole.UserTypeShortName)); + CreateMap(); + + + CreateMap() + .ForMember(t => t.TrialRoleName, u => u.MapFrom(d => d.TrialRoleName.Value)) + .ForMember(d => d.UserType, u => u.MapFrom(s => s.UserTypeRole.UserTypeShortName)); ; - - } } diff --git a/IRaCIS.Core.Application/_MediatR/CommandAndQueries/ConsistencyVerificationRequest.cs b/IRaCIS.Core.Application/_MediatR/CommandAndQueries/ConsistencyVerificationRequest.cs index f18087662..f7400d363 100644 --- a/IRaCIS.Core.Application/_MediatR/CommandAndQueries/ConsistencyVerificationRequest.cs +++ b/IRaCIS.Core.Application/_MediatR/CommandAndQueries/ConsistencyVerificationRequest.cs @@ -1,6 +1,11 @@ using Magicodes.ExporterAndImporter.Core; +using Magicodes.ExporterAndImporter.Core.Filters; +using Magicodes.ExporterAndImporter.Core.Models; +using Magicodes.ExporterAndImporter.Excel; using MediatR; using MiniExcelLibs.Attributes; +using System.ComponentModel.DataAnnotations; +using System.Linq; namespace IRaCIS.Core.Application.MediatR.CommandAndQueries { @@ -19,19 +24,76 @@ namespace IRaCIS.Core.Application.MediatR.CommandAndQueries public Guid StudyId { get; set; } } + + + public class ImportResultFilteTest : IImportResultFilter + { + + + public ImportResult Filter(ImportResult importResult) where T : class, new() + { + if (typeof(T).IsAssignableFrom(typeof(CheckViewModel))) + { + var data = (List)importResult.Data; + + var dt = DateTime.Now ; + + foreach (var item in data) + { + + var index= data.IndexOf(item); + if ( DateTime.TryParse(item.StudyDate, out dt) == false) + { + importResult.RowErrors.Add(new DataRowErrorInfo() { RowIndex = index, FieldErrors = new Dictionary { { "检查技术", "时间格式不对" } } }); + } + } + } + + return importResult; + } + } + + + + [ExcelImporter(/*ImportResultFilter = typeof(ImportResultFilteTest),*/ IsLabelingError = true)] + public class CheckViewModel { + [Required(ErrorMessage = "中心编号不能为空")] + [ImporterHeader(Name = "中心编号", AutoTrim = true)] [ExcelColumnName("中心编号")] public string SiteCode { get; set; } = string.Empty; + + + [Required(ErrorMessage = "受试者筛选号不能为空")] + [ImporterHeader(Name = "受试者筛选号", AutoTrim = true)] [ExcelColumnName("受试者筛选号")] public string SubjectCode { get; set; } = string.Empty; + + [Required(ErrorMessage = "访视名称不能为空")] + [ImporterHeader(Name = "访视名称", AutoTrim = true)] [ExcelColumnName("访视名称")] public string VisitName { get; set; } = string.Empty; + + + + [Required(ErrorMessage = "检查日期不能为空")] + [CanConvertToTime(ErrorMessage = "检查日期格式有问题")] + + [ImporterHeader(Name = "检查日期", AutoTrim = true)] [ExcelColumnName("检查日期")] public string StudyDate { get; set; } = string.Empty; + + + + [Required(ErrorMessage = "Modality不能为空")] + [ImporterHeader(Name = "检查技术", AutoTrim = true)] [ExcelColumnName("检查技术")] public string Modality { get; set; } = string.Empty; + + + public override bool Equals(object? obj) { if (obj == null) return false; diff --git a/IRaCIS.Core.Domain.Share/User/TrialExternalEnum.cs b/IRaCIS.Core.Domain.Share/User/TrialExternalEnum.cs index 97107bc1f..995019639 100644 --- a/IRaCIS.Core.Domain.Share/User/TrialExternalEnum.cs +++ b/IRaCIS.Core.Domain.Share/User/TrialExternalEnum.cs @@ -1,5 +1,7 @@  +using System.ComponentModel; + namespace IRaCIS.Core.Domain.Share { public enum TrialExternalUserStateEnum @@ -21,17 +23,23 @@ namespace IRaCIS.Core.Domain.Share public enum TrialSiteUserStateEnum { + [Description("待邀请")] //待发送 WaitSent = 0, + [Description("已邀请")] //已发送 HasSend = 1, + [Description("已确认")] //用户已确认 UserConfirmed = 2, + [Description("已拒绝")] + //用户已确认 UserReject = 3, + [Description("已超时")] OverTime = 4