diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index fc92f97ee..8062420c5 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -25,8 +25,9 @@ using Microsoft.AspNetCore.HttpOverrides; using IRaCIS.Application.Services.BackGroundJob; using LogDashboard; using OfficeOpenXml.Utils; +using FellowOakDicom.Network; +using IRaCIS.Core.Application.Service.ImageAndDoc; -Console.WriteLine("这是一个示例文本,示例文本中会出现示例多次。".Replace("示例", "替换")); #region 获取环境变量 //以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数) @@ -291,6 +292,8 @@ try //Log.Logger.Warning($"ContentRootPath——GetParent:{Directory.GetParent(env.ContentRootPath).Parent.FullName}"); //Log.Logger.Warning($"ContentRootPath——xx:{Path.GetDirectoryName(Path.GetDirectoryName(env.ContentRootPath))}"); + //DicomServerFactory.Create(11112); + app.Run(); } diff --git a/IRaCIS.Core.Application/Service/Document/DTO/SystemDocumentViewModel.cs b/IRaCIS.Core.Application/Service/Document/DTO/SystemDocumentViewModel.cs index cefd27089..cbdb8806c 100644 --- a/IRaCIS.Core.Application/Service/Document/DTO/SystemDocumentViewModel.cs +++ b/IRaCIS.Core.Application/Service/Document/DTO/SystemDocumentViewModel.cs @@ -101,6 +101,8 @@ namespace IRaCIS.Core.Application.Contracts public string Name { get; set; } = string.Empty; + public bool IsSigned { get; set; } + } @@ -113,6 +115,21 @@ namespace IRaCIS.Core.Application.Contracts public string SortField { get; set; } = ""; } + public class TrialDocQuery : PageInput + { + public Guid? TrialId { get; set; } + + public Guid? FileTypeId { get; set; } + + public string TrialCode { get; set;} = string.Empty; + + + public string Name { get; set; } = string.Empty; + + public bool IsSigned { get; set; } + + } + public class TrialUserDocUnionQuery: PageInput { [NotDefault] diff --git a/IRaCIS.Core.Application/Service/Document/SystemDocumentService.cs b/IRaCIS.Core.Application/Service/Document/SystemDocumentService.cs index 21480bae3..e90b73416 100644 --- a/IRaCIS.Core.Application/Service/Document/SystemDocumentService.cs +++ b/IRaCIS.Core.Application/Service/Document/SystemDocumentService.cs @@ -183,7 +183,9 @@ namespace IRaCIS.Core.Application.Services UserTypeShortName = user.UserTypeRole.UserTypeShortName }; - return await query.Where(t=>t.ConfirmTime==null).ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc); + return await query.WhereIf(querySystemDocument.IsSigned==true,t=>t.ConfirmTime!=null) + .WhereIf(querySystemDocument.IsSigned == false, t => t.ConfirmTime == null) + .ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc); diff --git a/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs b/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs index d4309f64f..405d1d974 100644 --- a/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs +++ b/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs @@ -60,13 +60,57 @@ namespace IRaCIS.Core.Application.Services var trialDocumentQueryable = _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == queryTrialDocument.TrialId) .WhereIf(!string.IsNullOrEmpty(queryTrialDocument.Name), t => t.Name.Contains(queryTrialDocument.Name)) .WhereIf(queryTrialDocument.FileTypeId != null, t => t.FileTypeId == queryTrialDocument.FileTypeId) - .WhereIf(queryTrialDocument.IsDeleted != null, t => t.IsDeleted == queryTrialDocument.IsDeleted) - .ProjectTo(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken, isEn_Us = _userInfo.IsEn_Us }); + .WhereIf(queryTrialDocument.IsDeleted != null, t => t.IsDeleted == queryTrialDocument.IsDeleted) + .ProjectTo(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken, isEn_Us = _userInfo.IsEn_Us }); return await trialDocumentQueryable.ToPagedListAsync(queryTrialDocument.PageIndex, queryTrialDocument.PageSize, queryTrialDocument.SortField, queryTrialDocument.Asc); } + public async Task> GetTrialSignDocumentList(TrialDocQuery querySystemDocument) + { + var trialDocQueryable = from trialDoc in _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == querySystemDocument.TrialId) + .Where(t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId)) + .Where(t => t.IsDeleted == false || (t.IsDeleted == true && t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id))) + + join trialUser in _repository.Where(t => t.TrialId == querySystemDocument.TrialId && t.UserId == _userInfo.Id) on trialDoc.TrialId equals trialUser.TrialId + join confirm in _repository.Where(t => t.TrialDocument.TrialId == querySystemDocument.TrialId) on + new { trialUser.UserId, TrialDocumentId = trialDoc.Id } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc + from confirm in cc.DefaultIfEmpty() + select new UnionDocumentWithConfirmInfoView() + { + Id = trialDoc.Id, + IsSystemDoc = false, + CreateTime = trialDoc.CreateTime, + FullFilePath = trialDoc.Path, + IsDeleted = trialDoc.IsDeleted, + Name = trialDoc.Name, + Path = trialDoc.Path, + FileTypeId = trialDoc.FileTypeId, + FileType = _userInfo.IsEn_Us ? trialDoc.FileType.Value : trialDoc.FileType.ValueCN, + UpdateTime = trialDoc.UpdateTime, + SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes, + + //IsConfirmed = confirm.ConfirmTime != null, + ConfirmUserId = confirm.ConfirmUserId, + ConfirmTime = confirm.ConfirmTime, + RealName = trialUser.User.FullName, + UserName = trialUser.User.UserName, + UserTypeId = trialUser.User.UserTypeId, + UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName + + }; + + trialDocQueryable = trialDocQueryable.WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name)) + .WhereIf(querySystemDocument.FileTypeId != null, t => t.FileTypeId == querySystemDocument.FileTypeId) + .WhereIf(querySystemDocument.IsSigned == true, t => t.ConfirmTime != null) + .WhereIf(querySystemDocument.IsSigned == false, t => t.ConfirmTime == null); + + + return await trialDocQueryable.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc); + + } + /// /// 获取下一个未签名的文件 /// @@ -166,7 +210,7 @@ namespace IRaCIS.Core.Application.Services var trialId = querySystemDocument.TrialId; - var trialInfo = await (_repository.Where(t => t.Id == querySystemDocument.TrialId,ignoreQueryFilters:true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync()); + var trialInfo = await (_repository.Where(t => t.Id == querySystemDocument.TrialId, ignoreQueryFilters: true).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync()); //系统文档查询 var systemDocumentQueryable = from needConfirmedUserType in _repository.Where(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId) @@ -366,7 +410,7 @@ namespace IRaCIS.Core.Application.Services - ConfirmUserId = confirm.ConfirmUserId, + ConfirmUserId = confirm.ConfirmUserId, ConfirmTime = confirm.ConfirmTime, RealName = trialUser.User.FullName, UserName = trialUser.User.UserName, @@ -398,9 +442,9 @@ namespace IRaCIS.Core.Application.Services FileType = _userInfo.IsEn_Us ? needConfirmEdUserType.SystemDocument.FileType.Value : needConfirmEdUserType.SystemDocument.FileType.ValueCN, FileTypeId = needConfirmEdUserType.SystemDocument.FileTypeId, UpdateTime = needConfirmEdUserType.SystemDocument.UpdateTime, - //IsConfirmed = confirm.ConfirmTime != null, + //IsConfirmed = confirm.ConfirmTime != null, - ConfirmUserId = confirm.ConfirmUserId, + ConfirmUserId = confirm.ConfirmUserId, ConfirmTime = confirm.ConfirmTime, RealName = trialUser.User.FullName, UserName = trialUser.User.UserName, @@ -413,10 +457,10 @@ namespace IRaCIS.Core.Application.Services var unionQuery = trialDocQuery.Union(systemDocQuery) .WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name)) .WhereIf(querySystemDocument.FileTypeId != null, t => t.FileTypeId == querySystemDocument.FileTypeId) - .WhereIf(querySystemDocument.IsConfirmed == true, t => t.ConfirmTime != null) + .WhereIf(querySystemDocument.IsConfirmed == true, t => t.ConfirmTime != null) .WhereIf(querySystemDocument.IsConfirmed == false, t => t.ConfirmTime == null) .WhereIf(querySystemDocument.IsDeleted != null, t => t.IsDeleted == querySystemDocument.IsDeleted) - .WhereIf(querySystemDocument.UserTypeId != null, t => t.UserTypeId == querySystemDocument.UserTypeId); + .WhereIf(querySystemDocument.UserTypeId != null, t => t.UserTypeId == querySystemDocument.UserTypeId); var result = await unionQuery.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc); diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/CStoreSCPService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/CStoreSCPService.cs new file mode 100644 index 000000000..934d2de1f --- /dev/null +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/CStoreSCPService.cs @@ -0,0 +1,132 @@ +using FellowOakDicom.Network; +using FellowOakDicom; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using IRaCIS.Core.Application.Contracts.Dicom; + +namespace IRaCIS.Core.Application.Service.ImageAndDoc +{ + + public class CStoreSCPService : DicomService, IDicomServiceProvider, IDicomCStoreProvider, IDicomCEchoProvider + { + public readonly IDicomArchiveService _dicomArchiveService; + + + private static readonly DicomTransferSyntax[] _acceptedTransferSyntaxes = new DicomTransferSyntax[] + { + DicomTransferSyntax.ExplicitVRLittleEndian, + DicomTransferSyntax.ExplicitVRBigEndian, + DicomTransferSyntax.ImplicitVRLittleEndian + }; + + private static readonly DicomTransferSyntax[] _acceptedImageTransferSyntaxes = new DicomTransferSyntax[] + { + // Lossless + DicomTransferSyntax.JPEGLSLossless, + DicomTransferSyntax.JPEG2000Lossless, + DicomTransferSyntax.JPEGProcess14SV1, + DicomTransferSyntax.JPEGProcess14, + DicomTransferSyntax.RLELossless, + // Lossy + DicomTransferSyntax.JPEGLSNearLossless, + DicomTransferSyntax.JPEG2000Lossy, + DicomTransferSyntax.JPEGProcess1, + DicomTransferSyntax.JPEGProcess2_4, + // Uncompressed + DicomTransferSyntax.ExplicitVRLittleEndian, + DicomTransferSyntax.ExplicitVRBigEndian, + DicomTransferSyntax.ImplicitVRLittleEndian + }; + + + public CStoreSCPService(INetworkStream stream, Encoding fallbackEncoding, ILogger log, DicomServiceDependencies dependencies/*, IDicomArchiveService dicomArchiveService*/) + : base(stream, fallbackEncoding, log, dependencies) + { + //_dicomArchiveService = dicomArchiveService; + } + + + public Task OnReceiveAssociationRequestAsync(DicomAssociation association) + { + if (association.CalledAE != "STORESCP") + { + return SendAssociationRejectAsync( + DicomRejectResult.Permanent, + DicomRejectSource.ServiceUser, + DicomRejectReason.CalledAENotRecognized); + } + + foreach (var pc in association.PresentationContexts) + { + if (pc.AbstractSyntax == DicomUID.Verification) + { + pc.AcceptTransferSyntaxes(_acceptedTransferSyntaxes); + } + else if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None) + { + pc.AcceptTransferSyntaxes(_acceptedImageTransferSyntaxes); + } + } + + return SendAssociationAcceptAsync(association); + } + + + public Task OnReceiveAssociationReleaseRequestAsync() + { + return SendAssociationReleaseResponseAsync(); + } + + + public void OnReceiveAbort(DicomAbortSource source, DicomAbortReason reason) + { + /* nothing to do here */ + } + + + public void OnConnectionClosed(Exception exception) + { + /* nothing to do here */ + } + + + public async Task OnCStoreRequestAsync(DicomCStoreRequest request) + { + var studyUid = request.Dataset.GetSingleValue(DicomTag.StudyInstanceUID).Trim(); + var instUid = request.SOPInstanceUID.UID; + + var path = Path.GetFullPath(@".\DICOM-Store"); + + path = Path.Combine(path, studyUid); + + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + + path = Path.Combine(path, instUid) + ".dcm"; + + await request.File.SaveAsync(path); + + return new DicomCStoreResponse(request, DicomStatus.Success); + } + + + public Task OnCStoreRequestExceptionAsync(string tempFileName, Exception e) + { + // let library handle logging and error response + return Task.CompletedTask; + } + + + public Task OnCEchoRequestAsync(DicomCEchoRequest request) + { + return Task.FromResult(new DicomCEchoResponse(request, DicomStatus.Success)); + } + + } +} diff --git a/IRaCIS.Core.Application/Service/Management/UserTypeService.cs b/IRaCIS.Core.Application/Service/Management/UserTypeService.cs index d1c443800..90683cbea 100644 --- a/IRaCIS.Core.Application/Service/Management/UserTypeService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserTypeService.cs @@ -144,7 +144,6 @@ namespace IRaCIS.Core.Application.Contracts { userTypeEnums = new List() { UserTypeEnum.CRA, UserTypeEnum.ClinicalResearchCoordinator }; - } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs index 622018b28..caab944e3 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs @@ -382,6 +382,10 @@ namespace IRaCIS.Core.Application.Contracts public int? TrialWaitSignDocCount { get; set; } public int? SysWaitSignDocCount { get; set; } + + public int? TrialSignedDocCount { get; set; } + public int? SysSignedDocCount { get; set; } + #region PM/APM public int? PM_SiteSurveryCount { get; set; } public int? PM_CheckCount { get; set; } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs index 6755809a9..cfa8fdc26 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs @@ -1212,6 +1212,17 @@ namespace IRaCIS.Core.Application .SelectMany(t => t.NeedConfirmedUserTypeList) .CountAsync(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId); + var signedTrialCount = await _trialRepository.Where(t => t.TrialStatusStr != StaticData.TrialState.TrialStopped).Where(t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id)) + .Where(c => c.TrialDocumentList.Where(t => t.IsDeleted == false && t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId) + && t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id && t.ConfirmTime != null)).Count() > 0).CountAsync(); + + var signedSysDocCont = await _systemDocumentRepository + .Where(t => t.IsDeleted == false && t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id && t.ConfirmTime != null)) + .SelectMany(t => t.NeedConfirmedUserTypeList) + .CountAsync(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId); + + + var siteSurveyCount = await _trialRepository .Where(t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM, c => c.TrialSiteSurveyList.Where(t => t.State == TrialSiteSurveyEnum.SPMApproved).Count() > 0) @@ -1248,6 +1259,9 @@ namespace IRaCIS.Core.Application SysWaitSignDocCount = needSignSysDocCont, TrialWaitSignDocCount = needSignTrialCount , + TrialSignedDocCount=signedTrialCount, + SysSignedDocCount=signedSysDocCont, + #region PM PM_SiteSurveryCount = isPM ? siteSurveyCount : 0,