Merge branch 'Test.Study' of http://192.168.3.69:3000/XCKJ/irc-netcore-api into Test.Study

Uat_Study
he 2023-09-01 15:47:02 +08:00
commit 5518609d54
13 changed files with 188 additions and 75 deletions

View File

@ -991,11 +991,14 @@ namespace IRaCIS.Core.API.Controllers
if (!fileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase)) if (!fileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase))
{ {
// 请用提供格式的模板excel上传需要处理的数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_TemplateUploadData")); throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_TemplateUploadData"));
} }
(serverFilePath, relativePath) = FileStoreHelper.GetOtherFileUploadPath(_hostEnvironment, StaticData.Folder.TempFile, fileName); (serverFilePath, relativePath) = FileStoreHelper.GetOtherFileUploadPath(_hostEnvironment, StaticData.Folder.TempFile, fileName);
//FileStoreHelper.UploadOOS(serverFilePath, "testc/test", true);
return serverFilePath; return serverFilePath;
}); });
@ -1006,6 +1009,7 @@ namespace IRaCIS.Core.API.Controllers
if (excelList.Any(t => string.IsNullOrWhiteSpace(t.TrialSiteCode) || string.IsNullOrWhiteSpace(t.FirstName) || string.IsNullOrWhiteSpace(t.LastName) || string.IsNullOrWhiteSpace(t.Email) || string.IsNullOrWhiteSpace(t.UserTypeStr))) 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")); throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_EnsureCompleteData"));
} }
@ -1013,25 +1017,33 @@ namespace IRaCIS.Core.API.Controllers
if (_trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode.ToUpper())).Count() != siteCodeList.Count) if (_trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode.ToUpper())).Count() != siteCodeList.Count)
{ {
//在项目中未找到该Excel中部分或全部中心
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidCenters")); throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidCenters"));
} }
if (excelList.GroupBy(t => new { t.UserTypeStr, t.Email }).Any(g => g.Count() > 1)) if (excelList.GroupBy(t => new {t.TrialSiteCode, t.UserTypeStr, t.Email }).Any(g => g.Count() > 1))
{ {
// 同一邮箱,同一用户类型,只能生成一个账户,请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_CheckDuplicateAccounts")); throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_CheckDuplicateAccounts"));
} }
if (excelList.Any(t => !t.Email.Contains("@"))) if (excelList.Any(t => !t.Email.Contains("@")))
{ {
//有邮箱不符合邮箱格式,请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidEmail")); throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidEmail"));
} }
var generateUserTypeList = new List<string>() { "CRC", "SR", "CRA" }; var generateUserTypeList = new List<string>() { "CRC", "SR", "CRA" };
if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper()))) if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper())))
{ {
//用户类型仅能为 CRC,SR,CRA 请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidUserType")); 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 || t.UserTypeEnum == UserTypeEnum.SR).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList(); var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.SR).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(); var siteList = _trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode)).Select(t => new { t.TrialSiteCode, t.SiteId }).ToList();
@ -1061,10 +1073,13 @@ namespace IRaCIS.Core.API.Controllers
item.SiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.ToUpper() == item.TrialSiteCode.ToUpper()).SiteId; item.SiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.ToUpper() == item.TrialSiteCode.ToUpper()).SiteId;
} }
await _trialSiteSurveyService.ImportGenerateAccountAndJoinTrialAsync(trialId, baseUrl, routeUrl, excelList.ToList()); await _trialSiteSurveyService.ImportGenerateAccountAndJoinTrialAsync(trialId, baseUrl, routeUrl, excelList.ToList());
return ResponseOutput.Ok(); return ResponseOutput.Ok();
} }

View File

@ -27,6 +27,8 @@ using Microsoft.AspNetCore.StaticFiles;
using IRaCIS.Application.Services.BackGroundJob; using IRaCIS.Application.Services.BackGroundJob;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Autofac.Core;
using DocumentFormat.OpenXml.InkML;
namespace IRaCIS.Core.API namespace IRaCIS.Core.API
{ {
@ -165,7 +167,7 @@ namespace IRaCIS.Core.API
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) public async void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{ {
//app.UsePathBase(PathString.FromUriComponent("/api")); //app.UsePathBase(PathString.FromUriComponent("/api"));
@ -242,7 +244,11 @@ namespace IRaCIS.Core.API
}); });
HangfireJobHelper.NotImmediatelyOnceOnlyJob<IIRaCISHangfireJob>(t => t.InitHangfireJobTaskAsync(),TimeSpan.FromSeconds(1)); var hangfireJobService = app.ApplicationServices.GetRequiredService<IIRaCISHangfireJob>();
await hangfireJobService.InitHangfireJobTaskAsync();
//有的时候每调用
//HangfireJobHelper.NotImmediatelyOnceOnlyJob<IIRaCISHangfireJob>(t => t.InitHangfireJobTaskAsync(),TimeSpan.FromSeconds(1));
} }

View File

@ -202,6 +202,14 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid? SouceReadModuleId { get; set; } public Guid? SouceReadModuleId { get; set; }
public List<PIReadingResult> PIReadingResultList { get; set; }
}
public class PIReadingResult
{
public Guid QuestionId { get; set; }
public string Answer { get; set; }
} }

View File

@ -44,6 +44,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
private readonly IRepository<VisitTaskReReading> _visitTaskReReadingRepository; private readonly IRepository<VisitTaskReReading> _visitTaskReReadingRepository;
private readonly IRepository<TaskMedicalReview> _taskMedicalReviewRepository; private readonly IRepository<TaskMedicalReview> _taskMedicalReviewRepository;
private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository; private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;
private readonly IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository;
private readonly IRepository<ReadingClinicalData> _readingClinicalDataReposiotry; private readonly IRepository<ReadingClinicalData> _readingClinicalDataReposiotry;
@ -59,7 +60,8 @@ namespace IRaCIS.Core.Application.Service.Allocation
IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository
, IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository, , IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository,
IRepository<ReadingClinicalData> readingClinicalDataReposiotry, IRepository<ReadingClinicalData> readingClinicalDataReposiotry,
IRepository<PIAudit> PIAuditRepository IRepository<PIAudit> PIAuditRepository,
IRepository<ReadingQuestionTrial> readingQuestionTrialRepository
) )
{ {
_PIAuditRepository = PIAuditRepository; _PIAuditRepository = PIAuditRepository;
@ -73,7 +75,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
_taskMedicalReviewRepository = taskMedicalReviewRepository; _taskMedicalReviewRepository = taskMedicalReviewRepository;
_readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository; _readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
_trialReadingCriterionRepository = trialReadingCriterionRepository; _trialReadingCriterionRepository = trialReadingCriterionRepository;
_readingQuestionTrialRepository = readingQuestionTrialRepository;
} }
/// <summary> /// <summary>
@ -232,6 +234,11 @@ namespace IRaCIS.Core.Application.Service.Allocation
var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialUrgentConfig>(_mapper.ConfigurationProvider).FirstOrDefault(); var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialUrgentConfig>(_mapper.ConfigurationProvider).FirstOrDefault();
var questionList = _readingQuestionTrialRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.ReadingQuestionCriterionTrialId == queryVisitTask.TrialReadingCriterionId)
.Where(t => t.IsJudgeQuestion == true)
.Select(t => new { QuestionId = t.Id, QuestionName = _userInfo.IsEn_Us ? t.QuestionEnName : t.QuestionName ,t.DictionaryCode}).ToList();
trialTaskConfig!.OtherObj = questionList;
return ResponseOutput.Ok(pageList, trialTaskConfig); return ResponseOutput.Ok(pageList, trialTaskConfig);
} }
@ -362,7 +369,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
public async Task<IResponseOutput<PageOutput<ReadingTaskView>>> GetReadingTaskList(VisitTaskQuery queryVisitTask) public async Task<IResponseOutput<PageOutput<ReadingTaskView>>> GetReadingTaskList(VisitTaskQuery queryVisitTask)
{ {
var visitTaskQueryable = GetReadingTaskQueryable(queryVisitTask) var visitTaskQueryable = GetReadingTaskQueryable(queryVisitTask)
.ProjectTo<ReadingTaskView>(_mapper.ConfigurationProvider); .ProjectTo<ReadingTaskView>(_mapper.ConfigurationProvider,new { isEn_Us =_userInfo.IsEn_Us });
var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) };
@ -370,6 +377,11 @@ namespace IRaCIS.Core.Application.Service.Allocation
var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialUrgentConfig>(_mapper.ConfigurationProvider).FirstOrDefault(); var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialUrgentConfig>(_mapper.ConfigurationProvider).FirstOrDefault();
var questionList = _readingQuestionTrialRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.Id == queryVisitTask.TrialReadingCriterionId)
.Where(t => t.IsJudgeQuestion == true)
.Select(t => new { QuestionId = t.Id, QuestionName = _userInfo.IsEn_Us ? t.QuestionEnName : t.QuestionName, t.DictionaryCode }).ToList();
trialTaskConfig!.OtherObj = questionList;
return ResponseOutput.Ok(pageList, trialTaskConfig); return ResponseOutput.Ok(pageList, trialTaskConfig);
} }

View File

@ -74,14 +74,16 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.PDState, t => t.MapFrom(u => u.SourceSubjectVisit.PDState)) ; .ForMember(o => o.PDState, t => t.MapFrom(u => u.SourceSubjectVisit.PDState)) ;
var isEn_Us = true;
CreateMap<VisitTask, JudgeVisitTaskView>().IncludeBase<VisitTask, VisitTaskView>() CreateMap<VisitTask, JudgeVisitTaskView>().IncludeBase<VisitTask, VisitTaskView>()
.ForMember(o => o.HistoryReadingDoctorUserList, t => t.MapFrom(u => u.JudgeVisitList)); .ForMember(o => o.HistoryReadingDoctorUserList, t => t.MapFrom(u => u.JudgeVisitList));
CreateMap<VisitTask, ReadingTaskView>().IncludeBase<VisitTask, VisitTaskView>(); CreateMap<VisitTask, ReadingTaskView>().IncludeBase<VisitTask, VisitTaskView>()
.ForMember(t=>t.PIReadingResultList,u=>u.MapFrom(c=>c.ReadingTaskQuestionAnswerList
.Where(t=>t.ReadingQuestionTrial.IsJudgeQuestion==true ).Select(d=>new PIReadingResult() { QuestionId= d.ReadingQuestionTrialId,Answer=d.Answer})));
CreateMap<VisitTask, PIReaingTaskView>().IncludeBase<VisitTask, ReadingTaskView>() CreateMap<VisitTask, PIReaingTaskView>().IncludeBase<VisitTask, ReadingTaskView>()
.ForMember(o => o.FirstAuditUserName, t => t.MapFrom(u => u.FirstAuditUser.UserName)) .ForMember(o => o.FirstAuditUserName, t => t.MapFrom(u => u.FirstAuditUser.UserName))

View File

@ -1,5 +1,7 @@
using DocumentFormat.OpenXml.EMMA; using DocumentFormat.OpenXml.EMMA;
using DocumentFormat.OpenXml.Spreadsheet; using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Application.Service.Reading.Dto;
@ -28,6 +30,7 @@ namespace IRaCIS.Core.Application.Service
Task SendTrialQCQuestionEmailAsync(Guid trialId); Task SendTrialQCQuestionEmailAsync(Guid trialId);
Task SendTrialImageQuestionAsync(Guid trialId); Task SendTrialImageQuestionAsync(Guid trialId);
Task SendPIAuditResultAsync(Guid visitTaskId);
} }
public class EmailSendService : BaseService, IEmailSendService public class EmailSendService : BaseService, IEmailSendService
@ -38,13 +41,18 @@ namespace IRaCIS.Core.Application.Service
private readonly IRepository<Trial> _trialRepository; private readonly IRepository<Trial> _trialRepository;
private readonly IDictionaryService _dictionaryService;
private readonly IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig; private readonly IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig;
public EmailSendService(IRepository<TrialEmailNoticeConfig> trialEmailNoticeConfigRepository, IRepository<EmailNoticeConfig> emailNoticeConfigRepository, IRepository<Trial> trialRepository, IOptionsMonitor<SystemEmailSendConfig> systemEmailSendConfig)
public readonly static string EmailNamePlaceholder="EmailNamePlaceholder";
public EmailSendService(IRepository<TrialEmailNoticeConfig> trialEmailNoticeConfigRepository, IRepository<EmailNoticeConfig> emailNoticeConfigRepository, IRepository<Trial> trialRepository, IOptionsMonitor<SystemEmailSendConfig> systemEmailSendConfig, IDictionaryService dictionaryService)
{ {
_trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository; _trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository;
_emailNoticeConfigRepository = emailNoticeConfigRepository; _emailNoticeConfigRepository = emailNoticeConfigRepository;
_trialRepository = trialRepository; _trialRepository = trialRepository;
_SystemEmailSendConfig = systemEmailSendConfig; _SystemEmailSendConfig = systemEmailSendConfig;
_dictionaryService = dictionaryService;
} }
//入组确认/PD确认 //入组确认/PD确认
@ -80,31 +88,33 @@ namespace IRaCIS.Core.Application.Service
}).FirstNotNullAsync(); }).FirstNotNullAsync();
var resultStr = _userInfo.IsEn_Us ? (result == true ? "Yes" : "No") : (result == true ? "是" : "否"); var isEn_us = _userInfo.IsEn_Us;
var resultStr = isEn_us ? (result == true ? "Yes" : "No") : (result == true ? "是" : "否");
if (isEnrollment == true) if (isEnrollment == true)
{ {
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig => Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
{ {
var topicStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode); var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode);
var htmlBodyStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN, var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
_userInfo.UserName, taskInfo.ResearchProgramNo, taskInfo.SubjectCode, resultStr); EmailNamePlaceholder, taskInfo.ResearchProgramNo, taskInfo.SubjectCode, resultStr);
return (topicStr, htmlBodyStr,null); return (topicStr, htmlBodyStr,isEn_us, null);
}; };
await SendTrialEmailAsync(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc); await SendTrialEmailAsync(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc);
} }
else else
{ {
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig => Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
{ {
var topicStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode, taskInfo.VisitName); var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode, taskInfo.VisitName);
var htmlBodyStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN, var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
_userInfo.UserName, taskInfo.ResearchProgramNo, taskInfo.SubjectCode, taskInfo.VisitName, resultStr); EmailNamePlaceholder, taskInfo.ResearchProgramNo, taskInfo.SubjectCode, taskInfo.VisitName, resultStr);
return (topicStr, htmlBodyStr,null); return (topicStr, htmlBodyStr, isEn_us, null);
}; };
await SendTrialEmailAsync(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc); await SendTrialEmailAsync(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc);
@ -120,6 +130,7 @@ namespace IRaCIS.Core.Application.Service
/// <returns></returns> /// <returns></returns>
public async Task SendTrialImageQCTaskEmailAsync(Guid trialId) public async Task SendTrialImageQCTaskEmailAsync(Guid trialId)
{ {
var isEn_us = false;
var trialInfo = await _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstNotNullAsync(); var trialInfo = await _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstNotNullAsync();
//找到 该项目的IQC 用户Id //找到 该项目的IQC 用户Id
@ -151,12 +162,12 @@ namespace IRaCIS.Core.Application.Service
if (sendStat != null && (sendStat.ToBeClaimedCount > 0 || sendStat.ToBeReviewedCount > 0)) if (sendStat != null && (sendStat.ToBeClaimedCount > 0 || sendStat.ToBeReviewedCount > 0))
{ {
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig => Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
{ {
var topicStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, trialInfo.ResearchProgramNo); var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, trialInfo.ResearchProgramNo);
var htmlBodyStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN, var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
user.FullName, DateTime.Now, sendStat.ToBeClaimedCount, sendStat.ToBeReviewedCount, _SystemEmailSendConfig.CurrentValue.SiteUrl); user.FullName, DateTime.Now, sendStat.ToBeClaimedCount, sendStat.ToBeReviewedCount, _SystemEmailSendConfig.CurrentValue.SiteUrl);
return (topicStr, htmlBodyStr, userId); return (topicStr, htmlBodyStr, false,userId);
}; };
await SendTrialEmailAsync(trialId, EmailBusinessScenario.QCTask, topicAndHtmlFunc); await SendTrialEmailAsync(trialId, EmailBusinessScenario.QCTask, topicAndHtmlFunc);
@ -171,7 +182,8 @@ namespace IRaCIS.Core.Application.Service
/// <returns></returns> /// <returns></returns>
public async Task SendTrialQCQuestionEmailAsync(Guid trialId) public async Task SendTrialQCQuestionEmailAsync(Guid trialId)
{ {
var trialInfo = _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstOrDefault(); var isEn_us = false;
var trialInfo = _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr,t.DeclarationTypeEnumList }).FirstOrDefault();
//找到 该项目的IQC 用户Id //找到 该项目的IQC 用户Id
var userList = await _repository.Where<TrialUser>(t => t.TrialId == trialId).Where(t => t.User.UserTypeEnum == UserTypeEnum.IQC).Select(t => new { t.UserId, t.User.FullName }).ToListAsync(); var userList = await _repository.Where<TrialUser>(t => t.TrialId == trialId).Where(t => t.User.UserTypeEnum == UserTypeEnum.IQC).Select(t => new { t.UserId, t.User.FullName }).ToListAsync();
@ -201,13 +213,13 @@ namespace IRaCIS.Core.Application.Service
if (sendStat != null && (sendStat.ToBeDealedCount > 0 || sendStat.ReUploadTobeDealedCount > 0)) if (sendStat != null && (sendStat.ToBeDealedCount > 0 || sendStat.ReUploadTobeDealedCount > 0))
{ {
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig => Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
{ {
var topicStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, trialInfo.ResearchProgramNo); var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, trialInfo.ResearchProgramNo);
var htmlBodyStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN, var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
user.FullName, DateTime.Now, sendStat.ToBeDealedCount- sendStat.ReUploadTobeDealedCount, sendStat.ReUploadTobeDealedCount, _SystemEmailSendConfig.CurrentValue.SiteUrl); user.FullName, DateTime.Now, sendStat.ToBeDealedCount- sendStat.ReUploadTobeDealedCount, sendStat.ReUploadTobeDealedCount, _SystemEmailSendConfig.CurrentValue.SiteUrl);
return (topicStr, htmlBodyStr, userId); return (topicStr, htmlBodyStr, false, userId);
}; };
await SendTrialEmailAsync(trialId, EmailBusinessScenario.QCQuestion, topicAndHtmlFunc); await SendTrialEmailAsync(trialId, EmailBusinessScenario.QCQuestion, topicAndHtmlFunc);
@ -222,6 +234,8 @@ namespace IRaCIS.Core.Application.Service
/// <returns></returns> /// <returns></returns>
public async Task SendTrialImageQuestionAsync(Guid trialId) public async Task SendTrialImageQuestionAsync(Guid trialId)
{ {
var isEn_us = false;
var trialInfo = _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstOrDefault(); var trialInfo = _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstOrDefault();
//找到 该项目的CRC 用户Id //找到 该项目的CRC 用户Id
@ -249,12 +263,12 @@ namespace IRaCIS.Core.Application.Service
if (sendStat != null && (sendStat.ToBeDealedCount > 0)) if (sendStat != null && (sendStat.ToBeDealedCount > 0))
{ {
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr,Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig => Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
{ {
var topicStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, trialInfo.ResearchProgramNo); var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, trialInfo.ResearchProgramNo);
var htmlBodyStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN, var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
user.FullName, DateTime.Now, sendStat.ToBeDealedCount, _SystemEmailSendConfig.CurrentValue.SiteUrl); user.FullName, DateTime.Now, sendStat.ToBeDealedCount, _SystemEmailSendConfig.CurrentValue.SiteUrl);
return (topicStr, htmlBodyStr,userId); return (topicStr, htmlBodyStr, isEn_us, userId);
}; };
await SendTrialEmailAsync(trialId, EmailBusinessScenario.ImageQuestion, topicAndHtmlFunc); await SendTrialEmailAsync(trialId, EmailBusinessScenario.ImageQuestion, topicAndHtmlFunc);
@ -266,24 +280,61 @@ namespace IRaCIS.Core.Application.Service
//临床数据质询 //临床数据质询
public async Task SendClinicalDataQuestionAsync(Guid visitTaskId, string content) public async Task SendClinicalDataQuestionAsync(Guid visitTaskId, string content)
{ {
var isEn_us = _userInfo.IsEn_Us;
var info = await _repository.Where<VisitTask>(t => t.Id == visitTaskId, ignoreQueryFilters: true).Select(t => new { t.TrialId, t.Trial.ResearchProgramNo, t.Trial.TrialCode, t.SourceSubjectVisit.VisitName, t.Subject.Code }).FirstOrDefaultAsync(); var info = await _repository.Where<VisitTask>(t => t.Id == visitTaskId, ignoreQueryFilters: true).Select(t => new { t.TrialId, t.Trial.ResearchProgramNo, t.Trial.TrialCode, t.SourceSubjectVisit.VisitName, t.Subject.Code }).FirstOrDefaultAsync();
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr,Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig => Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
{ {
var topicStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, info.ResearchProgramNo,info.Code,info.VisitName); var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, info.ResearchProgramNo,info.Code,info.VisitName);
var htmlBodyStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN, var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
_userInfo.UserName, info.ResearchProgramNo, info.Code, info.VisitName,_userInfo.UserName,content, _SystemEmailSendConfig.CurrentValue.SiteUrl); EmailNamePlaceholder, info.ResearchProgramNo, info.Code, info.VisitName,_userInfo.UserName,content, _SystemEmailSendConfig.CurrentValue.SiteUrl);
return (topicStr, htmlBodyStr,null); return (topicStr, htmlBodyStr, isEn_us, null);
}; };
await SendTrialEmailAsync(info.TrialId, EmailBusinessScenario.ClinicalDataQuestion, topicAndHtmlFunc); await SendTrialEmailAsync(info.TrialId, EmailBusinessScenario.ClinicalDataQuestion, topicAndHtmlFunc);
} }
public async Task SendPIAuditResultAsync(Guid visitTaskId)
{
var isEn_us = _userInfo.IsEn_Us;
var info = await _repository.Where<VisitTask>(t => t.Id == visitTaskId, ignoreQueryFilters: true).Select(t => new { t.TrialId, t.Trial.ResearchProgramNo, t.Trial.TrialCode, t.SourceSubjectVisit.VisitName, t.Subject.Code }).FirstOrDefaultAsync();
var answerList= await _repository.Where<VisitTask>(t => t.Id == visitTaskId, ignoreQueryFilters: true).SelectMany(t=>t.ReadingTaskQuestionAnswerList).Select(t=>new { QuestionName= isEn_us? t.ReadingQuestionTrial.QuestionEnName:t.ReadingQuestionTrial.QuestionName, t.ReadingQuestionTrial.DictionaryCode, t.Answer}).ToListAsync();
var template = " <div style=\"margin-left: 2ch;\"> {0}: {1} </div>";
var needTranslateDicNameList=answerList.Where(t=>!string.IsNullOrEmpty(t.DictionaryCode)).Select(t=>t.DictionaryCode).ToList();
var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslateDicNameList.ToArray());
public async Task SendTrialEmailAsync(Guid trialId, EmailBusinessScenario businessScenario, Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr,Guid? onlyToUserId)> topicAndHtmlFunc, Guid? trialReadingCriterionId = null, Guid? subjectId = null) Func<bool, string, string, string> transFunc = (bool isNeedTranslate, string dicCode, string answer) =>
{
var result = translateDataList[dicCode].Where(t => t.Code.ToLower() == answer.ToLower()).Select(t => isEn_us ? t.Value : t.ValueCN).FirstOrDefault();
return result;
};
var piResult= string.Join(' ', answerList.Select(t => string.Format(template, t.QuestionName, transFunc(!string.IsNullOrEmpty(t.DictionaryCode),t.DictionaryCode,t.Answer ) ))) ;
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc = trialEmailConfig =>
{
var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, info.ResearchProgramNo, info.Code, info.VisitName);
var htmlBodyStr = string.Format(isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
EmailNamePlaceholder, info.ResearchProgramNo, info.Code, info.VisitName, _userInfo.UserName, piResult, _SystemEmailSendConfig.CurrentValue.SiteUrl);
return (topicStr, htmlBodyStr, isEn_us, null);
};
await SendTrialEmailAsync(info.TrialId, EmailBusinessScenario.PIAuditResutl, topicAndHtmlFunc);
}
public async Task SendTrialEmailAsync(Guid trialId, EmailBusinessScenario businessScenario, Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr, bool isEn_us, Guid? onlyToUserId)> topicAndHtmlFunc, Guid? trialReadingCriterionId = null, Guid? subjectId = null)
{ {
//找到配置 //找到配置
var trialEmailConfig = await _trialEmailNoticeConfigRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.BusinessScenarioEnum == businessScenario, ignoreQueryFilters: true) var trialEmailConfig = await _trialEmailNoticeConfigRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.BusinessScenarioEnum == businessScenario, ignoreQueryFilters: true)
@ -294,12 +345,11 @@ namespace IRaCIS.Core.Application.Service
{ {
return; return;
} }
else else
{ {
var sendEmailConfig = new SMTPEmailConfig(); var sendEmailConfig = new SMTPEmailConfig();
var (topicStr, htmlBodyStr, onlyToUserId) = topicAndHtmlFunc(trialEmailConfig); var (topicStr, htmlBodyStr, isEn_us,onlyToUserId) = topicAndHtmlFunc(trialEmailConfig);
sendEmailConfig.TopicDescription = topicStr; sendEmailConfig.TopicDescription = topicStr;
@ -335,6 +385,10 @@ namespace IRaCIS.Core.Application.Service
{ {
toUserList= toUserList.Where(t=>t.UserId == onlyToUserId).ToList(); toUserList= toUserList.Where(t=>t.UserId == onlyToUserId).ToList();
} }
else
{
htmlBodyStr = htmlBodyStr.Replace(EmailNamePlaceholder, string.Join(isEn_us ? ", " : "、", toUserList.Select(t => t.FullName).ToList()));
}
if (toUserList.Count() == 0) if (toUserList.Count() == 0)
{ {
@ -348,7 +402,7 @@ namespace IRaCIS.Core.Application.Service
sendEmailConfig.FromEmailAddress = new MimeKit.MailboxAddress(trialEmailConfig.FromName, trialEmailConfig.FromEmail); sendEmailConfig.FromEmailAddress = new MimeKit.MailboxAddress(trialEmailConfig.FromName, trialEmailConfig.FromEmail);
sendEmailConfig.AuthorizationCode = trialEmailConfig.AuthorizationCode; sendEmailConfig.AuthorizationCode = trialEmailConfig.AuthorizationCode;
sendEmailConfig.UserName = trialEmailConfig.FromEmail; sendEmailConfig.UserName = trialEmailConfig.FromName;
sendEmailConfig.Host = trialEmailConfig.SMTPServerAddress; sendEmailConfig.Host = trialEmailConfig.SMTPServerAddress;
sendEmailConfig.Port = trialEmailConfig.SMTPServerPort; sendEmailConfig.Port = trialEmailConfig.SMTPServerPort;

View File

@ -12,7 +12,7 @@ namespace IRaCIS.Application.Contracts
{ {
public Guid? Id { get; set; } public Guid? Id { get; set; }
public string SiteName { get; set; } = String.Empty; public string SiteName { get; set; } = String.Empty;
public string SiteNameCN { get; set; } = String.Empty;
public int Code { get; set; } public int Code { get; set; }
public string SiteCode { get; set; } = String.Empty; public string SiteCode { get; set; } = String.Empty;

View File

@ -31,6 +31,7 @@ namespace IRaCIS.Application.Services
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.AliasName), t => t.AliasName.Contains(searchModel.AliasName)) .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.City), t => t.City.Contains(searchModel.City))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Country), t => t.Country.Contains(searchModel.Country)) .WhereIf(!string.IsNullOrWhiteSpace(searchModel.Country), t => t.Country.Contains(searchModel.Country))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Province), t => t.Country.Contains(searchModel.Province))
.ProjectTo<SiteSelectDTO>(_mapper.ConfigurationProvider); .ProjectTo<SiteSelectDTO>(_mapper.ConfigurationProvider);

View File

@ -119,7 +119,7 @@ namespace IRaCIS.Core.Application.Contracts
} }
else else
{ {
userTypeEnums = new List<UserTypeEnum>() { UserTypeEnum.PI, UserTypeEnum.MIM }; userTypeEnums = new List<UserTypeEnum>() { UserTypeEnum.PI, UserTypeEnum.MIM , UserTypeEnum.IQC};
} }
} }

View File

@ -333,7 +333,7 @@ namespace IRaCIS.Core.Application.Contracts
public UserTypeEnum? PDProgressDefaultUserType { get; set; } public UserTypeEnum? PDProgressDefaultUserType { get; set; }
public object OtherObj { get; set; }
} }
public class TrialStateChangeDTO public class TrialStateChangeDTO

View File

@ -10,33 +10,33 @@ using System.Linq.Expressions;
namespace IRaCIS.Core.Application.Triggers namespace IRaCIS.Core.Application.Triggers
{ {
public class VisitTaskIAfterSignTrigger : IAfterSaveTrigger<VisitTask> public class VisitTaskIAfterSignTrigger : IAfterSaveTrigger<VisitTask>,IBeforeSaveTrigger<VisitTask>
{ {
private readonly IRepository<VisitTask> _visitTaskRepository; private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IRepository<Subject> _subjectRepository; private readonly IRepository<Subject> _subjectRepository;
private readonly IUserInfo _userInfo;
private readonly IEmailSendService _emailSendService;
public VisitTaskIAfterSignTrigger(IRepository<VisitTask> visitTaskRepository, IRepository<Subject> subjectRepository) public VisitTaskIAfterSignTrigger(IRepository<VisitTask> visitTaskRepository, IRepository<Subject> subjectRepository, IUserInfo userInfo, IEmailSendService emailSendService)
{ {
_visitTaskRepository = visitTaskRepository; _visitTaskRepository = visitTaskRepository;
_subjectRepository = subjectRepository; _subjectRepository = subjectRepository;
_userInfo = userInfo;
_emailSendService = emailSendService;
} }
//添加任务的时候 如果需要签名 并且已经签名了
public async Task AfterSave(ITriggerContext<VisitTask> context, CancellationToken cancellationToken) public async Task AfterSave(ITriggerContext<VisitTask> context, CancellationToken cancellationToken)
{ {
var visitTask = context.Entity; var visitTask = context.Entity;
if (visitTask.SignTime != null && visitTask.ReadingTaskState == ReadingTaskState.HaveSigned if (visitTask.SignTime != null && visitTask.ReadingTaskState == ReadingTaskState.HaveSigned )
//&& _subjectRepository.Where(t=>t.Id==visitTask.SubjectId).SelectMany(c=>c.SubjectVisitList)
//.Any(t=>t.Id==visitTask.SourceSubjectVisitId && t.IsBaseLine)
)
{ {
//任务阅片完成 自动释放 //任务阅片完成 自动释放
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == visitTask.SubjectId && t.TrialReadingCriterionId==visitTask.TrialReadingCriterionId , t=>new VisitTask() { SubjectCriterionClaimUserId=null}); await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == visitTask.SubjectId && t.TrialReadingCriterionId==visitTask.TrialReadingCriterionId , t=>new VisitTask() { SubjectCriterionClaimUserId=null});
@ -45,6 +45,19 @@ namespace IRaCIS.Core.Application.Triggers
} }
public async Task BeforeSave(ITriggerContext<VisitTask> context, CancellationToken cancellationToken)
{
var visitTask = context.Entity;
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI)
{
visitTask.PIAuditState = PIAuditState.PIAgree;
}
if (context.ChangeType == ChangeType.Modified && visitTask.PIAuditState!=context.UnmodifiedEntity.PIAuditState && visitTask.PIAuditState==PIAuditState.PIAgree)
{
await _emailSendService.SendPIAuditResultAsync(visitTask.Id);
}
}
} }
} }

View File

@ -57,6 +57,8 @@ namespace IRaCIS.Core.Domain.Share
ImageQuestion = 7, ImageQuestion = 7,
ClinicalDataQuestion = 8, ClinicalDataQuestion = 8,
PIAuditResutl=9
} }

View File

@ -9,15 +9,15 @@ namespace IRaCIS.Core.Domain.Models
{ {
[JsonIgnore] [JsonIgnore]
public Hospital Hospital { get; set; } public Hospital Hospital { get; set; }
public string SiteName { get; set; } public string SiteName { get; set; } = string.Empty;
public string SiteNameCN{ get; set; } = string.Empty;
public string AliasName { get; set; } = string.Empty; public string AliasName { get; set; } = string.Empty;
public string SiteCode { get; set; } public string SiteCode { get; set; }
public int Code { get; set; } public int Code { get; set; }
public string City { get; set; } public string City { get; set; } = string.Empty;
public string Country { get; set; } public string Country { get; set; } = string.Empty;
public Guid? HospitalId { get; set; } public Guid? HospitalId { get; set; }
public int State { get; set; } public int State { get; set; }