irc-netcore-api/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs

1037 lines
48 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2021-12-23 13:20:59
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Share;
using System.Text.RegularExpressions;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Application.Services;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Application.Contracts;
using Microsoft.AspNetCore.Authorization;
using MailKit.Security;
using MimeKit;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Filter;
namespace IRaCIS.Core.Application.Contracts
{
/// <summary>
/// TrialSiteSurveyService
/// </summary>
[ApiExplorerSettings(GroupName = "Trial")]
public class TrialSiteSurveyService : BaseService, ITrialSiteSurveyService
{
private readonly IRepository<TrialSiteSurvey> _trialSiteSurveyRepository;
private readonly IRepository<TrialSiteUserSurvey> _trialSiteUserSurveyRepository;
private readonly IRepository<User> _userRepository;
private readonly IRepository<TrialSite> _trialSiteRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<TrialUser> _trialUserRepository;
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,
IRepository<Doctor> doctorRepository,
ITokenService tokenService,
IMailVerificationService mailVerificationService)
{
_trialSiteSurveyRepository = trialSiteSurveyRepository;
_trialSiteUserSurveyRepository = trialSiteUserSurveyRepository;
_userRepository = userRepository;
_trialUserRepository = trialUserRepository;
_trialSiteRepository = trialSiteRepository;
this._doctorRepository = doctorRepository;
_tokenService = tokenService;
_mailVerificationService = mailVerificationService;
}
private object lockObj { get; set; } = new object();
/// <summary>
/// 发送验证码
/// </summary>
/// <param name="userInfo"></param>
/// <returns></returns>
[AllowAnonymous]
public async Task<IResponseOutput> SendEmialVerifyCode(SendEmialVerifyCodeInDto userInfo)
{
//检查手机或者邮箱是否有效
if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"))
{
//---请输入正确的邮箱地址。
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_InvalidEmail"]);
}
//邮箱
//验证码 6位
int verificationCode = new Random().Next(100000, 1000000);
await _mailVerificationService.SendEmailVerification(userInfo.Email, verificationCode);
return ResponseOutput.Ok();
}
/// <summary>
/// 验证邮箱验证码 获取医生信息Id
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
[AllowAnonymous]
public async Task<VerifyEmialGetDoctorInfoOutDto> VerifyEmialGetDoctorInfo(VerifyEmialGetDoctorInfoInDto inDto)
{
var verificationRecord = await _repository.GetQueryable<VerificationCode>().OrderByDescending(x => x.ExpirationTime).Where(t => (t.EmailOrPhone == inDto.EmailOrPhone) && t.Code == inDto.VerificationCode && t.CodeType == VerifyType.Email).FirstOrDefaultAsync();
VerifyEmialGetDoctorInfoOutDto result = new VerifyEmialGetDoctorInfoOutDto();
var doctorInfo = await _doctorRepository.Where(x => x.EMail == inDto.EmailOrPhone).FirstOrDefaultAsync();
result.DoctorId = doctorInfo == null ? null : doctorInfo.Id;
result.ReviewStatus = doctorInfo == null ? null : doctorInfo.ReviewStatus;
//检查数据库是否存在该验证码
if (verificationRecord == null)
{
//---验证码错误。
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_WrongVerificationCode"]);
}
else
{
//检查验证码是否失效
if (verificationRecord.ExpirationTime < DateTime.Now)
{
//---验证码已经过期。
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_ExpiredVerificationCode"]);
}
else //验证码正确 并且 没有超时
{
result.Token = _tokenService.GetToken(IRaCISClaims.Create(new UserBasicInfo()));
}
}
return result;
}
/// <summary>
/// 发送验证码
/// </summary>
/// <param name="userInfo"></param>
/// <returns></returns>
[AllowAnonymous]
public async Task<IResponseOutput> SendVerifyCode(SiteSurveySendVerifyCode userInfo)
{
//检查手机或者邮箱是否有效
if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"))
{
//---请输入正确的邮箱地址。
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_InvalidEmail"]);
}
//邮箱
//验证码 6位
int verificationCode = new Random().Next(100000, 1000000);
var trialInfo = await _repository.FirstOrDefaultAsync<Trial>(t => t.Id == userInfo.TrialId);
await _mailVerificationService.AnolymousSendEmail(trialInfo.ResearchProgramNo, userInfo.Email, verificationCode);
return ResponseOutput.Ok();
}
/// <summary>
/// 验证后 如果数据库该项目不存在该邮箱 那么就插入记录 存在
/// </summary>
/// <param name="userInfo"></param>
/// <param name="_tokenService"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
[HttpPost]
[UnitOfWork]
[AllowAnonymous]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> VerifySendCode(LoginDto userInfo, [FromServices] ITokenService _tokenService)
{
var isReplaceUser = !string.IsNullOrEmpty(userInfo.ReplaceUserEmailOrPhone);
if (userInfo.IsUpdate && isReplaceUser && !await _trialSiteSurveyRepository.AnyAsync(t => (t.Email == userInfo.ReplaceUserEmailOrPhone || t.Phone == userInfo.ReplaceUserEmailOrPhone) && t.SiteId == userInfo.SiteId && t.TrialId == userInfo.TrialId))
{
//---该中心不存在该交接人的中心调研记录表,不允许选择更新。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_NoRecordToUpdate"]);
}
if (userInfo.IsUpdate && await _trialSiteSurveyRepository.AnyAsync(t => (t.Email == userInfo.EmailOrPhone || t.Phone == userInfo.EmailOrPhone) && t.SiteId == userInfo.SiteId && t.TrialId == userInfo.TrialId && t.State != TrialSiteSurveyEnum.PMCreatedAndLock))
{
//---您的中心调研记录正在审核中,不允许进行更新操作。若需要更新,请在驳回后进行操作。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_RecordUnderReview"]);
}
//自己的记录锁定了 只能更新自己的,不能更新别人的(但是别人能更新自己锁定的)
if (userInfo.IsUpdate && userInfo.ReplaceUserEmailOrPhone != userInfo.EmailOrPhone && await _trialSiteSurveyRepository.AnyAsync(t => (t.Email == userInfo.EmailOrPhone || t.Phone == userInfo.EmailOrPhone) && t.SiteId == userInfo.SiteId && t.TrialId == userInfo.TrialId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock))
{
//自己的锁了 想更新别人的
//---当前中心中,您提交调研记录表已锁定,不允许更新其他人邮箱调研记录。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_LockedByCurrentUser"]);
}
//自己的锁定了 如果有其他未锁定的,也不能更新自己的
if (userInfo.IsUpdate && userInfo.ReplaceUserEmailOrPhone == userInfo.EmailOrPhone &&
await _trialSiteSurveyRepository.AnyAsync(t => (t.Email == userInfo.EmailOrPhone || t.Phone == userInfo.EmailOrPhone) && t.SiteId == userInfo.SiteId && t.TrialId == userInfo.TrialId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock)
&& await _trialSiteSurveyRepository.AnyAsync(t => (t.Email != userInfo.EmailOrPhone && t.Phone != userInfo.EmailOrPhone) && t.SiteId == userInfo.SiteId && t.TrialId == userInfo.TrialId && t.State != TrialSiteSurveyEnum.PMCreatedAndLock))
{
//---当前中心,您提交的调研记录表已锁定。当前存在其他人员提交的调研记录表未锁定,不允许更新您之前提交的调研记录。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_LockedByOtherUsers"]);
}
////存在未锁定的记录,却去更新已锁定的
if (userInfo.IsUpdate && userInfo.ReplaceUserEmailOrPhone != userInfo.EmailOrPhone && await _trialSiteSurveyRepository.AnyAsync(t => t.SiteId == userInfo.SiteId && t.TrialId == userInfo.TrialId && t.State != TrialSiteSurveyEnum.PMCreatedAndLock)
&& await _trialSiteSurveyRepository.AnyAsync(t => (t.Email == userInfo.ReplaceUserEmailOrPhone || t.Phone == userInfo.ReplaceUserEmailOrPhone) && t.SiteId == userInfo.SiteId && t.TrialId == userInfo.TrialId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock)
&& !await _trialSiteSurveyRepository.AnyAsync(t => (t.Email == userInfo.ReplaceUserEmailOrPhone || t.Phone == userInfo.ReplaceUserEmailOrPhone) && t.SiteId == userInfo.SiteId && t.TrialId == userInfo.TrialId && t.State != TrialSiteSurveyEnum.PMCreatedAndLock)
)
{
//---当前中心存在未锁定的调研记录,不允许更新已锁定的调研记录。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_UnlockedRecordsExist"]);
}
var verificationRecord = await _repository
.FirstOrDefaultAsync<VerificationCode>(t => (t.EmailOrPhone == userInfo.EmailOrPhone) && t.Code == userInfo.verificationCode && t.CodeType == userInfo.verificationType);
//检查数据库是否存在该验证码
if (verificationRecord == null)
{
//---验证码错误。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_WrongVerificationCode"]);
}
else
{
//检查验证码是否失效
if (verificationRecord.ExpirationTime < DateTime.Now)
{
//---验证码已经过期。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_ExpiredVerificationCode"]);
}
else //验证码正确 并且 没有超时
{
TrialSiteSurvey? dbEntity = null;
//替换交接人
if (isReplaceUser)
{
//该交接人的记录 是否有未锁定的 有就用未锁定的,没有就用 锁定的最后一条
var noLockedLastSurvey = await _trialSiteSurveyRepository.Where(t => (t.Email == userInfo.ReplaceUserEmailOrPhone || t.Phone == userInfo.ReplaceUserEmailOrPhone) && t.SiteId == userInfo.SiteId && t.TrialId == userInfo.TrialId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock == false, true)
.Include(u => u.TrialSiteEquipmentSurveyList).Include(u => u.TrialSiteUserSurveyList).OrderByDescending(t => t.CreateTime).FirstOrDefaultAsync();
//都是锁定的
if (noLockedLastSurvey == null)
{
var latestLock = await _trialSiteSurveyRepository.Where(t => t.SiteId == userInfo.SiteId && t.TrialId == userInfo.TrialId).OrderByDescending(t => t.CreateTime).FirstOrDefaultAsync();
if (latestLock!.Email != userInfo.ReplaceUserEmailOrPhone)
{
return ResponseOutput.NotOk($"该邮箱{userInfo.ReplaceUserEmailOrPhone}对应的调查表不是最新锁定的记录,不允许更新!");
}
var lockedLastSurvey = await _trialSiteSurveyRepository.Where(t => (t.Email == userInfo.ReplaceUserEmailOrPhone || t.Phone == userInfo.ReplaceUserEmailOrPhone) && t.SiteId == userInfo.SiteId && t.TrialId == userInfo.TrialId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock == true)
.Include(u => u.TrialSiteEquipmentSurveyList).Include(u => u.TrialSiteUserSurveyList).OrderByDescending(t => t.CreateTime).FirstOrDefaultAsync().IfNullThrowException();
//Copy 一份 更换邮箱
var copy = lockedLastSurvey.Clone();
copy.State = TrialSiteSurveyEnum.ToSubmit;
copy.Email = userInfo.EmailOrPhone;
if (userInfo.ReplaceUserEmailOrPhone != userInfo.EmailOrPhone)
{
copy.UserName = String.Empty;
copy.Phone = String.Empty;
}
copy.Id = Guid.Empty;
copy.TrialSiteEquipmentSurveyList.ForEach(t => t.Id = Guid.Empty);
copy.TrialSiteUserSurveyList.ForEach(t => t.Id = Guid.Empty);
dbEntity = await _repository.AddAsync(copy);
}
else
{
//有未锁定的 更新下邮箱
noLockedLastSurvey.Email = userInfo.EmailOrPhone;
noLockedLastSurvey.UserName = String.Empty;
noLockedLastSurvey.Phone = String.Empty;
dbEntity = noLockedLastSurvey;
}
////邮箱相同的话 就是同一个人进来 copy一份
//if (userInfo.EmailOrPhone == userInfo.ReplaceUserEmailOrPhone)
//{
// dbEntity = await _repository.Where<TrialSiteSurvey>(t => (t.Email == userInfo.EmailOrPhone || t.Phone == userInfo.EmailOrPhone) && t.SiteId == userInfo.SiteId && t.TrialId == userInfo.TrialId).Include(u => u.TrialSiteEquipmentSurveyList).Include(u => u.TrialSiteUserSurveyList).FirstOrDefaultAsync().IfNullThrowConvertException();
// var clone = dbEntity.Clone();
// clone.Id = Guid.Empty;
// clone.TrialSiteEquipmentSurveyList.ForEach(t => t.Id = Guid.Empty);
// clone.TrialSiteUserSurveyList.ForEach(t => t.Id = Guid.Empty);
// clone.State = TrialSiteSurveyEnum.ToSubmit;
// dbEntity = await _repository.AddAsync(clone);
//}
}
else
{
var dbEntityList = await _trialSiteSurveyRepository.Where(t => t.TrialId == userInfo.TrialId && t.SiteId == userInfo.SiteId).ToListAsync();
//没有记录 new一份
if (dbEntityList.Count == 0)
{
dbEntity = await _repository.AddAsync(_mapper.Map<TrialSiteSurvey>(userInfo));
}
else
{
//该site 下不存在该邮箱的记录
if (!dbEntityList.Any(t => t.Email == userInfo.EmailOrPhone || t.Phone == userInfo.EmailOrPhone))
{
//---该中心下已经有其他用户已填写的调研表,您不被允许继续填写
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_AlreadyFilledByOtherUsers"]);
}
//有没有该邮箱 未锁定的
var nolockEntity = dbEntityList.Where(t => t.Email == userInfo.EmailOrPhone || t.Phone == userInfo.EmailOrPhone).FirstOrDefault(t => t.State != TrialSiteSurveyEnum.PMCreatedAndLock);
// 未锁定的 为空
if (nolockEntity == null)
{
//查看最新锁定的
dbEntity = dbEntityList.Where(t => t.Email == userInfo.EmailOrPhone || t.Phone == userInfo.EmailOrPhone).OrderByDescending(t => t.CreateTime).FirstOrDefault(t => t.State == TrialSiteSurveyEnum.PMCreatedAndLock).IfNullThrowException();
}
else //有未锁定的 直接用未锁定的
{
dbEntity = nolockEntity;
}
}
//_mapper.Map(userInfo, dbEntity);
}
//删除验证码历史记录
await _repository.BatchDeleteAsync<VerificationCode>(t => t.EmailOrPhone == userInfo.EmailOrPhone && t.Code == userInfo.verificationCode && t.CodeType == userInfo.verificationType);
await _repository.SaveChangesAsync();
return ResponseOutput.Ok(new
{
TrialSiteSurveyId = dbEntity!.Id,
Token = _tokenService.GetToken(IRaCISClaims.Create(new UserBasicInfo()
{
Id = Guid.NewGuid(),
IsReviewer = false,
IsAdmin = false,
RealName = "SiteSurvey",
UserName = "SiteSurvey",
Sex = 0,
//UserType = "ShareType",
UserTypeEnum = UserTypeEnum.Undefined,
Code = "SiteSurvey",
}))
});
}
}
}
/// <summary>
/// 直接查询相关所有数据
/// </summary>
/// <returns></returns>
[HttpGet("{trialId:guid}/{trialSiteSurveyId:guid}")]
public async Task<LoginReturnDTO> GetSiteSurveyInfo(Guid trialSiteSurveyId, Guid trialId)
{
var result = await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId && t.TrialId == trialId)
.ProjectTo<LoginReturnDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
return result;
}
/// <summary>
/// 实际这里只会是更新 添加在login的时候做了
/// </summary>
/// <param name="addOrEditTrialSiteSurvey"></param>
/// <returns></returns>
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> AddOrUpdateTrialSiteSurvey(TrialSiteSurveyAddOrEdit addOrEditTrialSiteSurvey)
{
if (addOrEditTrialSiteSurvey.Id != null)
{
if (await _trialSiteSurveyRepository.AnyAsync(t => t.Id == addOrEditTrialSiteSurvey.Id && t.State == TrialSiteSurveyEnum.PMCreatedAndLock))
{
//---中心调研已锁定,不允许操作。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_Locked"]);
}
}
if (addOrEditTrialSiteSurvey.Id == null)
{
var entity = _mapper.Map<TrialSiteSurvey>(addOrEditTrialSiteSurvey);
await _trialSiteSurveyRepository.AddAsync(entity, true);
return ResponseOutput.Ok(entity.Id.ToString());
}
else
{
var entity = await _trialSiteSurveyRepository.Where(t => t.Id == addOrEditTrialSiteSurvey.Id, true).Include(x => x.ReviewerUser).Include(x => x.PreliminaryUser).FirstOrDefaultAsync();
_mapper.Map(addOrEditTrialSiteSurvey, entity);
await _trialSiteSurveyRepository.SaveChangesAsync();
}
return ResponseOutput.Ok(true);
}
/// <summary>
/// 删除调研表
/// </summary>
/// <param name="trialSiteSurveyId"></param>
/// <returns></returns>
[HttpDelete("{trialSiteSurveyId:guid}/{trialId:guid}")]
public async Task<IResponseOutput> DeleteTrialSiteSurvey(Guid trialSiteSurveyId)
{
if (await _trialSiteSurveyRepository.AnyAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock))
{
//---中心调研已锁定,不允许操作。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_Locked"]);
}
var success = await _trialSiteSurveyRepository.BatchDeleteNoTrackingAsync(t => t.Id == trialSiteSurveyId);
return ResponseOutput.Result(success);
}
/// <summary>
/// 获取 项目 site的调研记录 New
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<TrialSiteSurveyView>> GetTrialSiteSurveyList(TrialSiteSurveyQueryDTO surveyQueryDTO)
{
var trialSiteSurveyQueryable = _trialSiteSurveyRepository.Where(t => t.TrialId == surveyQueryDTO.TrialId).IgnoreQueryFilters()
.WhereIf(surveyQueryDTO.SiteId != null, t => t.SiteId == surveyQueryDTO.SiteId)
.WhereIf(surveyQueryDTO.IsDeleted != null, t => t.IsDeleted == surveyQueryDTO.IsDeleted)
.WhereIf(!string.IsNullOrWhiteSpace(surveyQueryDTO.UserKeyInfo), t => t.UserName.Contains(surveyQueryDTO.UserKeyInfo) || t.Phone.Contains(surveyQueryDTO.UserKeyInfo) || t.Email.Contains(surveyQueryDTO.UserKeyInfo))
.WhereIf(surveyQueryDTO.State != null, t => t.State == surveyQueryDTO.State)
.WhereIf(surveyQueryDTO.UpdateTimeBegin != null, t => t.UpdateTime >= surveyQueryDTO.UpdateTimeBegin)
.WhereIf(surveyQueryDTO.UpdateTimeEnd != null, t => t.UpdateTime <= surveyQueryDTO.UpdateTimeEnd)
.ProjectTo<TrialSiteSurveyView>(_mapper.ConfigurationProvider);
return await trialSiteSurveyQueryable.ToPagedListAsync(surveyQueryDTO.PageIndex, surveyQueryDTO.PageSize, surveyQueryDTO.SortField, surveyQueryDTO.Asc);
}
/// <summary>
/// 项目Site调研用户列表 所有site的调研用户 最新的调研表的记录的用户 new
/// </summary>
/// <returns></returns>
public async Task<PageOutput<TrialSiteUserSurveyAllDTO>> TrialSiteSurveyUserList(TrialSiteUserSurveyAllQuery queryParam)
{
var groupSelectIdQuery =
_trialSiteSurveyRepository.Where(t => t.TrialId == queryParam.TrialId)
.WhereIf(queryParam.SiteId != null, t => t.SiteId == queryParam.SiteId)
.WhereIf(!string.IsNullOrEmpty(queryParam.FormWriterKeyInfo), t => (t.UserName).Contains(queryParam.FormWriterKeyInfo) || t.Email.Contains(queryParam.FormWriterKeyInfo) || t.Phone.Contains(queryParam.FormWriterKeyInfo))
.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))
.WhereIf(queryParam.UserTypeId != null, t => t.UserTypeId == queryParam.UserTypeId)
.WhereIf(queryParam.IsGenerateAccount != null, t => t.IsGenerateAccount == queryParam.IsGenerateAccount)
.WhereIf(queryParam.TrialRoleNameId != null, t => t.TrialRoleNameId == queryParam.TrialRoleNameId)
.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<TrialSiteUserSurveyAllDTO>(_mapper.ConfigurationProvider);
//var query = _trialSiteSurveyRepository.Where(t => t.TrialId == queryParam.TrialId && t.IsAbandon == false)
// .WhereIf(queryParam.SiteId != null, t => t.SiteId == queryParam.SiteId)
// .WhereIf(!string.IsNullOrEmpty(queryParam.FormWriterKeyInfo), t => (t.UserName).Contains(queryParam.FormWriterKeyInfo) || t.Email.Contains(queryParam.FormWriterKeyInfo) || t.Phone.Contains(queryParam.FormWriterKeyInfo))
// .GroupBy(t => t.SiteId)
// .Select(g => g.OrderByDescending(u => u.CreateTime).FirstOrDefault())
// .SelectMany(t => t.TrialSiteUserSurveyList)
//.WhereIf(queryParam.UserTypeId != null, t => t.UserTypeId == queryParam.UserTypeId)
//.WhereIf(queryParam.IsGenerateAccount != null, t => t.IsGenerateAccount == queryParam.IsGenerateAccount)
//.WhereIf(queryParam.TrialRoleNameId != null, t => t.TrialRoleNameId == queryParam.TrialRoleNameId)
//.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.UserKeyInfo), t => (t.LastName + " / " + t.FirstName).Contains(queryParam.UserKeyInfo) || t.Email.Contains(queryParam.UserKeyInfo) || t.Phone.Contains(queryParam.UserKeyInfo))
//.ProjectTo<TrialSiteUserSurveyAllDTO>(_mapper.ConfigurationProvider);
return await query.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, queryParam.SortField, queryParam.Asc);
//return await query.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, queryParam.SortField, queryParam.Asc);
}
/// <summary>
/// 初始登陆界面 项目基本信息+下拉框数据
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpGet("{trialId:guid}")]
public async Task<TrialSurveyInitInfo> GetTrialSurveyInitInfo(Guid trialId)
{
var info = await _repository.Where<Trial>(t => t.Id == trialId).IgnoreQueryFilters().ProjectTo<TrialSurveyInitInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
return info;
}
/// <summary>
/// 驳回 New
/// </summary>
/// <returns></returns>
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> SubmissionRejection(TrialSiteSubmitBackCommand trialSiteSubmitBackCommand, [FromServices] IMailVerificationService _IMailVerificationService)
{
var trialSiteSurveyId = trialSiteSubmitBackCommand.TrialSiteSurveyId;
var survey = await _trialSiteSurveyRepository.FirstOrDefaultAsync(t => t.Id == trialSiteSurveyId);
survey.LatestBackReason = trialSiteSubmitBackCommand.LatestBackReason;
User? user = null;
var messageToSend = new MimeMessage();
if (await _repository.AnyAsync<TrialSiteSurvey>(t => t.State == TrialSiteSurveyEnum.PMCreatedAndLock && t.Id == trialSiteSurveyId))
{
//---中心调研已锁定,不允许操作。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_Locked"]);
}
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM)
{
//SPM 给填表人发
messageToSend.To.Add(new MailboxAddress(String.Empty, survey.Email));
survey.State = TrialSiteSurveyEnum.ToSubmit;
}
else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM)
{
var hasSPMOrCPM = await _trialSiteSurveyRepository.AnyAsync(t => t.TrialId == trialSiteSubmitBackCommand.TrialId && t.Trial.TrialUserList.Any(u => u.User.UserTypeEnum == UserTypeEnum.SPM || u.User.UserTypeEnum == UserTypeEnum.CPM));
if (hasSPMOrCPM)
{
//PM 给SPM发 (初审人)
user = await _userRepository.FirstOrDefaultAsync(t => t.Id == survey.PreliminaryUserId);
messageToSend.To.Add(new MailboxAddress(String.Empty, survey.PreliminaryUserId == null ? survey.Email : user.EMail));
survey.State = TrialSiteSurveyEnum.CRCSubmitted;
survey.ReviewerUserId = null;
survey.ReviewerTime = null;
}
else
{
//没有SPM 给填表人发
messageToSend.To.Add(new MailboxAddress(String.Empty, survey.Email));
survey.State = TrialSiteSurveyEnum.ToSubmit;
survey.PreliminaryUserId = null;
survey.ReviewerUserId = null;
survey.PreliminaryTime = null;
survey.ReviewerTime = null;
}
}
var builder = new BodyBuilder();
var trialInfo = await _repository.FirstOrDefaultAsync<Trial>(t => t.Id == trialSiteSubmitBackCommand.TrialId);
var siteInfo = await _trialSiteRepository.FirstOrDefaultAsync(t => t.TrialId == trialSiteSubmitBackCommand.TrialId && t.SiteId == survey.SiteId, true);
//主题
// $"[来自展影IRC] [{trialInfo.ResearchProgramNo}] 关于中心调研审批的提醒";
messageToSend.Subject = _localizer["TrialSiteSurvey_IRCNotification", trialInfo.ResearchProgramNo];
var pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
+ "TrialSiteSurveyReject.html";
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(templateInfo,
(user == null ? survey.UserName : user.LastName + "/ " + user.FirstName),
trialInfo.TrialCode,
trialInfo.ResearchProgramNo,
trialInfo.ExperimentName,
siteInfo.TrialSiteCode,
siteInfo.TrialSiteAliasName,
survey.LatestBackReason,
trialSiteSubmitBackCommand.RouteUrl,
(survey.State == TrialSiteSurveyEnum.ToSubmit ? "inline - block" : "none")
);
}
messageToSend.Body = builder.ToMessageBody();
await _IMailVerificationService.SiteSurveyRejectEmail(messageToSend);
await _trialSiteSurveyRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 驳回
/// </summary>
/// <param name="trialId"></param>
/// <param name="trialSiteSurveyId"></param>
/// <returns></returns>
[HttpPut("{trialId:guid}/{trialSiteSurveyId:guid}")]
[Obsolete]
public async Task<IResponseOutput> SubmissionRejection(Guid trialId, Guid trialSiteSurveyId)
{
if (await _repository.AnyAsync<TrialSiteSurvey>(t => t.State == TrialSiteSurveyEnum.PMCreatedAndLock && t.Id == trialSiteSurveyId))
{
//---中心调研已锁定,不允许操作。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_Locked"]);
}
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM)
{
await _repository.BatchUpdateAsync<TrialSiteSurvey>(t => t.Id == trialSiteSurveyId, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.ToSubmit });
}
else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM)
{
var hasSPMOrCPM = await _trialSiteSurveyRepository.AnyAsync(t => t.TrialId == trialId && t.Trial.TrialUserList.Any(u => u.User.UserTypeEnum == UserTypeEnum.SPM || u.User.UserTypeEnum == UserTypeEnum.CPM));
if (hasSPMOrCPM)
{
await _trialSiteSurveyRepository.BatchUpdateNoTrackingAsync(t => t.Id == trialSiteSurveyId, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.CRCSubmitted });
}
else
{
await _trialSiteSurveyRepository.BatchUpdateNoTrackingAsync(t => t.Id == trialSiteSurveyId, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.ToSubmit });
}
}
return ResponseOutput.Ok();
}
[HttpPut("{trialId:guid}/{trialSiteSurveyId:guid}")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> AbandonSiteSurvey(Guid trialSiteSurveyId)
{
var survey = (await _trialSiteSurveyRepository.FirstOrDefaultAsync(t => t.Id == trialSiteSurveyId, true)).IfNullThrowException();
if (survey.State != TrialSiteSurveyEnum.ToSubmit)
{
//---只允许废除未提交的记录。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_CancelUnsubmittedRecord"]);
}
survey.IsDeleted = true;
await _repository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 提交 后台自动识别是谁提交
/// </summary>
/// <param name="siteSurvyeSubmit"></param>
/// <returns></returns>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[UnitOfWork]
public async Task<IResponseOutput> TrialSurveySubmit(TrialSiteSurvyeSubmitDTO siteSurvyeSubmit)
{
var trialId = siteSurvyeSubmit.TrialId;
var trialSiteSurveyId = siteSurvyeSubmit.TrialSiteSurveyId;
var trialSiteSurvey = (await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).FirstOrDefaultAsync()).IfNullThrowException();
var siteUserList = await _trialSiteUserSurveyRepository.Where(t => t.TrialSiteSurvey.TrialId==trialId && t.TrialSiteSurvey.SiteId == trialSiteSurvey.SiteId && t.TrialSiteSurvey.IsDeleted==false).Select(t =>
new { t.TrialSiteSurveyId, t.IsGenerateAccount, t.IsGenerateSuccess, t.UserTypeId,
UserTypeEnum= (UserTypeEnum?) t.UserTypeRole.UserTypeEnum , t.TrialRoleName.Code,t.Email }).ToListAsync();
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.Undefined)
{
//是第一次
if(!siteUserList.Any(t=>t.IsGenerateSuccess))
{
var currentUserList = siteUserList.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId).ToList();
if(!currentUserList.Any(t=>t.Code=="1") || !currentUserList.Any(t => t.Code == "4"))
{
throw new BusinessValidationFailedException("本次提交必须有CRC和影像负责人信息");
}
}
await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.ToSubmit, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.SPMApproved });
}
else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager)
{
foreach (var group in (siteUserList.Where(t=>t.IsGenerateAccount && t.TrialSiteSurveyId==trialSiteSurveyId)
.GroupBy(t => new { t.Email, t.IsGenerateAccount, t.UserTypeId })))
{
if (group.Count() > 1)
{
throw new BusinessValidationFailedException("同一邮箱同一用户类型,生成账号的数据只允许存在一条!");
}
}
//是第一次
if (!siteUserList.Any(t => t.IsGenerateSuccess))
{
var currentUserList = siteUserList.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId).ToList();
if (!currentUserList.Any(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator) ||
!currentUserList.Any(t => t.UserTypeEnum == UserTypeEnum.SR))
{
throw new BusinessValidationFailedException("本次提交生成账号必须要有CRC 和SR");
}
}
//已生成的不管 管的只需要是 生成失败的并且需要生成账号的
var needGenerateList = _trialSiteUserSurveyRepository.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId && t.IsGenerateAccount && t.IsJoin != true).ProjectTo<TrialSiteUserSurveyView>(_mapper.ConfigurationProvider).ToList();
//await SendInviteEmail(new InviteEmailCommand() { TrialId = trialId, RouteUrl = siteSurvyeSubmit.RouteUrl, UserList = needGenerateList });
await GenerateAccountAsync(needGenerateList, trialId);
await SendSiteSurveyUserJoinEmail(new TrialSiteUserSurveyJoinCommand() { TrialId = trialId, TrialSiteSurveyId = trialSiteSurveyId, RouteUrl = siteSurvyeSubmit.RouteUrl, BaseUrl = siteSurvyeSubmit.BaseUrl, UserList = needGenerateList });
}
await _trialSiteSurveyRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
private async Task GenerateAccountAsync(List<TrialSiteUserSurveyView> needGenerateList, Guid trialId)
{
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)
{
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;
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;
_ = _userRepository.SaveChangesAsync().Result;
sysUserInfo = newUser;
}
}
//发送邮件的时候需要用到该字段
item.SystemUserId = sysUserInfo.Id;
await _trialSiteUserSurveyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new TrialSiteUserSurvey() { IsGenerateSuccess = true, SystemUserId = sysUserInfo.Id });
}
await _trialSiteUserSurveyRepository.SaveChangesAsync();
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> SendSiteSurveyUserJoinEmail(TrialSiteUserSurveyJoinCommand joinCommand)
{
var trialSiteSurvey = await _trialSiteSurveyRepository.FirstAsync(t => t.Id == joinCommand.TrialSiteSurveyId);
foreach (var userInfo in joinCommand.UserList)
{
if (userInfo.SystemUserId == null)
{
//---生成账户Id 未取到值,请排查
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_FailedToGenerateAccountId"]);
}
var trialId = joinCommand.TrialId;
var userId = (Guid)userInfo.SystemUserId;
var siteId = trialSiteSurvey.SiteId;
//判断TrialUser中是否存在 不存在就插入
if (!await _trialUserRepository.AnyAsync(t => t.TrialId == trialId && t.UserId == userId, true))
{
await _repository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId, 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 _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == userId, u => new User() { Status = UserStateEnum.Enable });
await _trialSiteUserSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == userInfo.Id, u => new TrialSiteUserSurvey() { IsJoin = true });
await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, joinCommand.BaseUrl, joinCommand.RouteUrl);
}
await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurvey.Id && t.State == TrialSiteSurveyEnum.SPMApproved, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.PMCreatedAndLock, ReviewerUserId = _userInfo.Id, ReviewerTime = DateTime.Now });
await _userRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
#region 废弃
//Site 调研邀请
public async Task<IResponseOutput> SendInviteEmail(InviteEmailCommand inviteEmailCommand)
{
var trialInfo = await _repository.FirstOrDefaultAsync<Trial>(t => t.Id == inviteEmailCommand.TrialId);
foreach (var item in inviteEmailCommand.UserList)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, item.Email));
//主题
//$"[来自展影IRC] [{trialInfo.ResearchProgramNo}] 邀请信";
messageToSend.Subject = _localizer["TrialSiteSurvey_IRCInvitation", trialInfo.ResearchProgramNo];
var builder = new BodyBuilder();
//找下系统中是否存在该用户类型的 并且邮箱 或者手机的账户
var sysUserInfo = await _userRepository.Where(t => t.UserTypeId == item.UserTypeId && t.EMail == item.Email).Include(t => t.UserTypeRole).FirstOrDefaultAsync();
//int verificationCode = new Random().Next(100000, 1000000);
//var baseApiUrl = baseUrl.Remove(baseUrl.IndexOf("#")) + "api";
if (sysUserInfo == null)
{
lock (lockObj)
{
var saveItem = _mapper.Map<User>(item);
saveItem.Code = _userRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1;
saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(User)); ;
saveItem.UserName = saveItem.UserCode;
saveItem.UserTypeEnum = _repository.Where<UserType>(t => t.Id == saveItem.UserTypeId).Select(t => t.UserTypeEnum).First();
//saveItem.Password = MD5Helper.Md5(verificationCode.ToString());
_ = _repository.AddAsync(saveItem).Result;
_ = _repository.SaveChangesAsync().Result;
sysUserInfo = saveItem;
}
}
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;'>
{_localizer["TrialSiteSurvey_IRCInvitationContent", trialInfo.ResearchProgramNo]}
</div>
<a href=' {inviteEmailCommand.RouteUrl + "?Id=" + item.Id + "&IsExternalUser=0"}' 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>";
messageToSend.Body = builder.ToMessageBody();
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
{
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
smtp.MessageSent += (sender, args) =>
{
_ = _trialSiteUserSurveyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new TrialSiteUserSurvey() { IsGenerateSuccess = true, InviteState = TrialSiteUserStateEnum.HasSend, ConfirmTime = null, RejectReason = String.Empty, SystemUserId = sysUserInfo.Id, ExpireTime = DateTime.Now.AddDays(7) }).Result;
};
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();
}
#endregion
}
}