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

1013 lines
43 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;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.VisualBasic;
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Application.ViewModel;
using Medallion.Threading;
using Microsoft.Extensions.Options;
using NPOI.SS.Formula.Functions;
using Newtonsoft.Json;
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<TrialUser> _trialUserRepository;
private readonly IRepository<TrialSiteUser> _trialSiteUserRepository;
private readonly IDistributedLockProvider _distributedLockProvider;
private readonly ITokenService _tokenService;
private readonly IMailVerificationService _mailVerificationService;
private readonly SystemEmailSendConfig _systemEmailConfig;
public TrialSiteSurveyService(IRepository<TrialSiteSurvey> trialSiteSurveyRepository, IRepository<TrialUser> trialUserRepository, IRepository<TrialSiteUserSurvey> trialSiteUserSurveyRepository,
IRepository<User> userRepository, IRepository<TrialSite> trialSiteRepository,
ITokenService tokenService,
IMailVerificationService mailVerificationService, IRepository<TrialSiteUser> trialSiteUserRepository, IDistributedLockProvider distributedLockProvider, IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig)
{
_trialSiteSurveyRepository = trialSiteSurveyRepository;
_trialSiteUserSurveyRepository = trialSiteUserSurveyRepository;
_userRepository = userRepository;
_trialUserRepository = trialUserRepository;
_trialSiteRepository = trialSiteRepository;
_tokenService = tokenService;
_mailVerificationService = mailVerificationService;
_trialSiteUserRepository = trialSiteUserRepository;
_distributedLockProvider = distributedLockProvider;
_systemEmailConfig = systemEmailConfig.CurrentValue;
}
/// <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-Z]{2,}$"))
{
//---请输入正确的邮箱地址。
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();
//检查数据库是否存在该验证码
if (verificationRecord == null)
{
//---验证码错误。
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_WrongVerificationCode"]);
}
else
{
//检查验证码是否失效
if (verificationRecord.ExpirationTime < DateTime.Now)
{
//---验证码已经过期。
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_ExpiredVerificationCode"]);
}
else //验证码正确 并且 没有超时
{
//删除验证码历史记录
await _repository.BatchDeleteAsync<VerificationCode>(t => t.Id == verificationRecord.Id);
var dockerInfo = await _repository.Where<Doctor>(t => t.EMail == inDto.EmailOrPhone || t.Phone == inDto.EmailOrPhone).FirstOrDefaultAsync();
if (dockerInfo != null)
{
result.DoctorId = dockerInfo.Id;
result.ReviewStatus = dockerInfo.ReviewStatus;
}
result.Token = _tokenService.GetToken(IRaCISClaims.Create(new UserBasicInfo()));
}
}
return result;
}
/// <summary>
///site 调研 发送验证码
/// </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-Z]{2,}$"))
{
//---请输入正确的邮箱地址。
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)
{
#region 20230804 修改调研表逻辑
var verifyRecord = await _repository.FirstOrDefaultAsync<VerificationCode>(t => (t.EmailOrPhone == userInfo.EmailOrPhone) && t.Code == userInfo.verificationCode && t.CodeType == userInfo.verificationType);
//检查数据库是否存在该验证码
if (verifyRecord == null)
{
//---验证码错误。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_WrongVerificationCode"]);
}
else if (verifyRecord.ExpirationTime < DateTime.Now)
{
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_WrongVerificationCode"]);
}
else
{
//删除验证码历史记录
await _repository.BatchDeleteAsync<VerificationCode>(t => t.Id == verifyRecord.Id);
//验证码正确 不处理
}
TrialSiteSurvey? currentEntity = null;
var userList = await _trialSiteUserRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId, false, true).ProjectTo<TrialSiteUserSurvey>(_mapper.ConfigurationProvider).ToListAsync();
//普通登录
if (userInfo.IsUpdate == false)
{
var dbEntityList = await _trialSiteSurveyRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId).ToListAsync();
//没有记录 new一份
if (dbEntityList.Count == 0)
{
var addSurvey = _mapper.Map<TrialSiteSurvey>(userInfo);
//从项目site 中找到已存在的 加到历史人员中
addSurvey.TrialSiteUserSurveyList = userList;
currentEntity = await _repository.AddAsync(addSurvey);
}
else
{
//找到当前最新的调研表
var currentLatest = dbEntityList.OrderByDescending(t => t.CreateTime).FirstOrDefault();
if (currentLatest!.Email != userInfo.EmailOrPhone)
{
//---该中心下已经有其他用户已填写的调研表,您不被允许继续填写
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_AlreadyFilledByOtherUsers"]);
}
currentEntity = currentLatest;
if (currentEntity.State != TrialSiteSurveyEnum.PMCreatedAndLock)
{
await UnlockSyncSiteUserAsync(userInfo.TrialId, userInfo.TrialSiteId, currentEntity.Id, userList);
}
}
}
//更新调研表
else
{
//找到最新的调研表
var currentLatest = await _trialSiteSurveyRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId, true)
.Include(u => u.TrialSiteEquipmentSurveyList).Include(u => u.TrialSiteUserSurveyList).OrderByDescending(t => t.CreateTime).FirstOrDefaultAsync();
if (currentLatest == null)
{
return ResponseOutput.NotOk(_localizer["TrialSite_NoSurveyToUpdate"]);
}
if (currentLatest.Email != userInfo.ReplaceUserEmailOrPhone)
{
//---该中心不存在该交接人的中心调研记录表,不允许选择更新。
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_NoRecordToUpdate"]);
}
//未锁定的状态 就改为废除
if (currentLatest.State != TrialSiteSurveyEnum.PMCreatedAndLock)
{
currentLatest.IsDeleted = true;
}
//锁定的 需要改状态么?
else
{
}
var copy = currentLatest.Clone();
copy.State = TrialSiteSurveyEnum.ToSubmit;
copy.IsDeleted = false;
copy.Phone = string.Empty;
copy.UserName = string.Empty;
copy.Email = userInfo.EmailOrPhone;
copy.Id = Guid.Empty;
copy.CreateTime = DateAndTime.Now;
if (userInfo.ReplaceUserEmailOrPhone != userInfo.EmailOrPhone)
{
copy.UserName = String.Empty;
copy.Phone = String.Empty;
}
copy.TrialSiteEquipmentSurveyList = currentLatest.TrialSiteEquipmentSurveyList.Clone();
copy.TrialSiteEquipmentSurveyList.ForEach(t => { t.Id = Guid.Empty; t.CreateTime = DateTime.Now; });
//锁定了的话,就不拷贝
if (currentLatest.State != TrialSiteSurveyEnum.PMCreatedAndLock)
{
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);
}
//删除验证码历史记录
await _repository.BatchDeleteAsync<VerificationCode>(t => t.EmailOrPhone == userInfo.EmailOrPhone && t.Code == userInfo.verificationCode && t.CodeType == userInfo.verificationType);
await _trialSiteSurveyRepository.SaveChangesAsync();
return ResponseOutput.Ok(new
{
TrialSiteSurveyId = currentEntity!.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",
}))
});
#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.TrialSiteId == 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
{
find.IsHistoryUserOriginDeleted = item.IsHistoryUserOriginDeleted;
}
}
await _trialSiteUserSurveyRepository.SaveChangesAsync();
}
/// <summary>
/// 直接查询相关所有数据
/// </summary>
/// <returns></returns>
[HttpGet("{trialId:guid}/{trialSiteSurveyId:guid}")]
public async Task<LoginReturnDTO> GetSiteSurveyInfo(Guid trialSiteSurveyId, Guid trialId)
{
//有可能填表人提交了但是此时PM手动对人员信息进行了更改此时需要将数据同步下选择在这里同步是因为 不想改动 中心人员哪里的两个接口的逻辑)
var find = await _trialSiteSurveyRepository.FirstOrDefaultAsync(t => t.Id == trialSiteSurveyId, true);
if (find.State != TrialSiteSurveyEnum.PMCreatedAndLock && find.IsDeleted != true)
{
var userList = await _trialSiteUserRepository.Where(t => t.TrialId == find.TrialId && t.TrialSiteId == find.TrialSiteId, false, true).ProjectTo<TrialSiteUserSurvey>(_mapper.ConfigurationProvider).ToListAsync();
await UnlockSyncSiteUserAsync(find.TrialId, find.TrialSiteId, find.Id, userList);
}
var result = await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId && t.TrialId == trialId).IgnoreQueryFilters()
.ProjectTo<LoginReturnDTO>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync().IfNullThrowException();
var siteSurveryConfig = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).IgnoreQueryFilters().Select(t => t.Trial.TrialExtraConfigJsonStr).FirstOrDefault()??string.Empty;
result.SiteSurveyFiledConfig = JsonConvert.DeserializeObject<TrialExtraConfig>(siteSurveryConfig) ?? new TrialExtraConfig();
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 inQuery)
{
var trialSiteSurveyQueryable = _trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId).IgnoreQueryFilters()
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.UserKeyInfo), t => t.UserName.Contains(inQuery.UserKeyInfo) || t.Phone.Contains(inQuery.UserKeyInfo) || t.Email.Contains(inQuery.UserKeyInfo))
.WhereIf(inQuery.State != null, t => t.State == inQuery.State)
.WhereIf(inQuery.UpdateTimeBegin != null, t => t.UpdateTime >= inQuery.UpdateTimeBegin)
.WhereIf(inQuery.UpdateTimeEnd != null, t => t.UpdateTime <= inQuery.UpdateTimeEnd)
.ProjectTo<TrialSiteSurveyView>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us })
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.PreliminaryUserName), t => t.PreliminaryUser.RealName.Contains(inQuery.PreliminaryUserName))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.ReviewerUserName), t => t.ReviewerUser.RealName.Contains(inQuery.ReviewerUserName))
;
return await trialSiteSurveyQueryable.ToPagedListAsync(inQuery);
}
[HttpPost]
public async Task<List<TrialSiteSurveySelectView>> GetTrialSiteSurveySelectList(TrialSiteSurveySelectquery inQuery)
{
var trialSiteSurveyQueryable = _trialSiteSurveyRepository
.Where(t => t.Id != inQuery.TrialSiteSurveyId)
.Where(t => t.TrialId == inQuery.TrialId && t.TrialSiteId == inQuery.TrialSiteId).IgnoreQueryFilters()
.ProjectTo<TrialSiteSurveySelectView>(_mapper.ConfigurationProvider);
return await trialSiteSurveyQueryable.ToListAsync();
}
/// <summary>
/// 项目Site调研用户列表 所有site的调研用户 最新的调研表的记录的用户 new
/// </summary>
/// <returns></returns>
public async Task<PageOutput<TrialSiteUserSurveyAllDTO>> TrialSiteSurveyUserList(TrialSiteUserSurveyAllQuery inQuery)
{
var groupSelectIdQuery =
_trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(!string.IsNullOrEmpty(inQuery.FormWriterKeyInfo), t => (t.UserName).Contains(inQuery.FormWriterKeyInfo) || t.Email.Contains(inQuery.FormWriterKeyInfo) || t.Phone.Contains(inQuery.FormWriterKeyInfo))
.GroupBy(t => t.TrialSiteId)
.Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First());
var query = _trialSiteUserSurveyRepository
.Where(t => groupSelectIdQuery.Contains(t.TrialSiteSurveyId))
.WhereIf(inQuery.TrialRoleCode != null, t => t.TrialRoleCode == inQuery.TrialRoleCode)
.WhereIf(inQuery.UserTypeId != null, t => t.UserTypeId == inQuery.UserTypeId)
.WhereIf(inQuery.IsGenerateAccount != null, t => t.IsGenerateAccount == inQuery.IsGenerateAccount)
.WhereIf(inQuery.State != null && inQuery.State != TrialSiteUserStateEnum.OverTime, t => t.InviteState == inQuery.State)
.WhereIf(!string.IsNullOrEmpty(inQuery.UserName), t => (t.LastName + " / " + t.FirstName).Contains(inQuery.UserName))
.WhereIf(!string.IsNullOrEmpty(inQuery.OrganizationName), t => t.OrganizationName.Contains(inQuery.OrganizationName))
.ProjectTo<TrialSiteUserSurveyAllDTO>(_mapper.ConfigurationProvider);
return await query.ToPagedListAsync(inQuery);
//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;
}
}
await _IMailVerificationService.SiteSurveyRejectEmail(messageToSend, survey , trialSiteSubmitBackCommand.RouteUrl, user);
await _trialSiteSurveyRepository.SaveChangesAsync();
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, false, true).FirstOrDefaultAsync()).IfNullThrowException();
if (trialSiteSurvey.IsDeleted == true || trialSiteSurvey.State == TrialSiteSurveyEnum.PMCreatedAndLock)
{
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_Invalid"]);
}
var siteUserList = await _trialSiteUserSurveyRepository.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId)
.Where(t => !(t.IsHistoryUser && t.IsHistoryUserDeleted == true))
.Select(t =>
new
{
t.TrialSiteSurveyId,
t.IsGenerateAccount,
t.IsGenerateSuccess,
t.UserTypeId,
UserTypeEnum = (UserTypeEnum?)t.UserTypeRole.UserTypeEnum,
t.TrialRoleCode,
t.Email,
}).ToListAsync();
//var currentUserList = siteUserList.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId).ToList();
if (!siteUserList.Any(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.CRA))
{
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_MissingAccount"]);
}
if (siteUserList.Where(t => t.IsGenerateAccount && t.UserTypeId != null).GroupBy(t => new { t.UserTypeId, t.Email })
.Any(g => g.Count() > 1))
{
throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_DuplicateEmail"]);
}
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.Undefined)
{
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.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.ToSubmit, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.CRCSubmitted });
}
else
{
await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.ToSubmit, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.SPMApproved });
}
}
else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM)
{
await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.CRCSubmitted, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.SPMApproved, PreliminaryUserId = _userInfo.Id, PreliminaryTime = DateTime.Now });
}
else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM)
{
var allUserList = _trialSiteUserSurveyRepository.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId).ProjectTo<TrialSiteUserSurveyView>(_mapper.ConfigurationProvider).ToList();
//已生成的不管 管的只需要是 生成失败的并且需要生成账号的
var needGenerateList = allUserList.Where(t => t.IsHistoryUser == false && t.IsGenerateAccount && t.IsJoin != true).ToList();
await GenerateAccountAsync(needGenerateList, trialId);
//新加入的 或者历史人员退出改为加入的
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.TrialSiteId, needQuitUserList);
//将历史锁定的调研表废弃
await _trialSiteSurveyRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteSurvey.TrialSiteId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock && t.Id != trialSiteSurveyId, z => new TrialSiteSurvey() { IsDeleted = true });
}
await _trialSiteSurveyRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
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();
if (sysUserInfo == null)
{
var @lock = _distributedLockProvider.CreateLock($"UserCode");
using (await @lock.AcquireAsync())
{
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();
var newUser = _userRepository.AddAsync(saveItem).Result;
_ = _userRepository.SaveChangesAsync().Result;
sysUserInfo = newUser;
}
await _trialSiteUserSurveyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new TrialSiteUserSurvey() { IsGenerateSuccess = true, SystemUserId = sysUserInfo.Id });
}
//发送邮件的时候需要用到该字段
item.SystemUserId = sysUserInfo.Id;
}
await _trialSiteUserSurveyRepository.SaveChangesAsync();
}
private 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 trialSiteId = trialSiteSurvey.TrialSiteId;
//判断TrialUser中是否存在 不存在就插入
var findTrialUser = await _trialUserRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.UserId == userId, true);
if (findTrialUser == null)
{
await _repository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId, JoinTime = DateTime.Now });
await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, joinCommand.BaseUrl, joinCommand.RouteUrl);
}
else if (findTrialUser.IsDeleted == true)
{
await _trialUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.UserId == userId, c => new TrialUser()
{
IsDeleted = false,
DeletedTime = null,
JoinTime = DateTime.Now,
});
await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, joinCommand.BaseUrl, joinCommand.RouteUrl);
}
var findTrialSiteUser = await _trialSiteUserRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.UserId == userId && t.TrialSiteId == trialSiteId, true);
if (findTrialSiteUser == null)
{
await _repository.AddAsync(new TrialSiteUser() { TrialId = trialId, TrialSiteId = trialSiteId, UserId = userId });
}
else
{
findTrialSiteUser.IsDeleted = false;
findTrialSiteUser.DeletedTime = null;
}
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 _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();
}
private async Task DealSiteUserQuitSiteAsync(Guid trialId, Guid siteId, List<TrialSiteUserSurveyView> list)
{
var userIdList = list.Select(t => t.SystemUserId).ToList();
await _trialSiteUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.TrialSiteId == siteId && userIdList.Contains(t.UserId), c => new TrialSiteUser()
{
IsDeleted = true,
DeletedTime = DateTime.Now,
});
await _repository.SaveChangesAsync();
}
public async Task ImportGenerateAccountAndJoinTrialAsync(Guid trialId, string baseUrl, string routeUrl, 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)
{
var @lock = _distributedLockProvider.CreateLock($"UserCode");
using (await @lock.AcquireAsync())
{
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;
var trialSiteId = item.TrialSiteId;
//判断是否加入到项目
var findTrialUser = await _trialUserRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.UserId == userId, true);
if (findTrialUser == null)
{
await _repository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId, JoinTime = DateTime.Now });
await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, baseUrl, routeUrl);
}
else if (findTrialUser.IsDeleted == true)
{
await _trialUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.UserId == userId, c => new TrialUser()
{
IsDeleted = false,
DeletedTime = null,
JoinTime = DateTime.Now,
});
await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, baseUrl, routeUrl);
}
var findTrialSiteUser = await _trialSiteUserRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.UserId == userId && t.TrialSiteId == trialSiteId, true);
if (findTrialSiteUser == null)
{
await _repository.AddAsync(new TrialSiteUser() { TrialId = trialId, TrialSiteId = trialSiteId, UserId = userId });
}
else
{
findTrialSiteUser.IsDeleted = false;
findTrialSiteUser.DeletedTime = null;
}
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == userId, u => new User() { Status = UserStateEnum.Enable });
await _trialSiteUserRepository.SaveChangesAsync();
}
}
}
}