中心调研临时提交

Uat_Study
hang 2023-08-17 11:18:01 +08:00
parent 4bc2c3107a
commit b9ccf4bb12
14 changed files with 439 additions and 611 deletions

View File

@ -37,6 +37,7 @@ using Microsoft.Net.Http.Headers;
using MiniExcelLibs;
using Newtonsoft.Json;
using SharpCompress.Archives;
using SharpCompress.Common;
using System;
using System.Collections.Generic;
using System.Data;
@ -704,8 +705,8 @@ namespace IRaCIS.Core.API.Controllers
{
var subjectVisitId = incommand.SubjectVisitId;
var studyMonitorId=incommand.StudyMonitorId;
var noneDicomStudyId=incommand.NoneDicomStudyId;
var studyMonitorId = incommand.StudyMonitorId;
var noneDicomStudyId = incommand.NoneDicomStudyId;
await _qCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
@ -936,6 +937,97 @@ namespace IRaCIS.Core.API.Controllers
return ResponseOutput.Ok();
}
[HttpPost]
[UnitOfWork]
public async Task<IResponseOutput> UploadTrialSiteSurveyUser(Guid trialId,
[FromServices] IRepository<TrialSite> _trialSiteRepository,
[FromServices] IRepository<UserType> _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))
{
throw new BusinessValidationFailedException("请用提供格式的模板excel上传需要处理的数据");
}
(serverFilePath, relativePath) = FileStoreHelper.GetTrialSiteSurveyFilePath(_hostEnvironment, fileName, trialId);
return serverFilePath;
});
//去掉空白行
var excelList = MiniExcel.Query<SiteSurveyUserImportDto>(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));
if (excelList.Any(t => string.IsNullOrWhiteSpace(t.TrialSiteCode) || string.IsNullOrWhiteSpace(t.FirstName) || string.IsNullOrWhiteSpace(t.LastName) || string.IsNullOrWhiteSpace(t.Email) || string.IsNullOrWhiteSpace(t.UserTypeStr)))
{
throw new BusinessValidationFailedException("请确保Excel中 每一行的 中心编号,姓名,邮箱,用户类型数据记录完整再进行上传");
}
var siteCodeList = excelList.Select(t => t.TrialSiteCode.Trim()).Distinct().ToList();
if (_trialSiteRepository.Where(t => siteCodeList.Contains(t.TrialSiteCode)).Count() != siteCodeList.Count)
{
throw new BusinessValidationFailedException("在项目中未找到该Excel中部分或全部中心");
}
if (excelList.GroupBy(t => new { t.UserTypeStr, t.Email }).Any(g => g.Count() > 1))
{
throw new BusinessValidationFailedException("同一邮箱,同一用户类型,只能生成一个账户,请核查Excel数据");
}
if (excelList.Any(t => t.Email.Contains("@")))
{
throw new BusinessValidationFailedException("有邮箱不符合邮箱格式,请核查Excel数据");
}
var generateUserTypeList = new List<string>() { "CRC", "SR", "CRA" };
if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper())))
{
throw new BusinessValidationFailedException("用户类型仅能为 CRC,SR,CRA 请核查Excel数据");
}
//处理好 用户类型 和用户类型枚举
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();
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;
case "SR":
item.UserTypeId = sysUserTypeList.FirstOrDefault(t => t.UserTypeEnum == UserTypeEnum.SR).UserTypeId;
item.UserTypeEnum = UserTypeEnum.SR;
break;
}
item.SiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.ToUpper() == item.TrialSiteCode.ToUpper()).SiteId;
}
await _trialSiteSurveyService.ImportGenerateAccountAndJoinTrialAsync(trialId, excelList.ToList());
return ResponseOutput.Ok();
}
}

View File

@ -292,6 +292,28 @@ public static class FileStoreHelper
return (serverFilePath, relativePath);
}
//获取 中心调研用户路径
public static (string PhysicalPath, string RelativePath) GetTrialSiteSurveyFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId)
{
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
//上传根路径
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), StaticData.Folder.UploadSiteSurveyData);
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
var (trustedFileNameForFileStorage, realFileName) = FileStoreHelper.GetStoreFileName(fileName);
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{StaticData.Folder.UploadSiteSurveyData}/{trustedFileNameForFileStorage}";
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
return (serverFilePath, relativePath);
}
public static (string PhysicalPath, string RelativePath, string FileRealName) GetClinicalTemplatePath(IWebHostEnvironment _hostEnvironment, string fileName,Guid trialId)
{

View File

@ -7741,42 +7741,6 @@
<param name="addOrEditTrialExternalUser"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.TrialExternalUserService.SendInviteEmail(IRaCIS.Core.Application.ViewModel.TrialExternalUserSendEmail)">
<summary>
勾选用户 批量发送邮件
</summary>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.TrialExternalUserService.TrialExternalUserJoinTrial(IRaCIS.Core.Application.ViewModel.TrialExternalUserConfirm)">
<summary>
不带Token 访问 用户选择 参与 不参与 Id: TrialExternalUserId 加入发送邮件
</summary>
<param name="editTrialUserPreparation"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.TrialExternalUserService.TrialSiteSurveyUserJoinTrial(IRaCIS.Core.Application.ViewModel.TrialExternalUserConfirm)">
<summary>
不带Token 访问 Site调研用户 加入项目 Id: TrialSiteSurveyUserId
</summary>
<param name="editInfo"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.TrialExternalUserService.JoinBasicInfo(System.Guid,System.Boolean)">
<summary>
不带Token 访问 页面获取项目基本信息 和参与情况 (已经确认了 就不允许再次确认) Id: TrialExternalUserId/TrialSiteSurveyUserId
</summary>
<param name="id"></param>
<param name="isExternalUser"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.TrialExternalUserService.UserConfirmJoinTrial(System.Guid,System.Guid)">
<summary>
加入项目
</summary>
<param name="trialId"></param>
<param name="trialExternalUserId"></param>
<returns></returns>
</member>
<member name="T:IRaCIS.Core.Application.ViewModel.TaskAllocationRuleView">
<summary> TaskAllocationRuleView 列表视图模型 </summary>
</member>

View File

@ -156,7 +156,6 @@ namespace IRaCIS.Core.Application.Service.Common
.WhereIf(queryParam.UserTypeId != null, t => t.UserTypeId == queryParam.UserTypeId)
.WhereIf(queryParam.IsGenerateAccount != null, t => t.IsGenerateAccount == queryParam.IsGenerateAccount)
.WhereIf(queryParam.State != null && queryParam.State != TrialSiteUserStateEnum.OverTime, t => t.InviteState == queryParam.State)
.WhereIf(queryParam.State != null && queryParam.State == TrialSiteUserStateEnum.OverTime, t => t.InviteState == TrialSiteUserStateEnum.HasSend && t.ExpireTime < DateTime.Now)
.WhereIf(!string.IsNullOrEmpty(queryParam.UserName), t => (t.LastName + " / " + t.FirstName).Contains(queryParam.UserName))
.WhereIf(!string.IsNullOrEmpty(queryParam.OrganizationName), t => t.OrganizationName.Contains(queryParam.OrganizationName))
.ProjectTo<TrialSiteUserSummaryDto>(_mapper.ConfigurationProvider);

View File

@ -5,7 +5,9 @@
//--------------------------------------------------------------------
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share;
using MiniExcelLibs.Attributes;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;
namespace IRaCIS.Core.Application.Contracts
{
@ -54,6 +56,12 @@ namespace IRaCIS.Core.Application.Contracts
public Guid? SystemUserId { get; set; }
public bool? IsHistoryUserOriginDeleted { get; set; }
}
@ -99,8 +107,17 @@ namespace IRaCIS.Core.Application.Contracts
public int TrialRoleCode { get; set; }
public string OrganizationName { get; set; } = string.Empty;
public bool IsHistoryUser { get; set; }
public bool? IsHistoryUserDeleted { get; set; }
}
public class TrialSiteUserSurverQuery
{
public Guid TrialSiteSurveyId { get; set; }
public bool? IsHistoryUser { get; set; }
}
public class TrialSiteUserSurveyVerfyResult
{
@ -109,6 +126,44 @@ namespace IRaCIS.Core.Application.Contracts
public List<string> ErroMsgList { get; set; } = new List<string>();
}
public class SiteSurveyUserImportUploadDto
{
[NotDefault]
public Guid TrialId { get; set; }
public string BaseUrl { get; set; }
public string RouteUrl { get; set; }
}
public class SiteSurveyUserImportDto
{
public string TrialSiteCode { get;set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string OrganizationName { get; set; }
[ExcelColumnName("UserType")]
public string UserTypeStr { get; set; }
[JsonIgnore]
public Guid SiteId { get; set; }
[JsonIgnore]
public UserTypeEnum UserTypeEnum { get; set; } = UserTypeEnum.Undefined;
[JsonIgnore]
public Guid UserTypeId{ get; set; }
[JsonIgnore]
public bool IsGeneratedAccount { get; set; }
[JsonIgnore]
public bool IsJoinedTrial { get; set; }
}
}

View File

@ -20,5 +20,7 @@ namespace IRaCIS.Core.Application.Contracts
//Task<IResponseOutput> TrialSurveyLock(Guid trialSiteSurveyId, bool isLock);
//IResponseOutput TrialSurveySubmmit(Guid trialId, Guid trialSiteSurveyId);
Task<IResponseOutput> VerifySendCode(LoginDto userInfo, [FromServices] ITokenService _tokenService);
Task ImportGenerateAccountAndJoinTrialAsync(Guid trialId, List<SiteSurveyUserImportDto> list);
}
}

View File

@ -10,6 +10,6 @@ namespace IRaCIS.Core.Application.Contracts
{
Task<IResponseOutput> AddOrUpdateTrialSiteUserSurvey(TrialSiteUserSurveyAddOrEdit addOrEditTrialSiteUserSurvey);
Task<IResponseOutput> DeleteTrialSiteUserSurvey(Guid trialSiteUserSurveyId);
Task<List<TrialSiteUserSurveyView>> GetTrialSiteUserSurveyList(Guid trialSiteSurveyId);
Task<List<TrialSiteUserSurveyView>> GetTrialSiteUserSurveyList(TrialSiteUserSurverQuery inquery);
}
}

View File

@ -17,6 +17,9 @@ using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.VisualBasic;
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Application.ViewModel;
namespace IRaCIS.Core.Application.Contracts
{
@ -31,13 +34,14 @@ namespace IRaCIS.Core.Application.Contracts
private readonly IRepository<User> _userRepository;
private readonly IRepository<TrialSite> _trialSiteRepository;
private readonly IRepository<TrialUser> _trialUserRepository;
private readonly IRepository<TrialSiteUser> _trialSiteUserRepository;
private readonly ITokenService _tokenService;
private readonly IMailVerificationService _mailVerificationService;
public TrialSiteSurveyService(IRepository<TrialSiteSurvey> trialSiteSurveyRepository, IRepository<TrialUser> trialUserRepository, IRepository<TrialSiteUserSurvey> trialSiteUserSurveyRepository,
IRepository<User> userRepository, IRepository<TrialSite> trialSiteRepository,
ITokenService tokenService,
IMailVerificationService mailVerificationService)
IMailVerificationService mailVerificationService, IRepository<TrialSiteUser> trialSiteUserRepository)
{
_trialSiteSurveyRepository = trialSiteSurveyRepository;
_trialSiteUserSurveyRepository = trialSiteUserSurveyRepository;
@ -46,6 +50,7 @@ namespace IRaCIS.Core.Application.Contracts
_trialSiteRepository = trialSiteRepository;
_tokenService = tokenService;
_mailVerificationService = mailVerificationService;
_trialSiteUserRepository = trialSiteUserRepository;
}
private object lockObj { get; set; } = new object();
@ -225,6 +230,9 @@ namespace IRaCIS.Core.Application.Contracts
TrialSiteSurvey? currentEntity = null;
var userList = await _trialSiteUserRepository.Where(t => t.TrialId == userInfo.TrialId && t.SiteId == userInfo.SiteId, false, true).ProjectTo<TrialSiteUserSurvey>(_mapper.ConfigurationProvider).ToListAsync();
//普通登录
if (userInfo.IsUpdate == false)
{
@ -235,8 +243,13 @@ namespace IRaCIS.Core.Application.Contracts
//没有记录 new一份
if (dbEntityList.Count == 0)
{
var addSurvey = _mapper.Map<TrialSiteSurvey>(userInfo);
currentEntity = await _repository.AddAsync(_mapper.Map<TrialSiteSurvey>(userInfo));
//从项目site 中找到已存在的 加到历史人员中
addSurvey.TrialSiteUserSurveyList = userList;
currentEntity = await _repository.AddAsync(addSurvey);
}
else
@ -254,6 +267,16 @@ namespace IRaCIS.Core.Application.Contracts
currentEntity = currentLatest;
if (currentEntity.State != TrialSiteSurveyEnum.PMCreatedAndLock)
{
await UnlockSyncSiteUserAsync(userInfo.TrialId, userInfo.SiteId, currentEntity.Id, userList);
}
}
@ -306,11 +329,16 @@ namespace IRaCIS.Core.Application.Contracts
copy.TrialSiteEquipmentSurveyList = currentLatest.TrialSiteEquipmentSurveyList.Clone();
copy.TrialSiteEquipmentSurveyList.ForEach(t => { t.Id = Guid.Empty;t.CreateTime = DateTime.Now; });
copy.TrialSiteEquipmentSurveyList.ForEach(t => { t.Id = Guid.Empty; t.CreateTime = DateTime.Now; });
copy.TrialSiteUserSurveyList = currentLatest.TrialSiteUserSurveyList.Clone();
copy.TrialSiteUserSurveyList = currentLatest.TrialSiteUserSurveyList.Clone().Where(t => t.IsHistoryUser == false).ToList();
copy.TrialSiteUserSurveyList.ForEach(t => { t.Id = Guid.Empty; t.IsGenerateSuccess = false; t.CreateTime = DateTime.Now; });
//从项目site 中找到已存在的 加到历史人员中
copy.TrialSiteUserSurveyList.AddRange(userList);
currentEntity = await _trialSiteSurveyRepository.AddAsync(copy);
@ -343,6 +371,29 @@ namespace IRaCIS.Core.Application.Contracts
#endregion
}
private async Task UnlockSyncSiteUserAsync(Guid trialId, Guid siteId, Guid trialSiteSurveyId, List<TrialSiteUserSurvey> userList)
{
var existList = await _trialSiteUserSurveyRepository.Where(t => t.IsHistoryUser && t.TrialSiteSurvey.TrialId == trialId && t.TrialSiteSurvey.SiteId == siteId, true).ToListAsync();
foreach (var item in userList)
{
var find = existList.FirstOrDefault(t => t.SystemUserId == item.SystemUserId);
//不存在就加入
if (find == null)
{
item.TrialSiteSurveyId = trialSiteSurveyId;
await _trialSiteUserSurveyRepository.AddAsync(item);
}
else
{
item.IsHistoryUserOriginDeleted = find.IsHistoryUserOriginDeleted;
}
}
await _trialSiteUserSurveyRepository.SaveChangesAsync();
}
/// <summary>
/// 直接查询相关所有数据
@ -351,9 +402,22 @@ namespace IRaCIS.Core.Application.Contracts
[HttpGet("{trialId:guid}/{trialSiteSurveyId:guid}")]
public async Task<LoginReturnDTO> GetSiteSurveyInfo(Guid trialSiteSurveyId, Guid trialId)
{
//有可能填表人提交了但是此时PM手动对人员信息进行了更改此时需要将数据同步下选择在这里同步是因为 不想改动 中心人员哪里的两个接口的逻辑)
var find = await _trialSiteSurveyRepository.FirstOrDefaultAsync(t => t.Id == trialSiteSurveyId);
if (find.State != TrialSiteSurveyEnum.PMCreatedAndLock && find.IsDeleted != true)
{
var userList = await _trialSiteUserRepository.Where(t => t.TrialId == find.TrialId && t.SiteId == find.SiteId, false, true).ProjectTo<TrialSiteUserSurvey>(_mapper.ConfigurationProvider).ToListAsync();
await UnlockSyncSiteUserAsync(find.TrialId, find.SiteId, find.Id, userList);
}
var result = await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId && t.TrialId == trialId).IgnoreQueryFilters()
.ProjectTo<LoginReturnDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
return result;
}
@ -440,7 +504,7 @@ namespace IRaCIS.Core.Application.Contracts
public async Task<List<TrialSiteSurveySelectView>> GetTrialSiteSurveySelectList(TrialSiteSurveySelectquery inQuery)
{
var trialSiteSurveyQueryable = _trialSiteSurveyRepository
.Where(t=>t.Id!=inQuery.TrialSiteSurveyId)
.Where(t => t.Id != inQuery.TrialSiteSurveyId)
.Where(t => t.TrialId == inQuery.TrialId && t.SiteId == inQuery.SiteId).IgnoreQueryFilters()
.ProjectTo<TrialSiteSurveySelectView>(_mapper.ConfigurationProvider);
@ -667,18 +731,25 @@ namespace IRaCIS.Core.Application.Contracts
else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager)
{
var allUserList = _trialSiteUserSurveyRepository.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId).ProjectTo<TrialSiteUserSurveyView>(_mapper.ConfigurationProvider).ToList();
//已生成的不管 管的只需要是 生成失败的并且需要生成账号的
var needGenerateList = _trialSiteUserSurveyRepository.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId && t.IsGenerateAccount && t.IsJoin != true ).ProjectTo<TrialSiteUserSurveyView>(_mapper.ConfigurationProvider).ToList();
var needGenerateList = allUserList.Where(t => t.IsHistoryUser == false && t.IsGenerateAccount && t.IsJoin != true).ToList();
await GenerateAccountAsync(needGenerateList, trialId);
await SendSiteSurveyUserJoinEmail(new TrialSiteUserSurveyJoinCommand() { TrialId = trialId, TrialSiteSurveyId = trialSiteSurveyId, RouteUrl = siteSurvyeSubmit.RouteUrl, BaseUrl = siteSurvyeSubmit.BaseUrl, UserList = needGenerateList });
await DealSiteUserQuitSiteAsync(trialId, trialSiteSurvey.SiteId, needGenerateList);
//新加入的 或者历史人员退出改为加入的
var needSendEmailList = allUserList.Where(t => (t.IsHistoryUser == false && t.IsGenerateAccount && t.IsJoin != true) || (t.IsHistoryUser == true && t.IsHistoryUserOriginDeleted == true && t.IsHistoryUserDeleted == false)).ToList();
await SendSiteSurveyUserJoinEmail(new TrialSiteUserSurveyJoinCommand() { TrialId = trialId, TrialSiteSurveyId = trialSiteSurveyId, RouteUrl = siteSurvyeSubmit.RouteUrl, BaseUrl = siteSurvyeSubmit.BaseUrl, UserList = needSendEmailList });
var needQuitUserList = allUserList.Where(t => t.IsHistoryUser && t.IsHistoryUserOriginDeleted == false && t.IsHistoryUserDeleted == true).ToList();
await DealSiteUserQuitSiteAsync(trialId, trialSiteSurvey.SiteId, needQuitUserList);
//将历史锁定的调研表废弃
await _trialSiteSurveyRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.SiteId == trialSiteSurvey.SiteId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock && t.Id!= trialSiteSurveyId, z => new TrialSiteSurvey() { IsDeleted = true });
await _trialSiteSurveyRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.SiteId == trialSiteSurvey.SiteId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock && t.Id != trialSiteSurveyId, z => new TrialSiteSurvey() { IsDeleted = true });
}
await _trialSiteSurveyRepository.SaveChangesAsync();
@ -689,13 +760,14 @@ namespace IRaCIS.Core.Application.Contracts
private async Task GenerateAccountAsync(List<TrialSiteUserSurveyView> needGenerateList, Guid trialId)
{
var trialType = _repository.Where<Trial>(t => t.Id == trialId).Select(t => t.TrialType).FirstOrDefault();
foreach (var item in needGenerateList)
{
//找下系统中是否存在该用户类型的 并且邮箱 或者手机的账户
var sysUserInfo = await _userRepository.Where(t => t.UserTypeId == item.UserTypeId && t.EMail == item.Email).Include(t => t.UserTypeRole).FirstOrDefaultAsync();
var trialType = _repository.Where<Trial>(t => t.Id == trialId).Select(t => t.TrialType).FirstOrDefault();
if (sysUserInfo == null)
{
@ -720,7 +792,6 @@ namespace IRaCIS.Core.Application.Contracts
saveItem.UserTypeEnum = _repository.Where<UserType>(t => t.Id == saveItem.UserTypeId).Select(t => t.UserTypeEnum).First();
//saveItem.Password = MD5Helper.Md5(verificationCode.ToString());
var newUser = _userRepository.AddAsync(saveItem).Result;
@ -736,7 +807,6 @@ namespace IRaCIS.Core.Application.Contracts
}
//
//发送邮件的时候需要用到该字段
item.SystemUserId = sysUserInfo.Id;
@ -775,12 +845,30 @@ namespace IRaCIS.Core.Application.Contracts
await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, joinCommand.BaseUrl, joinCommand.RouteUrl);
}
else
{
await _trialUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.UserId == userId, c => new TrialUser()
{
IsDeleted = false,
DeletedTime = null,
JoinTime = DateTime.Now,
});
}
if (!await _repository.AnyAsync<TrialSiteUser>(t => t.TrialId == trialId && t.UserId == userId && t.SiteId == siteId, true))
{
await _repository.AddAsync(new TrialSiteUser() { TrialId = trialId, SiteId = siteId, UserId = userId });
await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, joinCommand.BaseUrl, joinCommand.RouteUrl);
}
else
{
await _trialSiteUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.UserId == userId && t.SiteId == siteId, c => new TrialSiteUser()
{
IsDeleted = false,
DeletedTime = null,
});
}
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == userId, u => new User() { Status = UserStateEnum.Enable });
@ -800,23 +888,139 @@ namespace IRaCIS.Core.Application.Contracts
private async Task DealSiteUserQuitSiteAsync(Guid trialId, Guid siteId, List<TrialSiteUserSurveyView> list)
{
//跟踪查询该site下的所有的用户
var siteUserList = await _repository.Where<TrialSiteUser>(t => t.TrialId == trialId && t.SiteId == siteId, true).ToListAsync();
foreach (var siteUser in siteUserList)
{
//当前中心用户 不在调研表存在,就将该人退出
if (!list.Any(t => t.SystemUserId == siteUser.UserId))
{
siteUser.IsDeleted = true;
siteUser.DeletedTime = DateTime.Now;
}
var userIdList = list.Select(t => t.SystemUserId).ToList();
await _trialSiteUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.SiteId == siteId && userIdList.Contains(t.UserId), c => new TrialSiteUser()
{
IsDeleted = true,
DeletedTime = DateTime.Now,
});
//var siteUserList = await _repository.Where<TrialSiteUser>(t => t.TrialId == trialId && t.SiteId == siteId && userIdList.Contains(t.UserId), true,true).ToListAsync();
//foreach (var siteUser in siteUserList)
//{
// var find= list.FirstOrDefault(t => t.SystemUserId == siteUser.UserId);
// if(find != null)
// {
// siteUser.IsDeleted =(bool) find.IsHistoryUserDeleted;
// siteUser.DeletedTime = find.IsHistoryUserDeleted==true? DateTime.Now:null;
// }
//}
#region MyRegion
////跟踪查询该site下的所有的用户
//var siteUserList = await _repository.Where<TrialSiteUser>(t => t.TrialId == trialId && t.SiteId == siteId, true).ToListAsync();
//foreach (var siteUser in siteUserList)
//{
// //当前中心用户 不在调研表存在,就将该人退出
// if (!list.Any(t => t.SystemUserId == siteUser.UserId))
// {
// siteUser.IsDeleted = true;
// siteUser.DeletedTime = DateTime.Now;
// }
//}
#endregion
}
await _repository.SaveChangesAsync();
}
public async Task ImportGenerateAccountAndJoinTrialAsync(Guid trialId, List<SiteSurveyUserImportDto> list)
{
var trialType = _repository.Where<Trial>(t => t.Id == trialId).Select(t => t.TrialType).FirstOrDefault();
//判断是否有系统账号
foreach (var item in list)
{
//找下系统中是否存在该用户类型的 并且邮箱 或者手机的账户
var sysUserInfo = await _userRepository.Where(t => t.UserTypeId == item.UserTypeId && t.EMail == item.Email).Include(t => t.UserTypeRole).FirstOrDefaultAsync();
if (sysUserInfo == null)
{
lock (lockObj)
{
var saveItem = _mapper.Map<User>(item);
if (trialType == TrialType.NoneOfficial)
{
saveItem.IsTestUser = true;
}
// 中心调研生成账号 都是外部的
saveItem.IsZhiZhun = false;
saveItem.Code = _userRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1;
saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(User));
saveItem.UserName = saveItem.UserCode;
var newUser = _userRepository.AddAsync(saveItem).Result;
_ = _userRepository.SaveChangesAsync().Result;
sysUserInfo = newUser;
}
item.IsGeneratedAccount = true;
}
var userId = sysUserInfo.Id;
if (!await _trialUserRepository.AnyAsync(t=>t.TrialId==trialId && t.UserId== userId, true))
{
await _repository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId, JoinTime = DateTime.Now });
}
else
{
await _trialUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.UserId == userId, c => new TrialUser()
{
IsDeleted = false,
DeletedTime = null,
JoinTime = DateTime.Now,
});
}
if (!await _repository.AnyAsync<TrialSiteUser>(t => t.TrialId == trialId && t.UserId == userId && t.SiteId == siteId, true))
{
await _repository.AddAsync(new TrialSiteUser() { TrialId = trialId, SiteId = siteId, UserId = userId });
await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, joinCommand.BaseUrl, joinCommand.RouteUrl);
}
else
{
await _trialSiteUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.UserId == userId && t.SiteId == siteId, c => new TrialSiteUser()
{
IsDeleted = false,
DeletedTime = null,
});
}
}
//判断是否加入到项目
}
}
}

View File

@ -26,18 +26,18 @@ namespace IRaCIS.Core.Application.Contracts
_trialSiteSurveyRepository = trialSiteSurveyRepository;
}
[HttpGet("{trialSiteSurveyId:guid}")]
public async Task<List<TrialSiteUserSurveyView>> GetTrialSiteUserSurveyList(Guid trialSiteSurveyId)
[HttpPost]
public async Task<List<TrialSiteUserSurveyView>> GetTrialSiteUserSurveyList(TrialSiteUserSurverQuery inquery)
{
var trialSiteUserSurveyQueryable = _trialSiteUserSurveyRepository.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId)
//.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM, t => t.TrialSiteSurvey.State >= TrialSiteSurveyEnum.CRCSubmitted)
//.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM|| _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM, t => t.TrialSiteSurvey.State >= TrialSiteSurveyEnum.SPMApproved)
var trialSiteUserSurveyQueryable = _trialSiteUserSurveyRepository.Where(t => t.TrialSiteSurveyId == inquery.TrialSiteSurveyId)
.WhereIf(inquery.IsHistoryUser !=null, t => t.IsHistoryUser==inquery.IsHistoryUser)
.ProjectTo<TrialSiteUserSurveyView>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us });
return await trialSiteUserSurveyQueryable.ToListAsync();
}
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
[HttpPost("{trialId:guid}")]
public async Task<IResponseOutput> AddOrUpdateTrialSiteUserSurvey(TrialSiteUserSurveyAddOrEdit addOrEditTrialSiteUserSurvey)

View File

@ -21,6 +21,23 @@ namespace IRaCIS.Core.Application.AutoMapper
CreateMap<LoginDto, TrialSiteSurvey>().ForMember(d => d.Email, t => t.MapFrom(t => t.EmailOrPhone));
CreateMap<TrialSiteUser, TrialSiteUserSurvey>()
.ForMember(d => d.Id, u => u.Ignore())
.ForMember(d => d.Phone, u => u.MapFrom(c => c.User.Phone))
.ForMember(d => d.Email, u => u.MapFrom(c => c.User.EMail))
.ForMember(d => d.OrganizationName, u => u.MapFrom(c => c.User.OrganizationName))
.ForMember(d => d.UserTypeId, u => u.MapFrom(c => c.User.UserTypeId))
.ForMember(d => d.IsHistoryUser, u => u.MapFrom(c => true))
.ForMember(d => d.IsHistoryUserOriginDeleted, u => u.MapFrom(c => c.IsDeleted))
.ForMember(d => d.IsHistoryUserDeleted, u => u.MapFrom(c => c.IsDeleted))
.ForMember(d => d.FirstName, u => u.MapFrom(c => c.User.FirstName))
.ForMember(d => d.LastName, u => u.MapFrom(c => c.User.LastName))
.ForMember(d => d.IsGenerateAccount, u => u.MapFrom(c => true))
.ForMember(d => d.IsGenerateSuccess, u => u.MapFrom(c => true))
.ForMember(d => d.SystemUserId, u => u.MapFrom(c => c.UserId))
.ForMember(d => d.IsJoin, u => u.MapFrom(c => !c.IsDeleted));
//列表
CreateMap<TrialSiteEquipmentSurvey, TrialSiteEquipmentSurveyView>()
@ -60,6 +77,10 @@ namespace IRaCIS.Core.Application.AutoMapper
CreateMap<TrialSiteUserSurvey, User>();
CreateMap<SiteSurveyUserImportDto, User>()
.ForMember(d => d.EMail, u => u.MapFrom(s => s.Email));
CreateMap<TrialSiteUserSurveyView, User>();

View File

@ -21,7 +21,6 @@ namespace IRaCIS.Core.Application.Interfaces
Task<IResponseOutput> DeleteTrialExternalUser(Guid trialExternalUserId, bool isSystemUser,
Guid systemUserId);
Task<IResponseOutput> UserConfirmJoinTrial(Guid trialId, Guid trialExternalUserId);
}
}

View File

@ -281,535 +281,5 @@ namespace IRaCIS.Core.Application.Service
#region 老版本流程 现在废弃
/// <summary>
/// 勾选用户 批量发送邮件
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SendInviteEmail(TrialExternalUserSendEmail sendEmail)
{
var trialInfo = await _repository.FirstOrDefaultAsync<Trial>(t => t.Id == sendEmail.TrialId);
foreach (var userInfo in sendEmail.SendUsers)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, userInfo.Email));
//主题
messageToSend.Subject = $"[{trialInfo.ResearchProgramNo}] 邀请";
//var baseApiUrl = sendEmail.BaseUrl.Remove(sendEmail.BaseUrl.IndexOf("#")) + "api";
var builder = new BodyBuilder();
var sysUserInfo = (await _userRepository.Where(t => t.Id == userInfo.SystemUserId).FirstOrDefaultAsync()).IfNullThrowException();
builder.HtmlBody = @$"<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;'>
<div style='line-height: 40px;font-size: 18px'>
{sysUserInfo.LastName + "/" + sysUserInfo.FirstName}:
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{
//您好,展影医疗作为 实验方案号:{trialInfo.ResearchProgramNo} 项目的IRC供应商诚邀您参加该项目IRC相关工作欢迎您提供指导和建议非常感谢
_localizer["TrialExternalUser_IRCInvitation", trialInfo.ResearchProgramNo]
}
</div>
<a href=' {sendEmail.RouteUrl + "?Id=" + userInfo.Id + "&IsExternalUser=1"}' 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;margin-bottom: 100px;'>
</a>
</div>
</div>
</body>";
//< 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' > 查看并确认 </ button >
// </ form >
messageToSend.Body = builder.ToMessageBody();
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
{
smtp.MessageSent += (sender, args) =>
{
_ = _trialExternalUseRepository.BatchUpdateNoTrackingAsync(t => t.Id == userInfo.Id, u => new TrialExternalUser() { InviteState = TrialExternalUserStateEnum.HasSend, ConfirmTime = null, RejectReason = String.Empty, ExpireTime = DateTime.Now.AddDays(7) }).Result;
};
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
await smtp.ConnectAsync("smtp.163.com", 465, SecureSocketOptions.StartTls);
await smtp.AuthenticateAsync("iracis_grr@163.com", "XLWVQKZAEKLDWOAH");
await smtp.SendAsync(messageToSend);
await smtp.DisconnectAsync(true);
}
}
return ResponseOutput.Ok();
}
/// <summary>
/// 不带Token 访问 用户选择 参与 不参与 Id: TrialExternalUserId 加入发送邮件
/// </summary>
/// <param name="editTrialUserPreparation"></param>
/// <returns></returns>
[AllowAnonymous]
public async Task<IResponseOutput> TrialExternalUserJoinTrial(TrialExternalUserConfirm editTrialUserPreparation)
{
var needUpdate = await _trialExternalUseRepository.FirstOrDefaultAsync(t => t.Id == editTrialUserPreparation.Id);
if (DateTime.Now > needUpdate.ExpireTime)
{
//---邀请加入时间已过期,重新被邀请后才可以进行确认操作
return ResponseOutput.NotOk(_localizer["TrialExternalUser_InvitationExpired"]);
}
_mapper.Map(editTrialUserPreparation, needUpdate);
needUpdate.InviteState = editTrialUserPreparation.IsJoin == true ? TrialExternalUserStateEnum.UserConfirmed : TrialExternalUserStateEnum.UserReject;
var trialId = needUpdate.TrialId;
var userId = needUpdate.SystemUserId;
//判断TrialUser中是否存在 不存在就插入
if (!await _trialUserRepository.AnyAsync(t => t.TrialId == trialId && t.UserId == userId))
{
await _trialUserRepository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId, JoinTime = DateTime.Now });
}
var success = await _trialExternalUseRepository.SaveChangesAsync();
if (editTrialUserPreparation.IsJoin == true)
{
var trialInfo = await _repository.FirstOrDefaultAsync<Trial>(t => t.Id == needUpdate.TrialId);
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, needUpdate.Email));
//主题
//$"[来自展影IRC] [{trialInfo.ResearchProgramNo}] 账户信息";
messageToSend.Subject = _localizer["TrialExternalUser_AccountInfo", trialInfo.ResearchProgramNo];
var builder = new BodyBuilder();
var sysUserInfo = (await _userRepository.Where(t => t.Id == needUpdate.SystemUserId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
int verificationCode = new Random().Next(100000, 1000000);
if (sysUserInfo.IsFirstAdd)
{
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id,
u => new User() { Password = MD5Helper.Md5(verificationCode.ToString()) });
}
builder.HtmlBody = @$"<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;padding-bottom:40px'>
<div style='line-height: 40px;font-size: 18px'>
{sysUserInfo.LastName + "/" + sysUserInfo.FirstName}:
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{
// 您好,欢迎您参加项目 实验方案号:{trialInfo.ResearchProgramNo}IRC相关工作。该项目采用电子化工作流系统及您的账号信息如下
_localizer["TrialExternalUser_Welcome", trialInfo.ResearchProgramNo]
}
</div>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 80%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
<div>
{
// 项目编号: {trialInfo.TrialCode}
_localizer["TrialExternalUser_ProjectNumber", trialInfo.TrialCode]
}
</div>
<div>
{
// 试验方案号: {trialInfo.ResearchProgramNo}
_localizer["TrialExternalUser_ExperimentPlanNumber", trialInfo.ResearchProgramNo]
}
</div>
<div>
{
// 试验名称: {trialInfo.ExperimentName}
_localizer["TrialExternalUser_ExperimentName", trialInfo.ExperimentName]
}
</div>
<div>
{
// 用户名: {sysUserInfo.UserName}
_localizer["TrialExternalUser_Username", sysUserInfo.UserName]
}
</div>
<div>
{
// 密码: {(sysUserInfo.IsFirstAdd ? verificationCode.ToString() + "(请在登录后进行修改)" : "***(您已有账号, 若忘记密码, 请通过邮箱找回)")}
_localizer["TrialExternalUser_Password", verificationCode.ToString()]
}
</div>
<div>
{
// 角色: {sysUserInfo.UserTypeRole.UserTypeShortName}
_localizer["TrialExternalUser_Role", sysUserInfo.UserTypeRole.UserTypeShortName]
}
</div>
<div>
: {editTrialUserPreparation.BaseUrl}
{
// 系统登录地址: {editTrialUserPreparation.BaseUrl}
_localizer["TrialExternalUser_LoginUrl", editTrialUserPreparation.BaseUrl]
}
</div>
</div>
</div>
</div>
</body>";
messageToSend.Body = builder.ToMessageBody();
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
{
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
await smtp.ConnectAsync("smtp.163.com", 465, SecureSocketOptions.StartTls);
await smtp.AuthenticateAsync("iracis_grr@163.com", "XLWVQKZAEKLDWOAH");
await smtp.SendAsync(messageToSend);
await smtp.DisconnectAsync(true);
}
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == userId, u => new User() { Status = UserStateEnum.Enable });
}
return ResponseOutput.Ok();
//else
//{
// builder.HtmlBody = @$"<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
// <div style='padding-left: 40px;background: #f6f6f6'>
// <div style='padding-top: 20px;padding-bottom:40px'>
// <div style='line-height: 40px;font-size: 18px'>
// {sysUserInfo.LastName + "/" + sysUserInfo.FirstName}:
// </div>
// <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
// 您好,您拒绝了参加 {trialInfo.ResearchProgramNo} 项目IRC相关工作的邀请。详细信息如下
// </div>
// <div style='border: 1px solid #eee;box-sizing:border-box;width: 80%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
// <div>
// 项目编号: {trialInfo.TrialCode}
// </div>
// <div>
// 试验方案号: {trialInfo.ResearchProgramNo}
// </div>
// <div>
// 试验名称: {trialInfo.ExperimentName}
// </div>
// <div>
// 用户名: {sysUserInfo.UserName}
// </div>
// <div>
// 角色: {sysUserInfo.UserTypeRole.UserTypeShortName}
// </div>
// </div>
// </div>
// </div>
// </body>";
//}
}
/// <summary>
/// 不带Token 访问 Site调研用户 加入项目 Id: TrialSiteSurveyUserId
/// </summary>
/// <param name="editInfo"></param>
/// <returns></returns>
[AllowAnonymous]
public async Task<IResponseOutput> TrialSiteSurveyUserJoinTrial(TrialExternalUserConfirm editInfo)
{
var needUpdate = (await _trialSiteSurveyUserRepository.Where(t => t.Id == editInfo.Id, true).Include(t => t.TrialSiteSurvey).FirstOrDefaultAsync()).IfNullThrowException();
var revieweUser = await _userRepository.FirstOrDefaultAsync(t => t.Id == needUpdate.TrialSiteSurvey.ReviewerUserId);
if (DateTime.Now > needUpdate.ExpireTime)
{
//---邀请加入时间已过期,重新被邀请后才可以进行确认操作
return ResponseOutput.NotOk(_localizer["TrialExternalUser_InvitationExpired"]);
}
_mapper.Map(editInfo, needUpdate);
needUpdate.InviteState = editInfo.IsJoin == true ? TrialSiteUserStateEnum.UserConfirmed : TrialSiteUserStateEnum.UserReject;
if (needUpdate.SystemUserId == null)
{
//---调研表系统用户Id 存储有问题
return ResponseOutput.NotOk(_localizer["TrialExternalUser_UserIdStorageProblem"]);
}
var trialId = needUpdate.TrialSiteSurvey.TrialId;
var siteId = needUpdate.TrialSiteSurvey.SiteId;
var userId = (Guid)needUpdate.SystemUserId;
if (!await _trialUserRepository.AnyAsync(t => t.TrialId == trialId && t.UserId == userId))
{
await _trialUserRepository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId, JoinTime = DateTime.Now });
await _trialSiteUserRepository.AddAsync(new TrialSiteUser() { TrialId = trialId, SiteId = siteId, UserId = userId });
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == needUpdate.SystemUserId, u => new User() { Status = UserStateEnum.Enable });
}
var success = await _trialExternalUseRepository.SaveChangesAsync();
var trialInfo = await _repository.FirstOrDefaultAsync<Trial>(t => t.Id == needUpdate.TrialSiteSurvey.TrialId);
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, editInfo.IsJoin == true ? needUpdate.Email : revieweUser.EMail));
//主题
// $"[来自展影IRC] [{trialInfo.ResearchProgramNo}] 账户信息";
messageToSend.Subject = _localizer["TrialExternalUser_IRCAccountInfo", trialInfo.ResearchProgramNo];
var builder = new BodyBuilder();
var sysUserInfo = await _userRepository.Where(t => t.Id == needUpdate.SystemUserId).Include(t => t.UserTypeRole).FirstOrDefaultAsync();
int verificationCode = new Random().Next(100000, 1000000);
if (sysUserInfo.IsFirstAdd)
{
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id,
u => new User() { Password = MD5Helper.Md5(verificationCode.ToString()) });
}
if (editInfo.IsJoin == true)
{
builder.HtmlBody = @$"<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
<div style='padding-left: 40px;background: #f6f6f6'>
<div style='padding-top: 20px;padding-bottom:40px'>
<div style='line-height: 40px;font-size: 18px'>
{sysUserInfo.LastName + "/" + sysUserInfo.FirstName}:
</div>
<div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
{trialInfo.ResearchProgramNo} IRC
</div>
<div style='border: 1px solid #eee;box-sizing:border-box;width: 80%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
<div>
: {trialInfo.TrialCode}
</div>
<div>
: {trialInfo.ResearchProgramNo}
</div>
<div>
: {trialInfo.ExperimentName}
</div>
<div>
: {sysUserInfo.UserName}
</div>
<div>
: {(sysUserInfo.IsFirstAdd ? verificationCode.ToString() + "(请在登录后进行修改)" : "***(您已有账号, 若忘记密码, 请通过邮箱找回)")}
</div>
<div>
: {sysUserInfo.UserTypeRole.UserTypeShortName}
</div>
<div>
: {editInfo.BaseUrl}
</div>
</div>
</div>
</div>
</body>";
messageToSend.Body = builder.ToMessageBody();
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
{
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
await smtp.ConnectAsync("smtp.163.com", 465, SecureSocketOptions.StartTls);
await smtp.AuthenticateAsync("iracis_grr@163.com", "XLWVQKZAEKLDWOAH");
await smtp.SendAsync(messageToSend);
await smtp.DisconnectAsync(true);
}
}
//else
//{
// builder.HtmlBody = @$"<body style='font-family: 微软雅黑;padding: 0;margin: 0;'>
// <div style='padding-left: 40px;background: #f6f6f6'>
// <div style='padding-top: 20px;padding-bottom:40px'>
// <div style='line-height: 40px;font-size: 18px'>
// {revieweUser.LastName + "/" + revieweUser.FirstName}:
// </div>
// <div style='line-height: 40px;padding-left: 40px;margin-bottom: 10px;'>
// 您好,{sysUserInfo.LastName + "/" + sysUserInfo.FirstName} 拒绝了参加 {trialInfo.ResearchProgramNo} 项目IRC相关工作的邀请。详细信息如下
// </div>
// <div style='border: 1px solid #eee;box-sizing:border-box;width: 80%;background: #fff;padding: 20px;line-height: 40px;font-size: 14px;border-radius: 5px;margin-left: 60px;margin-bottom: 30px;'>
// <div>
// 项目编号: {trialInfo.TrialCode}
// </div>
// <div>
// 试验方案号: {trialInfo.ResearchProgramNo}
// </div>
// <div>
// 试验名称: {trialInfo.ExperimentName}
// </div>
// <div>
// 用户名: {sysUserInfo.UserName}
// </div>
// <div>
// 角色: {sysUserInfo.UserTypeRole.UserTypeShortName}
// </div>
// <div>
// 拒绝原因: {editInfo.RejectReason}
// </div>
// </div>
// </div>
// </div>
// </body>";
//}
return ResponseOutput.Ok();
}
/// <summary>
/// 不带Token 访问 页面获取项目基本信息 和参与情况 (已经确认了 就不允许再次确认) Id: TrialExternalUserId/TrialSiteSurveyUserId
/// </summary>
/// <param name="id"></param>
/// <param name="isExternalUser"></param>
/// <returns></returns>
[AllowAnonymous]
public async Task<TrialInfoWithPreparationInfo> JoinBasicInfo(Guid id, bool isExternalUser)
{
if (isExternalUser)
{
return (await _trialExternalUseRepository.Where(t => t.Id == id)
.ProjectTo<TrialInfoWithPreparationInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
}
else
{
return (await _trialSiteSurveyUserRepository.Where(t => t.Id == id)
.ProjectTo<TrialInfoWithPreparationInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
}
}
/// <summary>
/// 加入项目
/// </summary>
/// <param name="trialId"></param>
/// <param name="trialExternalUserId"></param>
/// <returns></returns>
[HttpGet("{trialId:guid}/{trialExternalUserId:guid}")]
[NonDynamicMethod]
public async Task<IResponseOutput> UserConfirmJoinTrial(Guid trialId, Guid trialExternalUserId)
{
var externalUser = await _trialExternalUseRepository.FirstOrDefaultAsync(t => t.Id == trialExternalUserId);
//判断TrialUser中是否存在 不存在就插入
if (!await _repository.AnyAsync<TrialUser>(t => t.TrialId == trialId && t.UserId == externalUser.SystemUserId))
{
await _repository.AddAsync(new TrialUser() { TrialId = trialId, UserId = (Guid)externalUser.SystemUserId, JoinTime = DateTime.Now });
await _trialExternalUseRepository.BatchUpdateNoTrackingAsync(t => t.Id == trialExternalUserId,
u => new TrialExternalUser() { InviteState = TrialExternalUserStateEnum.UserConfirmed });
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == externalUser.SystemUserId, u => new User() { Status = UserStateEnum.Enable });
await _userRepository.SaveChangesAsync();
}
return ResponseOutput.Ok();
}
#endregion
}
}

View File

@ -59,7 +59,6 @@ namespace IRaCIS.Core.Domain.Models
[Required]
public Guid UpdateUserId { get; set; }
public string UserName { get; set; } = string.Empty;
/// <summary>
/// Phone
@ -97,16 +96,15 @@ namespace IRaCIS.Core.Domain.Models
public TrialSiteUserStateEnum InviteState { get; set; } = TrialSiteUserStateEnum.WaitSent;
#region 废弃
public DateTime? ExpireTime { get; set; }
public bool IsJoin { get; set; }
public DateTime? ConfirmTime { get; set; }
public string RejectReason { get; set; } = string.Empty;
#endregion
public bool IsHistoryUser { get; set; }
public bool? IsHistoryUserDeleted { get; set; }
public bool? IsHistoryUserOriginDeleted { get; set; }

View File

@ -104,6 +104,8 @@ public static class StaticData
public static readonly string UploadEDCData = "UploadEDCData";
public static readonly string UploadSiteSurveyData = "SiteSurveyData";
public static readonly string UploadFileFolder = "UploadFile";
}