272 lines
12 KiB
C#
272 lines
12 KiB
C#
using AutoMapper;
|
||
using IRaCIS.Application.ExpressionExtend;
|
||
using IRaCIS.Application.Interfaces;
|
||
using IRaCIS.Application.ViewModels;
|
||
using IRaCIS.Core.Application.Contracts.RequestAndResponse;
|
||
using IRaCIS.Core.Domain.Interfaces;
|
||
using IRaCIS.Core.Domain.Models;
|
||
using IRaCIS.Infra.Data.ExpressionExtend;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Linq.Expressions;
|
||
using EasyCaching.Core.Configurations;
|
||
using IRaCIS.Core.Domain.Share;
|
||
using IRaCIS.Core.Domain.Share.AuthUser;
|
||
|
||
namespace IRaCIS.Application.Services
|
||
{
|
||
public class SubjectService : ISubjectService
|
||
{
|
||
private readonly ISubjectRepository _subjectsRepository;
|
||
private readonly IVisitStageRepository _visitStageRepository;
|
||
private readonly ISiteRepository _siteRepository;
|
||
private readonly IMapper _mapper;
|
||
private readonly ISubjectVisitRepository _subjectVisitRepository;
|
||
private readonly IDicomStudyRepository _studyRepository;
|
||
private readonly IUserInfo _userInfo;
|
||
private readonly IUserRepository _userRepository;
|
||
private readonly IUserTrialRepository _userTrialRepository;
|
||
private readonly ITrialRepository _trialRepository;
|
||
|
||
public SubjectService(ISubjectRepository subjectRepository,
|
||
IVisitStageRepository visitStageRepository,
|
||
ISiteRepository siteRepository, IMapper mapper,
|
||
ISubjectVisitRepository subjectVisitRepository, IDicomStudyRepository studyRepository,
|
||
IUserInfo userInfo, IUserRepository userRepository, IUserTrialRepository userTrialRepository,ITrialRepository trialRepository)
|
||
{
|
||
_subjectsRepository = subjectRepository;
|
||
_visitStageRepository = visitStageRepository;
|
||
_siteRepository = siteRepository;
|
||
_mapper = mapper;
|
||
_subjectVisitRepository = subjectVisitRepository;
|
||
_studyRepository = studyRepository;
|
||
_userInfo = userInfo;
|
||
_userRepository = userRepository;
|
||
_userTrialRepository = userTrialRepository;
|
||
_trialRepository = trialRepository;
|
||
}
|
||
public IResponseOutput AddOrUpdateSubject(SubjectCommand model)
|
||
{
|
||
model.Code = model.Code.Trim();
|
||
if (model.Id == Guid.Empty || model.Id == null) //add
|
||
{
|
||
var saveItem = _mapper.Map<Subject>(model);
|
||
|
||
saveItem.StudyCount = 0;
|
||
saveItem.SubjectVisitId = Guid.Empty;
|
||
saveItem.Modalities = string.Empty;
|
||
|
||
//var last = _subjectsRepository.GetAll()
|
||
// .OrderByDescending(c => c.Code).FirstOrDefault();
|
||
//if (last != null)
|
||
//{
|
||
// var len = last.Code.Length;
|
||
// if (len > 9 && int.TryParse(last.Code.Substring(len - 9, 9), out var num))
|
||
// {
|
||
// saveItem.Code = "S" + (++num).ToString().PadLeft(9, '0');
|
||
// }
|
||
// else
|
||
// {
|
||
// return ResponseOutput.NotOk("Generated Code failed.", new DicomStudy());
|
||
// }
|
||
//}
|
||
//else
|
||
//{
|
||
// saveItem.Code = "S" + 1.ToString().PadLeft(9, '0');
|
||
//}
|
||
var subject = _subjectsRepository.GetAll().FirstOrDefault(u => u.Code == model.Code && u.TrialId == model.TrialId);
|
||
if (subject != null)
|
||
{
|
||
return ResponseOutput.NotOk("该项目下已经存在相同受试者编码的受试者。");
|
||
}
|
||
|
||
if (!_trialRepository.GetAll().Any(t => t.Id == model.TrialId && t.VisitPlanConfirmed))
|
||
{
|
||
return ResponseOutput.NotOk("该项目访视计划未确认,无法添加受试者及其访视计划安排");
|
||
}
|
||
var result = _subjectsRepository.Add(saveItem);
|
||
|
||
//获取访视计划列表
|
||
|
||
var visitPlan= _visitStageRepository.GetAll().Where(t => t.TrialId == model.TrialId).ToList();
|
||
|
||
var subjectVisitPlanList=new List<SubjectVisit>();
|
||
|
||
visitPlan.ForEach(plan=>subjectVisitPlanList.Add(new SubjectVisit()
|
||
{
|
||
TrialId = model.TrialId,
|
||
SubjectId = result.Id,
|
||
SiteId = model.SiteId,
|
||
InPlan =true,
|
||
VisitNum=plan.VisitNum,
|
||
VisitName= plan.VisitName,
|
||
VisitDay = plan.VisitDay
|
||
|
||
}));
|
||
|
||
|
||
_subjectVisitRepository.AddRange(subjectVisitPlanList);
|
||
|
||
var isSuccess = _subjectsRepository.SaveChanges();
|
||
|
||
return ResponseOutput.Result(isSuccess, result.Id.ToString());
|
||
|
||
}
|
||
else // update
|
||
{
|
||
var subject = _subjectsRepository.GetAll().FirstOrDefault(t => t.Id == model.Id);
|
||
_mapper.Map(model, subject);
|
||
|
||
var temp = _subjectsRepository.GetAll().FirstOrDefault(u => u.Code == model.Code
|
||
&& u.TrialId == model.TrialId && u.Id != model.Id);
|
||
if (temp != null)
|
||
{
|
||
return ResponseOutput.NotOk("该项目下已经存在相同受试者编码的受试者。");
|
||
}
|
||
_subjectsRepository.Update(subject);
|
||
|
||
var isSuccess = _subjectsRepository.SaveChanges();
|
||
|
||
return ResponseOutput.Result(isSuccess);
|
||
}
|
||
}
|
||
|
||
public IResponseOutput DeleteSubject(Guid id)
|
||
{
|
||
if (_studyRepository.GetAll().Any(t => t.SubjectId == id) ||
|
||
_subjectVisitRepository.GetAll().Any(u => u.SubjectId == id))
|
||
{
|
||
return ResponseOutput.NotOk("Subject’s visit or study data exists under the subject");
|
||
}
|
||
|
||
var isSuccess = _subjectsRepository.Delete(u => u.Id == id);
|
||
return ResponseOutput.Result(isSuccess);
|
||
}
|
||
|
||
public PageOutput<SubjectQueryModel> GetSubjectList(SubjectQueryParam param)
|
||
{
|
||
Expression<Func<Subject, bool>> subjectLambda = x => true;
|
||
Expression<Func<DicomStudy, bool>> studyLambda = x => x.TrialId == param.TrialId&& x.Status != (int)StudyStatus.Abandon;
|
||
Expression<Func<SubjectVisit, bool>> subjectVisitLambda = x => x.TrialId == param.TrialId;
|
||
|
||
if (!string.IsNullOrWhiteSpace(param.Code))
|
||
{
|
||
subjectLambda = subjectLambda.And(t => t.Code.Contains(param.Code.Trim()));
|
||
}
|
||
if (!string.IsNullOrWhiteSpace(param.Name))
|
||
{
|
||
subjectLambda = subjectLambda.And(t => t.Name.Contains(param.Name.Trim()));
|
||
}
|
||
if (!string.IsNullOrWhiteSpace(param.Sex))
|
||
{
|
||
subjectLambda = subjectLambda.And(t => t.Sex==param.Sex.Trim());
|
||
}
|
||
if (param.Status != null)
|
||
{
|
||
subjectLambda = subjectLambda.And(t => t.Status == param.Status);
|
||
}
|
||
|
||
|
||
if (param.SiteId != null)
|
||
{
|
||
subjectLambda = subjectLambda.And(t => t.SiteId == param.SiteId);
|
||
|
||
studyLambda = studyLambda.And(t => t.SiteId == param.SiteId);
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
//是CRC 需要过滤
|
||
var userId = _userInfo.Id;
|
||
var exist = _userRepository.GetAll()
|
||
.Any(t => t.Id == userId && t.UserType.Contains(StaticData.CRC));
|
||
|
||
if (exist)
|
||
{
|
||
var siteIds = _userTrialRepository.GetAll().Where(t => t.SiteId != Guid.Empty && t.UserId == userId && t.TrialId== param.TrialId)
|
||
.Select(u => u.SiteId);
|
||
|
||
subjectLambda = subjectLambda.And(t => siteIds.Contains(t.SiteId));
|
||
|
||
studyLambda = studyLambda.And(t => siteIds.Contains(t.SiteId));
|
||
}
|
||
|
||
}
|
||
|
||
var query = from subject in _subjectsRepository.Find(u => u.TrialId == param.TrialId).Where(subjectLambda)
|
||
join subjectVisit in _subjectVisitRepository.Find(u => u.TrialId == param.TrialId)
|
||
on subject.SubjectVisitId equals subjectVisit.Id into h
|
||
from subjectVisit in h.DefaultIfEmpty()
|
||
join site in _siteRepository.GetAll()
|
||
on subject.SiteId equals site.Id
|
||
|
||
join studyStat in _studyRepository.GetAll().Where(studyLambda)
|
||
.GroupBy(u => u.SubjectId).Select(g => new { SubjectId = g.Key, StudyCount = g.Count() })
|
||
on subject.Id equals studyStat.SubjectId into cc
|
||
from studyStatItem in cc.DefaultIfEmpty()
|
||
|
||
join visitStat in _subjectVisitRepository.Find(subjectVisitLambda).GroupBy(u => u.SubjectId).Select(g => new { SubjectId = g.Key, VisitCount = g.Count() }) on subject.Id equals visitStat.SubjectId into dd
|
||
from visitStatItem in dd.DefaultIfEmpty()
|
||
|
||
join subjectVisitStat2 in _subjectVisitRepository.Find(t => t.TrialId == param.TrialId && t.StudyUploaded ).GroupBy(t => t.SubjectId).Select(g => new { SubjectId = g.Key, VisitCount = g.Count() }) on subject.Id equals subjectVisitStat2.SubjectId into SSV2
|
||
from subjectVisitStatItem2 in SSV2.DefaultIfEmpty()
|
||
|
||
select new SubjectQueryModel()
|
||
{
|
||
Id = subject.Id,
|
||
TrialId = subject.TrialId,
|
||
Name = subject.Name,
|
||
Code = subject.Code,
|
||
SubjectVisitId = subject.SubjectVisitId,
|
||
Sex = subject.Sex,
|
||
Age = subject.Age,
|
||
MedicalNo = subject.MedicalNo,
|
||
|
||
Modalities = subject.Modalities,
|
||
SiteId = subject.SiteId,
|
||
SiteName = site.SiteName,
|
||
Status = subject.Status,
|
||
UpdateTime = subject.UpdateTime,
|
||
CreateTime = subject.CreateTime,
|
||
Reason = subject.Reason,
|
||
|
||
StudyCount = studyStatItem.StudyCount,
|
||
PlanVisitCount = visitStatItem.VisitCount,
|
||
VisitCount = subjectVisitStatItem2.VisitCount,
|
||
|
||
VisitName = subjectVisit.VisitName,
|
||
};
|
||
var count = query.Count();
|
||
|
||
var propName = param.SortField == string.Empty ? "Code" : param.SortField;
|
||
|
||
query = param.Asc
|
||
? query.OrderBy(propName).ThenBy(t => t.SiteName).ThenBy(t => t.Code)
|
||
: query.OrderByDescending(propName).ThenBy(t => t.SiteName).ThenBy(t => t.Code);
|
||
|
||
query = query.Skip((param.PageIndex - 1) * param.PageSize).Take(param.PageSize);
|
||
var list = query.ToList();
|
||
|
||
return new PageOutput<SubjectQueryModel>(param.PageIndex,
|
||
param.PageSize, count, list);
|
||
|
||
}
|
||
|
||
public List<SubjectSelect> GetSubjectListBySiteId(Guid siteId, Guid trialId)
|
||
{
|
||
var query = _subjectsRepository.GetAll().Where(t => t.SiteId == siteId && t.TrialId == trialId).Select(u => new SubjectSelect()
|
||
{
|
||
Code = u.Code,
|
||
Name = u.Name,
|
||
Sex = u.Sex,
|
||
SubjectId = u.Id,
|
||
Age = u.Age
|
||
});
|
||
|
||
return query.ToList();
|
||
}
|
||
}
|
||
}
|