using AutoMapper; using AutoMapper.QueryableExtensions; 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.Core.Domain.Share; using IRaCIS.Core.Infrastructure; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; namespace IRaCIS.Application.Services { public class DoctorService : IDoctorService { private readonly IDoctorRepository _doctorRepository; private readonly IDictionaryRepository _dictionaryRepository; private readonly IHospitalRepository _hospitalRepository; private readonly IMessageRepository _messageRepository; private readonly IEnrollRepository _enrollRepository; private readonly IDoctorDictionaryRepository _doctorDictionaryRepository; private readonly IAttachmentRepository _attachmentRepository; private readonly IUserDoctorRepository _userDoctorRepository; private readonly ITrialRepository _trialRepository; private readonly ITrialPaymentPriceRepository _trialExtRepository; private readonly IMapper _mapper; public DoctorService(IDoctorRepository doctorInfoRepository, IDictionaryRepository dictionaryRepository, IHospitalRepository hospitalRepository, IMessageRepository sysMessageRepository, IEnrollRepository intoGroupRepository, IDoctorDictionaryRepository doctorDictionaryRepository, IAttachmentRepository attachmentRepository, IUserDoctorRepository userDoctorRepository, ITrialRepository trialRepository, ITrialPaymentPriceRepository trialExtRepository,IMapper mapper) { _doctorRepository = doctorInfoRepository; _dictionaryRepository = dictionaryRepository; _hospitalRepository = hospitalRepository; _messageRepository = sysMessageRepository; _enrollRepository = intoGroupRepository; _doctorDictionaryRepository = doctorDictionaryRepository; _attachmentRepository = attachmentRepository; _userDoctorRepository = userDoctorRepository; _trialRepository = trialRepository; _trialExtRepository = trialExtRepository; _mapper = mapper; } #region 医生基本信息--查询、新增、更新 public IResponseOutput AddOrUpdateDoctorBasicInfo( DoctorBasicInfoCommand basicInfoModel, Guid userId) { if (basicInfoModel.Id == Guid.Empty|| basicInfoModel.Id==null) { var doctor = _mapper.Map(basicInfoModel); var phone = doctor.Phone.Trim(); //验证用户手机号 if (_doctorRepository.GetAll().FirstOrDefault(t => t.Phone == phone) != null) { return ResponseOutput.NotOk("Current phone number is existed!", new DoctorBasicInfoCommand()); } var email = doctor.EMail.Trim(); if (_doctorRepository.GetAll().Any(t => t.EMail == email)) { return ResponseOutput.NotOk("Current email is existed!", new DoctorBasicInfoCommand()); } var last = _doctorRepository.GetAll().OrderByDescending(c => c.Code).FirstOrDefault(); if (last != null) { var num = 0; if (int.TryParse(last.Code.Substring(2, 4), out num)) { doctor.Code = SystemConfig.CodePrefix + (++num).ToString().PadLeft(4, '0'); } else { return ResponseOutput.NotOk("Generated Code failed.", new DoctorBasicInfoCommand()); } } else { doctor.Code = SystemConfig.CodePrefix + 1.ToString().PadLeft(4, '0'); } doctor.Password = MD5Helper.Md5(doctor.Phone); doctor.ResumeStatus = (int)ResumeStatus.Failed; doctor.CooperateStatus = (int)ContractorStatus.Noncooperation; doctor.ReviewStatus = 2; //插入中间表 basicInfoModel.TitleIds.ForEach(titleId => doctor.DoctorDicList.Add(new DoctorDictionary() { DoctorId = doctor.Id, KeyName = StaticData.Title, DictionaryId = titleId })); _doctorRepository.Add(doctor); _userDoctorRepository.Add(new UserDoctor() { DoctorId = doctor.Id, UserId = userId }); var success = _doctorRepository.SaveChanges(); return ResponseOutput.Result(success, _mapper.Map(doctor)); } else { var updateModel = basicInfoModel; var phone = updateModel.Phone.Trim(); if (_doctorRepository.FindSingleOrDefault(t => t.Phone == phone && t.Id != updateModel.Id) != null) { return ResponseOutput.NotOk("Current phone number is existed!", new DoctorBasicInfoCommand()); } var email = updateModel.EMail.Trim(); if (_doctorRepository.GetAll().Any(t => t.EMail == email && t.Id != updateModel.Id)) { return ResponseOutput.NotOk("Current email is existed!", new DoctorBasicInfoCommand()); } var doctor = _doctorRepository.FindSingleOrDefault(t => t.Id == updateModel.Id); if (doctor != null) { //删除中间表 Title对应的记录 _doctorDictionaryRepository.Delete(t => t.DoctorId == updateModel.Id && t.KeyName == StaticData.Title); //重新插入新的 Title记录 updateModel.TitleIds.ForEach(titleId => _doctorDictionaryRepository.Add(new DoctorDictionary() { DoctorId = updateModel.Id.Value, KeyName = StaticData.Title, DictionaryId = titleId })); doctor.FirstName = updateModel.FirstName; doctor.LastName = updateModel.LastName; doctor.ChineseName = updateModel.ChineseName; doctor.Sex = updateModel.Sex; doctor.Phone = updateModel.Phone; doctor.EMail = updateModel.EMail; doctor.WeChat = updateModel.WeChat; doctor.Introduction = updateModel.Introduction; doctor.Nation = updateModel.Nation; _doctorRepository.Update(doctor); } var success = _doctorRepository.SaveChanges(); return ResponseOutput.Result(success, basicInfoModel); } } public DoctorBasicInfoDTO GetDoctorBasicInfo(Guid doctorId) { var dic = GetDictionary(); var doctorQueryable = _doctorRepository .Find(t => t.Id == doctorId) .Include(t => t.DoctorDicList) .Select(doctor => new DoctorBasicInfoDTO() { Id = doctor.Id, Code = doctor.Code, ChineseName = doctor.ChineseName, EMail = doctor.EMail, FirstName = doctor.FirstName, Introduction = doctor.Introduction, LastName = doctor.LastName, Phone = doctor.Phone, Sex = doctor.Sex, WeChat = doctor.WeChat, Nation = doctor.Nation, TitleIds = doctor.DoctorDicList .Where(t => t.KeyName == StaticData.Title).Select(t => t.DictionaryId).ToList() }); var doctorBasicInfo = doctorQueryable.FirstOrDefault(); if (doctorBasicInfo != null) { //连接具体名称 Title --MD Phd foreach (var dictionaryItem in dic) { if (doctorBasicInfo.TitleIds.Contains(dictionaryItem.Id)) { doctorBasicInfo.TitleList.AddRange(dic.Where(u => u.Id == dictionaryItem.Id) .Select(h => h.Value)); } } } return doctorBasicInfo; } #endregion #region Employment信息--查询和更新 public EmploymentDTO GetEmploymentInfo(Guid doctorId) { var dic = GetDictionary(); var employmentQueryable = from doctorItem in _doctorRepository .Find(t => t.Id == doctorId) join hospitalItem in _hospitalRepository.GetAll() on doctorItem.HospitalId equals hospitalItem.Id into g from hospital in g.DefaultIfEmpty() select new EmploymentDTO() { //部门 DepartmentId = doctorItem.DepartmentId, DepartmentOther = doctorItem.DepartmentOther, //医院 HospitalId = doctorItem.HospitalId, PositionId = doctorItem.PositionId, PositionOther = doctorItem.PositionOther, RankId = doctorItem.RankId, RankOther = doctorItem.RankOther, City = hospital.City, Country = hospital.Country, UniversityAffiliated = hospital.UniversityAffiliated, HospitalName = hospital.HospitalName, Province = hospital.Province }; var employmentInfo = employmentQueryable.FirstOrDefault(); if (employmentInfo != null) { //医院信息设置 if (employmentInfo.HospitalId == Guid.Empty) { employmentInfo.City = string.Empty; employmentInfo.Country = string.Empty; employmentInfo.UniversityAffiliated = string.Empty; employmentInfo.HospitalName = string.Empty; employmentInfo.Province = string.Empty; } employmentInfo.Department = employmentInfo.DepartmentId == Guid.Empty ? employmentInfo.DepartmentOther : dic.FirstOrDefault(o => o.Id == employmentInfo.DepartmentId)?.Value ?? ""; employmentInfo.Rank = employmentInfo.RankId == Guid.Empty ? employmentInfo.RankOther : dic.FirstOrDefault(o => o.Id == employmentInfo.RankId)?.Value ?? ""; employmentInfo.Position = employmentInfo.PositionId == Guid.Empty ? employmentInfo.PositionOther : dic.FirstOrDefault(o => o.Id == employmentInfo.PositionId)?.Value ?? ""; } return employmentInfo; } public IResponseOutput UpdateDoctorEmploymentInfo(EmploymentCommand doctorWorkInfoModel) { var success = _doctorRepository.Update(d => d.Id == doctorWorkInfoModel.Id, u => new Doctor() { DepartmentId = doctorWorkInfoModel.DepartmentId, DepartmentOther = doctorWorkInfoModel.DepartmentOther, SpecialityId = doctorWorkInfoModel.DepartmentId, SpecialityOther = doctorWorkInfoModel.DepartmentOther, RankId = doctorWorkInfoModel.RankId, RankOther = doctorWorkInfoModel.RankOther, PositionId = doctorWorkInfoModel.PositionId, PositionOther = doctorWorkInfoModel.PositionOther, HospitalId = doctorWorkInfoModel.HospitalId, UpdateTime = DateTime.Now }); return ResponseOutput.Result(success); } #endregion #region 医生技能信息 查询和 更新 public SpecialtyDTO GetDoctorSpecialty(Guid doctorId) { var dic = GetDictionary(); var specialtyQueryable = _doctorRepository .Find(t => t.Id == doctorId).Include(u => u.DoctorDicList) .Select(specialty => new SpecialtyDTO() { Id = specialty.Id, ReadingTypeOther = specialty.ReadingTypeOther, SubspecialityOther = specialty.SubspecialityOther, ReadingTypeIds = specialty.DoctorDicList.Where(t => t.KeyName == StaticData.ReadingType).Select(t => t.DictionaryId).ToList(), SubspecialityIds = specialty.DoctorDicList.Where(t => t.KeyName == StaticData.Subspeciality).Select(t => t.DictionaryId).ToList(), SpecialityId = specialty.SpecialityId, SpecialityOther = specialty.SpecialityOther }); var specialtyInfo = specialtyQueryable.FirstOrDefault(); if (specialtyInfo != null) { foreach (var dictionaryItem in dic) { if (specialtyInfo.ReadingTypeIds.Contains(dictionaryItem.Id)) { specialtyInfo.ReadingTypeList.AddRange(dic.Where(u => u.Id == dictionaryItem.Id) .Select(h => h.Value)); } if (specialtyInfo.SubspecialityIds.Contains(dictionaryItem.Id)) { specialtyInfo.SubspecialityList.AddRange(dic.Where(u => u.Id == dictionaryItem.Id) .Select(h => h.Value)); } } specialtyInfo.Speciality = dic.Where(u => u.Id == specialtyInfo.SpecialityId).Select(h => h.Value).FirstOrDefault(); return specialtyInfo; } return null; } public IResponseOutput UpdateDoctorSpecialty(SpecialtyCommand specialtyUpdateModel) { var doctor = _doctorRepository.Find(t => t.Id == specialtyUpdateModel.Id).FirstOrDefault(); if (doctor != null) { //删除中间表 _doctorDictionaryRepository.Delete(t => t.DoctorId == specialtyUpdateModel.Id && t.KeyName == StaticData.Subspeciality); _doctorDictionaryRepository.Delete(t => t.DoctorId == specialtyUpdateModel.Id && t.KeyName == StaticData.ReadingType); //重新插入新的 specialtyUpdateModel.ReadingTypeIds.ForEach(readingTypeId => _doctorDictionaryRepository.Add( new DoctorDictionary() { DoctorId = specialtyUpdateModel.Id, KeyName = StaticData.ReadingType, DictionaryId = readingTypeId })); specialtyUpdateModel.SubspecialityIds.ForEach(subspecialityId => _doctorDictionaryRepository.Add( new DoctorDictionary() { DoctorId = specialtyUpdateModel.Id, KeyName = StaticData.Subspeciality, DictionaryId = subspecialityId })); //更新字段 //doctor.OtherSkills = specialtyUpdateModel.OtherSkills; doctor.ReadingTypeOther = specialtyUpdateModel.ReadingTypeOther; doctor.SubspecialityOther = specialtyUpdateModel.SubspecialityOther; doctor.SpecialityId = specialtyUpdateModel.SpecialityId; doctor.SpecialityOther = specialtyUpdateModel.SpecialityOther; _doctorRepository.Update(doctor); var success= _doctorRepository.SaveChanges(); return ResponseOutput.Result(success); } return ResponseOutput.NotOk(); } #endregion #region 简历审核 public IResponseOutput AuditResume(ResumeConfirmCommand auditResumeParam,Guid userId) { //判断 合作协议、正式简历 是否有。如果没有,显示提示信息,并且不能保存 var attachmentList = _attachmentRepository.Find(u => u.DoctorId == auditResumeParam.Id) .Select(u=>u.Type).ToList(); if (auditResumeParam.ResumeStatus==1&&((!attachmentList.Contains("Resume")) || (!attachmentList.Contains("Consultant Agreement")))) { return ResponseOutput.NotOk("Must Upload Resume & Consultant Agreement"); } var success = _doctorRepository.Update(o => o.Id == auditResumeParam.Id, u => new Doctor() { CooperateStatus = auditResumeParam.CooperateStatus, ResumeStatus = auditResumeParam.ResumeStatus, AdminComment = auditResumeParam.AdminComment, ReviewStatus = auditResumeParam.ReviewStatus, AcceptingNewTrial = auditResumeParam.AcceptingNewTrial, ActivelyReading = auditResumeParam.ActivelyReading, AuditTime = DateTime.Now, AuditUserId = userId }); if (success) { if (!string.IsNullOrWhiteSpace(auditResumeParam.MessageContent)) { var message = new Message { FromUserId = userId, ToDoctorId = auditResumeParam.Id, Title = "简历审核反馈", Content = auditResumeParam.MessageContent, HasRead = false, MessageTime = DateTime.Now }; _messageRepository.Add(message); success = _messageRepository.SaveChanges(); } } return ResponseOutput.Result(success); } public ResumeConfirmDTO GetDoctorAuditStatus(Guid doctorId) { var doctor = _doctorRepository.GetAll().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(t => t.Id == doctorId); return doctor; } public DoctorEnrollInfoDTO GetDoctorEnrollInfo(Guid doctorId) { var doctorQueryable = from doctor in _doctorRepository.Find(t => t.Id == doctorId) join intoGroupItem in _enrollRepository.GetAll() on doctor.Id equals intoGroupItem.DoctorId into t from intoGroupItem in t.DefaultIfEmpty() group intoGroupItem by intoGroupItem.DoctorId into g select new DoctorEnrollInfoDTO { DoctorId = g.Key, Submitted = g.Sum(t => t.EnrollStatus == (int)EnrollStatus.HasCommittedToCRO?1:0), Approved = g.Sum(t => t.EnrollStatus == (int)EnrollStatus.InviteIntoGroup?1:0), Reading = g.Sum(t => t.EnrollStatus == (int)EnrollStatus.DoctorReading?1:0) }; return doctorQueryable.FirstOrDefault(); } public List GetDoctorSow(Guid doctorId) { var query = from enroll in _enrollRepository.Find(u => u.DoctorId == doctorId && u.EnrollStatus >= 10) join trialExt in _trialExtRepository.GetAll() on enroll.TrialId equals trialExt.TrialId join trial in _trialRepository.GetAll() on enroll.TrialId equals trial.Id select new SowDTO { FileName = trialExt.SowName, FilePath = trialExt.SowPath, TrialCode = trial.Code, CreateTime = trialExt.CreateTime }; return query.ToList().Where(u => !string.IsNullOrWhiteSpace(u.FileName)).ToList(); } public List GetDoctorAckSow(Guid doctorId) { var query = from enroll in _enrollRepository.Find(u => u.DoctorId == doctorId) join attachment in _attachmentRepository.Find(u => u.DoctorId == doctorId) on enroll.AttachmentId equals attachment.Id join trial in _trialRepository.GetAll() on enroll.TrialId equals trial.Id select new SowDTO { FileName = attachment.FileName, FilePath = attachment.Path, TrialCode = trial.Code, CreateTime = attachment.CreateTime }; return query.ToList(); } #endregion private List GetDictionary() { return //字典表 后面做缓存 _dictionaryRepository.GetAll().ProjectTo(_mapper.ConfigurationProvider).OrderBy(t => t.KeyName) .ThenBy(t => t.ShowOrder).ToList(); } } }