质疑状态修改

Uat_Study
hang 2022-04-22 16:05:15 +08:00
parent be969cd9f9
commit 16d39d9190
2 changed files with 166 additions and 229 deletions

View File

@ -20,6 +20,7 @@ using Newtonsoft.Json;
using IRaCIS.Core.Application.Service.Inspection.Interface; using IRaCIS.Core.Application.Service.Inspection.Interface;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Application.Service.Inspection.DTO; using IRaCIS.Core.Application.Service.Inspection.DTO;
using Nito.AsyncEx;
namespace IRaCIS.Core.Application.Image.QA namespace IRaCIS.Core.Application.Image.QA
{ {
@ -35,6 +36,8 @@ namespace IRaCIS.Core.Application.Image.QA
private readonly IInspectionService _inspectionService; private readonly IInspectionService _inspectionService;
private object _locker = new object(); private object _locker = new object();
private readonly AsyncLock _mutex = new AsyncLock();
public QCOperationService(DicomFileStoreHelper dicomFileStoreHelper, IRepository<SubjectVisit> subjectVisitRepository, public QCOperationService(DicomFileStoreHelper dicomFileStoreHelper, IRepository<SubjectVisit> subjectVisitRepository,
IRepository<Trial> trialRepository, IRepository<Trial> trialRepository,
IMediator mediator, IMediator mediator,
@ -83,60 +86,21 @@ namespace IRaCIS.Core.Application.Image.QA
if (await _repository.AnyAsync<QCChallenge>(t => t.IsClosed == false && t.SubjectVisitId == qaQuestionCommand.SubjectVisitId && t.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload)) if (await _repository.AnyAsync<QCChallenge>(t => t.IsClosed == false && t.SubjectVisitId == qaQuestionCommand.SubjectVisitId && t.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload))
{ {
throw new BusinessValidationFailedException("当前访视有未关闭的 同意CRC上传的质疑不允许再次添加质疑"); throw new BusinessValidationFailedException("当前访视有未关闭的 同意CRC上传的质疑不允许再次添加质疑");
}
var trialConfig = _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification }).FirstOrDefault();
//获取编号
var code = _repository.Where<QCChallenge>(t => t.TrialId == trialId).Select(t => t.ChallengeCode).DefaultIfEmpty().Max();
if (trialConfig == null)
{
throw new BusinessValidationFailedException("项目不存在");
} }
QCChallenge? qcChallenge = null; using (await _mutex.LockAsync())
var success = false;
lock (_locker)
{ {
var trialConfig = _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification }).FirstOrDefault(); var qcChallenge = _mapper.Map<QCChallenge>(qaQuestionCommand);
if (trialConfig == null)
{
throw new BusinessValidationFailedException("项目不存在");
}
#region 处理访视状态变更
//var dbSubjectVisit = _subjectVisitRepository.FirstOrDefault(t => t.Id == qaQuestionCommand.SubjectVisitId);
//if (trialConfig.QCProcessEnum == TrialQCProcess.NotAudit)
//{
// return ResponseOutput.NotOk("项目配置为不审不允许添加QA质疑 ");
//}
//else if (trialConfig.QCProcessEnum == TrialQCProcess.SingleAudit)
//{
// if ((int)dbSubjectVisit.AuditState == (int)SubjectVisitStateEnum.Submitted)
// {
// dbSubjectVisit.AuditState = AuditStateEnum.InPrimaryQC;
// }
// else
// {
// return ResponseOutput.NotOk($"项目配置为单审,当前审核状态不为{SubjectVisitStateEnum.Submitted},不允许添加QA质疑 ");
// }
//}
//else if (trialConfig.QCProcessEnum == TrialQCProcess.DoubleAudit)
//{
// if ((int)dbSubjectVisit.AuditState == (int)SubjectVisitStateEnum.Submitted)
// {
// dbSubjectVisit.AuditState = AuditStateEnum.InPrimaryQC;
// }
// else if ((int)dbSubjectVisit.AuditState == (int)SubjectVisitStateEnum.PrimaryQCPassed)
// {
// dbSubjectVisit.AuditState = AuditStateEnum.InSecondaryQC;
// }
// else
// {
// return ResponseOutput.NotOk($"项目配置为双审,访视状态为 {SubjectVisitStateEnum.Submitted}或{SubjectVisitStateEnum.PrimaryQCPassed}才允许添加QA质疑 ");
// }
//}
#endregion
//获取编号
var code = _repository.Where<QCChallenge>(t => t.TrialId == trialId).Select(t => t.ChallengeCode).DefaultIfEmpty().Max();
qcChallenge = _mapper.Map<QCChallenge>(qaQuestionCommand);
qcChallenge.QCProcessEnum = trialConfig.QCProcessEnum; qcChallenge.QCProcessEnum = trialConfig.QCProcessEnum;
qcChallenge.CurrentQCEnum = currentQCType; qcChallenge.CurrentQCEnum = currentQCType;
@ -144,53 +108,18 @@ namespace IRaCIS.Core.Application.Image.QA
qcChallenge.CreateUser = _userInfo.RealName; qcChallenge.CreateUser = _userInfo.RealName;
qcChallenge.ChallengeCode = code + 1; qcChallenge.ChallengeCode = code + 1;
qcChallenge.UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt; qcChallenge.UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt;
_ = _repository.AddAsync(qcChallenge).Result;
success = _repository.SaveChangesAsync().Result; qcChallenge= await _repository.AddAsync(qcChallenge,true);
return qcChallenge;
} }
//分开两个事务 处理访视质疑状态
await DealChallengeState(qcChallenge.SubjectVisitId);
return qcChallenge;
#region 添加的时候把记录给留存
//var templateItems = _mapper.Map<List<QARecordTemplateItemDetail>>(visitQaCommand.QATrialTemplateItemList);
//templateItems.ForEach(u =>
//{
// u.IQA = _userInfo.RealName;
// u.IQACreateTime = DateTime.Now;
// u.IQANote = visitQaCommand.QARecord.Note;
// u.IQADeadline = visitQaCommand.QARecord.DeadlineTime;
// u.QARecordId = qaRecord.Id;
// qaRecord.QARecordTemplateItemDetailList.Add(u);
//});
////添加了QA记录 引用了QA模板后就不允许删除和编辑需要维护项目模板状态 传统做法
//var qaTrailTemplate = _qaTrailTemplateRepository.FirstOrDefault(t => t.Id == visitQaCommand.QARecord.QATrialTemplateId);
//qaTrailTemplate.Status = QATrialTemplateStatus.HasQuote;
#endregion
} }
else else
{ {
var qcChallenge = await _repository.FirstOrDefaultAsync<QCChallenge>(t => t.Id == qaQuestionCommand.Id); return await _repository.UpdateFromDTOAsync<QCChallenge, QCChallengeCommand>(qaQuestionCommand, true);
if (qcChallenge == null)
{
throw new BusinessValidationFailedException("QC问题不存在");
};
_mapper.Map(qaQuestionCommand, qcChallenge);
var success = await _repository.SaveChangesAsync();
await DealChallengeState(qcChallenge.SubjectVisitId);
return qcChallenge;
} }
@ -237,39 +166,14 @@ namespace IRaCIS.Core.Application.Image.QA
var success = await _repository.SaveChangesAsync(); var success = await _repository.SaveChangesAsync();
await DealChallengeState(subjectVisitId);
return ResponseOutput.Result(success); return ResponseOutput.Result(success);
} }
/// <summary>
/// 访视级别统计 质疑最新的状态
/// </summary>
/// <param name="subjectVisitId"></param>
private async Task DealChallengeState(Guid subjectVisitId)
{
var sv = await _repository.FirstOrDefaultAsync<SubjectVisit>(t => t.Id == subjectVisitId);
var closedStateList = await _repository.Where<QCChallenge>(t => t.SubjectVisitId == subjectVisitId).Select(t => t.IsClosed).ToListAsync();
if (closedStateList.Count == 0)
{
sv.ChallengeState = ChallengeStateEnum.No;
}
else if (closedStateList.All(t => t is true))
{
sv.ChallengeState = ChallengeStateEnum.HaveAndAllClosed;
}
else
{
sv.ChallengeState = ChallengeStateEnum.HaveAndHaveNotClosed;
}
await _repository.SaveChangesAsync();
}
/// <summary> /// <summary>
/// 删除QC质疑记录 /// 删除QC质疑记录
@ -532,9 +436,9 @@ namespace IRaCIS.Core.Application.Image.QA
var success = await _repository.SaveChangesAsync(); var success = await _repository.SaveChangesAsync();
// var signSuccess = await _repository.UpdateFromQueryAsync<TrialSign>(t => t.Id == signId, u => new TrialSign() { IsCompleted = true }); // var signSuccess = await _repository.UpdateFromQueryAsync<TrialSign>(t => t.Id == signId, u => new TrialSign() { IsCompleted = true });
return ResponseOutput.Result( success); return ResponseOutput.Result(success);
} }
@ -549,7 +453,7 @@ namespace IRaCIS.Core.Application.Image.QA
/// <returns></returns> /// <returns></returns>
[HttpPost("{trialId:guid}")] [HttpPost("{trialId:guid}")]
[TypeFilter(typeof(TrialResourceFilter))] [TypeFilter(typeof(TrialResourceFilter))]
public async Task<IResponseOutput> UploadVisitCheckExcel(IFormFile file, Guid trialId) public async Task<IResponseOutput> UploadVisitCheckExcel(IFormFile file, Guid trialId)
{ {
if (_userInfo.UserTypeEnumInt != (int)UserTypeEnum.ProjectManager) if (_userInfo.UserTypeEnumInt != (int)UserTypeEnum.ProjectManager)
{ {
@ -902,13 +806,13 @@ namespace IRaCIS.Core.Application.Image.QA
public async Task<IResponseOutput> UpdateModality(Guid id, int type, [FromQuery] string modality, [FromQuery] string bodyPart) public async Task<IResponseOutput> UpdateModality(Guid id, int type, [FromQuery] string modality, [FromQuery] string bodyPart)
{ {
var DicomSeriesdata = await _repository.GetQueryable<DicomSeries>().Where(x=>x.StudyId==id).ToListAsync(); var DicomSeriesdata = await _repository.GetQueryable<DicomSeries>().Where(x => x.StudyId == id).ToListAsync();
var study = await _repository.FirstOrDefaultAsync<DicomStudy>(t => t.Id == id); var study = await _repository.FirstOrDefaultAsync<DicomStudy>(t => t.Id == id);
List<DataInspection> datas = new List<DataInspection>(); List<DataInspection> datas = new List<DataInspection>();
DateTime time = DateTime.Now.AddMilliseconds(500); DateTime time = DateTime.Now.AddMilliseconds(500);
if (type == 1) if (type == 1)
{ {
if (study == null) return Null404NotFound(study); if (study == null) return Null404NotFound(study);
study.BodyPartForEdit = bodyPart; study.BodyPartForEdit = bodyPart;
@ -977,7 +881,7 @@ namespace IRaCIS.Core.Application.Image.QA
{ {
} }
await _trialRepository.AddListInspectionRecordAsync(datas); await _trialRepository.AddListInspectionRecordAsync(datas);
await _repository.SaveChangesAsync(); await _repository.SaveChangesAsync();
return ResponseOutput.Ok(); return ResponseOutput.Ok();
@ -999,8 +903,8 @@ namespace IRaCIS.Core.Application.Image.QA
} }
return ResponseOutput.Ok(); return ResponseOutput.Ok();
} }
/// <summary> /// <summary>
@ -1021,7 +925,7 @@ namespace IRaCIS.Core.Application.Image.QA
{ {
return ResponseOutput.NotOk("CRC Has Submited Imagecan not delete"); return ResponseOutput.NotOk("CRC Has Submited Imagecan not delete");
} }
var waitDeleteStudyList= await _dicomStudyRepository.Where(x => ids.Contains(x.Id)).ToListAsync(); var waitDeleteStudyList = await _dicomStudyRepository.Where(x => ids.Contains(x.Id)).ToListAsync();
List<DataInspection> datas = new List<DataInspection>(); List<DataInspection> datas = new List<DataInspection>();
@ -1035,18 +939,18 @@ namespace IRaCIS.Core.Application.Image.QA
SiteId = x.SiteId, SiteId = x.SiteId,
SubjectId = x.SubjectId, SubjectId = x.SubjectId,
TrialId = x.TrialId, TrialId = x.TrialId,
SubjectVisitId=x.SubjectVisitId, SubjectVisitId = x.SubjectVisitId,
GeneralId=x.Id, GeneralId = x.Id,
CreateTime=DateTime.Now, CreateTime = DateTime.Now,
Identification= "Delete|DICOM Study|Data|Visit-Image Upload", Identification = "Delete|DICOM Study|Data|Visit-Image Upload",
JsonDetail = JsonConvert.SerializeObject(new JsonDetail = JsonConvert.SerializeObject(new
{ {
studyUid=x.StudyCode, studyUid = x.StudyCode,
modality=x.Modalities, modality = x.Modalities,
bodyPart=x.BodyPartForEdit, bodyPart = x.BodyPartForEdit,
seriesNum=x.SeriesCount, seriesNum = x.SeriesCount,
fileNum = x.InstanceCount, fileNum = x.InstanceCount,
studyTime=x.StudyTime?.ToString("yyyy-MM-dd") studyTime = x.StudyTime?.ToString("yyyy-MM-dd")
}) })
}); });
@ -1060,22 +964,23 @@ namespace IRaCIS.Core.Application.Image.QA
var id = study.Id; var id = study.Id;
await _dicomStudyRepository.DeleteAsync(study,true); await _dicomStudyRepository.DeleteAsync(study, true);
var succeess2 = await _repository.BatchDeleteAsync<DicomInstance>(t => t.StudyId == id); var succeess2 = await _repository.BatchDeleteAsync<DicomInstance>(t => t.StudyId == id);
var DicomSeriess = await _repository.GetQueryable<DicomSeries>().Where(t => t.StudyId == id).Select(x => new { var DicomSeriess = await _repository.GetQueryable<DicomSeries>().Where(t => t.StudyId == id).Select(x => new
{
x.StudyId, x.StudyId,
x.SubjectId, x.SubjectId,
x.SiteId, x.SiteId,
x.TrialId, x.TrialId,
x.Id, x.Id,
x.SubjectVisitId, x.SubjectVisitId,
x.SeriesTime, x.SeriesTime,
x.IsReading, x.IsReading,
x.InstanceCount, x.InstanceCount,
x.SeriesNumber, x.SeriesNumber,
StudyCode= x.DicomStudy.StudyCode, StudyCode = x.DicomStudy.StudyCode,
Modalities=x.DicomStudy.Modalities, Modalities = x.DicomStudy.Modalities,
}).ToListAsync(); }).ToListAsync();
@ -1128,7 +1033,7 @@ namespace IRaCIS.Core.Application.Image.QA
var subvisit = await _repository.GetQueryable<SubjectVisit>().FirstOrDefaultAsync(x => x.Id == subjectVisitId); var subvisit = await _repository.GetQueryable<SubjectVisit>().FirstOrDefaultAsync(x => x.Id == subjectVisitId);
datas.Add(new DataInspection() datas.Add(new DataInspection()
{ {
@ -1197,7 +1102,7 @@ namespace IRaCIS.Core.Application.Image.QA
#region 处理验证 #region 处理验证
if (dbSubjectVisit.IsTake&& dbSubjectVisit.CurrentActionUserId!=_userInfo.Id) if (dbSubjectVisit.IsTake && dbSubjectVisit.CurrentActionUserId != _userInfo.Id)
{ {
return ResponseOutput.NotOk("当前已被领取,不允许领取"); return ResponseOutput.NotOk("当前已被领取,不允许领取");
} }
@ -1274,12 +1179,12 @@ namespace IRaCIS.Core.Application.Image.QA
} }
else if (trialConfig.QCProcessEnum == TrialQCProcess.SingleAudit) else if (trialConfig.QCProcessEnum == TrialQCProcess.SingleAudit)
{ {
if (dbSubjectVisit.SubmitState == SubmitStateEnum.Submitted && dbSubjectVisit.AuditState == AuditStateEnum.InPrimaryQC) if (dbSubjectVisit.SubmitState == SubmitStateEnum.Submitted && dbSubjectVisit.AuditState == AuditStateEnum.InPrimaryQC)
{ {
dbSubjectVisit.AuditState = AuditStateEnum.ToAudit; dbSubjectVisit.AuditState = AuditStateEnum.ToAudit;
} }
else else
{ {
return ResponseOutput.NotOk("项目配置为单审,不满足SubmmitState已提交 或者 AuditStateInPrimaryQC, 不允许释放"); return ResponseOutput.NotOk("项目配置为单审,不满足SubmmitState已提交 或者 AuditStateInPrimaryQC, 不允许释放");
@ -1287,7 +1192,7 @@ namespace IRaCIS.Core.Application.Image.QA
} }
else if (trialConfig.QCProcessEnum == TrialQCProcess.DoubleAudit) else if (trialConfig.QCProcessEnum == TrialQCProcess.DoubleAudit)
{ {
//提交 并且初审通过 那么领取后进入 复审中 //提交 并且初审通过 那么领取后进入 复审中
if (dbSubjectVisit.SubmitState == SubmitStateEnum.Submitted && dbSubjectVisit.AuditState == AuditStateEnum.InSecondaryQC) if (dbSubjectVisit.SubmitState == SubmitStateEnum.Submitted && dbSubjectVisit.AuditState == AuditStateEnum.InSecondaryQC)
{ {
@ -1298,7 +1203,7 @@ namespace IRaCIS.Core.Application.Image.QA
{ {
dbSubjectVisit.AuditState = AuditStateEnum.ToAudit; dbSubjectVisit.AuditState = AuditStateEnum.ToAudit;
} }
else else
{ {
return ResponseOutput.NotOk("项目配置为复审,不满足提交状态:已提交 或者 审核状态InPrimaryQC/InSecondaryQC, 不允许领取"); return ResponseOutput.NotOk("项目配置为复审,不满足提交状态:已提交 或者 审核状态InPrimaryQC/InSecondaryQC, 不允许领取");
@ -1437,7 +1342,7 @@ namespace IRaCIS.Core.Application.Image.QA
// JsonDetail = JsonConvert.SerializeObject(new // JsonDetail = JsonConvert.SerializeObject(new
// { // {
// SubmitState = "已提交", // SubmitState = "已提交",
// }) // })
// }); // });
@ -1482,7 +1387,7 @@ namespace IRaCIS.Core.Application.Image.QA
[TypeFilter(typeof(TrialResourceFilter))] [TypeFilter(typeof(TrialResourceFilter))]
public async Task<IResponseOutput> QCPassedOrFailed(Guid trialId, Guid subjectVisitId, [FromRoute] AuditStateEnum auditState) public async Task<IResponseOutput> QCPassedOrFailed(Guid trialId, Guid subjectVisitId, [FromRoute] AuditStateEnum auditState)
{ {
if (!await _repository.AnyAsync<TrialUser>(t => t.TrialId == trialId && t.UserId == _userInfo.Id)) if (!await _repository.AnyAsync<TrialUser>(t => t.TrialId == trialId && t.UserId == _userInfo.Id))
{ {
@ -1596,7 +1501,7 @@ namespace IRaCIS.Core.Application.Image.QA
// 单审 // 单审
if (dbSubjectVisit.AuditState == AuditStateEnum.ToAudit) if (dbSubjectVisit.AuditState == AuditStateEnum.ToAudit)
{ {
dbSubjectVisit.AuditState = AuditStateEnum.QCFailed; dbSubjectVisit.AuditState = AuditStateEnum.QCFailed;
} }
else else
@ -1625,7 +1530,7 @@ namespace IRaCIS.Core.Application.Image.QA
//删除 软删除的物理文件 //删除 软删除的物理文件
var instanceIdList = await _repository.Where<DicomInstance>(t => t.DicomSerie.IsDeleted && t.SubjectVisitId == subjectVisitId) var instanceIdList = await _repository.Where<DicomInstance>(t => t.DicomSerie.IsDeleted && t.SubjectVisitId == subjectVisitId)
.Select(t => new { InstanceId = t.Id, t.SeriesId, t.StudyId, t.SubjectId, t.SiteId }).ToListAsync(); .Select(t => new { InstanceId = t.Id, t.SeriesId, t.StudyId, t.SubjectId, t.SiteId }).ToListAsync();
@ -1638,14 +1543,14 @@ namespace IRaCIS.Core.Application.Image.QA
SeriesNumber = x.SeriesNumber, SeriesNumber = x.SeriesNumber,
InstanceCount = x.InstanceCount, InstanceCount = x.InstanceCount,
SeriesTime = x.SeriesTime, SeriesTime = x.SeriesTime,
TrialId=x.TrialId, TrialId = x.TrialId,
SiteId=x.SiteId, SiteId = x.SiteId,
x.SubjectId, x.SubjectId,
x.SubjectVisitId, x.SubjectVisitId,
x.IsDeleted, x.IsDeleted,
x.IsReading, x.IsReading,
x.Id, x.Id,
}).ToListAsync(); }).ToListAsync();
DateTime time = DateTime.Now.AddMilliseconds(500); DateTime time = DateTime.Now.AddMilliseconds(500);
DicomSeriesdata.ForEach(x => DicomSeriesdata.ForEach(x =>
@ -1666,8 +1571,8 @@ namespace IRaCIS.Core.Application.Image.QA
SeriesNumber = x.SeriesNumber, SeriesNumber = x.SeriesNumber,
InstanceCount = x.InstanceCount, InstanceCount = x.InstanceCount,
SeriesTime = x.SeriesTime, SeriesTime = x.SeriesTime,
IsReading=x.IsReading, IsReading = x.IsReading,
IsDeleted=x.IsDeleted, IsDeleted = x.IsDeleted,
}) })
@ -1675,7 +1580,7 @@ namespace IRaCIS.Core.Application.Image.QA
}); });
await _inspectionService.AddListInspectionRecordAsync(datas); await _inspectionService.AddListInspectionRecordAsync(datas);
instanceIdList.ForEach(t => instanceIdList.ForEach(t =>
{ {
@ -1980,9 +1885,9 @@ namespace IRaCIS.Core.Application.Image.QA
}) })
}); });
} }
await _inspectionService.AddListInspectionRecordAsync(datas);
await _inspectionService.AddListInspectionRecordAsync(datas);
} }
////受试者基线 入组确认 或者访视PD 进展 默认加急 ////受试者基线 入组确认 或者访视PD 进展 默认加急
@ -2026,7 +1931,7 @@ namespace IRaCIS.Core.Application.Image.QA
foreach (var subjectVisitId in subjectVisitIdList) foreach (var subjectVisitId in subjectVisitIdList)
{ {
var info = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo<DicomTrialSiteSubjectInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); var info = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo<DicomTrialSiteSubjectInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
Dictionary<string, object> keyValuePairs = new Dictionary<string, object>() { Dictionary<string, object> keyValuePairs = new Dictionary<string, object>() {
@ -2038,11 +1943,11 @@ namespace IRaCIS.Core.Application.Image.QA
}; };
DataInspection data = new DataInspection() DataInspection data = new DataInspection()
{ {
TrialId= info.TrialId, TrialId = info.TrialId,
SiteId=info.SiteId, SiteId = info.SiteId,
SubjectId=info.SubjectId, SubjectId = info.SubjectId,
SubjectVisitId= subjectVisitId, SubjectVisitId = subjectVisitId,
Identification= "NaN-14-0" Identification = "NaN-14-0"
}; };
var targetPath = "/IMPORT-IMAGES/" + info.TrialCode + "_" + info.SubjectCode + "_" + info.VisitName; var targetPath = "/IMPORT-IMAGES/" + info.TrialCode + "_" + info.SubjectCode + "_" + info.VisitName;
@ -2111,14 +2016,14 @@ namespace IRaCIS.Core.Application.Image.QA
} }
await _subjectVisitRepository.BatchUpdateAsync(t => t.Id == subjectVisitId, await _subjectVisitRepository.BatchUpdateAsync(t => t.Id == subjectVisitId,
u => new SubjectVisit() { ForwardState = ForwardStateEnum.Forwarded,ForwardUserId = _userInfo.Id,ForwardTime = DateTime.Now}); u => new SubjectVisit() { ForwardState = ForwardStateEnum.Forwarded, ForwardUserId = _userInfo.Id, ForwardTime = DateTime.Now });
keyValuePairs["ForwardState"] = "转发成功"; keyValuePairs["ForwardState"] = "转发成功";
data.JsonDetail = JsonConvert.SerializeObject(keyValuePairs); data.JsonDetail = JsonConvert.SerializeObject(keyValuePairs);
datas.Add(data); datas.Add(data);
} }
await _subjectVisitRepository.AddListInspectionRecordAsync(datas); await _subjectVisitRepository.AddListInspectionRecordAsync(datas);
await _subjectVisitRepository.SaveChangesAsync(); await _subjectVisitRepository.SaveChangesAsync();

View File

@ -55,9 +55,11 @@ namespace IRaCIS.Core.Infra.EFCore
Task<T> InsertOrUpdateAsync<T, TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<T>[] verify) where T : Entity; Task<T> InsertOrUpdateAsync<T, TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<T>[] verify) where T : Entity;
EntityEntry<T> Entry<T>(T t) where T : Entity; Task<T> InsertFromDTOAsync<T, TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<T>[] verify) where T : Entity;
//Task<T> InsertOrUpdateAsync<T, TFrom>(this DbSet<T> dbset, TFrom from, bool autoSave = false, params EntityVerifyExp<T>[] verify) where T : Entity; Task<T> UpdateFromDTOAsync<T, TFrom>(TFrom from, bool autoSave = false, bool ignoreDtoNullProperty = true, params EntityVerifyExp<T>[] verify) where T : Entity;
EntityEntry<T> Entry<T>(T t) where T : Entity;
Task<bool> AnyAsync<T>(Expression<Func<T, bool>> filter, bool ignoreQueryFilters = false) where T : Entity; Task<bool> AnyAsync<T>(Expression<Func<T, bool>> filter, bool ignoreQueryFilters = false) where T : Entity;
@ -77,7 +79,7 @@ namespace IRaCIS.Core.Infra.EFCore
Task<bool> DeleteAsync<T>(T entity, bool autoSave = false) where T : Entity; Task<bool> DeleteAsync<T>(T entity, bool autoSave = false) where T : Entity;
Task<bool> DeleteManyAsync<T>(IEnumerable<T> entities, bool autoSave = false) where T : Entity; //Task<bool> DeleteManyAsync<T>(IEnumerable<T> entities, bool autoSave = false) where T : Entity;
Task<bool> SaveChangesAsync(); Task<bool> SaveChangesAsync();
@ -90,6 +92,8 @@ namespace IRaCIS.Core.Infra.EFCore
{ {
private IRaCISDBContext _dbContext { get; } private IRaCISDBContext _dbContext { get; }
public IMapper _mapper { get; set; } public IMapper _mapper { get; set; }
public IUserInfo _userInfo { get; set; } public IUserInfo _userInfo { get; set; }
@ -130,65 +134,21 @@ namespace IRaCIS.Core.Infra.EFCore
} }
private async Task EntityVerifyAsync<T>(bool isAdd, EntityVerifyExp<T>[] verify, Guid? entitydId = null) where T : Entity
public async Task<T> InsertOrUpdateAsync<T, TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<T>[] verify) where T : Entity
{ {
var entity = _mapper.Map<T>(from); if (isAdd)
if (entity.Id == Guid.Empty)
{ {
// verifyExp
//await verify.Where(t => t.verifyType != VerifyEnum.OnlyUpdate && t.IsVerify).ToList().ForeachAsync(async verifyItem =>
//{
// if (await _dbContext.Set<T>().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false))
// {
// throw new BusinessValidationFailedException(verifyItem.VerifyMsg);
// }
//});
foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyUpdate && t.IsVerify)) foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyUpdate && t.IsVerify))
{ {
if (await _dbContext.Set<T>().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) if (await _dbContext.Set<T>().IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false))
{ {
throw new BusinessValidationFailedException(verifyItem.VerifyMsg); throw new BusinessValidationFailedException(verifyItem.VerifyMsg);
} }
} }
await _dbContext.Set<T>().AddAsync(entity).ConfigureAwait(false);
if (autoSave)
{
await SaveChangesAsync();
}
return entity;
} }
else else
{ {
// verifyExp
//await verify.Where(t => t.verifyType != VerifyEnum.OnlyAdd && t.IsVerify).ToList().ForeachAsync(async verifyItem =>
// {
// if (verifyItem.verifyType == VerifyEnum.OnlyUpdate)
// {
// if (await _dbContext.Set<T>().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false))
// {
// throw new BusinessValidationFailedException(verifyItem.VerifyMsg);
// }
// }
// else if (verifyItem.verifyType == VerifyEnum.Both)
// {
// if (await _dbContext.Set<T>().AnyAsync(verifyItem.VerifyExp.And(t => t.Id != entity.Id)).ConfigureAwait(false))
// {
// throw new BusinessValidationFailedException(verifyItem.VerifyMsg);
// }
// }
// });
foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyAdd && t.IsVerify)) foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyAdd && t.IsVerify))
{ {
if (verifyItem.verifyType == VerifyEnum.OnlyUpdate) if (verifyItem.verifyType == VerifyEnum.OnlyUpdate)
@ -200,25 +160,97 @@ namespace IRaCIS.Core.Infra.EFCore
} }
else if (verifyItem.verifyType == VerifyEnum.Both) else if (verifyItem.verifyType == VerifyEnum.Both)
{ {
if (await _dbContext.Set<T>().IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp.And(t => t.Id != entity.Id)).ConfigureAwait(false)) if (await _dbContext.Set<T>().IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp.And(t => t.Id != entitydId)).ConfigureAwait(false))
{ {
throw new BusinessValidationFailedException(verifyItem.VerifyMsg); throw new BusinessValidationFailedException(verifyItem.VerifyMsg);
} }
} }
} }
}
var dbEntity = await FirstOrDefaultAsync<T>(t => t.Id == entity.Id).ConfigureAwait(false); }
var dbBeforEntity = dbEntity.Clone(); public async Task<T> InsertFromDTOAsync<T, TFrom>(TFrom from, bool autoSave = false,
params EntityVerifyExp<T>[] verify) where T : Entity
{
_mapper.Map(from, dbEntity); var entity = _mapper.Map<T>(from);
if (autoSave) await EntityVerifyAsync(true, verify);
entity = await AddAsync(entity, autoSave);
return entity;
}
public async Task<T> UpdateFromDTOAsync<T, TFrom>(TFrom from, bool autoSave = false, bool ignoreDtoNullProperty = true, params EntityVerifyExp<T>[] verify) where T : Entity
{
var entity = _mapper.Map<T>(from);
await EntityVerifyAsync(false, verify, entity.Id);
var dbEntity = await _dbContext.Set<T>().IgnoreQueryFilters().FirstOrDefaultAsync(t => t.Id == entity.Id).ConfigureAwait(false);
if (dbEntity == null)
{
throw new BusinessValidationFailedException(
" Update object not exist in db,Please check if the parameter Id is passed incorrectly");
}
var dbBeforEntity = dbEntity.Clone();
_mapper.Map(from, dbEntity);
//DTO null 属性不更新 防止意外操作,导致保存数据错误,或者 add 和update 用一个模型更新的时候只传递了部分字段导致不想更新的字段因为没传递值用null覆盖了
// Guid属性 为null 时 映射到 Guid 时 默认会变成 Guid.Empty
if (ignoreDtoNullProperty)
{
var dbEntityProp = typeof(T).GetProperties();
foreach (var propertyInfo in from.GetType().GetProperties())
{ {
await SaveChangesAsync(); if (propertyInfo.GetValue(from) == null && dbEntityProp.Any(t => t.Name == propertyInfo.Name))
{
_dbContext.Entry(dbEntity).Property(propertyInfo.Name).IsModified = false;
}
} }
return dbBeforEntity; }
await SaveChangesAsync(autoSave);
return dbBeforEntity;
}
private async Task<bool> SaveChangesAsync(bool autoSave)
{
if (autoSave)
{
return await SaveChangesAsync();
}
else
{
return false;
}
}
public async Task<T> InsertOrUpdateAsync<T, TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<T>[] verify) where T : Entity
{
var entity = _mapper.Map<T>(from);
if (entity.Id == Guid.Empty)
{
return await InsertFromDTOAsync(from, autoSave, verify);
}
else
{
return await UpdateFromDTOAsync(from, autoSave, false, verify);
} }
} }