添加项目文件。
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
|
||||
|
||||
public class BasicDicView: AddOrEditBasicDic
|
||||
{
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
public Guid CreateUserId { get; set; }
|
||||
public DateTime UpdateTime { get; set; }
|
||||
public Guid UpdateUserId { get; set; }
|
||||
|
||||
public string ConfigType { get; set; }
|
||||
|
||||
public string ConfigTypeDes { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class AddOrEditBasicDic
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
public string Code { get; set; } = String.Empty;
|
||||
|
||||
public string KeyName { get; set; } = String.Empty;
|
||||
|
||||
public string Description { get; set; } = String.Empty;
|
||||
|
||||
|
||||
|
||||
public string Value { get; set; } = String.Empty;
|
||||
|
||||
public string ValueCN { get; set; } = String.Empty;
|
||||
|
||||
|
||||
|
||||
public int ShowOrder { get; set; }
|
||||
|
||||
|
||||
//有父亲 就有值
|
||||
public Guid? ParentId { get; set; }
|
||||
|
||||
public bool IsEnable { get; set; }
|
||||
|
||||
|
||||
//默认不是字典项 类型配置
|
||||
public bool IsConfig { get; set; }
|
||||
|
||||
//是配置的话,就有值
|
||||
public Guid? ConfigTypeId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class BasicDicSelect
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string KeyName { get; set; } = string.Empty;
|
||||
public string ValueCN { get; set; } = string.Empty;
|
||||
public string Value { get; set; } = string.Empty;
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
public int ShowOrder { get; set; }
|
||||
|
||||
public Guid? ParentId { get; set; }
|
||||
public string ParentCode { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class BasicDicQuery:PageInput
|
||||
{
|
||||
public string? Code { get; set; }
|
||||
|
||||
public string? KeyName { get; set; }
|
||||
|
||||
public bool? IsConfig { get; set; }
|
||||
|
||||
public Guid? ConfigTypeId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class DicViewModelDTO : AddOrUpdateDicDTO
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class AddOrUpdateDicDTO
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string KeyName { get; set; } = String.Empty;
|
||||
public string Value { get; set; } = String.Empty;
|
||||
public string Description { get; set; } = String.Empty;
|
||||
public string ValueCN { get; set; } = String.Empty;
|
||||
public int ShowOrder { get; set; }
|
||||
public string Type { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
public class DicQueryDTO : PageInput
|
||||
{
|
||||
public string KeyName { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
public class KeyNameType
|
||||
{
|
||||
public Guid KeyId { get; set; }
|
||||
public string KeyName { get; set; } = String.Empty;
|
||||
public string Type { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
public class DicResultDTO
|
||||
{
|
||||
public Dictionary<string, Dictionary<Guid, string>> DicList = new Dictionary<string, Dictionary<Guid, string>>();
|
||||
}
|
||||
|
||||
|
||||
public class TrialDictionaryView
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string KeyName { get; set; } = String.Empty;
|
||||
public string Value { get; set; } = String.Empty;
|
||||
public int ShowOrder { get; set; }
|
||||
}
|
||||
|
||||
public class TrialDicSelect
|
||||
{
|
||||
public TrialDictionaryView[] Phase { get; set; } = new TrialDictionaryView[0];
|
||||
public TrialDictionaryView[] IndicationType { get; set; } = new TrialDictionaryView[0];
|
||||
public TrialDictionaryView[] DeclarationType { get; set; } = new TrialDictionaryView[0];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-02-15 11:55:57
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using Newtonsoft.Json;
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
/// <summary> EmailNoticeConfigView 列表视图模型 </summary>
|
||||
public class EmailNoticeConfigView : EmailNoticeConfigAddOrEdit
|
||||
{
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
public Guid CreateUserId { get; set; }
|
||||
public Guid UpdateUserId { get; set; }
|
||||
|
||||
public DateTime UpdateTime { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public SystemBasicDataSelect Scenario { get; set; }
|
||||
|
||||
|
||||
//public Guid? ScenarioParentId => Scenario.ParentId;
|
||||
|
||||
public string ScenarioName => Scenario.Value;
|
||||
public string ScenarioNameCN => Scenario.ValueCN;
|
||||
|
||||
}
|
||||
|
||||
///<summary>EmailNoticeConfigQuery 列表查询参数模型</summary>
|
||||
public class EmailNoticeConfigQuery:PageInput
|
||||
{
|
||||
public Guid? ScenarioId { get; set; }
|
||||
|
||||
public bool? IsReturnRequired { get; set; }
|
||||
public bool? IsUrgent { get; set; }
|
||||
public bool? IsEnable { get; set; }
|
||||
|
||||
}
|
||||
|
||||
///<summary> EmailNoticeConfigAddOrEdit 列表查询参数模型</summary>
|
||||
public class EmailNoticeConfigAddOrEdit
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Code { get; set; } = String.Empty;
|
||||
|
||||
public string AuthorizationCode { get; set; } = String.Empty;
|
||||
|
||||
public Guid ScenarioId { get; set; }
|
||||
public string Title { get; set; } = String.Empty;
|
||||
public string Body { get; set; } = String.Empty;
|
||||
public string FromEmail { get; set; } = String.Empty;
|
||||
public string ReceiveEmail { get; set; } = String.Empty;
|
||||
public string CopyEmail { get; set; } = String.Empty;
|
||||
public bool IsReturnRequired { get; set; }
|
||||
public bool IsUrgent { get; set; }
|
||||
public bool IsEnable { get; set; }
|
||||
public bool IsAutoSend { get; set; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
|
||||
|
||||
public class UploadFileInfoDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string FilePath { get; set; } = string.Empty;
|
||||
|
||||
//[JsonIgnore]
|
||||
//public string FullFilePathNoToken => FilePath;
|
||||
public string FullFilePath { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class SysMessageDTO
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int ToDoctorId { get; set; }
|
||||
public int FromUserId { get; set; }
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Content { get; set; } = string.Empty;
|
||||
public string MessageTime { get; set; } = string.Empty;
|
||||
public bool HasRead { get; set; }
|
||||
public string Memo { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-02-15 15:46:00
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
/// <summary> SystemBasicDataView 列表视图模型 </summary>
|
||||
public class SystemBasicDataView: SystemBasicDataAddOrEdit
|
||||
{
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
public Guid CreateUserId { get; set; }
|
||||
public DateTime UpdateTime { get; set; }
|
||||
public Guid UpdateUserId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class SystemBasicDataSelect
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string ValueCN { get; set; } = string.Empty;
|
||||
public string Value { get; set; } = string.Empty;
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
public Guid? ParentId { get; set; }
|
||||
public string ParentCode { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
///<summary>SystemBasicDataQuery 列表查询参数模型</summary>
|
||||
public class SystemBasicDataQuery:PageInput
|
||||
{
|
||||
///<summary> Name</summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
///<summary> Code</summary>
|
||||
public string? Code { get; set; }
|
||||
|
||||
}
|
||||
|
||||
///<summary> SystemBasicDataAddOrEdit 列表查询参数模型</summary>
|
||||
public class SystemBasicDataAddOrEdit
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Value { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public int ShowOrder { get; set; }
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public Guid? ParentId { get; set; }
|
||||
|
||||
public string ValueCN { get; set; } = string.Empty;
|
||||
|
||||
public bool IsEnable { get; set; }=true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class SystemLogDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string ApiPath { get; set; } = string.Empty;
|
||||
public string Params { get; set; } = string.Empty;
|
||||
public string Result { get; set; } = string.Empty;
|
||||
public DateTime RequestTime { get; set; } = DateTime.Now;
|
||||
public long ElapsedMilliseconds { get; set; } = 0;
|
||||
public Guid OptUserId { get; set; } = Guid.Empty;
|
||||
public string OptUserName { get; set; } = string.Empty;
|
||||
public string ClientIP { get; set; } = string.Empty;
|
||||
public bool Status { get; set; } = true;
|
||||
public string Message { get; set; } = string.Empty;
|
||||
public string LogCategory { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class QueryLogQueryDTO : PageInput
|
||||
{
|
||||
public string Keyword { get; set; } = string.Empty;
|
||||
public string LogCategory { get; set; } = string.Empty;
|
||||
public DateTime? BeginTime { get; set; }
|
||||
public DateTime? EndTime { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class AuditQueryDTO : PageInput
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid? StudyId { get; set; }
|
||||
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
public int? AuditType { get; set; }
|
||||
|
||||
public string SubjectInfo { get; set; } = string.Empty;
|
||||
|
||||
public Guid? OptUserId { get; set; }
|
||||
|
||||
|
||||
public DateTime? StartDate { get; set; }
|
||||
|
||||
public DateTime? EndDate { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class AuditDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public int AuditType { get; set; }
|
||||
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid StudyId { get; set; }
|
||||
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
public string SubjectName { get; set; } = string.Empty;
|
||||
|
||||
public string SubjectCode { get; set; } = string.Empty;
|
||||
|
||||
public Guid OptUserId { get; set; }
|
||||
|
||||
public string OptUser { get; set; } = string.Empty;
|
||||
|
||||
public DateTime OptTime { get; set; } = DateTime.Now;
|
||||
|
||||
public string Note { get; set; } = string.Empty;
|
||||
|
||||
public string Detail { get; set; } = string.Empty;
|
||||
|
||||
public string TrialCode { get; set; } = string.Empty;
|
||||
|
||||
public string TrialIndication { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public class OptUserDto
|
||||
{
|
||||
public Guid OptUserId { get; set; }
|
||||
public string OptUser { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class AuditSubjectSelectDto
|
||||
{
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
public string SubjectCode { get; set; } = string.Empty;
|
||||
|
||||
public string SubjectName { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
using IRaCIS.Core.Infrastructure.ExpressionExtend;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据字典-基础数据维护
|
||||
/// </summary>
|
||||
|
||||
[ApiExplorerSettings(GroupName = "Common")]
|
||||
public class DictionaryService : BaseService, IDictionaryService
|
||||
{
|
||||
private readonly IRepository<Dictionary> _dicRepository;
|
||||
private readonly IRepository<DoctorDictionary> _doctorDictionaryRepository;
|
||||
private readonly IRepository<TrialDictionary> _trialDictionaryRepository;
|
||||
private readonly IRepository<Doctor> _doctorRepository;
|
||||
private readonly IRepository<Trial> _trialRepository;
|
||||
|
||||
public DictionaryService(IRepository<Dictionary> sysDicRepository, IRepository<DoctorDictionary> doctorDictionaryRepository, IRepository<TrialDictionary> trialDictionaryRepository,
|
||||
IRepository<Doctor> doctorRepository, IRepository<Trial> trialRepository)
|
||||
{
|
||||
_dicRepository = sysDicRepository;
|
||||
_doctorDictionaryRepository = doctorDictionaryRepository;
|
||||
_trialDictionaryRepository = trialDictionaryRepository;
|
||||
_doctorRepository = doctorRepository;
|
||||
_trialRepository = trialRepository;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// New 查询条件 IsConfig 代表是字典类型配置项 否就是我们普通的项 和普通项的子项
|
||||
/// </summary>
|
||||
/// <param name="basicDicQuery"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<BasicDicView>> GetBasicDicList(BasicDicQuery basicDicQuery)
|
||||
{
|
||||
|
||||
var systemBasicDataQueryable = _repository.GetQueryable<Dictionary>().Where(t => t.ParentId == null)
|
||||
.WhereIf(!string.IsNullOrEmpty(basicDicQuery.Code), t => t.Code.Contains(basicDicQuery.Code!))
|
||||
.WhereIf(!string.IsNullOrEmpty(basicDicQuery.KeyName), t => t.KeyName.Contains(basicDicQuery.KeyName!))
|
||||
.WhereIf(basicDicQuery.ConfigTypeId != null, t => t.ConfigTypeId == basicDicQuery.ConfigTypeId!)
|
||||
.WhereIf(basicDicQuery.IsConfig != null, t => t.IsConfig == basicDicQuery.IsConfig)
|
||||
|
||||
.ProjectTo<BasicDicView>(_mapper.ConfigurationProvider);
|
||||
|
||||
return await systemBasicDataQueryable.ToPagedListAsync(basicDicQuery.PageIndex, basicDicQuery.PageSize, String.IsNullOrEmpty(basicDicQuery.SortField) ? "Code" : basicDicQuery.SortField, basicDicQuery.Asc);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// New
|
||||
/// </summary>
|
||||
/// <param name="addOrEditBasic"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdateBasicDic(AddOrEditBasicDic addOrEditBasic)
|
||||
{
|
||||
|
||||
var entity = await _repository.InsertOrUpdateAsync<Dictionary, AddOrEditBasicDic>(addOrEditBasic, true);
|
||||
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// New
|
||||
/// </summary>
|
||||
/// <param name="parentId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{parentId:guid}")]
|
||||
public async Task<List<BasicDicView>> GetChildList(Guid parentId)
|
||||
{
|
||||
return await _repository.GetQueryable<Dictionary>().Where(t => t.ParentId == parentId)
|
||||
.OrderBy(t => t.ShowOrder).ProjectTo<BasicDicView>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 传递父亲 code 字符串 数组 返回多个下拉框数据
|
||||
/// </summary>
|
||||
/// <param name="searchArray"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<Dictionary<string, List<BasicDicSelect>>> GetBasicDataSelect(string[] searchArray)
|
||||
{
|
||||
|
||||
var searchList = await _repository.GetQueryable<Dictionary>().Where(t => searchArray.Contains(t.Parent.Code) && t.ParentId != null && t.IsEnable).ProjectTo<BasicDicSelect>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
return searchList.GroupBy(t => t.ParentCode).ToDictionary(g => g.Key, g => g.ToList());
|
||||
|
||||
}
|
||||
|
||||
public async Task<List<BasicDicSelect>> GetBasicDataSelect(string searchKey)
|
||||
{
|
||||
var searchList = await _repository.GetQueryable<Dictionary>().Where(t => t.Parent.Code== searchKey && t.ParentId != null && t.IsEnable).ProjectTo<BasicDicSelect>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
return searchList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region old 待废弃
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目多选字典
|
||||
/// </summary>
|
||||
/// <param name="searchArray">Title、Department、Rank、Position、ReadingType、Subspeciality Sponsor CROCompany ReadingStandard ReviewMode ReviewType ProjectState</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public DicResultDTO GetDictionary(string[] searchArray)
|
||||
{
|
||||
var doctorViewList = _dicRepository.ProjectTo<DicViewModelDTO>(_mapper.ConfigurationProvider).OrderBy(t => t.KeyName)
|
||||
.ThenBy(t => t.ShowOrder).ToList();
|
||||
|
||||
var projectDicResult = new DicResultDTO();
|
||||
foreach (var searchItem in searchArray)
|
||||
{
|
||||
var item = searchItem.Trim();
|
||||
var tempDic = new Dictionary<Guid, string>();
|
||||
doctorViewList.Where(o => o.KeyName == item).ToList().ForEach(o => tempDic.Add(o.Id!.Value, o.Value));
|
||||
projectDicResult.DicList.Add(item, tempDic);
|
||||
}
|
||||
return projectDicResult;
|
||||
}
|
||||
|
||||
|
||||
public DicResultDTO GetAllDictionary()
|
||||
{
|
||||
var list = _dicRepository.ProjectTo<DicViewModelDTO>(_mapper.ConfigurationProvider).OrderBy(t => t.KeyName)
|
||||
.ThenBy(t => t.ShowOrder).ToList();
|
||||
|
||||
var types = list.Select(u => u.KeyName).Distinct();
|
||||
|
||||
var projectDicResult = new DicResultDTO();
|
||||
foreach (var type in types)
|
||||
{
|
||||
var tempDic = new Dictionary<Guid, string>();
|
||||
|
||||
//list.Where(o => o.KeyName == type).ToList().ForEach(o => tempDic.Add(o.Id, string.IsNullOrEmpty(o.ValueCN)?o.Value: o.Value + " / " + o.ValueCN));
|
||||
list.Where(o => o.KeyName == type).ToList().ForEach(o => tempDic.Add(o.Id!.Value, o.Value));
|
||||
|
||||
projectDicResult.DicList.Add(type, tempDic);
|
||||
}
|
||||
|
||||
// //用户类型从字典表 移到另外的表了,现在为了前端不变,在这里获取,给出数据
|
||||
|
||||
//var userTypes= _userTypeRoleRepository.GetAll().OrderBy(t => t.Order).Select(t => new {t.Id, t.UserType}).ToList();
|
||||
//var userTypeDic = new Dictionary<Guid, string>();
|
||||
//userTypes.ForEach(o => userTypeDic.Add(o.Id, o.UserType));
|
||||
|
||||
// projectDicResult.DicList.Add("UserType", userTypeDic);
|
||||
|
||||
|
||||
return projectDicResult;
|
||||
}
|
||||
|
||||
/// <summary> 根据Key,获取单个字典数组 </summary>
|
||||
[HttpPost]
|
||||
public PageOutput<DicViewModelDTO> getDictionarySelectList(DicQueryDTO dicSearchModel)
|
||||
{
|
||||
|
||||
|
||||
var dicQueryable = _dicRepository
|
||||
.WhereIf(!string.IsNullOrEmpty(dicSearchModel.KeyName), t => t.KeyName == dicSearchModel.KeyName && t.Value != "")
|
||||
.ProjectTo<DicViewModelDTO>(_mapper.ConfigurationProvider);
|
||||
|
||||
var pageList = dicQueryable.ToPagedList(dicSearchModel.PageIndex, dicSearchModel.PageSize, dicSearchModel.SortField, dicSearchModel.Asc);
|
||||
|
||||
return pageList;
|
||||
|
||||
}
|
||||
|
||||
/// <summary> 根据Type、Key 获取字典 树结构 </summary>
|
||||
public List<DictionaryTreeNode> GetDicTree()
|
||||
{
|
||||
var keyNameTypeDistinctList = _dicRepository.Where(t => t.ParentId != null)
|
||||
.ProjectTo<KeyNameType>(_mapper.ConfigurationProvider).Distinct().ToList();
|
||||
|
||||
var treeNodeList = new List<DictionaryTreeNode>();
|
||||
var group = keyNameTypeDistinctList.GroupBy(t => t.Type);
|
||||
foreach (var groupItem in group)
|
||||
{
|
||||
var node = new DictionaryTreeNode()
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
KeyName = groupItem.Key,
|
||||
Type = groupItem.Key,
|
||||
Children = keyNameTypeDistinctList.Where(t => t.Type == groupItem.Key).Select(t =>
|
||||
new DictionaryTreeNode()
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
KeyName = t.KeyName,
|
||||
Type = t.Type,
|
||||
Children = new List<DictionaryTreeNode>()
|
||||
}).ToList()
|
||||
};
|
||||
treeNodeList.Add(node);
|
||||
}
|
||||
return treeNodeList;
|
||||
}
|
||||
|
||||
|
||||
/// <summary> 添加或更新字典数据 </summary>
|
||||
//[HttpPost]
|
||||
//public IResponseOutput AddOrUpdateDictionary(AddOrUpdateDicDTO viewModel)
|
||||
//{
|
||||
// #region 封装前
|
||||
// //if (viewModel.Id == null)
|
||||
// //{
|
||||
// // var existItem = _dicRepository.FirstOrDefault(dic => dic.KeyName.Equals(viewModel.KeyName) && dic.Value.Equals(viewModel.Value));
|
||||
// // if (existItem != null)
|
||||
// // {
|
||||
// // return ResponseOutput.NotOk("The added item has the same name as a sub-item of current categpry. Please modify the name.");
|
||||
// // }
|
||||
// // var result = _dicRepository.Add(_mapper.Map<Dictionary>(viewModel));
|
||||
// // var success = _dicRepository.SaveChanges();
|
||||
// // return ResponseOutput.Result(success);
|
||||
// //}
|
||||
// //else
|
||||
// //{
|
||||
// // var existItem = _dicRepository.FirstOrDefault(dic => dic.KeyName.Equals(viewModel.KeyName) && dic.Value.Equals(viewModel.Value));
|
||||
// // if (existItem != null && existItem.Id != viewModel.Id)
|
||||
// // {
|
||||
// // return ResponseOutput.NotOk("The updated item has the same name as a sub-item of current categpry. Please modify the name.");
|
||||
// // }
|
||||
// // var updateItem = _dicRepository.FirstOrDefault(t => t.Id == viewModel.Id);
|
||||
// // _mapper.Map(viewModel, updateItem);
|
||||
// // var success = _dicRepository.SaveChanges();
|
||||
// // return ResponseOutput.Result(success);
|
||||
// //}
|
||||
// #endregion
|
||||
|
||||
// var exp = new EntityVerifyExp<Dictionary>()
|
||||
// {
|
||||
// VerifyExp = dic => dic.KeyName.Equals(viewModel.KeyName) && dic.Value.Equals(viewModel.Value),
|
||||
// VerifyMsg = "The item has the same name as a sub-item of current categpry"
|
||||
// };
|
||||
|
||||
// //var entity = _dicRepository.UseMapper(_mapper).InsertOrUpdate(viewModel, true, exp);
|
||||
|
||||
// return ResponseOutput.Ok(entity.Id);
|
||||
|
||||
//}
|
||||
|
||||
|
||||
/// <summary> 删除字典数据 </summary>
|
||||
[HttpDelete("{id:guid}")]
|
||||
public async Task<IResponseOutput> DeleteDictionary(Guid id)
|
||||
{
|
||||
if ((await _doctorDictionaryRepository.AnyAsync(t => t.DictionaryId == id)) ||
|
||||
(await _doctorRepository.AnyAsync(t => t.SpecialityId == id|| t.PositionId == id|| t.DepartmentId == id|| t.RankId == id))
|
||||
|
||||
)
|
||||
{
|
||||
return ResponseOutput.NotOk("This item is referenced by content of the reviewer's resume.");
|
||||
}
|
||||
|
||||
if (await _trialDictionaryRepository.AnyAsync(t => t.DictionaryId == id) ||
|
||||
await _trialRepository.AnyAsync(t => t.ReviewModeId == id))
|
||||
{
|
||||
return ResponseOutput.NotOk("This item is referenced by content of the trial infomation.");
|
||||
}
|
||||
|
||||
var success = await _dicRepository.DeleteFromQueryAsync(t => t.Id == id);
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
/// <summary> 获取所有字典数据 </summary>
|
||||
public async Task<IEnumerable<string>> getDictionarySelect()
|
||||
{
|
||||
return await _dicRepository.Select(t => t.KeyName).Distinct().ToListAsync();
|
||||
}
|
||||
|
||||
//[Obsolete]
|
||||
[NonDynamicMethod]
|
||||
public DicViewModelDTO GetDetailById(Guid id)
|
||||
{
|
||||
var result = _dicRepository.ProjectTo<DicViewModelDTO>(_mapper.ConfigurationProvider).FirstOrDefault(u => u.Id == id).IfNullThrowException();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TrialDicSelect GetGenerateTrialCodeDic()
|
||||
{
|
||||
var list = _dicRepository.Where(t => t.KeyName == "Phase" || t.KeyName == "IndicationType" || t.KeyName == "DeclarationType").ProjectTo<TrialDictionaryView>(_mapper.ConfigurationProvider).ToList();
|
||||
|
||||
return new TrialDicSelect()
|
||||
{
|
||||
Phase = list.Where(t => t.KeyName == "Phase").OrderBy(t => t.ShowOrder).ToArray(),
|
||||
IndicationType = list.Where(t => t.KeyName == "IndicationType").OrderBy(t => t.ShowOrder).ToArray(),
|
||||
DeclarationType = list.Where(t => t.KeyName == "DeclarationType").OrderBy(t => t.ShowOrder).ToArray()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-02-15 13:11:20
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// EmailNoticeConfigService
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "Common")]
|
||||
public class EmailNoticeConfigService : BaseService, IEmailNoticeConfigService
|
||||
{
|
||||
private readonly IRepository<EmailNoticeConfig> repository;
|
||||
|
||||
public EmailNoticeConfigService(IRepository<EmailNoticeConfig> repository)
|
||||
{
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<EmailNoticeConfigView>> GetEmailNoticeConfigList(EmailNoticeConfigQuery queryEmailNoticeConfig)
|
||||
{
|
||||
var emailNoticeConfigQueryable = _repository
|
||||
.WhereIf<EmailNoticeConfig>(queryEmailNoticeConfig.ScenarioId != null, t => t.ScenarioId == queryEmailNoticeConfig.ScenarioId)
|
||||
.WhereIf(queryEmailNoticeConfig.IsReturnRequired != null, t => t.IsReturnRequired == queryEmailNoticeConfig.IsReturnRequired)
|
||||
.WhereIf(queryEmailNoticeConfig.IsUrgent != null, t => t.IsUrgent == queryEmailNoticeConfig.IsUrgent)
|
||||
.WhereIf(queryEmailNoticeConfig.IsEnable != null, t => t.IsEnable == queryEmailNoticeConfig.IsEnable)
|
||||
.ProjectTo<EmailNoticeConfigView>(_mapper.ConfigurationProvider);
|
||||
|
||||
return await emailNoticeConfigQueryable.ToPagedListAsync(queryEmailNoticeConfig.PageIndex, queryEmailNoticeConfig.PageSize, queryEmailNoticeConfig.SortField, queryEmailNoticeConfig.Asc);
|
||||
}
|
||||
|
||||
|
||||
public async Task<IResponseOutput> AddOrUpdateEmailNoticeConfig(EmailNoticeConfigAddOrEdit addOrEditEmailNoticeConfig)
|
||||
{
|
||||
|
||||
var entity = await _repository.InsertOrUpdateAsync<EmailNoticeConfig, EmailNoticeConfigAddOrEdit>(addOrEditEmailNoticeConfig, true);
|
||||
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete("{emailNoticeConfigId:guid}")]
|
||||
public async Task<IResponseOutput> DeleteEmailNoticeConfig(Guid emailNoticeConfigId)
|
||||
{
|
||||
var success = await repository.DeleteFromQueryAsync(t => t.Id == emailNoticeConfigId);
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<Dictionary<object, string>> GetEmailScenarioEnumSelect()
|
||||
{
|
||||
return await Task.FromResult(EnumToSelectExtension.ToSelect<EmailScenarioEnum>());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
public class FileService : IFileService
|
||||
{
|
||||
|
||||
private readonly IDoctorService _doctorService;
|
||||
private readonly IAttachmentService _attachmentService;
|
||||
private readonly IHostEnvironment _hostEnvironment;
|
||||
private string defaultUploadFilePath = string.Empty;
|
||||
private readonly ILogger<FileService> _logger;
|
||||
public FileService(IDoctorService doctorService, IAttachmentService attachmentService,
|
||||
IHostEnvironment hostEnvironment, ILogger<FileService> logger)
|
||||
{
|
||||
_doctorService = doctorService;
|
||||
_attachmentService = attachmentService;
|
||||
_hostEnvironment = hostEnvironment;
|
||||
|
||||
defaultUploadFilePath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).IfNullThrowException().FullName;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打包医生官方简历
|
||||
/// </summary>
|
||||
/// <param name="language"></param>
|
||||
/// <param name="doctorIds"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> CreateOfficialResumeZip(int language, Guid[] doctorIds)
|
||||
{
|
||||
|
||||
//准备下载文件的临时路径
|
||||
var guidStr = Guid.NewGuid().ToString();
|
||||
|
||||
//string uploadFolderPath = HostingEnvironment.MapPath("/UploadFile/");
|
||||
string uploadFolderPath = Path.Combine(defaultUploadFilePath, "UploadFile");
|
||||
|
||||
var tempSavePath = Path.Combine(uploadFolderPath, "temp", guidStr); //待压缩的文件夹,将需要下载的文件拷贝到此文件夹
|
||||
if (!Directory.Exists(tempSavePath))
|
||||
{
|
||||
Directory.CreateDirectory(tempSavePath);
|
||||
}
|
||||
|
||||
//找到服务器简历路径 循环拷贝简历到临时路径
|
||||
foreach (var doctorId in doctorIds)
|
||||
{
|
||||
var doctor = await _doctorService.GetBasicInfo(doctorId);
|
||||
var doctorName = doctor.FirstName + "_" + doctor.LastName;
|
||||
|
||||
//找官方简历存在服务器的相对路径
|
||||
var sourceCvPath = await _attachmentService.GetDoctorOfficialCV(language, doctorId);
|
||||
if (!string.IsNullOrWhiteSpace(sourceCvPath))
|
||||
{
|
||||
//服务器简历文件实际路径
|
||||
//var sourceCvFullPath = HostingEnvironment.MapPath(sourceCvPath);
|
||||
var sourceCvPathTemp = sourceCvPath.Substring(1, sourceCvPath.Length - 1);//.Replace('/','\\');
|
||||
string sourceCvFullPath = Path.Combine(defaultUploadFilePath, sourceCvPathTemp);
|
||||
|
||||
var arr = sourceCvPath.Split('.');
|
||||
string extensionName = arr[arr.Length - 1]; //得到扩展名
|
||||
|
||||
//需要拷贝到的路径
|
||||
var doctorPath = Path.Combine(tempSavePath, doctor.ReviewerCode.ToString() + "_" + doctorName + "." + extensionName);
|
||||
|
||||
if (File.Exists(sourceCvFullPath))
|
||||
{
|
||||
File.Copy(sourceCvFullPath, doctorPath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//创建ZIP
|
||||
DateTime now = DateTime.Now;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(now.Year).Append(now.Month.ToString().PadLeft(2, '0')).Append(now.Day.ToString().PadLeft(2, '0'))
|
||||
.Append(now.Hour.ToString().PadLeft(2, '0')).Append(now.Minute.ToString().PadLeft(2, '0'))
|
||||
.Append(now.Second.ToString().PadLeft(2, '0')).Append(now.Millisecond.ToString().PadLeft(3, '0'));
|
||||
|
||||
string targetZipPath = Path.Combine(uploadFolderPath, "CV_" + sb.ToString() + ".zip");
|
||||
ZipHelper.CreateZip(tempSavePath, targetZipPath);
|
||||
|
||||
//返回Zip路径
|
||||
return Path.Combine("/UploadFile/", "CV_" + sb.ToString() + ".zip");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打包医生的所有附件
|
||||
/// </summary>
|
||||
/// <param name="doctorIds"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> CreateDoctorsAllAttachmentZip(Guid[] doctorIds)
|
||||
{
|
||||
//准备下载文件的临时路径
|
||||
var guidStr = Guid.NewGuid().ToString();
|
||||
//string uploadFolderPath = HostingEnvironment.MapPath("/UploadFile/");
|
||||
string uploadFolderPath = Path.Combine(defaultUploadFilePath, "UploadFile");
|
||||
var tempSavePath = Path.Combine(uploadFolderPath, "temp", guidStr); //待压缩的文件夹,将需要下载的文件拷贝到此文件夹
|
||||
if (!Directory.Exists(tempSavePath))
|
||||
{
|
||||
Directory.CreateDirectory(tempSavePath);
|
||||
}
|
||||
|
||||
|
||||
foreach (var doctorId in doctorIds)
|
||||
{
|
||||
//获取医生基本信息
|
||||
var doctor = await _doctorService.GetBasicInfo(doctorId);
|
||||
var doctorName = doctor.FirstName + "_" + doctor.LastName;
|
||||
var doctorCode = doctor.ReviewerCode;
|
||||
|
||||
var doctorDestPath = Path.Combine(tempSavePath, doctorCode + "_" + doctorName);
|
||||
if (!Directory.Exists(doctorDestPath))
|
||||
{
|
||||
Directory.CreateDirectory(doctorDestPath);
|
||||
}
|
||||
|
||||
//服务器上传后的源路径
|
||||
string doctorFileSourcePath = Path.Combine(uploadFolderPath, doctorId.ToString());
|
||||
|
||||
if (Directory.Exists(doctorFileSourcePath))
|
||||
{
|
||||
CopyDirectory(doctorFileSourcePath, doctorDestPath);
|
||||
}
|
||||
}
|
||||
string target = Guid.NewGuid().ToString();
|
||||
string targetPath = Path.Combine(uploadFolderPath, target + ".zip");
|
||||
ZipHelper.CreateZip(tempSavePath, targetPath);
|
||||
return Path.Combine("/UploadFile/", target + ".zip");
|
||||
}
|
||||
|
||||
|
||||
public async Task<string> CreateZipPackageByAttachment(Guid doctorId, Guid[] attachmentIds)
|
||||
{
|
||||
var doctor = await _doctorService.GetBasicInfo(doctorId);
|
||||
var doctorName = doctor.FirstName + "_" + doctor.LastName;
|
||||
|
||||
Guid temp = Guid.NewGuid();
|
||||
//string root = HostingEnvironment.MapPath("/UploadFile/"); //文件根目录
|
||||
string root = Path.Combine(defaultUploadFilePath, "UploadFile");
|
||||
|
||||
var tempPath = Path.Combine(root, "temp", temp.ToString(), doctor.ReviewerCode + doctorName); //待压缩的文件夹,将需要下载的文件拷贝到此文件夹
|
||||
var packagePath = Path.Combine(root, "temp", temp.ToString()); //打包目录
|
||||
if (!Directory.Exists(tempPath))
|
||||
{
|
||||
Directory.CreateDirectory(tempPath);
|
||||
}
|
||||
var attachemnts = (await _attachmentService.GetAttachments(doctorId)).Where(a => attachmentIds.Contains(a.Id));
|
||||
|
||||
foreach (var item in attachemnts)
|
||||
{
|
||||
var arr = item.Path.Trim().Split('/');
|
||||
var myPath = string.Empty;
|
||||
var myFile = string.Empty;
|
||||
//需要改进
|
||||
if (arr.Length > 0)
|
||||
{
|
||||
myFile = arr[arr.Length - 1];
|
||||
foreach (var arrItem in arr)
|
||||
{
|
||||
if (arrItem != string.Empty && !"UploadFile".Equals(arrItem))
|
||||
{
|
||||
myPath += (arrItem + "/");
|
||||
}
|
||||
}
|
||||
myPath = myPath.TrimEnd('/');
|
||||
}
|
||||
var sourcePath = Path.Combine(root, myPath);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(sourcePath) && File.Exists(sourcePath))
|
||||
{
|
||||
File.Copy(sourcePath, Path.Combine(tempPath, myFile), true);
|
||||
}
|
||||
}
|
||||
string target = Guid.NewGuid().ToString();
|
||||
string targetPath = Path.Combine(root, target + ".zip");
|
||||
ZipHelper.CreateZip(packagePath, targetPath);
|
||||
|
||||
return Path.Combine("/UploadFile/", target + ".zip");
|
||||
}
|
||||
|
||||
private static void CopyDirectory(string srcPath, string destPath)
|
||||
{
|
||||
|
||||
DirectoryInfo dir = new DirectoryInfo(srcPath);
|
||||
FileSystemInfo[] fileInfoArray = dir.GetFileSystemInfos(); //获取目录下(不包含子目录)的文件和子目录
|
||||
foreach (FileSystemInfo fileInfo in fileInfoArray)
|
||||
{
|
||||
if (fileInfo is DirectoryInfo) //判断是否文件夹
|
||||
{
|
||||
if (!Directory.Exists(destPath + "\\" + fileInfo.Name))
|
||||
{
|
||||
Directory.CreateDirectory(destPath + "\\" + fileInfo.Name); //目标目录下不存在此文件夹即创建子文件夹
|
||||
}
|
||||
CopyDirectory(fileInfo.FullName, destPath + "\\" + fileInfo.Name); //递归调用复制子文件夹
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Copy(fileInfo.FullName, destPath + "\\" + fileInfo.Name, true); //不是文件夹即复制文件,true表示可以覆盖同名文件
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using EasyCaching.Core.Interceptor;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IDictionaryService
|
||||
{
|
||||
|
||||
Task<IEnumerable<string>> getDictionarySelect();
|
||||
PageOutput<DicViewModelDTO> getDictionarySelectList(DicQueryDTO dicSearchModel);
|
||||
|
||||
Task<IResponseOutput> DeleteDictionary(Guid id);
|
||||
DicResultDTO GetDictionary(string[] searchArray);
|
||||
DicResultDTO GetAllDictionary();
|
||||
//IResponseOutput AddOrUpdateDictionary(AddOrUpdateDicDTO viewModel);
|
||||
|
||||
[EasyCachingAble(Expiration = 10)]
|
||||
List<DictionaryTreeNode> GetDicTree();
|
||||
DicViewModelDTO GetDetailById(Guid Id);
|
||||
|
||||
TrialDicSelect GetGenerateTrialCodeDic();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-02-15 13:11:20
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
public interface IEmailNoticeConfigService
|
||||
{
|
||||
Task<IResponseOutput> AddOrUpdateEmailNoticeConfig(EmailNoticeConfigAddOrEdit addOrEditEmailNoticeConfig);
|
||||
Task<IResponseOutput> DeleteEmailNoticeConfig(Guid emailNoticeConfigId);
|
||||
Task<PageOutput<EmailNoticeConfigView>> GetEmailNoticeConfigList(EmailNoticeConfigQuery queryEmailNoticeConfig);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IFileService
|
||||
{
|
||||
|
||||
//IResponseOutput<UploadFileInfo> DownloadOfficialResume(Guid[] doctorIds);
|
||||
|
||||
|
||||
Task<string> CreateOfficialResumeZip(int language, Guid[] doctorIds);
|
||||
|
||||
Task<string> CreateDoctorsAllAttachmentZip(Guid[] doctorIds);
|
||||
|
||||
Task<string> CreateZipPackageByAttachment(Guid doctorId, Guid[] attachmentIds);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using System.Collections.Generic;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface ILogService
|
||||
{
|
||||
IResponseOutput SaveLog2Db(SystemLogDTO viewModel);
|
||||
PageOutput<SystemLogDTO> GetLogList(QueryLogQueryDTO param);
|
||||
|
||||
PageOutput<AuditDTO> GetAuditList(AuditQueryDTO param);
|
||||
|
||||
List<OptUserDto> GetOptUserList(Guid trialId);
|
||||
|
||||
List<AuditSubjectSelectDto> GetSubjectList(Guid trialId);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IMessageService
|
||||
{
|
||||
int GetUnReadMessageCount(Guid doctorId);
|
||||
IResponseOutput DeleteSysMessage(Guid messageId);
|
||||
IResponseOutput MarkedAsRead(Guid messageId);
|
||||
|
||||
PageOutput<SysMessageDTO> GetMessageList(Guid doctorId, int pageSize, int pageIndex);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-02-15 15:47:41
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// ISystemBasicDataService
|
||||
/// </summary>
|
||||
public interface ISystemBasicDataService
|
||||
{
|
||||
|
||||
|
||||
Task<PageOutput<SystemBasicDataView>> GetSystemBasicDataList(SystemBasicDataQuery querySystemBasicData);
|
||||
|
||||
Task<IResponseOutput> AddOrUpdateSystemBasicData(SystemBasicDataAddOrEdit addOrEditSystemBasicData);
|
||||
|
||||
Task<IResponseOutput> DeleteSystemBasicData(Guid systemBasicDataId);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
//using IRaCIS.Application.Interfaces;
|
||||
//using IRaCIS.Application.Contracts;
|
||||
//using IRaCIS.Core.Infra.EFCore;
|
||||
//using IRaCIS.Core.Infrastructure;
|
||||
|
||||
//using Microsoft.AspNetCore.Http;
|
||||
//using Microsoft.AspNetCore.Mvc;
|
||||
//using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
//namespace IRaCIS.Application.Services
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 日志、项目审计日志
|
||||
// /// </summary>
|
||||
// [ApiExplorerSettings(GroupName = "Common")]
|
||||
// public class LogService : BaseService, ILogService
|
||||
// {
|
||||
// private readonly IRepository<SystemLog> _systemLogRepository;
|
||||
// private readonly IHttpContextAccessor _context;
|
||||
// private readonly IRepository<TrialAudit> _trialAuditRepository;
|
||||
// private readonly IRepository<Subject> _subjectRepository;
|
||||
// private readonly IRepository<Trial> _trialRepository;
|
||||
|
||||
// public LogService(IRepository<SystemLog> systemLogRepository, IHttpContextAccessor context, IRepository<TrialAudit> trialAuditRepository,
|
||||
// IRepository<Subject> subjectRepository, IRepository<Trial> trialRepository)
|
||||
// {
|
||||
// _systemLogRepository = systemLogRepository;
|
||||
// _context = context;
|
||||
// _trialAuditRepository = trialAuditRepository;
|
||||
// _subjectRepository = subjectRepository;
|
||||
// _trialRepository = trialRepository;
|
||||
// }
|
||||
|
||||
// [HttpPost]
|
||||
// public PageOutput<AuditDTO> GetAuditList(AuditQueryDTO param)
|
||||
// {
|
||||
// var subjectInfo = param.SubjectInfo == null ? string.Empty : param.SubjectInfo.Trim();
|
||||
|
||||
// var query = _trialAuditRepository.Where(x => x.TrialId == param.TrialId)
|
||||
// .WhereIf(param.AuditType != null, t => t.AuditType == param.AuditType)
|
||||
// .WhereIf(param.OptUserId != null, t => t.OptUserId == param.OptUserId)
|
||||
// .WhereIf(param.SubjectId != null, t => t.SubjectId == param.SubjectId)
|
||||
// .WhereIf(!string.IsNullOrEmpty(subjectInfo), t => t.Subject.Code.Contains(subjectInfo) || (t.Subject.LastName + " / " + t.Subject.FirstName).Contains(subjectInfo))
|
||||
// .WhereIf(param.StudyId != null, t => t.StudyId == param.StudyId)
|
||||
// .WhereIf(param.StartDate != null, t => t.OptTime >= param.StartDate)
|
||||
// .WhereIf(param.EndDate != null, t => t.OptTime <= param.EndDate)
|
||||
// .ProjectTo<AuditDTO>(_mapper.ConfigurationProvider);
|
||||
|
||||
|
||||
// return query.ToPagedList(param.PageIndex, param.PageSize, string.IsNullOrWhiteSpace(param.SortField) ? "OptTime" : param.SortField, param.Asc);
|
||||
|
||||
// }
|
||||
|
||||
// /// <summary> 查询系统日志信息 </summary>
|
||||
// [HttpPost]
|
||||
// public PageOutput<SystemLogDTO> GetLogList(QueryLogQueryDTO param)
|
||||
// {
|
||||
|
||||
// var LogCategory = param.LogCategory == null ? string.Empty : param.LogCategory.Trim();
|
||||
// var keyword = param.Keyword == null ? string.Empty : param.Keyword.Trim();
|
||||
// var logQueryable = _systemLogRepository
|
||||
// .WhereIf(param.BeginTime!=null,t=>t.RequestTime>= param.BeginTime)
|
||||
// .WhereIf(param.EndTime != null, t => t.RequestTime <= param.EndTime)
|
||||
// .WhereIf(!string.IsNullOrEmpty(LogCategory), t => t.LogCategory == param.LogCategory)
|
||||
// .WhereIf(!string.IsNullOrEmpty(keyword), t => t.Params.Contains(keyword) || t.Result.Contains(keyword))
|
||||
// .ProjectTo<SystemLogDTO>(_mapper.ConfigurationProvider);
|
||||
|
||||
// return logQueryable.ToPagedList(param.PageIndex, param.PageSize, string.IsNullOrWhiteSpace(param.SortField) ? "RequestTime" : param.SortField, param.Asc);
|
||||
|
||||
// }
|
||||
|
||||
// [HttpGet("{trialId:guid}")]
|
||||
// public List<OptUserDto> GetOptUserList(Guid trialId)
|
||||
// {
|
||||
// var list = _trialAuditRepository.Where(t => t.TrialId == trialId).Select(u => new OptUserDto()
|
||||
// {
|
||||
// OptUserId = u.OptUserId,
|
||||
// OptUser = u.OptUser
|
||||
// }).Distinct().ToList();
|
||||
|
||||
// return list;
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 审计列表 受试者下拉框 从受试者那里进去看的时候,这里需要固定,如果不采用下拉框,请传递指定格式的受试者信息查询才行
|
||||
// /// </summary>
|
||||
// /// <param name="trialId"></param>
|
||||
// /// <returns></returns>
|
||||
// [HttpGet("{trialId:guid}")]
|
||||
// public List<AuditSubjectSelectDto> GetSubjectList(Guid trialId)
|
||||
// {
|
||||
// var query = from trialAudit in _trialAuditRepository.Where(t => t.TrialId == trialId)
|
||||
// join subject in _subjectRepository.AsQueryable() on trialAudit.SubjectId equals subject.Id
|
||||
// select new AuditSubjectSelectDto()
|
||||
// {
|
||||
// SubjectCode = subject.Code,
|
||||
// SubjectId = trialAudit.SubjectId,
|
||||
// SubjectName = subject.LastName + " / " + subject.FirstName
|
||||
// };
|
||||
|
||||
// return query.Distinct().ToList();
|
||||
// }
|
||||
|
||||
// [NonDynamicMethod]
|
||||
// public IResponseOutput SaveLog2Db(SystemLogDTO input)
|
||||
// {
|
||||
// input.ClientIP = IPHelper.GetIP(_context?.HttpContext?.Request);
|
||||
|
||||
// _systemLogRepository.Add(_mapper.Map<SystemLog>(input));
|
||||
// var success = _systemLogRepository.SaveChanges();
|
||||
// return ResponseOutput.Result(success);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,231 @@
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using MailKit.Security;
|
||||
using MimeKit;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
public interface IMailVerificationService
|
||||
{
|
||||
Task SendMail(Guid userId, string userName, string emailAddress, int verificationCode);
|
||||
|
||||
Task AnolymousSendEmail(string emailAddress, int verificationCode);
|
||||
|
||||
Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode);
|
||||
}
|
||||
|
||||
public class MailVerificationService : IMailVerificationService
|
||||
{
|
||||
private readonly IRepository<VerificationCode> _verificationCodeRepository;
|
||||
|
||||
private readonly IRepository<SystemBasicData> _systemBasicDatarepository;
|
||||
|
||||
|
||||
public MailVerificationService(IRepository<VerificationCode> verificationCodeRepository, IRepository<SystemBasicData> systemBasicDatarepository)
|
||||
{
|
||||
_verificationCodeRepository = verificationCodeRepository;
|
||||
_systemBasicDatarepository = systemBasicDatarepository;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public async Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode)
|
||||
{
|
||||
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
|
||||
//收件地址
|
||||
messageToSend.To.Add(new MailboxAddress(userName, emailAddress));
|
||||
//主题
|
||||
messageToSend.Subject = "Reset PassWord (Verification Code)";
|
||||
|
||||
messageToSend.Body = new TextPart("plain")
|
||||
{
|
||||
Text = $@"Hey {userName},you are modify your email . The verification code is: {verificationCode}, which is valid within 3 minutes. If it is not your own operation, please ignore it!
|
||||
|
||||
-- GRR"
|
||||
};
|
||||
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
|
||||
{
|
||||
smtp.MessageSent += (sender, args) =>
|
||||
{
|
||||
// args.Response
|
||||
var code = verificationCode.ToString();
|
||||
_ = _verificationCodeRepository.AddAsync(new VerificationCode()
|
||||
{
|
||||
CodeType = 0,
|
||||
HasSend = true,
|
||||
Code = code,
|
||||
UserId = userId,
|
||||
ExpirationTime = DateTime.Now.AddMinutes(3)
|
||||
}).Result;
|
||||
_ = _verificationCodeRepository.SaveChangesAsync().Result;
|
||||
|
||||
};
|
||||
|
||||
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
|
||||
|
||||
await smtp.ConnectAsync("smtp.163.com", 25, SecureSocketOptions.StartTls);
|
||||
|
||||
await smtp.AuthenticateAsync("iracis_grr@163.com", "XLWVQKZAEKLDWOAH");
|
||||
|
||||
await smtp.SendAsync(messageToSend);
|
||||
|
||||
await smtp.DisconnectAsync(true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task SendMail(Guid userId, string userName, string emailAddress, int verificationCode)
|
||||
{
|
||||
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
|
||||
//收件地址
|
||||
messageToSend.To.Add(new MailboxAddress(userName, emailAddress));
|
||||
//主题
|
||||
messageToSend.Subject = "Reset PassWord (Verification Code)";
|
||||
|
||||
messageToSend.Body = new TextPart("plain")
|
||||
{
|
||||
Text = $@"Hey {userName},you are resetting your password via email. The verification code is: {verificationCode}, which is valid within 3 minutes. If it is not your own operation, please ignore it!
|
||||
|
||||
-- GRR"
|
||||
};
|
||||
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
|
||||
{
|
||||
smtp.MessageSent += (sender, args) =>
|
||||
{
|
||||
// args.Response
|
||||
var code = verificationCode.ToString();
|
||||
_= _verificationCodeRepository.AddAsync(new VerificationCode()
|
||||
{
|
||||
CodeType = 0,
|
||||
HasSend = true,
|
||||
Code = code,
|
||||
UserId = userId,
|
||||
ExpirationTime = DateTime.Now.AddMinutes(3)
|
||||
}).Result;
|
||||
_= _verificationCodeRepository.SaveChangesAsync().Result;
|
||||
|
||||
};
|
||||
|
||||
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
|
||||
|
||||
await smtp.ConnectAsync("smtp.163.com", 25, SecureSocketOptions.StartTls);
|
||||
|
||||
await smtp.AuthenticateAsync("iracis_grr@163.com", "XLWVQKZAEKLDWOAH");
|
||||
|
||||
await smtp.SendAsync(messageToSend);
|
||||
|
||||
await smtp.DisconnectAsync(true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task AnolymousSendEmail(string emailAddress, int verificationCode)
|
||||
{
|
||||
|
||||
|
||||
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
|
||||
//收件地址
|
||||
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
|
||||
//主题
|
||||
messageToSend.Subject = "GRR Site survey (Verification Code)";
|
||||
|
||||
messageToSend.Body = new TextPart("plain")
|
||||
{
|
||||
Text = $@"Hey ,you are login for site survey via email. The verification code is: {verificationCode}, which is valid within 3 minutes. If it is not your own operation, please ignore it!
|
||||
|
||||
-- GRR"
|
||||
};
|
||||
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
|
||||
{
|
||||
smtp.MessageSent += (sender, args) =>
|
||||
{
|
||||
// args.Response
|
||||
var code = verificationCode.ToString();
|
||||
_ = _verificationCodeRepository.AddAsync(new VerificationCode()
|
||||
{
|
||||
CodeType = 0,
|
||||
HasSend = true,
|
||||
Code = code,
|
||||
UserId = Guid.Empty,//此时不知道用户
|
||||
EmailOrPhone = emailAddress,
|
||||
ExpirationTime = DateTime.Now.AddMinutes(3)
|
||||
}).Result;
|
||||
_ = _verificationCodeRepository.SaveChangesAsync().Result;
|
||||
|
||||
};
|
||||
|
||||
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
|
||||
|
||||
await smtp.ConnectAsync("smtp.163.com", 25, SecureSocketOptions.StartTls);
|
||||
|
||||
await smtp.AuthenticateAsync("iracis_grr@163.com", "XLWVQKZAEKLDWOAH");
|
||||
|
||||
await smtp.SendAsync(messageToSend);
|
||||
|
||||
await smtp.DisconnectAsync(true);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SendEmailForExternalUser(string emailAddress, string verificationCode)
|
||||
{
|
||||
var messageToSend = new MimeMessage();
|
||||
//发件地址
|
||||
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
|
||||
//收件地址
|
||||
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
|
||||
//主题
|
||||
messageToSend.Subject = "GRR External User survey (Verification Code)";
|
||||
|
||||
messageToSend.Body = new TextPart("plain")
|
||||
{
|
||||
Text = $@"Hey ,you are login for site survey via email. The verification code is: {verificationCode}, If it is not your own operation, please ignore it!
|
||||
|
||||
-- GRR"
|
||||
};
|
||||
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
|
||||
{
|
||||
smtp.MessageSent += (sender, args) =>
|
||||
{
|
||||
// args.Response
|
||||
var code = verificationCode.ToString();
|
||||
_ = _verificationCodeRepository.AddAsync(new VerificationCode()
|
||||
{
|
||||
CodeType = 0,
|
||||
HasSend = true,
|
||||
Code = code,
|
||||
UserId = Guid.Empty,//此时不知道用户
|
||||
EmailOrPhone = emailAddress,
|
||||
ExpirationTime = DateTime.Now.AddMinutes(3)
|
||||
}).Result;
|
||||
_ = _verificationCodeRepository.SaveChangesAsync().Result;
|
||||
|
||||
};
|
||||
|
||||
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
|
||||
|
||||
await smtp.ConnectAsync("smtp.163.com", 25, SecureSocketOptions.StartTls);
|
||||
|
||||
await smtp.AuthenticateAsync("iracis_grr@163.com", "XLWVQKZAEKLDWOAH");
|
||||
|
||||
await smtp.SendAsync(messageToSend);
|
||||
|
||||
await smtp.DisconnectAsync(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-02-15 15:57:21
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
namespace IRaCIS.Core.Application.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// SystemBasicDataService
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "Common")]
|
||||
public class SystemBasicDataService : BaseService, ISystemBasicDataService
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 模板列表
|
||||
/// </summary>
|
||||
/// <param name="querySystemBasicData"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<SystemBasicDataView>> GetSystemBasicDataList(SystemBasicDataQuery querySystemBasicData)
|
||||
{
|
||||
var systemBasicDataQueryable = _repository.GetQueryable<SystemBasicData>().Where(t => t.ParentId == null)
|
||||
.ProjectTo<SystemBasicDataView>(_mapper.ConfigurationProvider);
|
||||
|
||||
return await systemBasicDataQueryable.ToPagedListAsync(querySystemBasicData.PageIndex, querySystemBasicData.PageSize, String.IsNullOrEmpty(querySystemBasicData.SortField) ? "Code" : querySystemBasicData.SortField, querySystemBasicData.Asc);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("{code}")]
|
||||
public async Task<SystemBasicDataView> GetSystemBasicData(string code)
|
||||
{
|
||||
return await _repository.Where<SystemBasicData>(t => t.Code == code).ProjectTo<SystemBasicDataView>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 模板关联的场景
|
||||
/// </summary>
|
||||
/// <param name="parentId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{parentId:guid}")]
|
||||
public async Task<List<SystemBasicDataView>> GetChildList(Guid parentId)
|
||||
{
|
||||
return await _repository.GetQueryable<SystemBasicData>().Where(t => t.ParentId == parentId&&t.IsEnable).OrderBy(t => t.Code).ProjectTo<SystemBasicDataView>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
public async Task<IResponseOutput> AddOrUpdateSystemBasicData(SystemBasicDataAddOrEdit addOrEditSystemBasicData)
|
||||
{
|
||||
|
||||
var entity = await _repository.InsertOrUpdateAsync<SystemBasicData, SystemBasicDataAddOrEdit>(addOrEditSystemBasicData, true);
|
||||
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[HttpDelete("{systemBasicDataId:guid}")]
|
||||
public async Task<IResponseOutput> DeleteSystemBasicData(Guid systemBasicDataId)
|
||||
{
|
||||
var success = await _repository.DeleteFromQueryAsync<SystemBasicData>(t => t.Id == systemBasicDataId);
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 传递父亲Code 数组 返回多个下拉框数据
|
||||
/// </summary>
|
||||
/// <param name="searchArray"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<Dictionary<string, List<SystemBasicDataSelect>>> GetBasicDataSelect(string[] searchArray)
|
||||
{
|
||||
|
||||
var searchList = await _repository.GetQueryable<SystemBasicData>().Where(t => searchArray.Contains(t.Parent.Code) && t.ParentId != null).ProjectTo<SystemBasicDataSelect>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
return searchList.GroupBy(t => t.ParentCode).ToDictionary(g => g.Key, g => g.ToList());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using AutoMapper;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
public class CommonConfig : Profile
|
||||
{
|
||||
public CommonConfig()
|
||||
{
|
||||
CreateMap<Message, SysMessageDTO>()
|
||||
.ForMember(o => o.MessageTime, t => t.MapFrom(u => u.MessageTime.ToString()));
|
||||
|
||||
CreateMap<SystemLog, SystemLogDTO>();
|
||||
|
||||
CreateMap<SystemLogDTO, SystemLog>();
|
||||
|
||||
|
||||
|
||||
CreateMap<EmailNoticeConfigAddOrEdit, EmailNoticeConfig>().ReverseMap();
|
||||
CreateMap<EmailNoticeConfig, EmailNoticeConfigView>();
|
||||
|
||||
|
||||
CreateMap<SystemBasicData, SystemBasicDataView>();
|
||||
|
||||
CreateMap<SystemBasicData, SystemBasicDataSelect>()
|
||||
.ForMember(o => o.ParentCode, t => t.MapFrom(u => u.Parent.Code));
|
||||
|
||||
CreateMap<SystemBasicDataAddOrEdit, SystemBasicData>().ReverseMap();
|
||||
|
||||
|
||||
|
||||
CreateMap<Dictionary, BasicDicView>()
|
||||
.ForMember(o => o.ConfigType, t => t.MapFrom(u => u.ConfigDictionary.Code))
|
||||
.ForMember(o => o.ConfigTypeDes, t => t.MapFrom(u => u.ConfigDictionary.Description));
|
||||
|
||||
CreateMap<AddOrEditBasicDic, Dictionary>().ReverseMap();
|
||||
|
||||
|
||||
CreateMap<Dictionary, BasicDicSelect>()
|
||||
.ForMember(o => o.ParentCode, t => t.MapFrom(u => u.Parent.Code));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// 医生文档关联关系维护
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "Reviewer")]
|
||||
public class AttachmentService : BaseService, IAttachmentService
|
||||
{
|
||||
private readonly IRepository<Attachment> attachmentrepository;
|
||||
|
||||
public AttachmentService(IRepository<Attachment> attachmentrepository)
|
||||
{
|
||||
this.attachmentrepository = attachmentrepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除附件
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public async Task<IResponseOutput> DeleteAttachment([FromBody]AttachementCommand param)
|
||||
{
|
||||
//var attachment = _doctorAttachmentApp.GetDetailById(id);
|
||||
//string file = HostingEnvironment.MapPath(attachment.Path);
|
||||
|
||||
//if (File.Exists(file))
|
||||
//{
|
||||
// File.Delete(file);
|
||||
//}
|
||||
//var temp = HostingEnvironment.MapPath(param.Path);
|
||||
//if (File.Exists(temp))
|
||||
//{
|
||||
// File.Delete(temp);
|
||||
//}
|
||||
|
||||
var success =await attachmentrepository.DeleteFromQueryAsync(a => a.Id == param.Id);
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据医生Id 和 附件类型,获取记录
|
||||
/// </summary>
|
||||
/// <param name="doctorId">医生Id</param>
|
||||
/// <param name="type">附件类型</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{doctorId:guid}/{type}")]
|
||||
public async Task<IEnumerable<AttachmentDTO>> GetAttachmentByType(Guid doctorId, string type)
|
||||
{
|
||||
var attachmentList = await attachmentrepository.Where(a => a.DoctorId == doctorId && a.Type.Equals(type)).ProjectTo<AttachmentDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
attachmentList.ForEach(t => t.FullPath = t.Path + "?access_token=" + _userInfo.UserToken);
|
||||
|
||||
return attachmentList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取单个医生的多种证书附件
|
||||
/// </summary>
|
||||
/// <param name="doctorId">医生Id</param>
|
||||
/// <param name="types">类型数组</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{doctorId:guid}")]
|
||||
public async Task<IEnumerable<AttachmentDTO>> GetAttachmentByTypes(Guid doctorId, string[] types)
|
||||
{
|
||||
|
||||
var attachmentList =await attachmentrepository.Where(a => a.DoctorId == doctorId && types.Contains(a.Type)).OrderBy(s => s.Type).ThenBy(m => m.CreateTime).ProjectTo<AttachmentDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
attachmentList.ForEach(t => t.FullPath = t.Path + "?access_token=" + _userInfo.UserToken);
|
||||
|
||||
return attachmentList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据医生Id获取医生附件
|
||||
/// </summary>
|
||||
/// <param name="doctorId">医生Id</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{doctorId:guid}")]
|
||||
public async Task<IEnumerable<AttachmentDTO>> GetAttachments(Guid doctorId)
|
||||
{
|
||||
var attachmentList =await attachmentrepository.Where(a => a.DoctorId == doctorId).OrderBy(s => s.Type).ThenBy(m => m.CreateTime).ProjectTo<AttachmentDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
attachmentList.ForEach(t => t.FullPath = t.Path + "?access_token=" + _userInfo.UserToken);
|
||||
|
||||
return attachmentList;
|
||||
}
|
||||
|
||||
[NonDynamicMethod]
|
||||
public async Task<AttachmentDTO> GetDetailById(Guid attachmentId)
|
||||
{
|
||||
var attachment = await attachmentrepository.FirstOrDefaultAsync(a => a.Id == attachmentId).IfNullThrowException();
|
||||
var temp= _mapper.Map<AttachmentDTO>(attachment);
|
||||
temp.FullPath = temp.Path + "?access_token=" + _userInfo.UserToken;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存多个附件
|
||||
/// </summary>
|
||||
/// <param name="attachmentList"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<AttachmentDTO>> SaveAttachments(IEnumerable<AttachmentDTO> attachmentList)
|
||||
{
|
||||
var attachments = _mapper.Map<IEnumerable<Attachment>>(attachmentList).ToList();
|
||||
|
||||
//1 是中文 2是英文 中英文第一份简历默认设置为官方
|
||||
|
||||
var zhCount = attachments.Count(t => t.Language == 1);
|
||||
var usCount = attachments.Count(t => t.Language == 2);
|
||||
|
||||
if (zhCount == 1)
|
||||
{
|
||||
var k = attachments.First(t => t.Language == 1);
|
||||
k.IsOfficial = true;
|
||||
}
|
||||
if (usCount == 1)
|
||||
{
|
||||
var k = attachments.First(t => t.Language == 2);
|
||||
k.IsOfficial = true;
|
||||
}
|
||||
|
||||
|
||||
//处理重传
|
||||
var reUpload = attachmentList.FirstOrDefault(t => t.ReUpload == true);
|
||||
if (reUpload != null)
|
||||
{
|
||||
//因为界面现实的列表用了 接口返回的列表,所以要把返回的模型对应的字段也要更改
|
||||
var attach = attachments.First(t => t.Id == reUpload.Id);
|
||||
attach.CreateTime = DateTime.Now;
|
||||
|
||||
|
||||
//重传的时候,发现 相同语言的官方简历数量为2 那么将重传的简历设置为非官方
|
||||
if (attachments.Count(t => t.Language == reUpload.Language && t.IsOfficial) == 2)
|
||||
{
|
||||
await attachmentrepository.UpdateFromQueryAsync(t => t.Id == reUpload.Id, u => new Attachment()
|
||||
{
|
||||
Path = reUpload.Path,
|
||||
CreateTime = DateTime.Now,
|
||||
Language = reUpload.Language,
|
||||
IsOfficial = false
|
||||
});
|
||||
attach.IsOfficial = false;
|
||||
}
|
||||
else //相同语言的重传
|
||||
{
|
||||
await attachmentrepository.UpdateFromQueryAsync(t => t.Id == reUpload.Id, u => new Attachment()
|
||||
{
|
||||
Path = reUpload.Path,
|
||||
CreateTime = DateTime.Now,
|
||||
Language = reUpload.Language
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
var newAttachment = attachments.Where(t => t.Id == Guid.Empty);
|
||||
|
||||
await _repository.AddRangeAsync(newAttachment);
|
||||
await _repository.SaveChangesAsync();
|
||||
|
||||
//_doctorAttachmentRepository.AddRange(newAttachment);
|
||||
//_doctorAttachmentRepository.SaveChanges();
|
||||
|
||||
var list = _mapper.Map<IEnumerable<AttachmentDTO>>(attachments).ToList();
|
||||
|
||||
list.ForEach(t => t.FullPath = t.Path + "?access_token=" + _userInfo.UserToken);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public async Task<IResponseOutput<AttachmentDTO>> AddAttachment(AttachmentDTO attachment)
|
||||
{
|
||||
|
||||
var newAttachment = _mapper.Map<Attachment>(attachment);
|
||||
//如果这个医生不存在 这个语言的官方简历 就设置为官方简历
|
||||
if (! await attachmentrepository.AnyAsync(t => t.Type == "Resume" && t.DoctorId == attachment.DoctorId && t.Language == attachment.Language && t.IsOfficial))
|
||||
{
|
||||
newAttachment.IsOfficial = true;
|
||||
|
||||
attachment.IsOfficial = true;
|
||||
}
|
||||
|
||||
await _repository.AddAsync(newAttachment);
|
||||
var success = await _repository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(success, attachment);
|
||||
}
|
||||
|
||||
|
||||
[NonDynamicMethod]
|
||||
public async Task<string> GetDoctorOfficialCV(int language, Guid doctorId)
|
||||
{
|
||||
var result = await attachmentrepository.FirstOrDefaultAsync(a => a.DoctorId == doctorId &&
|
||||
a.IsOfficial && a.Type.Equals("Resume") && a.Language == language);
|
||||
if (result != null)
|
||||
{
|
||||
return result.Path;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 将简历设置为官方简历
|
||||
/// </summary>
|
||||
/// <param name="doctorId"></param>
|
||||
/// <param name="attachmentId"></param>
|
||||
/// <param name="language"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
[HttpPost("{doctorId:guid}/{attachmentId:guid}/{language}")]
|
||||
public async Task<IResponseOutput> SetOfficial(Guid doctorId, Guid attachmentId, int language)
|
||||
{
|
||||
var resumeList = await _repository.GetQueryable<Attachment>().Where(t => t.DoctorId == doctorId && t.Type == "Resume" && t.Language == language).ToListAsync();
|
||||
foreach (var item in resumeList)
|
||||
{
|
||||
if (item.Id == attachmentId) item.IsOfficial = true;
|
||||
else item.IsOfficial = false;
|
||||
await _repository.UpdateAsync(item);
|
||||
}
|
||||
|
||||
return ResponseOutput.Result(await _repository.SaveChangesAsync());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置简历的语言类型
|
||||
/// </summary>
|
||||
/// <param name="doctorId"></param>
|
||||
/// <param name="attachmentId"></param>
|
||||
/// <param name="language">0-未设置,1-中文,2-英文</param>
|
||||
/// <returns></returns>
|
||||
|
||||
[HttpPost("{doctorId:guid}/{attachmentId:guid}/{language}")]
|
||||
public async Task<IResponseOutput> SetLanguage(Guid doctorId, Guid attachmentId, int language)
|
||||
{
|
||||
bool result =await attachmentrepository.UpdateFromQueryAsync(t => t.Id == attachmentId, a => new Attachment
|
||||
{
|
||||
Language = language,
|
||||
IsOfficial = false
|
||||
});
|
||||
return ResponseOutput.Result(result);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class AttachmentDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid DoctorId { get; set; }
|
||||
public bool IsOfficial { get; set; }
|
||||
public string Type { get; set; } = string.Empty;
|
||||
public string Path { get; set; } = string.Empty;
|
||||
public string FullPath { get; set; } = string.Empty;
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
public DateTime? CreateTime { get; set; }
|
||||
public int Language { get; set; }
|
||||
|
||||
public bool ReUpload { get; set; } = false;
|
||||
}
|
||||
|
||||
public class ReviewerAckDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid DoctorId { get; set; }
|
||||
public string Type { get; set; } = string.Empty;
|
||||
public string Path { get; set; } = string.Empty;
|
||||
public string FullPath => Path;
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public class TrialSOWPathDTO
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public string SowName { get; set; } = string.Empty;
|
||||
public string SowPath { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class DeleteSowPathDTO
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
public string Path { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
|
||||
public class UploadAgreementAttachmentDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public Guid DoctorId { get; set; }
|
||||
public string Type { get; set; } = string.Empty;
|
||||
public string Path { get; set; } = string.Empty;
|
||||
public string FullPath => Path;
|
||||
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class AttachementCommand
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Path { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class DoctorAccountRegisterModel : DoctorAccountLoginDTO
|
||||
{
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
public string LastName { get; set; } = string.Empty;
|
||||
public string EMail { get; set; } = string.Empty;
|
||||
public DateTime RegisterTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,665 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using Newtonsoft.Json;
|
||||
using System.Linq;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
|
||||
#region 医生管理列表
|
||||
|
||||
public class DoctorDTO
|
||||
{
|
||||
|
||||
[JsonIgnore]
|
||||
public List<DicView> DictionaryList { get; set; } = new List<DicView>();
|
||||
|
||||
|
||||
|
||||
//临床实践中使用的模式
|
||||
public List<string> ReadingTypeList => DictionaryList.Where(t => t.ParentCode == StaticData.ReadingType).OrderBy(t => t.ShowOrder).Select(t => t.Value).ToList();
|
||||
public List<string> ReadingTypeCNList => DictionaryList.Where(t => t.ParentCode == StaticData.ReadingType).OrderBy(t => t.ShowOrder).Select(t => t.ValueCN).ToList();
|
||||
|
||||
public List<Guid> ReadingTypeIds => DictionaryList.Where(t => t.ParentCode == StaticData.ReadingType).OrderBy(t => t.ShowOrder).Select(t => t.Id).ToList();
|
||||
|
||||
|
||||
//第二专业
|
||||
public List<string> SubspecialityList => DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).OrderBy(t => t.ShowOrder).Select(t => t.Value).ToList();
|
||||
|
||||
public List<string> SubspecialityCNList => DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).OrderBy(t => t.ShowOrder).Select(t => t.ValueCN).ToList();
|
||||
|
||||
public List<Guid> SubspecialityIds => DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).OrderBy(t => t.ShowOrder).Select(t => t.Id).ToList();
|
||||
|
||||
|
||||
|
||||
public string ReadingTypeOther { get; set; } = String.Empty;
|
||||
public string ReadingTypeOtherCN { get; set; } = String.Empty;
|
||||
|
||||
public Guid Id { get; set; }
|
||||
public DateTime CreateTime { get; set; }
|
||||
public string ReviewerCode { get; set; } = String.Empty;//GUID
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
public string LastName { get; set; } = string.Empty;
|
||||
public string ChineseName { get; set; } = string.Empty;
|
||||
public List<Guid> TitleIdList { get; set; } = new List<Guid>();
|
||||
public List<string> TitleList { get; set; } = new List<string>();
|
||||
public List<string> TitleCNList { get; set; } = new List<string>();
|
||||
public string Phone { get; set; } = string.Empty;
|
||||
public string Introduction { get; set; } = string.Empty;
|
||||
public string EMail { get; set; } = string.Empty;
|
||||
public string WeChat { get; set; } = string.Empty;
|
||||
|
||||
//部门
|
||||
public string Department { get; set; } = string.Empty;
|
||||
public string DepartmentCN { get; set; } = string.Empty;
|
||||
public Guid? DepartmentId { get; set; }
|
||||
public string DepartmentOther { get; set; } = String.Empty;
|
||||
public string DepartmentOtherCN { get; set; } = String.Empty;
|
||||
|
||||
//增加的
|
||||
public Guid? SpecialityId { get; set; } = Guid.Empty;
|
||||
public string Speciality { get; set; } = string.Empty;
|
||||
public string SpecialityCN { get; set; } = string.Empty;
|
||||
public string SpecialityOther { get; set; } = string.Empty;
|
||||
public string SpecialityOtherCN { get; set; } = string.Empty;
|
||||
|
||||
//职称
|
||||
public string Rank { get; set; } = string.Empty;
|
||||
public string RankCN { get; set; } = string.Empty;
|
||||
public Guid? RankId { get; set; }
|
||||
public string RankOther { get; set; } = String.Empty;
|
||||
public string RankOtherCN { get; set; } = String.Empty;
|
||||
|
||||
//职位
|
||||
public string Position { get; set; } = string.Empty;
|
||||
public string PositionCN { get; set; } = string.Empty;
|
||||
public Guid? PositionId { get; set; }
|
||||
public string PositionOther { get; set; } = String.Empty;
|
||||
public string PositionOtherCN { get; set; } = String.Empty;
|
||||
|
||||
|
||||
|
||||
|
||||
public string SubspecialityOther { get; set; } = String.Empty;
|
||||
public string SubspecialityOtherCN { get; set; } = String.Empty;
|
||||
|
||||
public int GCP { get; set; }
|
||||
public Guid? GCPId { get; set; }
|
||||
public string ResumePath { get; set; } = string.Empty;
|
||||
public bool HasResume
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public bool Reconfirmed { get; set; }
|
||||
public int CooperateStatus { get; set; }
|
||||
public int ResumeStatus { get; set; }
|
||||
public bool AcceptingNewTrial { get; set; } = false;
|
||||
public bool ActivelyReading { get; set; } = false;
|
||||
|
||||
//医院
|
||||
|
||||
public Guid? HospitalId { get; set; }
|
||||
public string HospitalOther { get; set; } = String.Empty;
|
||||
public string HospitalName { get; set; } = string.Empty;
|
||||
public string City { get; set; } = String.Empty;
|
||||
public string Country { get; set; } = String.Empty;
|
||||
|
||||
public string HospitalNameCN { get; set; } = string.Empty;
|
||||
public string CityCN { get; set; } = String.Empty;
|
||||
public string CountryCN { get; set; } = String.Empty;
|
||||
|
||||
|
||||
public int? Reading { get; set; }
|
||||
public int? Approved { get; set; }
|
||||
public int? Submitted { get; set; }
|
||||
|
||||
public int? Finished { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reviewer 列表查询参数
|
||||
/// </summary>
|
||||
|
||||
public class DoctorSearchDTO : PageInput
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public List<Guid> ReadingTypeIdList { get; set; } = new List<Guid>();
|
||||
public List<Guid> SubspecialityIdList { get; set; } = new List<Guid>();
|
||||
|
||||
public List<Guid> EvaluationCriteriaIdList { get; set; } = new List<Guid>();
|
||||
|
||||
public List<Guid> TitleIdList { get; set; } = new List<Guid>();
|
||||
public Guid? DepartmentId { get; set; }
|
||||
public Guid? SpecialityId { get; set; }
|
||||
public Guid? PositionId { get; set; }
|
||||
public Guid? RankId { get; set; }
|
||||
public Guid? HospitalId { get; set; }
|
||||
|
||||
//合作状态
|
||||
public ContractorStatusEnum? ContractorStatus { get; set; }
|
||||
|
||||
// 简历审核状态
|
||||
public ResumeStatusEnum? InformationConfirmed { get; set; }
|
||||
public int? EnrollStatus { get; set; } //入组状态
|
||||
|
||||
public bool? AcceptingNewTrial { get; set; }//是否接受新的项目
|
||||
public bool? ActivelyReading { get; set; }// 是否接受新的读片任务
|
||||
public int? Nation { get; set; }// 0-中国医生,2-美国医生,3-全部
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 入组 Selection 列表查询参数
|
||||
/// </summary>
|
||||
public class ReviewerSelectionQueryDTO : DoctorSearchDTO
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
}
|
||||
|
||||
public class ReviewerSubmissionQueryDTO : PageInput
|
||||
{
|
||||
public Guid TrialId { get; set; } = Guid.Empty;
|
||||
public int IntoGroupSearchState { get; set; }
|
||||
}
|
||||
|
||||
public class ReviewerConfirmationQueryDTO : PageInput
|
||||
{
|
||||
public Guid TrialId { get; set; } = Guid.Empty;
|
||||
}
|
||||
|
||||
public class SelectionReviewerDTO : DoctorDTO
|
||||
{
|
||||
public int DoctorTrialState { get; set; }
|
||||
public string OptUserName { get; set; } = string.Empty;
|
||||
public DateTime? OptTime { get; set; }
|
||||
public string? OptTimeStr => OptTime?.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
public class DoctorOptDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Code { get; set; } = String.Empty;//GUID
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
public string LastName { get; set; } = string.Empty;
|
||||
public string ChineseName { get; set; } = string.Empty;
|
||||
|
||||
public string City { get; set; } = string.Empty;
|
||||
public string HospitalName { get; set; } = string.Empty;
|
||||
public string Country { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public class ConfirmationReviewerDTO : DoctorOptDTO
|
||||
{
|
||||
public int DoctorTrialState { get; set; }
|
||||
public string OptUserName { get; set; } = string.Empty;
|
||||
public DateTime? OptTime { get; set; }
|
||||
public string? OptTimeStr => OptTime?.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
public class DoctorStateModelDTO
|
||||
{
|
||||
public Guid DoctorId { get; set; }
|
||||
public int IntoGroupState { get; set; }
|
||||
public string OptUserName { get; set; } = String.Empty;
|
||||
public DateTime? OptTime { get; set; }
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public class DoctorDetailDTO
|
||||
{
|
||||
public DoctorBasicInfoDTO BasicInfoView { get; set; }
|
||||
public EmploymentDTO EmploymentView { get; set; }
|
||||
public SpecialtyDTO SpecialtyView { get; set; }
|
||||
public IEnumerable<EducationInfoViewModel> EducationList { get; set; }
|
||||
public IEnumerable<PostgraduateViewModel> PostgraduateList { get; set; }
|
||||
public ResearchPublicationDTO ResearchPublicationView { get; set; }
|
||||
public TrialExperienceModel TrialExperienceView { get; set; }
|
||||
public ResumeConfirmDTO AuditView { get; set; }
|
||||
public IEnumerable<AttachmentDTO> AttachmentList { get; set; }
|
||||
|
||||
public List<SowDTO> SowList { get; set; }
|
||||
public List<SowDTO> AckSowList { get; set; }
|
||||
|
||||
public DoctorEnrollInfoDTO IntoGroupInfo { get; set; }
|
||||
|
||||
public bool InHoliday { get; set; }
|
||||
public DoctorDetailDTO()
|
||||
{
|
||||
BasicInfoView = new DoctorBasicInfoDTO();
|
||||
EmploymentView = new EmploymentDTO();
|
||||
SpecialtyView = new SpecialtyDTO();
|
||||
EducationList = new List<EducationInfoViewModel>();
|
||||
PostgraduateList = new List<PostgraduateViewModel>();
|
||||
ResearchPublicationView = new ResearchPublicationDTO();
|
||||
TrialExperienceView = new TrialExperienceModel();
|
||||
AuditView = new ResumeConfirmDTO();
|
||||
AttachmentList = new List<AttachmentDTO>();
|
||||
IntoGroupInfo = new DoctorEnrollInfoDTO();
|
||||
SowList = new List<SowDTO>();
|
||||
AckSowList = new List<SowDTO>();
|
||||
}
|
||||
}
|
||||
|
||||
public class DoctorEnrollInfoDTO
|
||||
{
|
||||
public Guid? DoctorId { get; set; }
|
||||
public int? Submitted { get; set; }
|
||||
public int? Approved { get; set; }
|
||||
public int? Reading { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region 基本信息模型
|
||||
|
||||
public class DoctorBasicInfo
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string ReviewerCode { get; set; } = string.Empty;
|
||||
public string FirstName { get; set; } = String.Empty;
|
||||
public string LastName { get; set; } = String.Empty;
|
||||
public string ChineseName { get; set; } = String.Empty;
|
||||
public int Sex { get; set; }
|
||||
public string Phone { get; set; } = String.Empty;
|
||||
public string Introduction { get; set; } = String.Empty;
|
||||
public string EMail { get; set; } = String.Empty;
|
||||
public string WeChat { get; set; } = String.Empty;
|
||||
public int Nation { get; set; }
|
||||
}
|
||||
|
||||
public class DoctorBasicInfoCommand : DoctorBasicInfo
|
||||
{
|
||||
|
||||
//职称
|
||||
public List<Guid> TitleIds { get; set; } = new List<Guid>();
|
||||
}
|
||||
|
||||
public class TempObj
|
||||
{
|
||||
public int ShowOrder { get; set; }
|
||||
public Guid TitleId { get; set; }
|
||||
public string TitleCN { get; set; } = string.Empty;
|
||||
public string Title { get; set; } = string.Empty;
|
||||
}
|
||||
public class DicView
|
||||
{
|
||||
public int ShowOrder { get; set; }
|
||||
public Guid Id { get; set; }
|
||||
public string ValueCN { get; set; } = string.Empty;
|
||||
public string ParentCode { get; set; } = string.Empty;
|
||||
|
||||
|
||||
public string Value { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public class DoctorBasicInfoDTO : DoctorBasicInfo
|
||||
{
|
||||
public List<DicView> DoctorDicViewDtos = new List<DicView>();
|
||||
|
||||
//职称
|
||||
public List<Guid> TitleIds => DoctorDicViewDtos.Select(t => t.Id).ToList();
|
||||
|
||||
public List<string> TitleList=> DoctorDicViewDtos.Select(t => t.Value).ToList();
|
||||
|
||||
public List<string> TitleCNList=> DoctorDicViewDtos.Select(t => t.ValueCN).ToList();
|
||||
|
||||
#region ef select
|
||||
//[JsonIgnore]
|
||||
//public List<TempObj> TempObjList { get; set; }
|
||||
////职称
|
||||
//public List<Guid> TitleIds
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// if (TempObjList.Count > 0)
|
||||
// {
|
||||
// return TempObjList.Select(t => t.TitleId).ToList();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return new List<Guid>();
|
||||
// }
|
||||
// }
|
||||
|
||||
//}
|
||||
//public List<string> TitleList
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// if (TempObjList.Count > 0)
|
||||
// {
|
||||
// return TempObjList.Select(t => t.Title).ToList();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return new List<string>();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//public List<string> TitleCNList
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// if (TempObjList.Count > 0)
|
||||
// {
|
||||
// return TempObjList.Select(t => t.TitleCN).ToList();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return new List<string>();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class SowDTO
|
||||
{
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
public string TrialCode { get; set; } = string.Empty;
|
||||
public string FilePath { get; set; } = string.Empty;
|
||||
public string FullPath { get { return FilePath; } }
|
||||
public DateTime CreateTime { get; set; }
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 工作信息模型
|
||||
|
||||
|
||||
//public class DoctorHospitalView
|
||||
//{
|
||||
// public string HospitalName { get; set; }
|
||||
// public string UniversityAffiliated { get; set; }
|
||||
// public string Country { get; set; }
|
||||
// public string Province { get; set; }
|
||||
// public string City { get; set; }
|
||||
|
||||
// public string HospitalNameCN { get; set; }
|
||||
|
||||
// public string UniversityAffiliatedCN { get; set; }
|
||||
// public string CountryCN { get; set; }
|
||||
|
||||
// public string ProvinceCN { get; set; }
|
||||
|
||||
// public string CityCN { get; set; }
|
||||
//}
|
||||
|
||||
public class EmploymentDTO : EmploymentInfo
|
||||
{
|
||||
//public DoctorHospitalView Hospital { get; set; }
|
||||
|
||||
public string Department { get; set; } = String.Empty;
|
||||
|
||||
public string Rank { get; set; } = String.Empty;
|
||||
|
||||
public string Position { get; set; } = String.Empty;
|
||||
|
||||
#region 医院信息
|
||||
public string HospitalName { get; set; } = String.Empty;
|
||||
|
||||
public string UniversityAffiliated { get; set; } = String.Empty;
|
||||
public string Country { get; set; } = String.Empty;
|
||||
|
||||
public string Province { get; set; } = String.Empty;
|
||||
|
||||
public string City { get; set; } = String.Empty;
|
||||
|
||||
#endregion
|
||||
|
||||
public string DepartmentCN { get; set; } = String.Empty;
|
||||
|
||||
public string RankCN { get; set; } = String.Empty;
|
||||
|
||||
public string PositionCN { get; set; } = String.Empty;
|
||||
|
||||
|
||||
public string HospitalNameCN { get; set; } = String.Empty;
|
||||
|
||||
public string UniversityAffiliatedCN { get; set; } = String.Empty;
|
||||
public string CountryCN { get; set; } = String.Empty;
|
||||
|
||||
public string ProvinceCN { get; set; } = String.Empty;
|
||||
|
||||
public string CityCN { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
public class EmploymentCommand : EmploymentInfo
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EmploymentInfo
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
//部门
|
||||
public Guid? DepartmentId { get; set; } = Guid.Empty;
|
||||
public string DepartmentOther { get; set; } = string.Empty;
|
||||
public string DepartmentOtherCN { get; set; } = string.Empty;
|
||||
//职称
|
||||
public Guid? RankId { get; set; } = Guid.Empty;
|
||||
public string RankOther { get; set; } = string.Empty;
|
||||
public string RankOtherCN { get; set; } = string.Empty;
|
||||
//职位 主席 副主席
|
||||
public Guid? PositionId { get; set; } = Guid.Empty;
|
||||
public string PositionOther { get; set; } = string.Empty;
|
||||
public string PositionOtherCN { get; set; } = string.Empty;
|
||||
|
||||
public Guid? HospitalId { get; set; } = Guid.Empty;
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Specialty模型
|
||||
public class SpecialtyDTO : SpecialtyCommand
|
||||
{
|
||||
[JsonIgnore]
|
||||
public List<DicView> DictionaryList { get; set; } = new List<DicView>();
|
||||
|
||||
public string Speciality { get; set; } = string.Empty;
|
||||
|
||||
|
||||
//临床实践中使用的模式
|
||||
public new List<Guid> ReadingTypeIds
|
||||
{
|
||||
get
|
||||
{
|
||||
if (DictionaryList.Count > 0)
|
||||
{
|
||||
return DictionaryList.Where(t => t.ParentCode == StaticData.ReadingType).Select(t => t.Id).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<Guid>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public new List<Guid> SubspecialityIds
|
||||
{
|
||||
get
|
||||
{
|
||||
if (DictionaryList.Count > 0)
|
||||
{
|
||||
return DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).Select(t => t.Id).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<Guid>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public List<string> ReadingTypeList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (DictionaryList.Count > 0)
|
||||
{
|
||||
return DictionaryList.Where(t => t.ParentCode == StaticData.ReadingType).Select(t => t.Value).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public List<string> SubspecialityList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (DictionaryList.Count > 0)
|
||||
{
|
||||
return DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).Select(t => t.Value).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<string> ReadingTypeCNList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (DictionaryList.Count > 0)
|
||||
{
|
||||
return DictionaryList.Where(t => t.ParentCode == StaticData.ReadingType).Select(t => t.ValueCN).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public List<string> SubspecialityCNList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (DictionaryList.Count > 0)
|
||||
{
|
||||
return DictionaryList.Where(t => t.ParentCode == StaticData.Subspeciality).Select(t => t.ValueCN).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class SpecialtyCommand
|
||||
{
|
||||
public List<Guid> ReadingTypeIds { get; set; } = new List<Guid>();
|
||||
|
||||
public List<Guid> SubspecialityIds { get; set; } = new List<Guid>();
|
||||
|
||||
public Guid Id { get; set; }
|
||||
public string OtherSkills { get; set; } = string.Empty;
|
||||
|
||||
public string ReadingTypeOther { get; set; } = string.Empty;
|
||||
public string ReadingTypeOtherCN { get; set; } = string.Empty;
|
||||
//亚专科
|
||||
|
||||
public string SubspecialityOther { get; set; } = string.Empty;
|
||||
public string SubspecialityOtherCN { get; set; } = string.Empty;
|
||||
|
||||
public Guid? SpecialityId { get; set; } = Guid.Empty;
|
||||
public string SpecialityCN { get; set; } = string.Empty;
|
||||
public string SpecialityOther { get; set; } = string.Empty;
|
||||
public string SpecialityOtherCN { get; set; } = string.Empty;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region 医生账户
|
||||
public class DoctorAccountLoginDTO
|
||||
{
|
||||
public string Phone { get; set; } = String.Empty;
|
||||
public string Password { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
public class DoctorAccountDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string FirstName { get; set; } = String.Empty;
|
||||
public string LastName { get; set; } = String.Empty;
|
||||
public string Phone { get; set; } = String.Empty;
|
||||
public string PhotoPath { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
public class DoctorAccountUpdatePasswordCommand
|
||||
{
|
||||
public string Phone { get; set; } = String.Empty;
|
||||
public string OldPassword { get; set; } = String.Empty;
|
||||
public string NewPassword { get; set; } = String.Empty;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 审核模型
|
||||
|
||||
public class ResumeConfirmCommand
|
||||
{
|
||||
//int userId, int doctorId, int status, string memo
|
||||
//public Guid FromUserId { get; set; }
|
||||
public Guid Id { get; set; }
|
||||
public ResumeStatusEnum ResumeStatus { get; set; }
|
||||
public int ReviewStatus { get; set; }
|
||||
public bool AcceptingNewTrial { get; set; } = false;
|
||||
public bool ActivelyReading { get; set; } = false;
|
||||
public string AdminComment { get; set; } = String.Empty;
|
||||
public string MessageContent { get; set; } = String.Empty;
|
||||
public ContractorStatusEnum CooperateStatus { get; set; }
|
||||
}
|
||||
|
||||
public class ResumeConfirmDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public int CooperateStatus { get; set; }
|
||||
public int ResumeStatus { get; set; }
|
||||
public int ReviewStatus { get; set; } //复审状态
|
||||
public bool AcceptingNewTrial { get; set; }
|
||||
public bool ActivelyReading { get; set; }
|
||||
public string AdminComment { get; set; } = String.Empty;
|
||||
public bool InHoliday { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public class TrialPaymentPriceQueryDTO : PageInput
|
||||
{
|
||||
public string KeyWord { get; set; } = String.Empty;
|
||||
|
||||
public Guid? CroId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class DoctorPaymentInfoQueryDTO : PageInput
|
||||
{
|
||||
public string SearchName { get; set; } = String.Empty;
|
||||
public Guid? HospitalId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class EducationCommand
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public Guid DoctorId { get; set; }
|
||||
public DateTime BeginDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
public string Degree { get; set; } = String.Empty;
|
||||
public string Major { get; set; } = String.Empty;
|
||||
public string Organization { get; set; } = String.Empty;
|
||||
public string Country { get; set; } = String.Empty;
|
||||
public string Province { get; set; } = String.Empty;
|
||||
public string City { get; set; } = String.Empty;
|
||||
|
||||
public string DegreeCN { get; set; } = String.Empty;
|
||||
public string MajorCN { get; set; } = String.Empty;
|
||||
public string OrganizationCN { get; set; } = String.Empty;
|
||||
public string CountryCN { get; set; } = String.Empty;
|
||||
public string ProvinceCN { get; set; } = String.Empty;
|
||||
public string CityCN { get; set; } = String.Empty;
|
||||
|
||||
}
|
||||
|
||||
public class EducationInfoViewModel : EducationCommand
|
||||
{
|
||||
public DateTime? CreateTime { get; set; }
|
||||
public string BeginDateStr => BeginDate.ToString("yyyy-MM");
|
||||
public string EndDateStr => EndDate.ToString("yyyy-MM");
|
||||
|
||||
}
|
||||
public class PostgraduateCommand
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public Guid DoctorId { get; set; }
|
||||
|
||||
public DateTime BeginDate { get; set; }
|
||||
|
||||
public DateTime EndDate { get; set; }
|
||||
|
||||
public string Training { get; set; } = String.Empty;
|
||||
|
||||
public string Major { get; set; } = String.Empty;
|
||||
|
||||
public string Hospital { get; set; } = String.Empty;
|
||||
|
||||
public string School { get; set; } = String.Empty;
|
||||
|
||||
public string Country { get; set; } = String.Empty;
|
||||
|
||||
public string Province { get; set; } = String.Empty;
|
||||
|
||||
public string City { get; set; } = String.Empty;
|
||||
|
||||
public string TrainingCN { get; set; } = String.Empty;
|
||||
|
||||
public string MajorCN { get; set; } = String.Empty;
|
||||
|
||||
public string HospitalCN { get; set; } = String.Empty;
|
||||
|
||||
public string SchoolCN { get; set; } = String.Empty;
|
||||
|
||||
public string CountryCN { get; set; } = String.Empty;
|
||||
|
||||
public string ProvinceCN { get; set; } = String.Empty;
|
||||
|
||||
public string CityCN { get; set; } = String.Empty;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class PostgraduateViewModel: PostgraduateCommand
|
||||
{
|
||||
public DateTime? CreateTime { get; set; }
|
||||
public string BeginDateStr => BeginDate.ToString("yyyy-MM");
|
||||
|
||||
public string EndDateStr => EndDate.ToString("yyyy-MM");
|
||||
}
|
||||
public class DoctorEducationExperienceDTO
|
||||
{
|
||||
public IEnumerable<EducationInfoViewModel> EducationList=new List<EducationInfoViewModel>();
|
||||
|
||||
public IEnumerable<PostgraduateViewModel> PostgraduateList = new List<PostgraduateViewModel>();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class VacationCommand
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public Guid DoctorId { get; set; }
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
public int Status { get; set; } = 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class ResearchPublicationDTO
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public Guid DoctorId { get; set; }
|
||||
public string Research { get; set; } = String.Empty;
|
||||
public string Grants { get; set; } = String.Empty;
|
||||
public string Publications { get; set; } = String.Empty;
|
||||
public string AwardsHonors { get; set; } = String.Empty;
|
||||
|
||||
public string ResearchCN { get; set; } = String.Empty;
|
||||
public string GrantsCN { get; set; } = String.Empty;
|
||||
public string PublicationsCN { get; set; } = String.Empty;
|
||||
public string AwardsHonorsCN { get; set; } = String.Empty;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class TrialExperienceCommand
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
public Guid DoctorId { get; set; }
|
||||
|
||||
public Guid? PhaseId { get; set; }
|
||||
public string EvaluationContent { get; set; } = String.Empty;
|
||||
|
||||
|
||||
//public string Term { get; set; }
|
||||
|
||||
//public string EvaluationCriteria { get; set; }
|
||||
|
||||
public List<Guid> EvaluationCriteriaIdList { get; set; } = new List<Guid>();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class TrialExperienceListDTO: TrialExperienceCommand
|
||||
{
|
||||
public string Phase { get; set; } = String.Empty;
|
||||
|
||||
public List<string> EvaluationCriteriaList { get; set; } = new List<string>();
|
||||
|
||||
}
|
||||
|
||||
//public class EvaluationCriteriaDTO
|
||||
//{
|
||||
// public Guid EvaluationCriteriaId { get; set; }
|
||||
// public string EvaluationCriteria { get; set; }
|
||||
//}
|
||||
|
||||
|
||||
public class TrialExperienceModel : GcpAndOtherExperienceDTO
|
||||
{
|
||||
public List<TrialExperienceListDTO> ClinicalTrialExperienceList = new List<TrialExperienceListDTO>();
|
||||
|
||||
public string ExpiryDateStr { get; set; } = string.Empty;
|
||||
public string GCPFullPath { get; set; } = String.Empty;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class GcpAndOtherExperienceDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public int GCP { get; set; }
|
||||
|
||||
public Guid? GCPId { get; set; }
|
||||
|
||||
public string OtherClinicalExperience { get; set; }=String.Empty;
|
||||
public string OtherClinicalExperienceCN { get; set; } = String.Empty;
|
||||
|
||||
public string Type { get; set; } = string.Empty;
|
||||
|
||||
public string Path { get; set; } = string.Empty;
|
||||
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
|
||||
public class GCPExperienceCommand
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public int GCP { get; set; }
|
||||
|
||||
public Guid? GCPId { get; set; }
|
||||
}
|
||||
|
||||
public class ClinicalExperienceCommand
|
||||
{
|
||||
public Guid DoctorId { get; set; }
|
||||
|
||||
public string OtherClinicalExperience { get; set; } = String.Empty;
|
||||
public string OtherClinicalExperienceCN { get; set; } = String.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using System.Linq.Dynamic.Core;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
[ApiExplorerSettings(GroupName = "Reviewer")]
|
||||
public class DoctorListService : BaseService, IDoctorListQueryService
|
||||
{
|
||||
private readonly IRepository<Doctor> _doctorRepository;
|
||||
|
||||
public DoctorListService(IRepository<Doctor> doctorRepository)
|
||||
{
|
||||
_doctorRepository = doctorRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reviewer列表分页查询
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<DoctorDTO>> GetDoctorSearchList(DoctorSearchDTO doctorSearch)
|
||||
{
|
||||
|
||||
// 项目经验 多选
|
||||
var evaluationCriteriaCount = doctorSearch.EvaluationCriteriaIdList.Count();
|
||||
|
||||
// 搜索条件 ReadingType 、Subspeciality、Title 多选
|
||||
var count = doctorSearch.ReadingTypeIdList.Count + doctorSearch.TitleIdList.Count + doctorSearch.SubspecialityIdList.Count;
|
||||
|
||||
var guidList = doctorSearch.ReadingTypeIdList.Concat(doctorSearch.SubspecialityIdList).Concat(doctorSearch.TitleIdList);
|
||||
|
||||
|
||||
var query = _doctorRepository.AsQueryable()
|
||||
.WhereIf(doctorSearch.DepartmentId != null, t => t.DepartmentId == doctorSearch.DepartmentId)
|
||||
.WhereIf(doctorSearch.SpecialityId != null, t => t.SpecialityId == doctorSearch.SpecialityId)
|
||||
.WhereIf(doctorSearch.HospitalId != null, t => t.HospitalId == doctorSearch.HospitalId)
|
||||
.WhereIf(doctorSearch.PositionId != null, t => t.PositionId == doctorSearch.PositionId)
|
||||
.WhereIf(doctorSearch.RankId != null, t => t.RankId == doctorSearch.RankId)
|
||||
.WhereIf(doctorSearch.ContractorStatus != null, t => t.CooperateStatus == doctorSearch.ContractorStatus)
|
||||
.WhereIf(doctorSearch.InformationConfirmed != null, t => t.ResumeStatus == doctorSearch.InformationConfirmed)
|
||||
.WhereIf(doctorSearch.AcceptingNewTrial != null, t => t.AcceptingNewTrial == doctorSearch.AcceptingNewTrial)
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(doctorSearch.Name), t => t.ChineseName.Contains(doctorSearch.Name) || (t.LastName + t.FirstName).Contains(doctorSearch.Name))
|
||||
.WhereIf(doctorSearch.Nation != null, t => t.Nation == doctorSearch.Nation)
|
||||
.WhereIf(evaluationCriteriaCount > 0, t => t.TrialExperienceCriteriaList.Count(t => doctorSearch.EvaluationCriteriaIdList.Contains(t.EvaluationCriteriaId)) == evaluationCriteriaCount)
|
||||
//用户类型 看到简历的范围这里需要确认
|
||||
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ReviewerCoordinator, t => t.UserList.Any(u => u.UserId == _userInfo.Id))
|
||||
.WhereIf(count > 0, t => t.DoctorDicRelationList.Count(u => guidList.Contains(u.DictionaryId)) == count)
|
||||
.WhereIf(doctorSearch.EnrollStatus != null && doctorSearch.EnrollStatus == (int)ReviewerEnrollStatus.Yes, t => t.EnrollList.Any(u => u.EnrollStatus == (int)EnrollStatus.DoctorReading))
|
||||
|
||||
.ProjectTo<DoctorDTO>(_mapper.ConfigurationProvider);
|
||||
|
||||
return await query.ToPagedListAsync(doctorSearch.PageIndex, doctorSearch.PageSize, doctorSearch.SortField == string.Empty ? "CreateTime" : doctorSearch.SortField, doctorSearch.Asc);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#region 入组查询相关
|
||||
/// <summary>
|
||||
/// 获取可筛选筛选及已经筛选的医生列表
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<SelectionReviewerDTO>> GetSelectionReviewerList(
|
||||
ReviewerSelectionQueryDTO selectionQuery)
|
||||
{
|
||||
//项目配置需要的医生过滤 2表示混合
|
||||
var nation = await _repository.Where<Trial>(s => s.Id == selectionQuery.TrialId).Select(t=>t.AttendedReviewerType).FirstOrDefaultAsync().IfNullThrowException();
|
||||
|
||||
// 临床项目经验 多选
|
||||
var evaluationCriteriaCount = selectionQuery.EvaluationCriteriaIdList.Count();
|
||||
|
||||
// 搜索条件 ReadingType 、Subspeciality、Title 多选
|
||||
var count = selectionQuery.ReadingTypeIdList.Count + selectionQuery.TitleIdList.Count + selectionQuery.SubspecialityIdList.Count;
|
||||
|
||||
var guidList = selectionQuery.ReadingTypeIdList.Concat(selectionQuery.SubspecialityIdList).Concat(selectionQuery.TitleIdList);
|
||||
|
||||
var query = _doctorRepository.WhereIf(nation != 2, t => t.Nation == nation)
|
||||
.WhereIf(selectionQuery.DepartmentId != null, t => t.DepartmentId == selectionQuery.DepartmentId)
|
||||
.WhereIf(selectionQuery.SpecialityId != null, t => t.SpecialityId == selectionQuery.SpecialityId)
|
||||
.WhereIf(selectionQuery.HospitalId != null, t => t.HospitalId == selectionQuery.HospitalId)
|
||||
.WhereIf(selectionQuery.PositionId != null, t => t.PositionId == selectionQuery.PositionId)
|
||||
.WhereIf(selectionQuery.RankId != null, t => t.RankId == selectionQuery.RankId)
|
||||
.WhereIf(selectionQuery.ContractorStatus != null, t => t.CooperateStatus == selectionQuery.ContractorStatus)
|
||||
.WhereIf(selectionQuery.InformationConfirmed != null, t => t.ResumeStatus == selectionQuery.InformationConfirmed)
|
||||
.WhereIf(selectionQuery.AcceptingNewTrial != null, t => t.AcceptingNewTrial == selectionQuery.AcceptingNewTrial)
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(selectionQuery.Name), t => t.ChineseName.Contains(selectionQuery.Name) || (t.LastName + t.FirstName).Contains(selectionQuery.Name))
|
||||
.WhereIf(evaluationCriteriaCount > 0, t => t.TrialExperienceCriteriaList.Count(t => selectionQuery.EvaluationCriteriaIdList.Contains(t.EvaluationCriteriaId)) == evaluationCriteriaCount)
|
||||
//用户类型 看到简历的范围这里需要确认
|
||||
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ReviewerCoordinator, t => t.UserList.Any(u => u.UserId == _userInfo.Id))
|
||||
.WhereIf(count > 0, t => t.DoctorDicRelationList.Count(u => guidList.Contains(u.DictionaryId)) == count)
|
||||
.WhereIf(selectionQuery.EnrollStatus != null && selectionQuery.EnrollStatus == (int)ReviewerEnrollStatus.Yes, t => t.EnrollList.Any(u => u.EnrollStatus == (int)EnrollStatus.DoctorReading))
|
||||
|
||||
.ProjectTo<SelectionReviewerDTO>(_mapper.ConfigurationProvider);
|
||||
|
||||
var result = await query.ToPagedListAsync(selectionQuery.PageIndex, selectionQuery.PageSize, selectionQuery.SortField == string.Empty ? "ReviewerCode" : selectionQuery.SortField, selectionQuery.Asc);
|
||||
|
||||
//是否已申请 申请时间 申请人
|
||||
var doctorStateList = await _repository.Where<EnrollDetail>(x => x.TrialId == selectionQuery.TrialId && x.EnrollStatus == (int)EnrollStatus.HasApplyDownloadResume)
|
||||
.ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
result.CurrentPageData.ToList().ForEach(doctor =>
|
||||
{
|
||||
//简历申请列表 --处理已经申请的
|
||||
var doctorState = doctorStateList.FirstOrDefault(t => t.DoctorId == doctor.Id && t.IntoGroupState == (int)EnrollStatus.HasApplyDownloadResume);
|
||||
if (doctorState != null)
|
||||
{
|
||||
doctor.DoctorTrialState = (int)EnrollStatus.HasApplyDownloadResume;
|
||||
doctor.OptTime = doctorState.OptTime;
|
||||
doctor.OptUserName = doctorState.OptUserName;
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取提交CRO或者CRO审核的Reviewer列表
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 根据状态获取医生列表,入组 相关接口 (提交CRO-1) CRO确认-4
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<ConfirmationReviewerDTO>> GetSubmissionOrApprovalReviewerList(
|
||||
ReviewerSubmissionQueryDTO param)
|
||||
{
|
||||
|
||||
var doctorQuery = _repository.Where<Enroll>(x => x.TrialId == param.TrialId)
|
||||
//提交CRO 以及下载简历列表
|
||||
.WhereIf(param.IntoGroupSearchState == 1, t => t.EnrollStatus >= (int)EnrollStatus.HasApplyDownloadResume)
|
||||
//CRO确认列表 状态为 已提交CRO
|
||||
.WhereIf(param.IntoGroupSearchState == 4, t => t.EnrollStatus >= (int)EnrollStatus.HasCommittedToCRO)
|
||||
.ProjectTo<ConfirmationReviewerDTO>(_mapper.ConfigurationProvider);
|
||||
|
||||
var doctorPageList = await doctorQuery.ToPagedListAsync(param.PageIndex, param.PageSize, param.SortField == "" ? "Code" : param.SortField, param.Asc);
|
||||
|
||||
|
||||
var enrollStateList = await _repository.Where<EnrollDetail>(x => x.TrialId == param.TrialId)
|
||||
//提交CRO 以及下载简历列表
|
||||
.WhereIf(param.IntoGroupSearchState == 1, t => t.EnrollStatus == (int)EnrollStatus.HasCommittedToCRO)
|
||||
//CRO确认列表 状态为 已提交CRO
|
||||
.WhereIf(param.IntoGroupSearchState == 4, t => t.EnrollStatus == (int)EnrollStatus.InviteIntoGroup)
|
||||
.ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
|
||||
doctorPageList.CurrentPageData.ToList().ForEach(u =>
|
||||
{
|
||||
var opt = enrollStateList.FirstOrDefault(t => t.DoctorId == u.Id);
|
||||
if (opt != null)
|
||||
{
|
||||
u.DoctorTrialState = param.IntoGroupSearchState == 1 ? (int)EnrollStatus.HasCommittedToCRO : (int)EnrollStatus.InviteIntoGroup;
|
||||
u.OptTime = opt.OptTime;
|
||||
u.OptUserName = opt.OptUserName;
|
||||
}
|
||||
});
|
||||
|
||||
return doctorPageList;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目下医生入组状态列表[Confirmation]
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<ConfirmationReviewerDTO>> GetConfirmationReviewerList(
|
||||
ReviewerConfirmationQueryDTO param)
|
||||
{
|
||||
|
||||
|
||||
var doctorQuery = _repository.Where<Enroll>(x => x.TrialId == param.TrialId && x.EnrollStatus >= (int)EnrollStatus.InviteIntoGroup)
|
||||
.ProjectTo<ConfirmationReviewerDTO>(_mapper.ConfigurationProvider);
|
||||
|
||||
var doctorPageList = await doctorQuery.ToPagedListAsync(param.PageIndex, param.PageSize, param.SortField == "" ? "Code" : param.SortField, param.Asc);
|
||||
|
||||
var enrollStateList = await _repository.Where<EnrollDetail>(x => x.TrialId == param.TrialId && x.EnrollStatus > (int)EnrollStatus.InviteIntoGroup)
|
||||
.ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
|
||||
|
||||
doctorPageList.CurrentPageData.ToList().ForEach(u =>
|
||||
{
|
||||
u.DoctorTrialState = (int)EnrollStatus.InviteIntoGroup;
|
||||
var opt = enrollStateList.FirstOrDefault(t => t.DoctorId == u.Id);
|
||||
if (opt != null)
|
||||
{
|
||||
u.DoctorTrialState = opt.IntoGroupState;
|
||||
u.OptTime = opt.OptTime;
|
||||
u.OptUserName = opt.OptUserName;
|
||||
}
|
||||
});
|
||||
|
||||
return doctorPageList;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,558 @@
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
[ApiExplorerSettings(GroupName = "Reviewer")]
|
||||
public class DoctorService : BaseService, IDoctorService
|
||||
{
|
||||
private readonly IRepository<Doctor> _doctorRepository;
|
||||
private readonly IRepository<Message> _messageRepository;
|
||||
private readonly IRepository<Enroll> _enrollRepository;
|
||||
private readonly IRepository<DoctorDictionary> _doctorDictionaryRepository;
|
||||
private readonly IRepository<Attachment> _attachmentRepository;
|
||||
private readonly IRepository<UserDoctor> _userDoctorRepository;
|
||||
private readonly IRepository<Trial> _trialRepository;
|
||||
private readonly IRepository<TrialPaymentPrice> _trialExtRepository;
|
||||
private readonly IRepository<Vacation> _vacationRepository;
|
||||
|
||||
|
||||
|
||||
public DoctorService(IRepository<Doctor> doctorInfoRepository,
|
||||
IRepository<Dictionary> dictionaryRepository,
|
||||
IRepository<Message> sysMessageRepository, IRepository<Enroll> intoGroupRepository,
|
||||
IRepository<DoctorDictionary> doctorDictionaryRepository,
|
||||
IRepository<Attachment> attachmentRepository,
|
||||
IRepository<UserDoctor> userDoctorRepository,
|
||||
IRepository<Trial> trialRepository,
|
||||
IRepository<TrialPaymentPrice> trialExtRepository, IRepository<Vacation> vacationRepository)
|
||||
{
|
||||
_doctorRepository = doctorInfoRepository;
|
||||
_messageRepository = sysMessageRepository;
|
||||
_enrollRepository = intoGroupRepository;
|
||||
_doctorDictionaryRepository = doctorDictionaryRepository;
|
||||
_attachmentRepository = attachmentRepository;
|
||||
_userDoctorRepository = userDoctorRepository;
|
||||
_trialRepository = trialRepository;
|
||||
_trialExtRepository = trialExtRepository;
|
||||
_vacationRepository = vacationRepository;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#region 医生基本信息--查询、新增、更新
|
||||
|
||||
/// <summary>
|
||||
/// 添加/更新 医生基本信息 BasicInfo
|
||||
/// </summary>
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput<DoctorBasicInfoCommand>> AddOrUpdateDoctorBasicInfo(DoctorBasicInfoCommand basicInfoModel)
|
||||
{
|
||||
Expression<Func<Doctor, bool>> verifyExp = t => t.Phone == basicInfoModel.Phone || t.EMail == basicInfoModel.EMail;
|
||||
|
||||
var verifyPair = new KeyValuePair<Expression<Func<Doctor, bool>>, string>(verifyExp, "current phone or email number already existed");
|
||||
|
||||
if (basicInfoModel.Id == Guid.Empty || basicInfoModel.Id == null)
|
||||
{
|
||||
|
||||
var doctor = _mapper.Map<Doctor>(basicInfoModel);
|
||||
|
||||
//验证用户手机号
|
||||
if (await _doctorRepository.AnyAsync(t => t.Phone == doctor.Phone))
|
||||
{
|
||||
return ResponseOutput.NotOk("The current phone number already existed!", new DoctorBasicInfoCommand());
|
||||
}
|
||||
|
||||
if (await _doctorRepository.AnyAsync(t => t.EMail == doctor.EMail))
|
||||
{
|
||||
return ResponseOutput.NotOk("The current email already existed!", new DoctorBasicInfoCommand());
|
||||
}
|
||||
|
||||
doctor.Code = await _repository.GetQueryable<Doctor>().MaxAsync(t => t.Code) + 1;
|
||||
|
||||
doctor.ReviewerCode = AppSettings.CodePrefix + doctor.Code.ToString("D4");
|
||||
|
||||
doctor.Password = MD5Helper.Md5(doctor.Phone);
|
||||
|
||||
//插入中间表
|
||||
basicInfoModel.TitleIds.ForEach(titleId => doctor.DoctorDicRelationList.Add(new DoctorDictionary() { DoctorId = doctor.Id, KeyName = StaticData.Title, DictionaryId = titleId }));
|
||||
|
||||
|
||||
await _doctorRepository.AddAsync(doctor);
|
||||
//_doctorRepository.Add(doctor);
|
||||
|
||||
await _repository.AddAsync(new UserDoctor() { DoctorId = doctor.Id, UserId = _userInfo.Id });
|
||||
//_userDoctorRepository.Add(new UserDoctor() { DoctorId = doctor.Id, UserId = _userInfo.Id });
|
||||
|
||||
var success = await _repository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(success, _mapper.Map<DoctorBasicInfoCommand>(doctor));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var updateModel = basicInfoModel;
|
||||
|
||||
var phone = updateModel.Phone.Trim();
|
||||
if ((await _doctorRepository.FirstOrDefaultAsync(t => t.Phone == phone && t.Id != updateModel.Id) )!= null)
|
||||
{
|
||||
return ResponseOutput.NotOk("The current phone number already existed!", new DoctorBasicInfoCommand());
|
||||
}
|
||||
var email = updateModel.EMail.Trim();
|
||||
if (await _doctorRepository.AnyAsync(t => t.EMail == email && t.Id != updateModel.Id))
|
||||
{
|
||||
return ResponseOutput.NotOk("The current email already existed!", new DoctorBasicInfoCommand());
|
||||
}
|
||||
|
||||
var doctor = await _doctorRepository.FirstOrDefaultAsync(t => t.Id == updateModel.Id).IfNullThrowException();
|
||||
|
||||
//删除中间表 Title对应的记录
|
||||
await _repository.DeleteFromQueryAsync<DoctorDictionary>(t => t.DoctorId == updateModel.Id && t.KeyName == StaticData.Title);
|
||||
|
||||
|
||||
var adddata=new List<DoctorDictionary>();
|
||||
//重新插入新的 Title记录
|
||||
updateModel.TitleIds.ForEach(titleId => adddata.Add(new DoctorDictionary() { DoctorId = updateModel.Id.Value, KeyName = StaticData.Title, DictionaryId = titleId }));
|
||||
|
||||
await _repository.AddRangeAsync(adddata);
|
||||
|
||||
_mapper.Map(basicInfoModel, doctor);
|
||||
|
||||
var success = await _repository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Result(success, basicInfoModel);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///详情、编辑-获取 医生基本信息 BasicInfo
|
||||
/// </summary>
|
||||
/// <param name="doctorId">ReviewerID</param>
|
||||
/// <returns></returns>
|
||||
|
||||
[HttpGet("{doctorId:guid}")]
|
||||
public async Task<DoctorBasicInfoDTO> GetBasicInfo(Guid doctorId)
|
||||
{
|
||||
|
||||
#region 用导航属性直接查询
|
||||
|
||||
//SELECT[t].[Id], [t].[Code], [t].[ChineseName], [t].[EMail], [t].[FirstName], [t].[Introduction], [t].[LastName], [t].[Phone], [t].[Sex], [t].[WeChat], [t].[Nation], [t0].[Title], [t0].[TitleCN], [t0].[TitleId], [t0].[ShowOrder], [t0].[Id], [t0].[Id0]
|
||||
//FROM(
|
||||
// SELECT TOP(1)[d].[Id], [d].[Code], [d].[ChineseName], [d].[EMail], [d].[FirstName], [d].[Introduction], [d].[LastName], [d].[Phone], [d].[Sex], [d].[WeChat], [d].[Nation]
|
||||
// FROM[Doctor] AS[d] WITH(NOLOCK)
|
||||
// WHERE[d].[Id] = @__doctorId_0
|
||||
//) AS[t]
|
||||
//LEFT JOIN(
|
||||
// SELECT[d1].[Value] AS[Title], [d1].[ValueCN] AS[TitleCN], [d0].[DictionaryId] AS[TitleId], [d1].[ShowOrder], [d0].[Id], [d1].[Id] AS[Id0], [d0].[DoctorId]
|
||||
// FROM [DoctorDictionary] AS [d0] WITH (NOLOCK)
|
||||
// INNER JOIN[Dictionary] AS [d1] WITH (NOLOCK) ON [d0].[DictionaryId] = [d1].[Id]
|
||||
// WHERE[d0].[KeyName] = N'Title'
|
||||
//) AS[t0] ON[t].[Id] = [t0].[DoctorId]
|
||||
//ORDER BY[t].[Id], [t0].[ShowOrder], [t0].[Id]
|
||||
|
||||
//var doctorQueryable = _doctorRepository
|
||||
// .Find(t => t.Id == doctorId)
|
||||
// .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,
|
||||
|
||||
// //不要分三个属性查询,会做三次左连接,这样 只会一个左连接
|
||||
// TempObjList = doctor.DoctorDicList.Where(t => t.KeyName == StaticData.Title)
|
||||
// .Select(t => new TempObj { Title = t.Dictionary.Value, TitleCN = t.Dictionary.ValueCN, TitleId = t.DictionaryId, ShowOrder = t.Dictionary.ShowOrder }).OrderBy(k => k.ShowOrder).ToList(),
|
||||
// });
|
||||
|
||||
//var doctorBasicInfo = doctorQueryable.FirstOrDefault();
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
var doctorBasicInfo = (await _doctorRepository.Where(t => t.Id == doctorId)
|
||||
.ProjectTo<DoctorBasicInfoDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
|
||||
|
||||
return doctorBasicInfo;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Employment信息--查询和更新
|
||||
/// <summary>
|
||||
/// 详情、编辑-获取医生工作信息 Employment
|
||||
/// </summary>
|
||||
[HttpGet("{doctorId:Guid}")]
|
||||
public async Task<EmploymentDTO> GetEmploymentInfo(Guid doctorId)
|
||||
{
|
||||
|
||||
#region init EF select 废弃
|
||||
//var dic = GetDictionary();
|
||||
|
||||
//var employmentQueryable = from doctorItem in _doctorRepository
|
||||
// .Where(t => t.Id == doctorId)
|
||||
// join hospitalItem in _hospitalRepository.AsQueryable() on doctorItem.HospitalId equals hospitalItem.Id into g
|
||||
// from hospital in g.DefaultIfEmpty()
|
||||
// select new EmploymentDTO()
|
||||
// {
|
||||
// Id = doctorItem.Id,
|
||||
// //部门
|
||||
// DepartmentId = doctorItem.DepartmentId,
|
||||
// DepartmentOther = doctorItem.DepartmentOther,
|
||||
// DepartmentOtherCN = doctorItem.DepartmentOtherCN,
|
||||
|
||||
// //医院
|
||||
// HospitalId = doctorItem.HospitalId,
|
||||
|
||||
// PositionId = doctorItem.PositionId,
|
||||
// PositionOther = doctorItem.PositionOther,
|
||||
// PositionOtherCN = doctorItem.PositionOtherCN,
|
||||
|
||||
// RankId = doctorItem.RankId,
|
||||
// RankOther = doctorItem.RankOther,
|
||||
// RankOtherCN = doctorItem.RankOtherCN,
|
||||
|
||||
// City = hospital.City,
|
||||
// Country = hospital.Country,
|
||||
// UniversityAffiliated = hospital.UniversityAffiliated,
|
||||
// HospitalName = hospital.HospitalName,
|
||||
// Province = hospital.Province,
|
||||
|
||||
// CityCN = hospital.CityCN,
|
||||
// CountryCN = hospital.CountryCN,
|
||||
// UniversityAffiliatedCN = hospital.UniversityAffiliatedCN,
|
||||
// HospitalNameCN = hospital.HospitalNameCN,
|
||||
// ProvinceCN = hospital.ProvinceCN
|
||||
// };
|
||||
|
||||
//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 ?? "";
|
||||
|
||||
|
||||
// employmentInfo.DepartmentCN = employmentInfo.DepartmentId == Guid.Empty ? employmentInfo.DepartmentOther : dic.FirstOrDefault(o => o.Id == employmentInfo.DepartmentId)?.ValueCN ?? "";
|
||||
|
||||
// employmentInfo.RankCN = employmentInfo.RankId == Guid.Empty ? employmentInfo.RankOther : dic.FirstOrDefault(o => o.Id == employmentInfo.RankId)?.ValueCN ?? "";
|
||||
|
||||
// employmentInfo.PositionCN = employmentInfo.PositionId == Guid.Empty ? employmentInfo.PositionOther : dic.FirstOrDefault(o => o.Id == employmentInfo.PositionId)?.ValueCN ?? "";
|
||||
//}
|
||||
#endregion
|
||||
|
||||
var query = _doctorRepository.Where(t => t.Id == doctorId)
|
||||
.ProjectTo<EmploymentDTO>(_mapper.ConfigurationProvider);
|
||||
|
||||
var employmentInfo = (await query.FirstOrDefaultAsync()).IfNullThrowException();
|
||||
|
||||
return employmentInfo;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
|
||||
public async Task<IResponseOutput> UpdateEmploymentInfo(EmploymentCommand doctorWorkInfoModel)
|
||||
{
|
||||
#region 废弃
|
||||
//var success = _doctorRepository.Update(d => d.Id == doctorWorkInfoModel.Id, u => new Doctor()
|
||||
//{
|
||||
// DepartmentId = doctorWorkInfoModel.DepartmentId,
|
||||
// DepartmentOther = doctorWorkInfoModel.DepartmentOther,
|
||||
// DepartmentOtherCN = doctorWorkInfoModel.DepartmentOtherCN,
|
||||
|
||||
// SpecialityId = doctorWorkInfoModel.DepartmentId,
|
||||
// SpecialityOther = doctorWorkInfoModel.DepartmentOther,
|
||||
// SpecialityOtherCN = doctorWorkInfoModel.DepartmentOtherCN,
|
||||
|
||||
// RankId = doctorWorkInfoModel.RankId,
|
||||
// RankOther = doctorWorkInfoModel.RankOther,
|
||||
// RankOtherCN = doctorWorkInfoModel.RankOtherCN,
|
||||
|
||||
// PositionId = doctorWorkInfoModel.PositionId,
|
||||
// PositionOther = doctorWorkInfoModel.PositionOther,
|
||||
// PositionOtherCN = doctorWorkInfoModel.PositionOtherCN,
|
||||
|
||||
// HospitalId = doctorWorkInfoModel.HospitalId,
|
||||
// UpdateTime = DateTime.Now
|
||||
//});
|
||||
|
||||
//var doctor = _doctorRepository.FirstOrDefault(d => d.Id == doctorWorkInfoModel.Id);
|
||||
//_mapper.Map(doctorWorkInfoModel, doctor);
|
||||
//var success = _doctorRepository.SaveChanges();
|
||||
#endregion
|
||||
|
||||
|
||||
var entity = await _repository.InsertOrUpdateAsync<Doctor, EmploymentCommand>(doctorWorkInfoModel, true);
|
||||
|
||||
//_doctorRepository.UseMapper(_mapper).InsertOrUpdate(doctorWorkInfoModel, autoSave: true);
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 医生技能信息 查询和 更新
|
||||
[HttpGet, Route("{doctorId:Guid}")]
|
||||
public async Task<SpecialtyDTO> GetSpecialtyInfo(Guid doctorId)
|
||||
{
|
||||
|
||||
#region 利用导航属性直接查询出来 生成的sql ok 废弃
|
||||
|
||||
//var specialtyQueryable = _doctorRepository
|
||||
// .Where(t => t.Id == doctorId).Include(u => u.DoctorDicRelationList)
|
||||
// .Select(specialty => new SpecialtyDTO()
|
||||
// {
|
||||
// Id = specialty.Id,
|
||||
// ReadingTypeOther = specialty.ReadingTypeOther,
|
||||
// ReadingTypeOtherCN = specialty.ReadingTypeOtherCN,
|
||||
|
||||
// SubspecialityOther = specialty.SubspecialityOther,
|
||||
// SubspecialityOtherCN = specialty.SubspecialityOtherCN,
|
||||
|
||||
|
||||
// DictionaryList = specialty.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality)
|
||||
// .Select(t => new SpecialtyDTO.DoctorDictionaryView() { DictionaryId = t.DictionaryId, Value = t.Dictionary.Value, ValueCN = t.Dictionary.ValueCN, ShowOrder = t.Dictionary.ShowOrder, KeyName = t.Dictionary.KeyName })
|
||||
// .OrderBy(t => t.ShowOrder).ToList(),
|
||||
|
||||
// SpecialityId = specialty.SpecialityId,
|
||||
// Speciality = specialty.Speciality.Value,
|
||||
// SpecialityCN = specialty.Speciality.ValueCN,
|
||||
|
||||
// SpecialityOther = specialty.SpecialityOther,
|
||||
// SpecialityOtherCN = specialty.SpecialityOtherCN
|
||||
// });
|
||||
|
||||
//var specialtyInfo = specialtyQueryable.FirstOrDefault();
|
||||
|
||||
//return specialtyInfo;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
var test = await (_doctorRepository.Where(t => t.Id == doctorId)
|
||||
.ProjectTo<SpecialtyDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> UpdateSpecialtyInfo(SpecialtyCommand specialtyUpdateModel)
|
||||
{
|
||||
var doctor = await _doctorRepository.FirstOrDefaultAsync(t => t.Id == specialtyUpdateModel.Id);
|
||||
|
||||
if (doctor == null) return Null404NotFound(doctor);
|
||||
|
||||
|
||||
|
||||
////删除中间表
|
||||
//_doctorDictionaryRepository.Delete(t =>
|
||||
// t.DoctorId == specialtyUpdateModel.Id && t.KeyName == StaticData.Subspeciality);
|
||||
//_doctorDictionaryRepository.Delete(t =>
|
||||
// t.DoctorId == specialtyUpdateModel.Id && t.KeyName == StaticData.ReadingType);
|
||||
|
||||
await _repository.DeleteFromQueryAsync<DoctorDictionary>(t =>
|
||||
t.DoctorId == specialtyUpdateModel.Id && (t.KeyName == StaticData.Subspeciality || t.KeyName == StaticData.ReadingType));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//重新插入新的
|
||||
var adddata = new List<DoctorDictionary>();
|
||||
specialtyUpdateModel.ReadingTypeIds.ForEach(readingTypeId => adddata.Add(
|
||||
new DoctorDictionary()
|
||||
{
|
||||
DoctorId = specialtyUpdateModel.Id,
|
||||
KeyName = StaticData.ReadingType,
|
||||
DictionaryId = readingTypeId
|
||||
}));
|
||||
specialtyUpdateModel.SubspecialityIds.ForEach(subspecialityId => adddata.Add(
|
||||
new DoctorDictionary()
|
||||
{
|
||||
DoctorId = specialtyUpdateModel.Id,
|
||||
KeyName = StaticData.Subspeciality,
|
||||
DictionaryId = subspecialityId
|
||||
}));
|
||||
|
||||
await _repository.AddRangeAsync(adddata);
|
||||
|
||||
_mapper.Map(specialtyUpdateModel, doctor);
|
||||
|
||||
var success = await _repository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(success);
|
||||
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 简历审核
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> UpdateAuditResume(ResumeConfirmCommand auditResumeParam)
|
||||
{
|
||||
var userId = _userInfo.Id;
|
||||
//判断 合作协议、正式简历 是否有。如果没有,显示提示信息,并且不能保存
|
||||
var attachmentList = await _repository.GetQueryable<Attachment>().Where(u => u.DoctorId == auditResumeParam.Id)
|
||||
.Select(u => u.Type).ToListAsync();
|
||||
if (auditResumeParam.ResumeStatus == ResumeStatusEnum.Pass && ((!attachmentList.Contains("Resume")) || (!attachmentList.Contains("Consultant Agreement"))))
|
||||
{
|
||||
return ResponseOutput.NotOk("Resume & Consultant Agreement must be upload ");
|
||||
}
|
||||
var success = await _doctorRepository.UpdateFromQueryAsync(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 = "Resume review results",
|
||||
Content = auditResumeParam.MessageContent,
|
||||
HasRead = false,
|
||||
MessageTime = DateTime.Now
|
||||
};
|
||||
await _repository.AddAsync(message);
|
||||
success = await _repository.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("{doctorId:guid}")]
|
||||
public async Task<ResumeConfirmDTO> GetAuditState(Guid doctorId)
|
||||
{
|
||||
var doctor = (await _doctorRepository
|
||||
.ProjectTo<ResumeConfirmDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync(t => t.Id == doctorId)).IfNullThrowException();
|
||||
|
||||
doctor.InHoliday = (await _repository.CountAsync<Vacation>(x=>x.DoctorId==doctorId&&x.EndDate<=DateTime.Now&&x.StartDate<=DateTime.Now)) > 0;
|
||||
|
||||
return doctor;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取医生入组信息 正在提交的数量 已同意入组项目个数 正在读的
|
||||
/// </summary>
|
||||
[HttpPost, Route("{doctorId:guid}")]
|
||||
public DoctorEnrollInfoDTO GetDoctorIntoGroupInfo(Guid doctorId)
|
||||
{
|
||||
var doctorQueryable =
|
||||
from doctor in _doctorRepository.Where(t => t.Id == doctorId)
|
||||
join intoGroupItem in _enrollRepository.AsQueryable() 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)
|
||||
|
||||
Submitted = g.Count(t =>
|
||||
t.EnrollStatus == (int)EnrollStatus.HasCommittedToCRO),
|
||||
Approved = g.Count(t =>
|
||||
t.EnrollStatus == (int)EnrollStatus.InviteIntoGroup),
|
||||
Reading = g.Count(t =>
|
||||
t.EnrollStatus == (int)EnrollStatus.DoctorReading)
|
||||
};
|
||||
|
||||
return doctorQueryable.FirstOrDefault().IfNullThrowException();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get Statement of Work list.[New]
|
||||
/// </summary>
|
||||
[HttpGet("{doctorId:guid}")]
|
||||
public List<SowDTO> GetDoctorSowList(Guid doctorId)
|
||||
{
|
||||
var query = from enroll in _enrollRepository.Where(u => u.DoctorId == doctorId && u.EnrollStatus >= 10)
|
||||
join trialExt in _trialExtRepository.AsQueryable() on enroll.TrialId equals trialExt.TrialId
|
||||
join trial in _trialRepository.AsQueryable() on enroll.TrialId equals trial.Id
|
||||
select new SowDTO
|
||||
{
|
||||
FileName = trialExt.SowName,
|
||||
FilePath = trialExt.SowPath,
|
||||
TrialCode = trial.TrialCode,
|
||||
CreateTime = trialExt.CreateTime
|
||||
};
|
||||
return query.ToList().Where(u => !string.IsNullOrWhiteSpace(u.FileName)).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Ack Statement of Work[New]
|
||||
/// </summary>
|
||||
[HttpGet("{doctorId:guid}")]
|
||||
public List<SowDTO> GetDoctorAckSowList(Guid doctorId)
|
||||
{
|
||||
var query = from enroll in _enrollRepository.Where(u => u.DoctorId == doctorId)
|
||||
join attachment in _attachmentRepository.Where(u => u.DoctorId == doctorId)
|
||||
on enroll.AttachmentId equals attachment.Id
|
||||
join trial in _trialRepository.AsQueryable() on enroll.TrialId equals trial.Id
|
||||
select new SowDTO
|
||||
{
|
||||
FileName = attachment.FileName,
|
||||
FilePath = attachment.Path,
|
||||
TrialCode = trial.TrialCode,
|
||||
CreateTime = attachment.CreateTime
|
||||
};
|
||||
return query.ToList();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
[ApiExplorerSettings(GroupName = "Reviewer")]
|
||||
public class EducationService : BaseService, IEducationService
|
||||
{
|
||||
private readonly IRepository<Postgraduate> _postgraduateRepository;
|
||||
private readonly IRepository<Education> _educationRepository;
|
||||
|
||||
public EducationService(IRepository<Education> doctorNormalEducationRepository,
|
||||
IRepository<Postgraduate> doctorContinueLearningRepository)
|
||||
{
|
||||
_educationRepository = doctorNormalEducationRepository;
|
||||
_postgraduateRepository = doctorContinueLearningRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据医生Id获取医生教育经历和继续学习经历列表
|
||||
/// </summary>
|
||||
[HttpGet("{doctorId:Guid}")]
|
||||
public async Task<DoctorEducationExperienceDTO> GetEducation(Guid doctorId)
|
||||
{
|
||||
var educationList = await _educationRepository.Where(o => o.DoctorId == doctorId)
|
||||
.OrderBy(t => t.CreateTime).ProjectTo<EducationInfoViewModel>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
var postgraduateList = await _repository.GetQueryable<Postgraduate>().Where(o => o.DoctorId == doctorId)
|
||||
.OrderBy(t => t.CreateTime).ProjectTo<PostgraduateViewModel>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
|
||||
return new DoctorEducationExperienceDTO()
|
||||
{
|
||||
EducationList = educationList,
|
||||
PostgraduateList = postgraduateList
|
||||
};
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 新增医生教育经历
|
||||
/// </summary>
|
||||
/// <param name="educationInfoViewModel"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdateEducationInfo(EducationCommand educationInfoViewModel)
|
||||
{
|
||||
if (educationInfoViewModel.Id == Guid.Empty || educationInfoViewModel.Id == null)
|
||||
{
|
||||
var doctorEducationInfo = _mapper.Map<Education>(educationInfoViewModel);
|
||||
switch (educationInfoViewModel.Degree)
|
||||
{
|
||||
case StaticData.Bachelor:
|
||||
doctorEducationInfo.ShowOrder = 1;
|
||||
break;
|
||||
case StaticData.Master:
|
||||
doctorEducationInfo.ShowOrder = 2;
|
||||
break;
|
||||
case StaticData.Doctorate:
|
||||
doctorEducationInfo.ShowOrder = 3;
|
||||
break;
|
||||
}
|
||||
await _educationRepository.AddAsync(doctorEducationInfo);
|
||||
var success = await _repository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Result(success, doctorEducationInfo.Id.ToString());
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
var needUpdate = await _educationRepository.FirstOrDefaultAsync(t => t.Id == educationInfoViewModel.Id);
|
||||
|
||||
if (needUpdate == null) return Null404NotFound(needUpdate);
|
||||
|
||||
_mapper.Map(educationInfoViewModel, needUpdate);
|
||||
|
||||
var success = await _repository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Ok(success);
|
||||
|
||||
}
|
||||
//_educationRepository.Update(needUpdate);
|
||||
|
||||
|
||||
}
|
||||
|
||||
[HttpDelete, Route("{doctorId:guid}")]
|
||||
public async Task<IResponseOutput> DeleteEducationInfo(Guid id)
|
||||
{
|
||||
var success = await _educationRepository.DeleteFromQueryAsync(o => o.Id == id);
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
/// <summary> 添加/更新医生继续学习经历</summary>
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdatePostgraduateInfo(PostgraduateCommand postgraduateViewModel)
|
||||
{
|
||||
#region 封装前
|
||||
|
||||
//if (postgraduateViewModel.Id == Guid.Empty || postgraduateViewModel.Id == null)
|
||||
//{
|
||||
// var doctorContinueLearning = _mapper.Map<Postgraduate>(postgraduateViewModel);
|
||||
// _postgraduateRepository.Add(doctorContinueLearning);
|
||||
// var success = _postgraduateRepository.SaveChanges();
|
||||
|
||||
// return ResponseOutput.Result(success, doctorContinueLearning.Id.ToString());
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// _postgraduateRepository.Update(_mapper.Map<Postgraduate>(postgraduateViewModel));
|
||||
// var success = _postgraduateRepository.SaveChanges();
|
||||
|
||||
// return ResponseOutput.Result(success);
|
||||
|
||||
//}
|
||||
#endregion
|
||||
|
||||
var entity = await _repository.InsertOrUpdateAsync<Postgraduate, PostgraduateCommand>(postgraduateViewModel, true);
|
||||
return ResponseOutput.Ok(entity.Id);
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除医生继续学习经历
|
||||
/// </summary>
|
||||
/// <param name="doctorId">医生Id</param>
|
||||
/// <returns></returns>
|
||||
|
||||
[HttpDelete("{doctorId:guid}")]
|
||||
public async Task<IResponseOutput> DeletePostgraduateInfo(Guid doctorId)
|
||||
{
|
||||
var success = await _repository.DeleteFromQueryAsync<Postgraduate>(o => o.Id == doctorId);
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using IRaCIS.Application.Contracts;
|
||||
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IAttachmentService
|
||||
{
|
||||
Task<IEnumerable<AttachmentDTO>> SaveAttachments(IEnumerable<AttachmentDTO> attachmentList);
|
||||
|
||||
|
||||
Task<IResponseOutput<AttachmentDTO>> AddAttachment(AttachmentDTO attachment);
|
||||
Task<IResponseOutput> DeleteAttachment(AttachementCommand param);
|
||||
Task<AttachmentDTO> GetDetailById(Guid attachmentId);
|
||||
Task<IEnumerable<AttachmentDTO>> GetAttachmentByType(Guid doctorId, string type);
|
||||
Task<IEnumerable<AttachmentDTO>> GetAttachmentByTypes(Guid doctorId, string[] types);
|
||||
Task<IEnumerable<AttachmentDTO>> GetAttachments(Guid doctorId);
|
||||
Task<string> GetDoctorOfficialCV(int language, Guid doctorId);
|
||||
|
||||
Task<IResponseOutput> SetOfficial(Guid doctorId, Guid attachmentId, int language);
|
||||
|
||||
Task<IResponseOutput> SetLanguage(Guid doctorId, Guid attachmentId, int language);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IDoctorAccountService
|
||||
{
|
||||
IResponseOutput Register(DoctorAccountRegisterModel doctorAccount);
|
||||
DoctorAccountDTO Login(DoctorAccountLoginDTO doctorAccount);
|
||||
IResponseOutput UpdatePassword(DoctorAccountUpdatePasswordCommand doctorAccount);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using IRaCIS.Application.Contracts;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IDoctorListQueryService
|
||||
{
|
||||
/// <summary>
|
||||
/// 医生多条件查询
|
||||
/// </summary>
|
||||
Task<PageOutput<DoctorDTO>> GetDoctorSearchList(DoctorSearchDTO param);
|
||||
|
||||
/// <summary>
|
||||
/// 筛选医生列表
|
||||
/// </summary>
|
||||
/// <param name="doctorSearchModel"></param>
|
||||
/// <returns></returns>
|
||||
//
|
||||
Task<PageOutput<SelectionReviewerDTO>> GetSelectionReviewerList(
|
||||
ReviewerSelectionQueryDTO doctorSearchModel);
|
||||
|
||||
/// <summary>
|
||||
/// //入组 相关接口 (提交CRO-1) CRO确认-4
|
||||
/// </summary>
|
||||
Task<PageOutput<ConfirmationReviewerDTO>> GetSubmissionOrApprovalReviewerList(
|
||||
ReviewerSubmissionQueryDTO doctorIntoGroupSearchModel);
|
||||
|
||||
|
||||
//医生确认状态列表
|
||||
Task<PageOutput<ConfirmationReviewerDTO>> GetConfirmationReviewerList(
|
||||
ReviewerConfirmationQueryDTO trialIdPageModel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IDoctorService
|
||||
{
|
||||
#region 医生 基本信息
|
||||
|
||||
/// <summary>
|
||||
/// 基本信息详情展示、编辑使用
|
||||
/// </summary>
|
||||
/// <param name="doctorId"></param>
|
||||
/// <returns></returns>
|
||||
Task<DoctorBasicInfoDTO> GetBasicInfo(Guid doctorId);
|
||||
|
||||
/// <summary>
|
||||
/// 添加医生基本信息
|
||||
/// </summary>
|
||||
/// <param name="addBasicInfoParam"></param>
|
||||
/// <returns></returns>
|
||||
Task<IResponseOutput<DoctorBasicInfoCommand>> AddOrUpdateDoctorBasicInfo(DoctorBasicInfoCommand addBasicInfoParam);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 医生 工作信息
|
||||
|
||||
/// <summary>
|
||||
/// 获取医生 工作信息
|
||||
/// </summary>
|
||||
/// <param name="doctorId"></param>
|
||||
/// <returns></returns>
|
||||
Task<EmploymentDTO> GetEmploymentInfo(Guid doctorId);
|
||||
/// <summary>
|
||||
/// 更新医生 工作信息
|
||||
/// </summary>
|
||||
/// <param name="updateDoctorWorkInfoViewModel"></param>
|
||||
/// <returns></returns>
|
||||
Task<IResponseOutput> UpdateEmploymentInfo(EmploymentCommand updateDoctorWorkInfoViewModel);
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 获取医生技能信息
|
||||
/// </summary>
|
||||
Task<SpecialtyDTO> GetSpecialtyInfo(Guid doctorId);
|
||||
|
||||
/// <summary>
|
||||
/// 更新医生技能信息
|
||||
/// </summary>
|
||||
Task<IResponseOutput> UpdateSpecialtyInfo(SpecialtyCommand specialtyUpdateModel);
|
||||
|
||||
/// <summary>
|
||||
/// 获取医生 审核状态
|
||||
/// </summary>
|
||||
Task<ResumeConfirmDTO> GetAuditState(Guid doctorId);
|
||||
|
||||
/// <summary>
|
||||
/// 审核简历 和合作关系
|
||||
/// </summary>
|
||||
Task<IResponseOutput> UpdateAuditResume(ResumeConfirmCommand auditResumeParam);
|
||||
|
||||
/// <summary> 医生详情 入组信息 </summary>
|
||||
DoctorEnrollInfoDTO GetDoctorIntoGroupInfo(Guid doctorId);
|
||||
|
||||
/// <summary> 获取医生参与项目的Sow协议 </summary>
|
||||
List<SowDTO> GetDoctorSowList(Guid doctorId);
|
||||
|
||||
/// <summary> 获取医生入组的 ack Sow </summary>
|
||||
List<SowDTO> GetDoctorAckSowList(Guid doctorId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IEducationService
|
||||
{
|
||||
|
||||
Task<DoctorEducationExperienceDTO> GetEducation(Guid doctorId);
|
||||
|
||||
#region 教育经历
|
||||
Task<IResponseOutput> AddOrUpdateEducationInfo(EducationCommand doctorEducationInfoViewModel);
|
||||
|
||||
Task<IResponseOutput> DeleteEducationInfo(Guid doctorId);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 继续教育经历
|
||||
Task<IResponseOutput> AddOrUpdatePostgraduateInfo(PostgraduateCommand doctorContinueLearningViewModel);
|
||||
Task<IResponseOutput> DeletePostgraduateInfo(Guid doctorId);
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IResearchPublicationService
|
||||
{
|
||||
Task<ResearchPublicationDTO> GetResearchPublication(Guid doctorId);
|
||||
|
||||
Task<IResponseOutput> AddOrUpdateResearchPublication(ResearchPublicationDTO param);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface ITrialExperienceService
|
||||
{
|
||||
Task<TrialExperienceModel> GetTrialExperience(Guid doctorId);
|
||||
Task<IResponseOutput> AddOrUpdateTrialExperience(TrialExperienceCommand model);
|
||||
Task<IResponseOutput> DeleteTrialExperience(Guid id);
|
||||
Task<IResponseOutput> UpdateGcpExperience(GCPExperienceCommand model);
|
||||
Task<IResponseOutput> UpdateOtherExperience(ClinicalExperienceCommand updateOtherClinicalExperience);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using IRaCIS.Application.Contracts;
|
||||
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IVacationService
|
||||
{
|
||||
Task<IResponseOutput> AddOrUpdateVacation(VacationCommand vacationViewModel);
|
||||
Task<IResponseOutput> DeleteVacation(Guid id);
|
||||
Task<PageOutput<VacationCommand>> GetVacationList(Guid doctorId, int pageIndex, int pageSize);
|
||||
|
||||
/// <summary> 判断当前时间是否在休假 </summary>
|
||||
Task<IResponseOutput> OnVacation(Guid reviewerId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using AutoMapper.QueryableExtensions;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
[ApiExplorerSettings(GroupName = "Reviewer")]
|
||||
public class ResearchPublicationService : BaseService, IResearchPublicationService
|
||||
{
|
||||
private readonly IRepository<ResearchPublication> researchPublicationRepository;
|
||||
|
||||
public ResearchPublicationService(IRepository<ResearchPublication> _researchPublicationRepository)
|
||||
{
|
||||
researchPublicationRepository = _researchPublicationRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询-医生科学研究信息
|
||||
/// </summary>
|
||||
/// <param name="doctorId">医生Id</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{doctorId:guid}")]
|
||||
public async Task<ResearchPublicationDTO> GetResearchPublication(Guid doctorId)
|
||||
{
|
||||
var doctorScientificResearchInfo = await researchPublicationRepository.Where(o => o.DoctorId == doctorId)
|
||||
.ProjectTo<ResearchPublicationDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
|
||||
|
||||
return doctorScientificResearchInfo;
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdateResearchPublication(ResearchPublicationDTO param)
|
||||
{
|
||||
|
||||
var entity = await _repository.InsertOrUpdateAsync<ResearchPublication, ResearchPublicationDTO>(param, true);
|
||||
|
||||
return ResponseOutput.Ok(entity.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
[ApiExplorerSettings(GroupName = "Reviewer")]
|
||||
public class TrialExperienceService : BaseService, ITrialExperienceService
|
||||
{
|
||||
//private readonly IRepository<TrialExperience> _trialExperienceRepository;
|
||||
//private readonly IRepository<Doctor> _doctorRepository;
|
||||
//private readonly IRepository<Attachment> _attachmentRepository;
|
||||
//private readonly IRepository<TrialExperienceCriteria> _trialExperienceCriteriaRepository;
|
||||
|
||||
|
||||
|
||||
//public TrialExperienceService(IRepository<TrialExperience> trialExperienceRepository, IRepository<Doctor> doctorRepository, IRepository<Attachment> attachmentRepository,
|
||||
// IRepository<TrialExperienceCriteria> trialExperienceCriteriaRepository)
|
||||
//{
|
||||
// _trialExperienceRepository = trialExperienceRepository;
|
||||
// _doctorRepository = doctorRepository;
|
||||
// _attachmentRepository = attachmentRepository;
|
||||
// _trialExperienceCriteriaRepository = trialExperienceCriteriaRepository;
|
||||
|
||||
//}
|
||||
|
||||
private IQueryable<Doctor> _doctor => _repository.GetQueryable<Doctor>();
|
||||
private IQueryable<Attachment> _attachment => _repository.GetQueryable<Attachment>();
|
||||
private IQueryable<TrialExperience> _trialExperience => _repository.GetQueryable<TrialExperience>();
|
||||
private IQueryable<TrialExperienceCriteria> _trialExperienceCriteria => _repository.GetQueryable<TrialExperienceCriteria>();
|
||||
|
||||
/// <summary>
|
||||
/// 根据医生Id,获取临床试验经历 界面所有数据
|
||||
/// </summary>
|
||||
[HttpGet("{doctorId:guid}")]
|
||||
public async Task<TrialExperienceModel> GetTrialExperience(Guid doctorId)
|
||||
{
|
||||
var trialExperience = new TrialExperienceModel();
|
||||
|
||||
var doctor = await _doctor.Where(o => o.Id == doctorId)
|
||||
.ProjectTo<TrialExperienceModel>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
|
||||
|
||||
trialExperience.ClinicalTrialExperienceList = await GetTrialExperienceList(doctorId);
|
||||
|
||||
if (doctor != null)
|
||||
{
|
||||
trialExperience.GCP = doctor.GCP;
|
||||
trialExperience.Id = doctor.Id;
|
||||
trialExperience.OtherClinicalExperience = doctor.OtherClinicalExperience ?? "";
|
||||
trialExperience.OtherClinicalExperienceCN = doctor.OtherClinicalExperienceCN ?? "";
|
||||
var attachment = await _attachment.FirstOrDefaultAsync(t => t.Id == doctor.GCPId);
|
||||
if (attachment != null)
|
||||
{
|
||||
trialExperience.ExpiryDateStr = attachment.ExpiryDate == null ? "" : attachment.ExpiryDate.Value.ToString("yyyy-MM-dd HH:mm");
|
||||
|
||||
trialExperience.Path = attachment.Path;
|
||||
trialExperience.GCPFullPath = attachment.Path + "?access_token=" + _userInfo.UserToken;
|
||||
trialExperience.Type = attachment.Type;
|
||||
trialExperience.FileName = attachment.FileName;
|
||||
trialExperience.GCPId = attachment.Id;
|
||||
}
|
||||
}
|
||||
|
||||
return trialExperience;
|
||||
}
|
||||
|
||||
private async Task<List<TrialExperienceListDTO>> GetTrialExperienceList(Guid doctorId)
|
||||
{
|
||||
var doctorClinicalTrialExperienceList = await _trialExperience.Where(o => o.DoctorId == doctorId).OrderBy(t => t.CreateTime)
|
||||
.ProjectTo<TrialExperienceListDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
|
||||
return doctorClinicalTrialExperienceList;
|
||||
|
||||
}
|
||||
/// <summary> 添加或更新医生临床经验列表项</summary>
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdateTrialExperience(TrialExperienceCommand trialExperienceViewModel)
|
||||
{
|
||||
if (trialExperienceViewModel.Id == Guid.Empty || trialExperienceViewModel.Id == null)
|
||||
{
|
||||
var trialExperience =
|
||||
_mapper.Map<TrialExperience>(trialExperienceViewModel);
|
||||
|
||||
trialExperience = await _repository.AddAsync(trialExperience);
|
||||
|
||||
List<TrialExperienceCriteria> criteriaList = new List<TrialExperienceCriteria>();
|
||||
trialExperienceViewModel.EvaluationCriteriaIdList.ForEach(t => criteriaList.Add(new TrialExperienceCriteria()
|
||||
{
|
||||
DoctorId = trialExperienceViewModel.DoctorId,
|
||||
//EvaluationCriteria = t.EvaluationCriteria,
|
||||
EvaluationCriteriaId = t,
|
||||
TrialExperienceId = trialExperience.Id
|
||||
}));
|
||||
|
||||
await _repository.AddRangeAsync(criteriaList);
|
||||
|
||||
|
||||
var success = await _repository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(success, trialExperience.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
var needUpdate = await _trialExperience.FirstOrDefaultAsync(t => t.Id == trialExperienceViewModel.Id);
|
||||
|
||||
if (needUpdate == null) return Null404NotFound(needUpdate);
|
||||
|
||||
_mapper.Map(trialExperienceViewModel, needUpdate);
|
||||
await _repository.UpdateAsync(needUpdate);
|
||||
|
||||
await _repository.DeleteFromQueryAsync<TrialExperienceCriteria>(t => t.TrialExperienceId == needUpdate.Id);
|
||||
|
||||
List<TrialExperienceCriteria> criteriaList = new List<TrialExperienceCriteria>();
|
||||
|
||||
trialExperienceViewModel.EvaluationCriteriaIdList.ForEach(t => criteriaList.Add(new TrialExperienceCriteria()
|
||||
{
|
||||
DoctorId = trialExperienceViewModel.DoctorId,
|
||||
EvaluationCriteriaId = t,
|
||||
TrialExperienceId = needUpdate.Id
|
||||
}));
|
||||
|
||||
await _repository.AddRangeAsync<TrialExperienceCriteria>(criteriaList);
|
||||
|
||||
|
||||
var success = await _repository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(success, trialExperienceViewModel.Id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除临床经验
|
||||
/// </summary>
|
||||
|
||||
[HttpDelete, Route("{doctorId:guid}")]
|
||||
public async Task<IResponseOutput> DeleteTrialExperience(Guid doctorId)
|
||||
{
|
||||
var success = await _repository.DeleteFromQueryAsync<TrialExperience>(o => o.Id == doctorId);
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新-GCP和其他临床经验
|
||||
/// </summary>
|
||||
/// <param name="updateGCPExperienceParam"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> UpdateGcpExperience(GCPExperienceCommand updateGCPExperienceParam)
|
||||
{
|
||||
//_attachmentRepository.Delete(t => t.DoctorId == updateGCPExperienceParam.Id && t.Type == StaticData.GCP);
|
||||
|
||||
var successs = await _repository.UpdateFromQueryAsync<Doctor>(o => o.Id == updateGCPExperienceParam.Id, u => new Doctor()
|
||||
{
|
||||
GCP = updateGCPExperienceParam.GCP,
|
||||
GCPId = updateGCPExperienceParam.GCP==0&&updateGCPExperienceParam.GCPId==null?Guid.Empty: updateGCPExperienceParam.GCPId!.Value
|
||||
});
|
||||
|
||||
if (updateGCPExperienceParam.GCP == 0 && updateGCPExperienceParam.GCPId != null)
|
||||
{
|
||||
await _repository.DeleteFromQueryAsync<Attachment>(a => a.Id == updateGCPExperienceParam.GCPId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return ResponseOutput.Result(successs, updateGCPExperienceParam.GCPId.ToString());
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新其他技能经验
|
||||
/// </summary>
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> UpdateOtherExperience(ClinicalExperienceCommand updateOtherClinicalExperience)
|
||||
{
|
||||
var success = await _repository.UpdateFromQueryAsync<Doctor>(o => o.Id == updateOtherClinicalExperience.DoctorId, u => new Doctor()
|
||||
{
|
||||
OtherClinicalExperience = updateOtherClinicalExperience.OtherClinicalExperience ?? string.Empty,
|
||||
OtherClinicalExperienceCN = updateOtherClinicalExperience.OtherClinicalExperienceCN ?? string.Empty
|
||||
});
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
[ ApiExplorerSettings(GroupName = "Reviewer")]
|
||||
public class VacationService : BaseService, IVacationService
|
||||
{
|
||||
private readonly IRepository<Vacation> _vacationRepository;
|
||||
|
||||
public VacationService(IRepository<Vacation> vacationRepository)
|
||||
{
|
||||
_vacationRepository = vacationRepository;
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加休假时间段
|
||||
/// </summary>
|
||||
/// <param name="param">Status不传</param>
|
||||
/// <returns></returns>
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdateVacation(VacationCommand param)
|
||||
{
|
||||
if (param.Id == Guid.Empty|| param.Id ==null)
|
||||
{
|
||||
var result = await _vacationRepository.AddAsync(_mapper.Map<Vacation>(param));
|
||||
|
||||
var success = await _repository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Result(success, result.Id);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var success = await _vacationRepository.UpdateFromQueryAsync(u => u.Id == param.Id,
|
||||
h => new Vacation
|
||||
{
|
||||
StartDate = param.StartDate,
|
||||
EndDate = param.EndDate
|
||||
});
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除休假时间段
|
||||
/// </summary>
|
||||
/// <param name="holidayId">记录Id</param>
|
||||
/// <returns></returns>
|
||||
|
||||
[HttpDelete("{holidayId:guid}")]
|
||||
public async Task<IResponseOutput> DeleteVacation(Guid holidayId)
|
||||
{
|
||||
var success = await _vacationRepository.DeleteFromQueryAsync(u => u.Id == holidayId);
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取休假时间段列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{doctorId:guid}/{pageIndex:int}/{pageSize:int}")]
|
||||
public async Task<PageOutput<VacationCommand>> GetVacationList(Guid doctorId, int pageIndex, int pageSize)
|
||||
{
|
||||
var query = _vacationRepository.Where(u => u.DoctorId == doctorId)
|
||||
.ProjectTo<VacationCommand>(_mapper.ConfigurationProvider);
|
||||
|
||||
return await query.ToPagedListAsync(pageIndex, pageSize, "StartDate");
|
||||
|
||||
}
|
||||
|
||||
[NonDynamicMethod]
|
||||
public async Task<IResponseOutput> OnVacation(Guid doctorId)
|
||||
{
|
||||
var count = await _vacationRepository.CountAsync(u => u.DoctorId == doctorId && u.EndDate >= DateTime.Now && u.StartDate <= DateTime.Now);
|
||||
|
||||
return ResponseOutput.Result(count > 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
using AutoMapper;
|
||||
using AutoMapper.EquivalencyExpression;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Application.Contracts.Pay;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
public class DoctorConfig : Profile
|
||||
{
|
||||
public DoctorConfig()
|
||||
{
|
||||
#region reviewer
|
||||
|
||||
//基本信息 工作信息 添加时转换使用
|
||||
CreateMap<DoctorBasicInfoCommand, Doctor>().EqualityComparison((odto, o) => odto.Id == o.Id);
|
||||
|
||||
//学习经历 添加时转换使用
|
||||
CreateMap<EducationCommand, Education>().EqualityComparison((odto, o) => odto.Id == o.Id);
|
||||
CreateMap<PostgraduateCommand, Postgraduate>().EqualityComparison((odto, o) => odto.Id == o.Id);
|
||||
CreateMap<ResearchPublicationDTO, ResearchPublication>().EqualityComparison((odto, o) => odto.Id == o.Id);
|
||||
CreateMap<TrialExperienceCommand, TrialExperience>().EqualityComparison((odto, o) => odto.Id == o.Id);
|
||||
|
||||
//医生账户
|
||||
CreateMap<DoctorAccountLoginDTO, Doctor>();
|
||||
CreateMap<DoctorAccountRegisterModel, Doctor>();
|
||||
|
||||
CreateMap<VacationCommand, Vacation>().EqualityComparison((odto, o) => odto.Id == o.Id);
|
||||
|
||||
|
||||
CreateMap<AttachmentDTO, Attachment>().EqualityComparison((odto, o) => odto.Id == o.Id);
|
||||
|
||||
CreateMap<ReviewerAckDTO, Attachment>().EqualityComparison((odto, o) => odto.Id == o.Id);
|
||||
|
||||
|
||||
CreateMap<Doctor, DoctorBasicInfoCommand>();
|
||||
CreateMap<Education, EducationInfoViewModel>();
|
||||
|
||||
CreateMap<Vacation, VacationCommand>();
|
||||
CreateMap<Education, EducationInfoViewModel>();
|
||||
CreateMap<ResearchPublication, ResearchPublicationDTO>();
|
||||
CreateMap<Postgraduate, PostgraduateViewModel>();
|
||||
CreateMap<Attachment, AttachmentDTO>();
|
||||
CreateMap<Doctor, ResumeConfirmDTO>();
|
||||
|
||||
CreateMap<Doctor, DoctorSelectDTO>();
|
||||
|
||||
CreateMap<Doctor, TrialExperienceModel>();
|
||||
CreateMap<TrialExperience, TrialExperienceCommand>();
|
||||
|
||||
CreateMap<Doctor, DoctorBasicInfo>();
|
||||
|
||||
#endregion
|
||||
CreateMap<Dictionary, KeyNameType>();
|
||||
|
||||
CreateMap<Dictionary, DicViewModelDTO>();
|
||||
|
||||
CreateMap<AddOrUpdateDicDTO, Dictionary>().ReverseMap();
|
||||
|
||||
//医生列表、项目显示列表模型转换
|
||||
CreateMap<DoctorDTO, SelectionReviewerDTO>();
|
||||
|
||||
CreateMap<User, UserBasicInfo>()
|
||||
.ForMember(d => d.UserTypeShortName, u => u.MapFrom(t => t.UserTypeRole.UserTypeShortName))
|
||||
.ForMember(d => d.Code, u => u.MapFrom(t => t.UserCode))
|
||||
.ForMember(d => d.PermissionStr, u => u.MapFrom(t => t.UserTypeRole.PermissionStr))
|
||||
.ForMember(d => d.RealName, u => u.MapFrom(user => string.IsNullOrEmpty(user.FirstName) ? user.LastName : user.LastName + " / " + user.FirstName));
|
||||
|
||||
CreateMap<TrialExperience, TrialExperienceListDTO>()
|
||||
.ForMember(d => d.Phase, u => u.MapFrom(t => t.Phase.Value))
|
||||
.ForMember(d => d.EvaluationCriteriaList, u => u.MapFrom(t => t.ExperienceCriteriaList.Select(t => t.EvaluationCriteria.Value)))
|
||||
.ForMember(d => d.EvaluationCriteriaIdList, u => u.MapFrom(t => t.ExperienceCriteriaList.Select(t => t.EvaluationCriteriaId)));
|
||||
|
||||
CreateMap<Doctor, UserBasicInfo>()
|
||||
.ForMember(d => d.Code, u => u.MapFrom(t => t.ReviewerCode))
|
||||
.ForMember(d => d.RealName, u => u.MapFrom(t => t.ChineseName))
|
||||
.ForMember(d => d.IsReviewer, u => u.MapFrom(t => true))
|
||||
.ForMember(d => d.UserName, u => u.MapFrom(doctor => doctor.LastName + " / " + doctor.FirstName));
|
||||
|
||||
#region 医生基本信息
|
||||
CreateMap<Doctor, SelectionReviewerDTO>();
|
||||
CreateMap<Doctor, DoctorDTO>().IncludeMembers(t => t.Hospital).Include<Doctor, SelectionReviewerDTO>()
|
||||
.ForMember(d => d.Department, u => u.MapFrom(s => s.Department.Value))
|
||||
.ForMember(d => d.DepartmentCN, u => u.MapFrom(s => s.Department.ValueCN))
|
||||
.ForMember(d => d.Position, u => u.MapFrom(s => s.Position.Value))
|
||||
.ForMember(d => d.PositionCN, u => u.MapFrom(s => s.Position.ValueCN))
|
||||
.ForMember(d => d.Rank, u => u.MapFrom(s => s.Rank.Value))
|
||||
.ForMember(d => d.RankCN, u => u.MapFrom(s => s.Rank.ValueCN))
|
||||
.ForMember(d => d.Speciality, u => u.MapFrom(s => s.Speciality.Value))
|
||||
.ForMember(d => d.SpecialityCN, u => u.MapFrom(s => s.Speciality.ValueCN))
|
||||
.ForMember(d => d.HasResume, u => u.MapFrom(s => s.AttachmentList.Any(u => u.Type == "Resume" && u.IsOfficial)))
|
||||
.ForMember(d => d.Submitted, u => u.MapFrom(s => s.EnrollList.Count(t => t.EnrollStatus == (int)EnrollStatus.HasCommittedToCRO)))
|
||||
.ForMember(d => d.Approved, u => u.MapFrom(s => s.EnrollList.Count(t => t.EnrollStatus == (int)EnrollStatus.InviteIntoGroup)))
|
||||
.ForMember(d => d.Reading, u => u.MapFrom(s => s.EnrollList.Count(t => t.EnrollStatus == (int)EnrollStatus.DoctorReading)))
|
||||
.ForMember(d => d.Finished, u => u.MapFrom(s => s.EnrollList.Count(t => t.EnrollStatus == (int)EnrollStatus.Finished)))
|
||||
.ForMember(d => d.Reconfirmed, u => u.MapFrom(s => s.ReviewStatus == 1))
|
||||
.ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)));
|
||||
CreateMap<Hospital, DoctorDTO>();
|
||||
|
||||
CreateMap<EmploymentCommand, Doctor>();
|
||||
|
||||
|
||||
//这样会左连接三次
|
||||
// CreateMap<Doctor, DoctorBasicInfoDTO>()
|
||||
//.ForMember(d => d.TitleCNList, u => u.MapFrom(s => s.DoctorDicRelationList.Where(t => t.KeyName == StaticData.Title)
|
||||
//.Select(t => new { TitleCN = t.Dictionary.ValueCN, ShowOrder = t.Dictionary.ShowOrder }).OrderBy(k => k.ShowOrder).Select(t => t.TitleCN)))
|
||||
// .ForMember(d => d.TitleList, u => u.MapFrom(s => s.DoctorDicRelationList.Where(t => t.KeyName == StaticData.Title)
|
||||
//.Select(t => new { Title = t.Dictionary.Value, ShowOrder = t.Dictionary.ShowOrder }).OrderBy(k => k.ShowOrder).Select(t => t.Title)))
|
||||
// .ForMember(d => d.TitleIds, u => u.MapFrom(s => s.DoctorDicRelationList.Where(t => t.KeyName == StaticData.Title)
|
||||
//.Select(t => new { TitleId = t.Dictionary.Id, ShowOrder = t.Dictionary.ShowOrder }).OrderBy(k => k.ShowOrder).Select(t => t.TitleId)));
|
||||
|
||||
//这样只会查询一次
|
||||
CreateMap<Doctor, DoctorBasicInfoDTO>()
|
||||
.ForMember(o => o.DoctorDicViewDtos, t => t.MapFrom(u => u.DoctorDicRelationList.Where(t => t.KeyName == StaticData.Title).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)));
|
||||
CreateMap<Dictionary, DicView>()
|
||||
.ForMember(t=>t.ParentCode,u=>u.MapFrom(c=>c.Parent.Code));
|
||||
//CreateMap<DoctorDictionary, DicView>();
|
||||
|
||||
CreateMap<Doctor, SpecialtyDTO>()
|
||||
.ForMember(o => o.Speciality, t => t.MapFrom(u => u.Speciality.Value))
|
||||
.ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)));
|
||||
CreateMap<SpecialtyCommand, Doctor>();
|
||||
|
||||
//医生职业信息
|
||||
CreateMap<Doctor, EmploymentDTO>().IncludeMembers(t => t.Hospital)
|
||||
.ForMember(d => d.Department, u => u.MapFrom(s => s.Department.Value))
|
||||
.ForMember(d => d.DepartmentCN, u => u.MapFrom(s => s.Department.ValueCN))
|
||||
.ForMember(d => d.Position, u => u.MapFrom(s => s.Position.Value))
|
||||
.ForMember(d => d.PositionCN, u => u.MapFrom(s => s.Position.ValueCN))
|
||||
.ForMember(d => d.Rank, u => u.MapFrom(s => s.Rank.Value))
|
||||
.ForMember(d => d.RankCN, u => u.MapFrom(s => s.Rank.ValueCN));
|
||||
CreateMap<Hospital, EmploymentDTO>();
|
||||
|
||||
CreateMap<EnrollDetail, DoctorStateModelDTO>()
|
||||
.ForMember(d => d.IntoGroupState, u => u.MapFrom(s => s.EnrollStatus))
|
||||
.ForMember(d => d.OptTime, u => u.MapFrom(s => s.CreateTime))
|
||||
.ForMember(d => d.OptUserName, u => u.MapFrom(s => s.CreateUser.UserName));
|
||||
|
||||
CreateMap<Enroll, ConfirmationReviewerDTO>().IncludeMembers(t => t.Doctor, t => t.Doctor.Hospital)
|
||||
.ForMember(d => d.Id, u => u.MapFrom(s => s.Doctor.Id));
|
||||
CreateMap<Doctor, ConfirmationReviewerDTO>();
|
||||
CreateMap<Hospital, ConfirmationReviewerDTO>();
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-01-05 09:17:10
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
/// <summary> SystemDocumentView 列表视图模型 </summary>
|
||||
public class SystemDocumentView : SystemDocumentAddOrEdit
|
||||
{
|
||||
public string FullFilePath { get; set; } = string.Empty;
|
||||
public DateTime CreateTime { get; set; }
|
||||
public DateTime UpdateTime { get; set; }
|
||||
|
||||
public List<NeedConfirmedUserTypeView> NeedConfirmedUserTypeList { get; set; }=new List<NeedConfirmedUserTypeView>();
|
||||
}
|
||||
|
||||
public class UnionDocumentView : SystemDocumentAddOrEdit
|
||||
{
|
||||
public string FullFilePath { get; set; } = string.Empty;
|
||||
public DateTime CreateTime { get; set; }
|
||||
public DateTime UpdateTime { get; set; }
|
||||
|
||||
public bool IsSystemDoc { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class UnionDocumentWithConfirmInfoView: UnionDocumentView
|
||||
{
|
||||
public DateTime? ConfirmTime { get; set; }
|
||||
|
||||
public Guid? ConfirmUserId { get; set; }
|
||||
|
||||
public string UserName { get; set; } = string.Empty;
|
||||
|
||||
public string RealName { get; set; } = string.Empty;
|
||||
|
||||
public string UserTypeShortName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public class TrialUserDto
|
||||
{
|
||||
public Guid UserId { get; set; }
|
||||
public string UserName { get; set; } = string.Empty;
|
||||
|
||||
public string RealName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class DocumentUnionWithUserStatView: UnionDocumentView
|
||||
{
|
||||
public int? DocumentUserCount { get; set; }
|
||||
public int? DocumentConfirmedUserCount { get; set; }
|
||||
}
|
||||
|
||||
public class TrialUserUnionDocumentView
|
||||
{
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
public string UserTypeShortName { get; set; } = string.Empty;
|
||||
public string UserName { get; set; } = string.Empty;
|
||||
public string RealName { get; set; } = string.Empty;
|
||||
|
||||
|
||||
public int? SystemDocumentCount { get; set; }
|
||||
public int? TrialDocumentCount { get; set; }
|
||||
public int? TrialDocumentConfirmedCount { get; set; }
|
||||
public int? SystemDocumentConfirmedCount { get; set; }
|
||||
|
||||
//public List<UnionDocumentView> DocumentList { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///<summary>SystemDocumentQuery 列表查询参数模型</summary>
|
||||
public class SystemDocumentQuery : PageInput
|
||||
{
|
||||
|
||||
|
||||
public Guid? SystemDocumentId { get; set; }
|
||||
|
||||
public string Type { get; set; } = string.Empty;
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class TrialUserDocUnionQuery: PageInput
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public string Type { get; set; } = string.Empty;
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
|
||||
public class UserConfirmCommand
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
[NotDefault]
|
||||
public Guid DocumentId { get; set; }
|
||||
|
||||
|
||||
public bool isSystemDoc { get; set; }
|
||||
|
||||
|
||||
public string UserName { get; set; } = String.Empty;
|
||||
|
||||
public string PassWord { get; set; } = String.Empty;
|
||||
|
||||
public string SignText { get; set; } = String.Empty;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class DocumentTrialUnionQuery : TrialUserDocUnionQuery
|
||||
{
|
||||
|
||||
public Guid? UserTypeId { get; set; }
|
||||
public Guid? UserId { get; set; }
|
||||
}
|
||||
|
||||
///<summary> SystemDocumentAddOrEdit 列表查询参数模型</summary>
|
||||
public class SystemDocumentAddOrEdit
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string Type { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Path { get; set; } = string.Empty;
|
||||
|
||||
public bool IsAbandon { get; set; }
|
||||
|
||||
public int SignViewMinimumMinutes { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class AddOrEditSystemDocument : SystemDocumentAddOrEdit
|
||||
{
|
||||
|
||||
public List<Guid> NeedConfirmedUserTypeIdList { get; set; }=new List<Guid>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-01-05 09:17:10
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
/// <summary> TrialDocumentUserConfirmView 列表视图模型 </summary>
|
||||
public class TrialDocumentUserConfirmView
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid? TrialDocumentId { get; set; }
|
||||
|
||||
public DateTime? ConfirmTime { get; set; }
|
||||
|
||||
public Guid? ConfirmUserId { get; set; }
|
||||
|
||||
public string UserName { get; set; } = string.Empty;
|
||||
|
||||
public string RealName { get; set; } = string.Empty;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class NeedConfirmedUserTypeView
|
||||
{
|
||||
public Guid NeedConfirmUserTypeId { get; set; }
|
||||
|
||||
public string UserTypeShortName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-01-05 09:17:10
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
/// <summary> TrialDocumentView 列表视图模型 </summary>
|
||||
public class TrialDocumentView : TrialDocumentAddOrEdit
|
||||
{
|
||||
public string FullFilePath { get; set; } = String.Empty;
|
||||
|
||||
public bool IsSomeUserSigned{get;set;}
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
public Guid CreateUserId { get; set; }
|
||||
public DateTime UpdateTime { get; set; }
|
||||
public Guid UpdateUserId { get; set; }
|
||||
|
||||
public List<NeedConfirmedUserTypeView> NeedConfirmedUserTypeList { get; set; } = new List<NeedConfirmedUserTypeView>();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
///<summary>TrialDocumentQuery 列表查询参数模型</summary>
|
||||
public class TrialDocumentQuery : PageInput
|
||||
{
|
||||
|
||||
public string Type { get; set; } = String.Empty;
|
||||
|
||||
public string Name { get; set; } = String.Empty;
|
||||
|
||||
[NotDefault]
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
///<summary> TrialDocumentAddOrEdit 列表查询参数模型</summary>
|
||||
public class TrialDocumentAddOrEdit
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public string Type { get; set; } = String.Empty;
|
||||
public string Name { get; set; } = String.Empty;
|
||||
public string Path { get; set; } = String.Empty;
|
||||
|
||||
public string Description { get; set; } = String.Empty;
|
||||
public bool IsAbandon { get; set; }
|
||||
|
||||
public int SignViewMinimumMinutes { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class AddOrEditTrialDocument: TrialDocumentAddOrEdit
|
||||
{
|
||||
|
||||
public List<Guid> NeedConfirmedUserTypeIdList { get; set; } = new List<Guid>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-01-05 09:17:00
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// ISystemDocumentService
|
||||
/// </summary>
|
||||
public interface ISystemDocumentService
|
||||
{
|
||||
|
||||
//PageOutput<SystemDocumentView> GetSystemDocumentList(SystemDocumentQuery querySystemDocument);
|
||||
|
||||
|
||||
//IResponseOutput AddOrUpdateSystemDocument(AddOrEditSystemDocument addOrEditSystemDocument);
|
||||
|
||||
//IResponseOutput DeleteSystemDocument(Guid systemDocumentId);
|
||||
|
||||
Task<PageOutput<SystemDocumentView>> GetSystemDocumentListAsync(SystemDocumentQuery querySystemDocument);
|
||||
|
||||
Task<IResponseOutput> AddOrUpdateSystemDocumentAsync(AddOrEditSystemDocument addOrEditSystemDocument);
|
||||
|
||||
Task<IResponseOutput> DeleteSystemDocumentAsync(Guid systemDocumentId);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-01-05 09:17:03
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
public interface ITrialDocumentService
|
||||
{
|
||||
Task<IResponseOutput> AddOrUpdateTrialDocument(AddOrEditTrialDocument addOrEditTrialDocument);
|
||||
Task<IResponseOutput> DeleteTrialDocument(Guid trialDocumentId, Guid trialId);
|
||||
Task<PageOutput<UnionDocumentWithConfirmInfoView>> GetDocumentConfirmList(DocumentTrialUnionQuery querySystemDocument);
|
||||
Task<PageOutput<TrialDocumentView>> GetTrialDocumentList(TrialDocumentQuery queryTrialDocument);
|
||||
|
||||
Task<PageOutput<UnionDocumentWithConfirmInfoView>> GetUserDocumentList(TrialUserDocUnionQuery querySystemDocument);
|
||||
Task<IResponseOutput> SetFirstViewDocumentTime(Guid documentId, bool isSystemDoc);
|
||||
Task<IResponseOutput> UserConfirm(UserConfirmCommand userConfirmCommand);
|
||||
Task<List<TrialUserDto>> GetTrialUserSelect(Guid trialId);
|
||||
|
||||
|
||||
PageOutput<DocumentUnionWithUserStatView> GetTrialSystemDocumentList(DocumentTrialUnionQuery querySystemDocument);
|
||||
List<TrialUserUnionDocumentView> GetTrialUserDocumentList(Guid trialId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-01-05 09:17:03
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
|
||||
namespace IRaCIS.Core.Application.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// SystemDocumentService
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "Trial")]
|
||||
public class SystemDocumentService : BaseService, ISystemDocumentService
|
||||
{
|
||||
|
||||
private readonly IWebHostEnvironment _hostEnvironment;
|
||||
private readonly IRepository<SystemDocument> systemDocumentRepository;
|
||||
|
||||
public SystemDocumentService(IWebHostEnvironment hostEnvironment, IRepository<SystemDocument> systemDocumentRepository)
|
||||
{
|
||||
_hostEnvironment = hostEnvironment;
|
||||
this.systemDocumentRepository = systemDocumentRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 管理端列表
|
||||
/// </summary>
|
||||
/// <param name="querySystemDocument"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<SystemDocumentView>> GetSystemDocumentListAsync(SystemDocumentQuery querySystemDocument)
|
||||
{
|
||||
var systemDocumentQueryable = systemDocumentRepository
|
||||
.WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name))
|
||||
.WhereIf(!string.IsNullOrEmpty(querySystemDocument.Type), t => t.Type.Contains(querySystemDocument.Type))
|
||||
.ProjectTo<SystemDocumentView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken, userId = _userInfo.Id });
|
||||
|
||||
return await systemDocumentQueryable.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);
|
||||
}
|
||||
|
||||
public async Task<IResponseOutput> AddOrUpdateSystemDocumentAsync(AddOrEditSystemDocument addOrEditSystemDocument)
|
||||
{
|
||||
if (addOrEditSystemDocument.Id == null)
|
||||
{
|
||||
var entity = _mapper.Map<SystemDocument>(addOrEditSystemDocument);
|
||||
|
||||
|
||||
if (await systemDocumentRepository.AnyAsync(t => t.Type == addOrEditSystemDocument.Type && t.Name == addOrEditSystemDocument.Name))
|
||||
{
|
||||
return ResponseOutput.NotOk("同类型已存在该文件名");
|
||||
}
|
||||
|
||||
await systemDocumentRepository.AddAsync(entity,true);
|
||||
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var document = await systemDocumentRepository.Where(t => t.Id == addOrEditSystemDocument.Id, true).Include(t => t.NeedConfirmedUserTypeList).FirstOrDefaultAsync();
|
||||
|
||||
if (document == null) return Null404NotFound(document);
|
||||
|
||||
if (await systemDocumentRepository.AnyAsync(t => t.Type == addOrEditSystemDocument.Type && t.Name == addOrEditSystemDocument.Name && t.Id != addOrEditSystemDocument.Id))
|
||||
{
|
||||
return ResponseOutput.NotOk("同类型已存在该文件名");
|
||||
}
|
||||
var dbDocumentType = document.Type;
|
||||
|
||||
_mapper.Map(addOrEditSystemDocument, document);
|
||||
|
||||
if (dbDocumentType != addOrEditSystemDocument.Type)
|
||||
{
|
||||
var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).IfNullThrowException().FullName;
|
||||
var beforeFilePath = Path.Combine(rootPath, document.Path);
|
||||
|
||||
document.Path = document.Path.Replace(dbDocumentType, addOrEditSystemDocument.Type);
|
||||
|
||||
var nowPath = Path.Combine(rootPath, document.Path);
|
||||
|
||||
if (File.Exists(beforeFilePath))
|
||||
{
|
||||
File.Move(beforeFilePath, nowPath, true);
|
||||
File.Delete(beforeFilePath);
|
||||
}
|
||||
|
||||
}
|
||||
var success = _repository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Ok(document.Id.ToString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete("{systemDocumentId:guid}")]
|
||||
public async Task<IResponseOutput> DeleteSystemDocumentAsync(Guid systemDocumentId)
|
||||
{
|
||||
|
||||
if (await _repository.Where<SystemDocument>(t => t.Id == systemDocumentId).AnyAsync(u => u.SystemDocConfirmedUserList.Any()))
|
||||
{
|
||||
return ResponseOutput.NotOk("该文档下已有签名的用户");
|
||||
}
|
||||
|
||||
var success = await _repository.DeleteFromQueryAsync<SystemDocument>(t => t.Id == systemDocumentId);
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,642 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-01-05 09:17:03
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
namespace IRaCIS.Core.Application.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// TrialDocumentService
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "Trial")]
|
||||
public class TrialDocumentService : BaseService, ITrialDocumentService
|
||||
{
|
||||
|
||||
|
||||
private readonly IWebHostEnvironment _hostEnvironment;
|
||||
private readonly IRepository<TrialDocument> trialDocumentRepository;
|
||||
|
||||
public TrialDocumentService(IWebHostEnvironment hostEnvironment, IRepository<TrialDocument> trialDocumentRepository)
|
||||
{
|
||||
_hostEnvironment = hostEnvironment;
|
||||
this.trialDocumentRepository = trialDocumentRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setting 界面的 项目所有文档列表
|
||||
/// </summary>
|
||||
/// <param name="queryTrialDocument"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<TrialDocumentView>> GetTrialDocumentList(TrialDocumentQuery queryTrialDocument)
|
||||
{
|
||||
|
||||
var trialDocumentQueryable = trialDocumentRepository.Where(t => t.TrialId == queryTrialDocument.TrialId)
|
||||
.WhereIf(!string.IsNullOrEmpty(queryTrialDocument.Name), t => t.Name.Contains(queryTrialDocument.Name))
|
||||
.WhereIf(!string.IsNullOrEmpty(queryTrialDocument.Type), t => t.Type.Contains(queryTrialDocument.Type))
|
||||
.ProjectTo<TrialDocumentView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken });
|
||||
|
||||
return await trialDocumentQueryable.ToPagedListAsync(queryTrialDocument.PageIndex, queryTrialDocument.PageSize, queryTrialDocument.SortField, queryTrialDocument.Asc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 具体用户看到的 系统文件列表 + 项目类型文档
|
||||
/// </summary>
|
||||
/// <param name="querySystemDocument"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<UnionDocumentWithConfirmInfoView>> GetUserDocumentList(TrialUserDocUnionQuery querySystemDocument)
|
||||
{
|
||||
#region https://github.com/dotnet/efcore/issues/16243 操作不行
|
||||
////系统文档查询
|
||||
//var systemDocumentQueryable = _systemDocumentRepository
|
||||
// .WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
|
||||
// .WhereIf(!_userInfo.IsAdmin, t => t.IsAbandon == false || (t.IsAbandon == true && t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
|
||||
//.ProjectTo<UnionDocumentView>(_mapper.ConfigurationProvider, new { userId = _userInfo.Id, token = _userInfo.UserToken });
|
||||
|
||||
////项目文档查询
|
||||
//var trialDocQueryable = _trialDocumentRepository.Where(t => t.TrialId == querySystemDocument.TrialId)
|
||||
// .WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
|
||||
// .WhereIf(!_userInfo.IsAdmin, t => t.IsAbandon == false || (t.IsAbandon == true && t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
|
||||
// .ProjectTo<UnionDocumentView>(_mapper.ConfigurationProvider, new { userId = _userInfo.Id, token = _userInfo.UserToken });
|
||||
|
||||
//var unionQuery = systemDocumentQueryable.Union(trialDocQueryable);
|
||||
// .WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name))
|
||||
// .WhereIf(!string.IsNullOrEmpty(querySystemDocument.Type), t => t.Type.Contains(querySystemDocument.Type));
|
||||
#endregion
|
||||
|
||||
#region 仅仅文档信息
|
||||
|
||||
////系统文档查询
|
||||
//var systemDocumentQueryable = _systemDocumentRepository
|
||||
// .WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
|
||||
// .WhereIf(!_userInfo.IsAdmin, t => t.IsAbandon == false || (t.IsAbandon == true && t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
|
||||
// .Select(t => new UnionDocumentView()
|
||||
// {
|
||||
// Id = t.Id,
|
||||
// IsSystemDoc = true,
|
||||
// CreateTime = t.CreateTime,
|
||||
// FullFilePath = t.Path + "?access_token=" + _userInfo.UserToken,
|
||||
// IsAbandon = t.IsAbandon,
|
||||
// Name = t.Name,
|
||||
// Path = t.Path,
|
||||
// Type = t.Type,
|
||||
// UpdateTime = t.UpdateTime,
|
||||
// SignViewMinimumMinutes = t.SignViewMinimumMinutes,
|
||||
|
||||
// });
|
||||
|
||||
////项目文档查询
|
||||
//var trialDocQueryable = _trialDocumentRepository.Where(t => t.TrialId == querySystemDocument.TrialId)
|
||||
// .WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
|
||||
// .WhereIf(!_userInfo.IsAdmin, t => t.IsAbandon == false || (t.IsAbandon == true && t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
|
||||
// .Select(t => new UnionDocumentView()
|
||||
// {
|
||||
// Id = t.Id,
|
||||
// IsSystemDoc = false,
|
||||
// CreateTime = t.CreateTime,
|
||||
// FullFilePath = t.Path + "?access_token=" + _userInfo.UserToken,
|
||||
// IsAbandon = t.IsAbandon,
|
||||
// Name = t.Name,
|
||||
// Path = t.Path,
|
||||
// Type = t.Type,
|
||||
// UpdateTime = t.UpdateTime,
|
||||
// SignViewMinimumMinutes = t.SignViewMinimumMinutes,
|
||||
|
||||
// });
|
||||
|
||||
#endregion
|
||||
|
||||
var trialFininshedTime = await _repository.Where<Trial>(t => t.Id == querySystemDocument.TrialId).Select(t => t.TrialFinishedTime).FirstOrDefaultAsync();
|
||||
|
||||
//系统文档查询
|
||||
var systemDocumentQueryable = from needConfirmedUserType in _repository.Where<SystemDocNeedConfirmedUserType>(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId)
|
||||
//.Where(u => u.UserTypeRole.UserList.SelectMany(cc => cc.UserTrials.Where(t => t.TrialId == querySystemDocument.TrialId)).Any(e => e.Trial.TrialFinishedTime < u.SystemDocument.CreateTime))
|
||||
.WhereIf(trialFininshedTime != null, u => u.SystemDocument.CreateTime < trialFininshedTime)
|
||||
.WhereIf(!_userInfo.IsAdmin, t => t.SystemDocument.IsAbandon == false || (t.SystemDocument.IsAbandon == true && t.SystemDocument.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
|
||||
|
||||
join trialUser in _repository.Where<TrialUser>(t => t.TrialId == querySystemDocument.TrialId && t.UserId == _userInfo.Id)
|
||||
on needConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId
|
||||
join confirm in _repository.GetQueryable<SystemDocConfirmedUser>() on new { ConfirmUserId = trialUser.UserId, SystemDocumentId = needConfirmedUserType.SystemDocumentId } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
|
||||
from confirm in cc.DefaultIfEmpty()
|
||||
select new UnionDocumentWithConfirmInfoView()
|
||||
{
|
||||
IsSystemDoc = true,
|
||||
|
||||
Id = needConfirmedUserType.SystemDocument.Id,
|
||||
CreateTime = needConfirmedUserType.SystemDocument.CreateTime,
|
||||
IsAbandon = needConfirmedUserType.SystemDocument.IsAbandon,
|
||||
SignViewMinimumMinutes = needConfirmedUserType.SystemDocument.SignViewMinimumMinutes,
|
||||
Name = needConfirmedUserType.SystemDocument.Name,
|
||||
Path = needConfirmedUserType.SystemDocument.Path,
|
||||
Type = needConfirmedUserType.SystemDocument.Type,
|
||||
UpdateTime = needConfirmedUserType.SystemDocument.UpdateTime,
|
||||
|
||||
FullFilePath = needConfirmedUserType.SystemDocument.Path + "?access_token=" + _userInfo.UserToken,
|
||||
|
||||
ConfirmUserId = confirm.ConfirmUserId,
|
||||
ConfirmTime = confirm.ConfirmTime,
|
||||
RealName = trialUser.User.LastName + " / " + trialUser.User.FirstName,
|
||||
UserName = trialUser.User.UserName,
|
||||
UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName
|
||||
};
|
||||
|
||||
//项目文档查询
|
||||
var trialDocQueryable = from trialDoc in trialDocumentRepository.Where(t => t.TrialId == querySystemDocument.TrialId)
|
||||
.WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
|
||||
.WhereIf(!_userInfo.IsAdmin, t => t.IsAbandon == false || (t.IsAbandon == true && t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
|
||||
|
||||
join trialUser in _repository.Where<TrialUser>(t => t.TrialId == querySystemDocument.TrialId && t.UserId == _userInfo.Id) on trialDoc.TrialId equals trialUser.TrialId
|
||||
join confirm in _repository.Where<TrialDocUserTypeConfirmedUser>(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 + "?access_token=" + _userInfo.UserToken,
|
||||
IsAbandon = trialDoc.IsAbandon,
|
||||
Name = trialDoc.Name,
|
||||
Path = trialDoc.Path,
|
||||
Type = trialDoc.Type,
|
||||
UpdateTime = trialDoc.UpdateTime,
|
||||
SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes,
|
||||
|
||||
ConfirmUserId = confirm.ConfirmUserId,
|
||||
ConfirmTime = confirm.ConfirmTime,
|
||||
RealName = trialUser.User.LastName + " / " + trialUser.User.FirstName,
|
||||
UserName = trialUser.User.UserName,
|
||||
UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
var unionQuery = systemDocumentQueryable.Union(trialDocQueryable)
|
||||
.WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name))
|
||||
.WhereIf(!string.IsNullOrEmpty(querySystemDocument.Type), t => t.Type.Contains(querySystemDocument.Type));
|
||||
|
||||
return await unionQuery.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户是否有文档未签署
|
||||
/// </summary>
|
||||
/// <param name="trialId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{trialId:guid}")]
|
||||
public async Task<bool> GetUserIsHaveDocumentNeedSign(Guid trialId)
|
||||
{
|
||||
var trialFininshedTime = await _repository.Where<Trial>(t => t.Id == trialId).Select(t => t.TrialFinishedTime).FirstOrDefaultAsync();
|
||||
|
||||
//系统文档查询
|
||||
var systemDocumentQueryable = from needConfirmedUserType in _repository.Where<SystemDocNeedConfirmedUserType>(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId)
|
||||
//.Where(u => u.UserTypeRole.UserList.SelectMany(cc => cc.UserTrials.Where(t => t.TrialId == querySystemDocument.TrialId)).Any(e => e.Trial.TrialFinishedTime < u.SystemDocument.CreateTime))
|
||||
.WhereIf(trialFininshedTime != null, u => u.SystemDocument.CreateTime < trialFininshedTime)
|
||||
.WhereIf(!_userInfo.IsAdmin, t => t.SystemDocument.IsAbandon == false || (t.SystemDocument.IsAbandon == true && t.SystemDocument.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
|
||||
|
||||
join trialUser in _repository.Where<TrialUser>(t => t.TrialId == trialId && t.UserId == _userInfo.Id)
|
||||
on needConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId
|
||||
join confirm in _repository.GetQueryable<SystemDocConfirmedUser>() on new { ConfirmUserId = trialUser.UserId, SystemDocumentId = needConfirmedUserType.SystemDocumentId } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
|
||||
from confirm in cc.DefaultIfEmpty()
|
||||
select new
|
||||
{
|
||||
//ConfirmUserId = confirm.ConfirmUserId,
|
||||
ConfirmTime = confirm.ConfirmTime,
|
||||
};
|
||||
|
||||
//项目文档查询
|
||||
var trialDocQueryable = from trialDoc in trialDocumentRepository.Where(t => t.TrialId == trialId)
|
||||
.WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
|
||||
.WhereIf(!_userInfo.IsAdmin, t => t.IsAbandon == false || (t.IsAbandon == true && t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
|
||||
|
||||
join trialUser in _repository.Where<TrialUser>(t => t.TrialId == trialId && t.UserId == _userInfo.Id) on trialDoc.TrialId equals trialUser.TrialId
|
||||
join confirm in _repository.Where<TrialDocUserTypeConfirmedUser>(t => t.TrialDocument.TrialId == trialId) on
|
||||
new { trialUser.UserId, TrialDocumentId = trialDoc.Id } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
|
||||
from confirm in cc.DefaultIfEmpty()
|
||||
select new
|
||||
{
|
||||
//ConfirmUserId = confirm.ConfirmUserId,
|
||||
ConfirmTime = confirm.ConfirmTime,
|
||||
};
|
||||
|
||||
var unionQuery = systemDocumentQueryable.Union(trialDocQueryable);
|
||||
|
||||
return await unionQuery.AnyAsync(t => t.ConfirmTime == null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取确认列表情况 项目文档+系统文档+具体的人
|
||||
/// </summary>
|
||||
/// <param name="querySystemDocument"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<UnionDocumentWithConfirmInfoView>> GetDocumentConfirmList(DocumentTrialUnionQuery querySystemDocument)
|
||||
{
|
||||
|
||||
|
||||
#region linq join 方式
|
||||
//var trialDocQuery = from trialDocumentNeedConfirmedUserType in _trialDocumentNeedConfirmedUserTypeRepository.Where(t => t.TrialDocument.TrialId == querySystemDocument.TrialId)
|
||||
// join trialUser in _trialUserRepository.Where(t => t.TrialId == querySystemDocument.TrialId)
|
||||
// .WhereIf(querySystemDocument.UserId != null, t => t.UserId == querySystemDocument.UserId)
|
||||
// on trialDocumentNeedConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId
|
||||
|
||||
// join confirm in _trialDocuserConfrimedRepository.AsQueryable() on trialUser.UserId equals confirm.ConfirmUserId into cc
|
||||
// from confirm in cc.DefaultIfEmpty()
|
||||
// select new UnionDocumentConfirmListView()
|
||||
// {
|
||||
// Id = trialDocumentNeedConfirmedUserType.TrialDocument.Id,
|
||||
// CreateTime = trialDocumentNeedConfirmedUserType.TrialDocument.CreateTime,
|
||||
// IsAbandon = trialDocumentNeedConfirmedUserType.TrialDocument.IsAbandon,
|
||||
// SignViewMinimumMinutes = trialDocumentNeedConfirmedUserType.TrialDocument.SignViewMinimumMinutes,
|
||||
// Name = trialDocumentNeedConfirmedUserType.TrialDocument.Name,
|
||||
// Path = trialDocumentNeedConfirmedUserType.TrialDocument.Path,
|
||||
// Type = trialDocumentNeedConfirmedUserType.TrialDocument.Type,
|
||||
// UpdateTime = trialDocumentNeedConfirmedUserType.TrialDocument.UpdateTime,
|
||||
|
||||
// UserConfirmInfo = /*confirm == null ? null : */new UnionDocumentUserConfirmView()
|
||||
// {
|
||||
|
||||
// ConfirmUserId = confirm.ConfirmUserId,
|
||||
// ConfirmTime = confirm.ConfirmTime,
|
||||
// RealName = trialUser.User.LastName + " / " + trialUser.User.LastName,
|
||||
// UserName = trialUser.User.UserName,
|
||||
// },
|
||||
|
||||
// FullFilePath = trialDocumentNeedConfirmedUserType.TrialDocument.Path + "?access_token=" + _userInfo.UserToken
|
||||
// };
|
||||
|
||||
#endregion
|
||||
|
||||
var trialFininshedTime = await _repository.Where<Trial>(t => t.Id == querySystemDocument.TrialId).Select(t => t.TrialFinishedTime).FirstOrDefaultAsync();
|
||||
|
||||
var trialDocQuery = from trialDocumentNeedConfirmedUserType in _repository.Where<TrialDocNeedConfirmedUserType>(t => t.TrialDocument.TrialId == querySystemDocument.TrialId)
|
||||
//.Where(t => t.TrialDocument.Trial.TrialUserList.Any(cc => cc.User.UserTypeId == t.NeedConfirmUserTypeId))
|
||||
join trialUser in _repository.Where<TrialUser>(t => t.TrialId == querySystemDocument.TrialId)
|
||||
.WhereIf(querySystemDocument.UserId != null, t => t.UserId == querySystemDocument.UserId)
|
||||
.WhereIf(querySystemDocument.UserTypeId != null, t => t.User.UserTypeId == querySystemDocument.UserTypeId)
|
||||
on trialDocumentNeedConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId
|
||||
|
||||
join confirm in _repository.Where<TrialDocUserTypeConfirmedUser>(t => t.TrialDocument.TrialId == querySystemDocument.TrialId) on
|
||||
new { trialUser.UserId, TrialDocumentId = trialDocumentNeedConfirmedUserType.TrialDocumentId } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
|
||||
from confirm in cc.DefaultIfEmpty()
|
||||
select new UnionDocumentWithConfirmInfoView()
|
||||
{
|
||||
IsSystemDoc = false,
|
||||
|
||||
Id = trialDocumentNeedConfirmedUserType.TrialDocument.Id,
|
||||
CreateTime = trialDocumentNeedConfirmedUserType.TrialDocument.CreateTime,
|
||||
IsAbandon = trialDocumentNeedConfirmedUserType.TrialDocument.IsAbandon,
|
||||
SignViewMinimumMinutes = trialDocumentNeedConfirmedUserType.TrialDocument.SignViewMinimumMinutes,
|
||||
Name = trialDocumentNeedConfirmedUserType.TrialDocument.Name,
|
||||
Path = trialDocumentNeedConfirmedUserType.TrialDocument.Path,
|
||||
Type = trialDocumentNeedConfirmedUserType.TrialDocument.Type,
|
||||
UpdateTime = trialDocumentNeedConfirmedUserType.TrialDocument.UpdateTime,
|
||||
|
||||
|
||||
|
||||
ConfirmUserId = confirm.ConfirmUserId,
|
||||
ConfirmTime = confirm.ConfirmTime,
|
||||
RealName = trialUser.User.LastName + " / " + trialUser.User.FirstName,
|
||||
UserName = trialUser.User.UserName,
|
||||
UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName,
|
||||
|
||||
FullFilePath = trialDocumentNeedConfirmedUserType.TrialDocument.Path + "?access_token=" + _userInfo.UserToken
|
||||
};
|
||||
|
||||
|
||||
|
||||
var systemDocQuery = from needConfirmEdUserType in _repository.WhereIf<SystemDocNeedConfirmedUserType>(trialFininshedTime != null, u => u.SystemDocument.CreateTime < trialFininshedTime)
|
||||
|
||||
join trialUser in _repository.Where<TrialUser>(t => t.TrialId == querySystemDocument.TrialId)
|
||||
.WhereIf(querySystemDocument.UserId != null, t => t.UserId == querySystemDocument.UserId)
|
||||
on needConfirmEdUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId
|
||||
join confirm in _repository.GetQueryable<SystemDocConfirmedUser>() on new { ConfirmUserId = trialUser.UserId, SystemDocumentId = needConfirmEdUserType.SystemDocumentId } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
|
||||
from confirm in cc.DefaultIfEmpty()
|
||||
select new UnionDocumentWithConfirmInfoView()
|
||||
{
|
||||
IsSystemDoc = true,
|
||||
|
||||
Id = needConfirmEdUserType.SystemDocument.Id,
|
||||
CreateTime = needConfirmEdUserType.SystemDocument.CreateTime,
|
||||
IsAbandon = needConfirmEdUserType.SystemDocument.IsAbandon,
|
||||
SignViewMinimumMinutes = needConfirmEdUserType.SystemDocument.SignViewMinimumMinutes,
|
||||
Name = needConfirmEdUserType.SystemDocument.Name,
|
||||
Path = needConfirmEdUserType.SystemDocument.Path,
|
||||
Type = needConfirmEdUserType.SystemDocument.Type,
|
||||
UpdateTime = needConfirmEdUserType.SystemDocument.UpdateTime,
|
||||
|
||||
|
||||
ConfirmUserId = confirm.ConfirmUserId,
|
||||
ConfirmTime = confirm.ConfirmTime,
|
||||
RealName = trialUser.User.LastName + " / " + trialUser.User.FirstName,
|
||||
UserName = trialUser.User.UserName,
|
||||
UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName,
|
||||
|
||||
FullFilePath = needConfirmEdUserType.SystemDocument.Path + "?access_token=" + _userInfo.UserToken
|
||||
};
|
||||
|
||||
var unionQuery = trialDocQuery.Union(systemDocQuery)
|
||||
.WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name))
|
||||
.WhereIf(!string.IsNullOrEmpty(querySystemDocument.Type), t => t.Type.Contains(querySystemDocument.Type));
|
||||
|
||||
return await unionQuery.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpGet("{trialId:guid}")]
|
||||
public async Task<List<TrialUserDto>> GetTrialUserSelect(Guid trialId)
|
||||
{
|
||||
return await _repository.Where<TrialUser>(t => t.TrialId == trialId)
|
||||
.Select(t => new TrialUserDto() { UserId = t.UserId, RealName = t.User.LastName + " / " + t.User.FirstName, UserName = t.User.UserName })
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpGet("{trialId:guid}")]
|
||||
public async Task<List<string>> GetTrialDocAndSystemDocType(Guid trialId)
|
||||
{
|
||||
return await trialDocumentRepository.Where(t => t.TrialId == trialId).Select(t => t.Type).Union(_repository.GetQueryable<SystemDocument>().Select(t => t.Type)).Distinct()
|
||||
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IResponseOutput> AddOrUpdateTrialDocument(AddOrEditTrialDocument addOrEditTrialDocument)
|
||||
{
|
||||
if (addOrEditTrialDocument.Id == null)
|
||||
{
|
||||
var entity = _mapper.Map<TrialDocument>(addOrEditTrialDocument);
|
||||
|
||||
|
||||
if (await trialDocumentRepository.AnyAsync(t => t.Type == addOrEditTrialDocument.Type && t.Name == addOrEditTrialDocument.Name && t.TrialId == addOrEditTrialDocument.TrialId))
|
||||
{
|
||||
return ResponseOutput.NotOk("同类型已存在该文件名");
|
||||
}
|
||||
|
||||
await _repository.AddAsync(entity, true);
|
||||
return ResponseOutput.Ok(entity.Id.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (await trialDocumentRepository.AnyAsync(t => t.Type == addOrEditTrialDocument.Type && t.Name == addOrEditTrialDocument.Name && t.Id != addOrEditTrialDocument.Id && t.TrialId == addOrEditTrialDocument.TrialId))
|
||||
{
|
||||
return ResponseOutput.NotOk("同类型已存在该文件名");
|
||||
}
|
||||
|
||||
var document = trialDocumentRepository.Where(t => t.Id == addOrEditTrialDocument.Id, true).Include(t => t.NeedConfirmedUserTypeList).FirstOrDefault();
|
||||
|
||||
if (document == null) return Null404NotFound(document);
|
||||
|
||||
var dbDocumentType = document.Type;
|
||||
|
||||
_mapper.Map(addOrEditTrialDocument, document);
|
||||
|
||||
if (dbDocumentType != addOrEditTrialDocument.Type)
|
||||
{
|
||||
|
||||
|
||||
var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).IfNullThrowException().FullName;
|
||||
var beforeFilePath = Path.Combine(rootPath, document.Path);
|
||||
|
||||
document.Path = document.Path.Replace(dbDocumentType, addOrEditTrialDocument.Type);
|
||||
|
||||
var nowPath = Path.Combine(rootPath, document.Path);
|
||||
|
||||
if (File.Exists(beforeFilePath))
|
||||
{
|
||||
File.Move(beforeFilePath, nowPath, true);
|
||||
File.Delete(beforeFilePath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var success = await _repository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Ok(document.Id.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 已签名的文档 不允许删除
|
||||
/// </summary>
|
||||
/// <param name="trialDocumentId"></param>
|
||||
/// <param name="trialId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{trialId:guid}/{trialDocumentId:guid}")]
|
||||
public async Task<IResponseOutput> DeleteTrialDocument(Guid trialDocumentId, Guid trialId)
|
||||
{
|
||||
if (await trialDocumentRepository.Where(t => t.Id == trialDocumentId).AnyAsync(t => t.TrialDocConfirmedUserList.Any()))
|
||||
{
|
||||
return ResponseOutput.NotOk("该文档,已有用户签名 不允许删除");
|
||||
}
|
||||
|
||||
var success = await trialDocumentRepository.DeleteFromQueryAsync(t => t.Id == trialDocumentId);
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 浏览文档说明时调用,记录第一次看的时间
|
||||
/// </summary>
|
||||
/// <param name="documentId"></param>
|
||||
/// <param name="isSystemDoc"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("{trialId:guid}/{documentId:guid}/{isSystemDoc:bool}")]
|
||||
[UnitOfWork]
|
||||
public async Task<IResponseOutput> SetFirstViewDocumentTime(Guid documentId, bool isSystemDoc)
|
||||
{
|
||||
|
||||
var success = false;
|
||||
if (isSystemDoc)
|
||||
{
|
||||
await _repository.AddAsync(new SystemDocConfirmedUser() { SystemDocumentId = documentId, SignFirstViewTime = DateTime.Now });
|
||||
//success = await _repository.UpdateFromQueryAsync<SystemDocConfirmedUser>(t => t.Id == documentId, d => new SystemDocConfirmedUser() { SignFirstViewTime = DateTime.Now });
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
await _repository.AddAsync(new TrialDocUserTypeConfirmedUser() { TrialDocumentId = documentId, SignFirstViewTime = DateTime.Now });
|
||||
|
||||
//success = await _repository.UpdateFromQueryAsync<TrialDocUserTypeConfirmedUser>(t => t.Id == documentId , d => new TrialDocUserTypeConfirmedUser() { SignFirstViewTime = DateTime.Now });
|
||||
}
|
||||
|
||||
success= await _repository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户 签名某个文档
|
||||
/// </summary>
|
||||
|
||||
/// <returns></returns>
|
||||
[NonDynamicMethod]
|
||||
public async Task<IResponseOutput> UserConfirm(UserConfirmCommand userConfirmCommand)
|
||||
{
|
||||
|
||||
var user = await _repository.FirstOrDefaultAsync<User>(u => u.UserName == userConfirmCommand.UserName && u.Password == userConfirmCommand.PassWord);
|
||||
if (user == null)
|
||||
{
|
||||
return ResponseOutput.NotOk("password error");
|
||||
}
|
||||
else if (user.Status == UserStateEnum.Disable)
|
||||
{
|
||||
return ResponseOutput.NotOk("The user has been disabled!");
|
||||
}
|
||||
|
||||
|
||||
if (userConfirmCommand.isSystemDoc)
|
||||
{
|
||||
if (await _repository.AnyAsync<SystemDocConfirmedUser>(t => t.SystemDocumentId == userConfirmCommand.DocumentId && t.ConfirmUserId == _userInfo.Id))
|
||||
{
|
||||
return ResponseOutput.NotOk("该文档已经签名");
|
||||
}
|
||||
if (!await _repository.AnyAsync<SystemDocument>(t => t.Id == userConfirmCommand.DocumentId) || await trialDocumentRepository.AnyAsync(t => t.Id == userConfirmCommand.DocumentId && t.IsAbandon))
|
||||
{
|
||||
return ResponseOutput.NotOk("文件已删除或者废除,签署失败!");
|
||||
}
|
||||
|
||||
await _repository.AddAsync(new SystemDocConfirmedUser() { ConfirmTime = DateTime.Now, ConfirmUserId = _userInfo.Id, SystemDocumentId = userConfirmCommand.DocumentId });
|
||||
}
|
||||
else
|
||||
{
|
||||
if (await _repository.AnyAsync<TrialDocUserTypeConfirmedUser>(t => t.TrialDocumentId == userConfirmCommand.DocumentId && t.ConfirmUserId == _userInfo.Id))
|
||||
{
|
||||
return ResponseOutput.NotOk("该文档已经签名");
|
||||
}
|
||||
|
||||
if (!await trialDocumentRepository.AnyAsync(t => t.Id == userConfirmCommand.DocumentId) || await _repository.AnyAsync<TrialDocument>(t => t.Id == userConfirmCommand.DocumentId && t.IsAbandon))
|
||||
{
|
||||
return ResponseOutput.NotOk("文件已删除或者废除,签署失败!");
|
||||
}
|
||||
|
||||
await _repository.AddAsync(new TrialDocUserTypeConfirmedUser() { ConfirmTime = DateTime.Now, ConfirmUserId = _userInfo.Id, TrialDocumentId = userConfirmCommand.DocumentId });
|
||||
}
|
||||
|
||||
await _repository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 用户 废除某个文档
|
||||
/// </summary>
|
||||
/// <param name="documentId"></param>
|
||||
/// <param name="isSystemDoc"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("{documentId:guid}/{isSystemDoc:bool}")]
|
||||
public async Task<IResponseOutput> UserAbandonDoc(Guid documentId, bool isSystemDoc)
|
||||
{
|
||||
if (isSystemDoc)
|
||||
{
|
||||
await _repository.UpdateFromQueryAsync<SystemDocument>(t => t.Id == documentId, u => new SystemDocument() { IsAbandon = true });
|
||||
}
|
||||
else
|
||||
{
|
||||
await trialDocumentRepository.UpdateFromQueryAsync(t => t.Id == documentId, u => new TrialDocument() { IsAbandon = true });
|
||||
}
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从项目下参与者的维度 先看人员列表(展示统计数字) 点击数字 再看人员具体签署的 系统文档+项目文档(共用上面与人相关的具体文档列表)
|
||||
/// </summary>
|
||||
/// <param name="trialId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{trialId:guid}")]
|
||||
public List<TrialUserUnionDocumentView> GetTrialUserDocumentList(Guid trialId)
|
||||
{
|
||||
var query = _repository.Where<TrialUser>(t => t.TrialId == trialId)
|
||||
.Select(t => new TrialUserUnionDocumentView()
|
||||
{
|
||||
UserId = t.UserId,
|
||||
UserName = t.User.UserName,
|
||||
RealName = t.User.LastName + " / " + t.User.FirstName,
|
||||
UserTypeShortName = t.User.UserTypeRole.UserTypeShortName,
|
||||
TrialDocumentCount = t.Trial.TrialDocumentList.Count(u => u.NeedConfirmedUserTypeList.Any(k => k.NeedConfirmUserTypeId == t.User.UserTypeId)),
|
||||
TrialDocumentConfirmedCount = t.Trial.TrialDocumentList.SelectMany(u => u.TrialDocConfirmedUserList).Count(k => k.ConfirmUserId == t.UserId),
|
||||
SystemDocumentConfirmedCount = t.User.SystemDocConfirmedList.Count(),
|
||||
//这样写不行
|
||||
//SystemDocumentCount = _systemDocumentRepository.Where(s => s.NeedConfirmedUserTypeList.Any(kk => kk.NeedConfirmUserTypeId == t.User.UserTypeId))
|
||||
// .WhereIf(!_userInfo.IsAdmin, s => s.IsAbandon == false || (s.IsAbandon == true && s.SystemDocConfirmedUserList.Any(uu => uu.ConfirmUserId == t.UserId))).Count()
|
||||
SystemDocumentCount = t.User.UserTypeRole.SystemDocNeedConfirmedUserTypeList.Where(cc => cc.NeedConfirmUserTypeId == t.User.UserTypeId).Select(y => y.SystemDocument).Count()
|
||||
});
|
||||
|
||||
return query.ToList();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 从 文档的维度 先看到文档列表(系统文档+项目文档 以及需要确认的人数 和已经确认人数) 点击数字查看某文档下面人确认情况
|
||||
/// </summary>
|
||||
/// <param name="querySystemDocument"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public PageOutput<DocumentUnionWithUserStatView> GetTrialSystemDocumentList(DocumentTrialUnionQuery querySystemDocument)
|
||||
{
|
||||
var systemDocumentQueryable = _repository
|
||||
.WhereIf<SystemDocument>(!_userInfo.IsAdmin, t => t.IsAbandon == false)
|
||||
.Select(t => new DocumentUnionWithUserStatView()
|
||||
{
|
||||
Id = t.Id,
|
||||
IsSystemDoc = true,
|
||||
CreateTime = t.CreateTime,
|
||||
FullFilePath = t.Path + "?access_token=" + _userInfo.UserToken,
|
||||
IsAbandon = t.IsAbandon,
|
||||
Name = t.Name,
|
||||
Path = t.Path,
|
||||
Type = t.Type,
|
||||
UpdateTime = t.UpdateTime,
|
||||
SignViewMinimumMinutes = t.SignViewMinimumMinutes,
|
||||
DocumentConfirmedUserCount = t.SystemDocConfirmedUserList.Count(),
|
||||
|
||||
//DocumentUserCount= _trialUserRepository.Where(tu=>tu.TrialId== querySystemDocument.TrialId).Count(u=>t.NeedConfirmedUserTypeList.Any(cc=>cc.NeedConfirmUserTypeId== u.User.UserTypeId ))
|
||||
DocumentUserCount = t.NeedConfirmedUserTypeList.SelectMany(u => u.UserTypeRole.UserList.SelectMany(b => b.UserTrials.Where(r => r.TrialId == querySystemDocument.TrialId))).Count()
|
||||
});
|
||||
|
||||
var trialDocQueryable = trialDocumentRepository.Where(t => t.TrialId == querySystemDocument.TrialId).Select(t => new DocumentUnionWithUserStatView()
|
||||
{
|
||||
Id = t.Id,
|
||||
IsSystemDoc = false,
|
||||
CreateTime = t.CreateTime,
|
||||
FullFilePath = t.Path + "?access_token=" + _userInfo.UserToken,
|
||||
IsAbandon = t.IsAbandon,
|
||||
Name = t.Name,
|
||||
Path = t.Path,
|
||||
Type = t.Type,
|
||||
UpdateTime = t.UpdateTime,
|
||||
SignViewMinimumMinutes = t.SignViewMinimumMinutes,
|
||||
|
||||
DocumentConfirmedUserCount = t.TrialDocConfirmedUserList.Count(),
|
||||
DocumentUserCount = t.Trial.TrialUserList.Count(cc => t.NeedConfirmedUserTypeList.Any(k => k.NeedConfirmUserTypeId == cc.User.UserTypeId))
|
||||
|
||||
});
|
||||
|
||||
var unionQuery = systemDocumentQueryable.Union(trialDocQueryable)
|
||||
.WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name))
|
||||
.WhereIf(!string.IsNullOrEmpty(querySystemDocument.Type), t => t.Type.Contains(querySystemDocument.Type));
|
||||
|
||||
return unionQuery.ToPagedList(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using AutoMapper;
|
||||
using AutoMapper.EquivalencyExpression;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
public class DocumentConfig : Profile
|
||||
{
|
||||
public DocumentConfig()
|
||||
{
|
||||
|
||||
var userId = Guid.Empty;
|
||||
var token = string.Empty;
|
||||
CreateMap<SystemDocument, SystemDocumentView>()
|
||||
//.ForMember(d => d.UserConfirmInfo, u => u.MapFrom(s => s.SystemDocConfirmedUserList.FirstOrDefault(t=>t.ConfirmUserId==userId)))
|
||||
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token));
|
||||
|
||||
CreateMap<TrialDocument, TrialDocumentView>()
|
||||
.ForMember(d => d.IsSomeUserSigned, u => u.MapFrom(s => s.TrialDocConfirmedUserList.Any()))
|
||||
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token));
|
||||
|
||||
|
||||
CreateMap<SystemDocument, UnionDocumentView>()
|
||||
.ForMember(d => d.IsSystemDoc, u => u.MapFrom(s => true))
|
||||
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token));
|
||||
|
||||
CreateMap<TrialDocument, UnionDocumentView>()
|
||||
.ForMember(d => d.IsSystemDoc, u => u.MapFrom(s => false))
|
||||
.ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token));
|
||||
|
||||
CreateMap<TrialDocNeedConfirmedUserType, NeedConfirmedUserTypeView>().ForMember(d => d.UserTypeShortName, t => t.MapFrom(c => c.UserTypeRole.UserTypeShortName));
|
||||
CreateMap<SystemDocNeedConfirmedUserType, NeedConfirmedUserTypeView>().ForMember(d => d.UserTypeShortName, t => t.MapFrom(c => c.UserTypeRole.UserTypeShortName));
|
||||
|
||||
|
||||
//CreateMap<TrialDocument, TrialDocumentUserView>()
|
||||
// .ForMember(t => t.UserConfirmInfo, c => c.MapFrom(t => t.TrialDocConfirmedUserList.Where(u => u.ConfirmUserId == userId).FirstOrDefault()))
|
||||
// .ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path + "?access_token=" + token)); ;
|
||||
|
||||
CreateMap<TrialDocUserTypeConfirmedUser, TrialDocumentUserConfirmView>()
|
||||
.ForMember(d => d.UserName, c => c.MapFrom(t => t.User.UserName))
|
||||
.ForMember(d => d.RealName, c => c.MapFrom(t => t.User.LastName + " / " + t.User.FirstName));
|
||||
|
||||
//CreateMap<SystemDocConfirmedUser, SystemDocumentUserConfirmView>()
|
||||
// .ForMember(d => d.UserName, c => c.MapFrom(t => t.User.UserName))
|
||||
// .ForMember(d => d.RealName, c => c.MapFrom(t => t.User.LastName + " / " + t.User.FirstName));
|
||||
|
||||
|
||||
CreateMap<TrialUser, TrialDocumentUserConfirmView>();
|
||||
|
||||
|
||||
|
||||
|
||||
CreateMap<AddOrEditTrialDocument, TrialDocument>()
|
||||
.ForMember(d => d.NeedConfirmedUserTypeList, c => c.MapFrom(t => t.NeedConfirmedUserTypeIdList));
|
||||
|
||||
CreateMap<Guid, TrialDocNeedConfirmedUserType>().EqualityComparison((odto, o) => odto == o.NeedConfirmUserTypeId)
|
||||
.ForMember(d => d.NeedConfirmUserTypeId, c => c.MapFrom(t => t))
|
||||
.ForMember(d => d.TrialDocumentId, c => c.Ignore());
|
||||
|
||||
|
||||
|
||||
CreateMap<AddOrEditSystemDocument, SystemDocument>().ForMember(d => d.NeedConfirmedUserTypeList, c => c.MapFrom(t => t.NeedConfirmedUserTypeIdList));
|
||||
CreateMap<Guid, SystemDocNeedConfirmedUserType>().EqualityComparison((odto, o) => odto == o.NeedConfirmUserTypeId)
|
||||
.ForMember(d => d.NeedConfirmUserTypeId, c => c.MapFrom(t => t))
|
||||
.ForMember(d => d.SystemDocumentId, c => c.Ignore());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,714 @@
|
||||
using AutoMapper;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Application.Contracts.Pay;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure.ExpressionExtend;
|
||||
using System.Linq.Expressions;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
public class CalculateService : ICalculateService
|
||||
{
|
||||
private readonly IRepository<Payment> _paymentRepository;
|
||||
private readonly IRepository<TrialPaymentPrice> _trialPaymentRepository;
|
||||
private readonly IRepository<ReviewerPayInformation> _doctorPayInfoRepository;
|
||||
private readonly IRepository<Trial> _trialRepository;
|
||||
private readonly IRepository<Doctor> _doctorRepository;
|
||||
private readonly IRepository<Workload> _doctorWorkloadRepository;
|
||||
private readonly IRepository<RankPrice> _rankPriceRepository;
|
||||
private readonly IRepository<PaymentDetail> _paymentDetailRepository;
|
||||
private readonly IVolumeRewardService _volumeRewardPriceService;
|
||||
private readonly IRepository<ExchangeRate> _exchangeRateRepository;
|
||||
private readonly IRepository<PaymentAdjustment> _payAdjustmentRepository;
|
||||
private readonly IRepository<Enroll> _enrollRepository;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public CalculateService(IRepository<Payment> paymentRepository, IRepository<TrialPaymentPrice> trialPaymentPriceRepository,
|
||||
IRepository<ReviewerPayInformation> reviewerPayInfoRepository,
|
||||
IRepository<Trial> trialRepository,
|
||||
IRepository<Doctor> doctorRepository,
|
||||
IRepository<Workload> workloadRepository,
|
||||
IRepository<RankPrice> rankPriceRepository,
|
||||
IRepository<PaymentDetail> paymentDetailRepository,
|
||||
IVolumeRewardService volumeRewardService,
|
||||
IRepository<ExchangeRate> exchangeRateRepository,
|
||||
IRepository<Enroll> EnrollRepository,
|
||||
IRepository<PaymentAdjustment> paymentAdjustmentRepository, IMapper mapper)
|
||||
{
|
||||
_paymentRepository = paymentRepository;
|
||||
_trialPaymentRepository = trialPaymentPriceRepository;
|
||||
_doctorPayInfoRepository = reviewerPayInfoRepository;
|
||||
_trialRepository = trialRepository;
|
||||
_doctorRepository = doctorRepository;
|
||||
_doctorWorkloadRepository = workloadRepository;
|
||||
_rankPriceRepository = rankPriceRepository;
|
||||
_paymentDetailRepository = paymentDetailRepository;
|
||||
_volumeRewardPriceService = volumeRewardService;
|
||||
_exchangeRateRepository = exchangeRateRepository;
|
||||
_payAdjustmentRepository = paymentAdjustmentRepository;
|
||||
this._enrollRepository = EnrollRepository;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取某个月下的某些医生最终确认的工作量,用于计算月度费用
|
||||
/// </summary>
|
||||
private async Task< List<CalculatePaymentDTO>> GetFinalConfirmedWorkloadAndPayPriceList(CalculateDoctorAndMonthDTO calculateFeeParam)
|
||||
{
|
||||
Expression<Func<Workload, bool>> workloadLambda = x => true;
|
||||
|
||||
DateTime bTime = new DateTime(calculateFeeParam.CalculateMonth.Year, calculateFeeParam.CalculateMonth.Month, 1);
|
||||
var eTime = bTime.AddMonths(1);
|
||||
workloadLambda = workloadLambda.And(t =>
|
||||
t.WorkTime >= bTime && t.WorkTime < eTime);
|
||||
|
||||
workloadLambda = workloadLambda.And(t => calculateFeeParam.NeedCalculateReviewers.Contains(t.DoctorId) && t.DataFrom == (int)WorkLoadFromStatus.FinalConfirm);
|
||||
var workLoadQueryable = from doctor in _doctorRepository.AsQueryable()
|
||||
join workLoad in _doctorWorkloadRepository.Where(workloadLambda) on
|
||||
doctor.Id equals workLoad.DoctorId
|
||||
join trial in _trialRepository.AsQueryable() on workLoad.TrialId equals trial.Id
|
||||
join trialPay in _trialPaymentRepository.AsQueryable() on trial.Id equals trialPay.TrialId
|
||||
into temp
|
||||
from trialPay in temp.DefaultIfEmpty()
|
||||
join doctorPayInfo in _doctorPayInfoRepository.AsQueryable() on doctor.Id equals doctorPayInfo.DoctorId
|
||||
join rankPrice in _rankPriceRepository.AsQueryable() on doctorPayInfo.RankId equals rankPrice.Id
|
||||
select new CalculatePaymentDTO()
|
||||
{
|
||||
Id = workLoad.Id,
|
||||
DoctorId = workLoad.DoctorId,
|
||||
WorkTime = workLoad.WorkTime,
|
||||
DataFrom = workLoad.DataFrom,
|
||||
TrialId = workLoad.TrialId,
|
||||
TrialCode = trial.TrialCode,
|
||||
|
||||
Timepoint = workLoad.Timepoint,
|
||||
TimepointIn24H = workLoad.TimepointIn24H,
|
||||
TimepointIn48H = workLoad.TimepointIn48H,
|
||||
Global = workLoad.Global,
|
||||
Adjudication = workLoad.Adjudication,
|
||||
AdjudicationIn24H = workLoad.AdjudicationIn24H,
|
||||
AdjudicationIn48H = workLoad.AdjudicationIn48H,
|
||||
Training = workLoad.Training,
|
||||
RefresherTraining = workLoad.RefresherTraining,
|
||||
Downtime = workLoad.Downtime,
|
||||
|
||||
TrialAdditional = trialPay.TrialAdditional,
|
||||
PersonalAdditional = doctorPayInfo.Additional,
|
||||
AdjustmentMultiple = trialPay.AdjustmentMultiple,
|
||||
|
||||
TimepointPrice = rankPrice.Timepoint,
|
||||
TimepointIn24HPrice = rankPrice.TimepointIn24H,
|
||||
TimepointIn48HPrice = rankPrice.TimepointIn48H,
|
||||
AdjudicationPrice = rankPrice.Adjudication,
|
||||
AdjudicationIn24HPrice = rankPrice.AdjudicationIn24H,
|
||||
AdjudicationIn48HPrice = rankPrice.AdjudicationIn48H,
|
||||
DowntimePrice = rankPrice.Downtime,
|
||||
GlobalPrice = rankPrice.Global,
|
||||
TrainingPrice = rankPrice.Training,
|
||||
RefresherTrainingPrice = rankPrice.RefresherTraining
|
||||
};
|
||||
|
||||
return await workLoadQueryable.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算月度费用,并调用AddOrUpdateMonthlyPayment和AddOrUpdateMonthlyPaymentDetail方法,
|
||||
/// 将费用计算的月度数据及详情保存
|
||||
/// </summary>
|
||||
[NonDynamicMethod]
|
||||
public async Task<IResponseOutput> CalculateMonthlyPayment(CalculateDoctorAndMonthDTO param, string token)
|
||||
{
|
||||
var yearMonth = param.CalculateMonth.ToString("yyyy-MM");
|
||||
var rate = await _exchangeRateRepository.FirstOrDefaultAsync(u => u.YearMonth == yearMonth);
|
||||
|
||||
decimal exchangeRate = rate?.Rate ?? 0;
|
||||
|
||||
var workLoadAndPayPriceList = await GetFinalConfirmedWorkloadAndPayPriceList(param);
|
||||
var volumeRewardPriceList = await _volumeRewardPriceService.GetVolumeRewardPriceList();
|
||||
|
||||
#region 奖励数据校验
|
||||
for (int i = 0; i < volumeRewardPriceList.Count; i++)
|
||||
{
|
||||
if (i == 0 && volumeRewardPriceList[i].Min != 0)
|
||||
{
|
||||
return ResponseOutput.NotOk("Volume reward data error.");
|
||||
}
|
||||
if (i > 0)
|
||||
{
|
||||
if (volumeRewardPriceList[i - 1].Max + 1 != volumeRewardPriceList[i].Min)
|
||||
return ResponseOutput.NotOk("Volume reward data error.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
List<PaymentModel> paymentList = new List<PaymentModel>();
|
||||
List<ReviewerPaymentUSD> reviewerPaymentUSDList = new List<ReviewerPaymentUSD>();
|
||||
|
||||
// 获取所有医生费用 一次从数据库里面全部取出来
|
||||
|
||||
var allDoctorList = workLoadAndPayPriceList.Where(x => param.NeedCalculateReviewers.Contains(x.DoctorId)).ToList();
|
||||
var allDoctorIds = allDoctorList.Select(x => x.DoctorId).Distinct().ToList();
|
||||
var listTrialId = allDoctorList.Select(x => x.TrialId).Distinct().ToList();
|
||||
|
||||
var trialDoctorlist= await (from enroll in _enrollRepository.Where(x=> listTrialId.Contains(x.TrialId)|| allDoctorIds.Contains(x.DoctorId))
|
||||
join price in _trialPaymentRepository.Where() on enroll.TrialId equals price.TrialId
|
||||
select new DoctorPrice()
|
||||
{
|
||||
IsNewTrial = price.IsNewTrial,
|
||||
AdjustmentMultiple = enroll.AdjustmentMultiple,
|
||||
TrialId=enroll.TrialId,
|
||||
DoctorId = enroll.DoctorId,
|
||||
Training=enroll.Training,
|
||||
Adjudication=enroll.Adjudication,
|
||||
Adjudication24H=enroll.Adjudication24H,
|
||||
Adjudication48H= enroll.Adjudication48H,
|
||||
Downtime=enroll.Downtime,
|
||||
Global=enroll.Global,
|
||||
RefresherTraining=enroll.RefresherTraining,
|
||||
Timepoint= enroll.Timepoint,
|
||||
Timepoint24H=enroll.Timepoint24H,
|
||||
Timepoint48H=enroll.Timepoint48H,
|
||||
}).ToListAsync();
|
||||
|
||||
|
||||
foreach (var doctor in param.NeedCalculateReviewers)
|
||||
{
|
||||
if (await _paymentRepository.AnyAsync(u => u.DoctorId == doctor && u.YearMonth == yearMonth && u.IsLock))
|
||||
{
|
||||
break;
|
||||
}
|
||||
List<PaymentDetailCommand> paymentDetailList = new List<PaymentDetailCommand>();
|
||||
decimal totalNormal = 0;
|
||||
|
||||
//计算单个医生费用统,并且插入到统计表
|
||||
var doctorWorkloadAndPayPriceList = workLoadAndPayPriceList.Where(u => u.DoctorId == doctor).ToList();
|
||||
|
||||
//阅片数量 计算奖励费用
|
||||
int readCount = 0;
|
||||
|
||||
int codeOrder = 0;
|
||||
|
||||
//这里需要改
|
||||
|
||||
foreach (var item in doctorWorkloadAndPayPriceList)
|
||||
{
|
||||
var doctordata = trialDoctorlist.Where(x => x.IsNewTrial ?? false && x.Training == item.Training && x.DoctorId == item.DoctorId).FirstOrDefault();
|
||||
|
||||
if (doctordata != null)
|
||||
{
|
||||
item.Training = doctordata.Training??0;
|
||||
item.Adjudication = doctordata.Adjudication??0;
|
||||
item.AdjudicationIn24H = doctordata.Adjudication24H??0;
|
||||
item.AdjudicationIn48H = doctordata.Adjudication48H??0;
|
||||
item.Downtime = doctordata.Downtime??0;
|
||||
item.Global = doctordata.Global??0;
|
||||
item.RefresherTraining = doctordata.RefresherTraining??0;
|
||||
item.Timepoint = doctordata.Timepoint??0;
|
||||
item.TimepointIn24H = doctordata.Timepoint24H??0;
|
||||
item.TimepointIn48H = doctordata.Timepoint48H??0;
|
||||
item.PersonalAdditional = 0;
|
||||
}
|
||||
++codeOrder;
|
||||
readCount += (item.Timepoint + item.TimepointIn24H + item.TimepointIn48H
|
||||
+ item.Adjudication + item.AdjudicationIn24H + item.AdjudicationIn48H);
|
||||
decimal trainingTotal = item.Training * item.TrainingPrice;
|
||||
decimal refresherTrainingTotal = item.RefresherTraining * item.RefresherTrainingPrice;
|
||||
decimal downtimeTotal = item.Downtime * item.DowntimePrice;
|
||||
//规则定义 global 的价格是Tp和个人附加的一半
|
||||
decimal globalTotal = item.Global * (item.TimepointPrice / 2 + item.PersonalAdditional / 2);
|
||||
|
||||
//项目如果没有添加附加数据 默认为0
|
||||
decimal timePointTotal = item.Timepoint * (item.TimepointPrice * item.AdjustmentMultiple + item.PersonalAdditional + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional));
|
||||
|
||||
decimal timePointIn24HTotal = item.TimepointIn24H * (item.TimepointIn24HPrice * item.AdjustmentMultiple + item.PersonalAdditional);
|
||||
decimal timePointIn48HTotal = item.TimepointIn48H * (item.TimepointIn48HPrice * item.AdjustmentMultiple + item.PersonalAdditional);
|
||||
decimal adjudicationTotal = item.Adjudication * (item.AdjudicationPrice * item.AdjustmentMultiple + item.PersonalAdditional + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional));
|
||||
decimal adjudicationIn24HTotal = item.AdjudicationIn24H * (item.AdjudicationIn24HPrice * item.AdjustmentMultiple + item.PersonalAdditional);
|
||||
decimal adjudicationIn48HTotal = item.AdjudicationIn48H * (item.AdjudicationIn48HPrice * item.AdjustmentMultiple + item.PersonalAdditional);
|
||||
|
||||
totalNormal += (trainingTotal + refresherTrainingTotal + downtimeTotal + globalTotal + timePointTotal + timePointIn24HTotal
|
||||
+ timePointIn48HTotal + adjudicationTotal + adjudicationIn24HTotal + adjudicationIn48HTotal);
|
||||
|
||||
#region 统计明细信息
|
||||
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = item.TrialCode,
|
||||
PaymentType = "Training",
|
||||
Count = item.Training,
|
||||
BasePrice = item.TrainingPrice,
|
||||
PersonalAdditional = 0,
|
||||
TrialAdditional = 0,
|
||||
PaymentId = Guid.Empty,
|
||||
DoctorId = item.DoctorId,
|
||||
TrialId = item.TrialId,
|
||||
ShowTypeOrder = 1,
|
||||
ShowCodeOrder = codeOrder,
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = item.Training * item.TrainingPrice,
|
||||
PaymentCNY = item.Training * item.TrainingPrice * exchangeRate
|
||||
});
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = item.TrialCode,
|
||||
PaymentType = "Refresher Training",
|
||||
Count = item.RefresherTraining,
|
||||
BasePrice = item.RefresherTrainingPrice,
|
||||
PersonalAdditional = 0,
|
||||
TrialAdditional = 0,
|
||||
PaymentId = Guid.Empty,
|
||||
DoctorId = item.DoctorId,
|
||||
TrialId = item.TrialId,
|
||||
ShowTypeOrder = 2,
|
||||
ShowCodeOrder = codeOrder,
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = item.RefresherTraining * item.RefresherTrainingPrice,
|
||||
PaymentCNY = item.RefresherTraining * item.RefresherTrainingPrice * exchangeRate
|
||||
});
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = item.TrialCode,
|
||||
PaymentType = "Downtime",
|
||||
Count = item.Downtime,
|
||||
BasePrice = item.DowntimePrice,
|
||||
PersonalAdditional = 0,
|
||||
TrialAdditional = 0,
|
||||
PaymentId = Guid.Empty,
|
||||
DoctorId = item.DoctorId,
|
||||
TrialId = item.TrialId,
|
||||
ShowTypeOrder = 3,
|
||||
ShowCodeOrder = codeOrder,
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = item.Downtime * item.DowntimePrice,
|
||||
PaymentCNY = item.Downtime * item.DowntimePrice * exchangeRate
|
||||
});
|
||||
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = item.TrialCode,
|
||||
PaymentType = "Timepoint Regular",
|
||||
Count = item.Timepoint,
|
||||
BasePrice = item.TimepointPrice,
|
||||
PersonalAdditional = doctordata!=null?0: item.PersonalAdditional,
|
||||
TrialAdditional = doctordata != null ? 0 : item.TimepointPrice * (item.AdjustmentMultiple - 1) + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional),
|
||||
PaymentId = Guid.Empty,
|
||||
DoctorId = item.DoctorId,
|
||||
TrialId = item.TrialId,
|
||||
ShowTypeOrder = 4,
|
||||
ShowCodeOrder = codeOrder,
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = item.Timepoint * (item.TimepointPrice * item.AdjustmentMultiple + item.PersonalAdditional + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional)),
|
||||
PaymentCNY = item.Timepoint * (item.TimepointPrice * item.AdjustmentMultiple + item.PersonalAdditional + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional)) * exchangeRate
|
||||
});
|
||||
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = item.TrialCode,
|
||||
PaymentType = "Timepoint 48-Hour",
|
||||
Count = item.TimepointIn48H,
|
||||
BasePrice = item.TimepointIn48HPrice,
|
||||
PersonalAdditional = doctordata != null ? 0 : item.PersonalAdditional,
|
||||
TrialAdditional = doctordata != null ? 0 : item.TimepointIn48HPrice * (item.AdjustmentMultiple - 1) + 0,//48小时不加项目附加
|
||||
PaymentId = Guid.Empty,
|
||||
DoctorId = item.DoctorId,
|
||||
TrialId = item.TrialId,
|
||||
ShowTypeOrder = 5,
|
||||
ShowCodeOrder = codeOrder,
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = item.TimepointIn48H * (item.TimepointIn48HPrice * item.AdjustmentMultiple + 0 + item.PersonalAdditional),
|
||||
PaymentCNY = item.TimepointIn48H * (item.TimepointIn48HPrice * item.AdjustmentMultiple + 0 + item.PersonalAdditional) * exchangeRate
|
||||
});
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = item.TrialCode,
|
||||
PaymentType = "Timepoint 24-Hour",
|
||||
Count = item.TimepointIn24H,
|
||||
BasePrice = item.TimepointIn24HPrice,
|
||||
PersonalAdditional = doctordata != null ? 0 : item.PersonalAdditional,
|
||||
TrialAdditional = doctordata != null ? 0 : item.TimepointIn24HPrice * (item.AdjustmentMultiple - 1) + 0,
|
||||
PaymentId = Guid.Empty,
|
||||
DoctorId = item.DoctorId,
|
||||
TrialId = item.TrialId,
|
||||
ShowTypeOrder = 6,
|
||||
ShowCodeOrder = codeOrder,
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = item.TimepointIn24H * (item.TimepointIn24HPrice * item.AdjustmentMultiple + 0 + item.PersonalAdditional),
|
||||
PaymentCNY = item.TimepointIn24H * (item.TimepointIn24HPrice * item.AdjustmentMultiple + 0 + item.PersonalAdditional) * exchangeRate
|
||||
});
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = item.TrialCode,
|
||||
PaymentType = "Adjudication Regular",
|
||||
Count = item.Adjudication,
|
||||
BasePrice = item.AdjudicationPrice,
|
||||
PersonalAdditional = doctordata != null ? 0 : item.PersonalAdditional,
|
||||
TrialAdditional = doctordata != null ? 0 : item.AdjudicationPrice * (item.AdjustmentMultiple - 1) + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional),
|
||||
PaymentId = Guid.Empty,
|
||||
DoctorId = item.DoctorId,
|
||||
TrialId = item.TrialId,
|
||||
ShowTypeOrder = 7,
|
||||
ShowCodeOrder = codeOrder,
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = item.Adjudication * (item.AdjudicationPrice * item.AdjustmentMultiple + item.PersonalAdditional + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional)),
|
||||
PaymentCNY = item.Adjudication * (item.AdjudicationPrice * item.AdjustmentMultiple + item.PersonalAdditional + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional)) * exchangeRate
|
||||
});
|
||||
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = item.TrialCode,
|
||||
PaymentType = "Adjudication 48-Hour",
|
||||
Count = item.AdjudicationIn48H,
|
||||
BasePrice = item.AdjudicationIn48HPrice,
|
||||
PersonalAdditional = doctordata != null ? 0 : item.PersonalAdditional,
|
||||
TrialAdditional = doctordata != null ? 0 : item.AdjudicationIn48HPrice * (item.AdjustmentMultiple - 1) + 0,
|
||||
PaymentId = Guid.Empty,
|
||||
DoctorId = item.DoctorId,
|
||||
TrialId = item.TrialId,
|
||||
ShowTypeOrder = 8,
|
||||
ShowCodeOrder = codeOrder,
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = item.AdjudicationIn48H * (item.AdjudicationIn48HPrice * item.AdjustmentMultiple + item.PersonalAdditional + 0),
|
||||
PaymentCNY = item.AdjudicationIn48H * (item.AdjudicationIn48HPrice * item.AdjustmentMultiple + item.PersonalAdditional + 0) * exchangeRate
|
||||
});
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = item.TrialCode,
|
||||
PaymentType = "Adjudication 24-Hour",
|
||||
Count = item.AdjudicationIn24H,
|
||||
BasePrice = item.AdjudicationIn24HPrice,
|
||||
PersonalAdditional = doctordata != null ? 0 : item.PersonalAdditional,
|
||||
TrialAdditional = doctordata != null ? 0 : item.AdjudicationIn24HPrice * (item.AdjustmentMultiple - 1) + 0,
|
||||
PaymentId = Guid.Empty,
|
||||
DoctorId = item.DoctorId,
|
||||
TrialId = item.TrialId,
|
||||
ShowTypeOrder = 9,
|
||||
ShowCodeOrder = codeOrder,
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = item.AdjudicationIn24H * (item.AdjudicationIn24HPrice * item.AdjustmentMultiple + 0 + item.PersonalAdditional),
|
||||
PaymentCNY = item.AdjudicationIn24H * (item.AdjudicationIn24HPrice * item.AdjustmentMultiple + 0 + item.PersonalAdditional) * exchangeRate
|
||||
});
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = item.TrialCode,
|
||||
PaymentType = "Global",
|
||||
Count = item.Global,
|
||||
BasePrice = item.TimepointPrice / 2,//item.GlobalPrice,
|
||||
PersonalAdditional = doctordata != null ? 0 : item.PersonalAdditional / 2,
|
||||
TrialAdditional = 0,
|
||||
PaymentId = Guid.Empty,
|
||||
DoctorId = item.DoctorId,
|
||||
TrialId = item.TrialId,
|
||||
ShowTypeOrder = 10,
|
||||
ShowCodeOrder = codeOrder,
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = item.Global * (item.TimepointPrice / 2 + item.PersonalAdditional / 2),
|
||||
PaymentCNY = item.Global * (item.TimepointPrice / 2 + item.PersonalAdditional / 2) * exchangeRate
|
||||
});
|
||||
#endregion
|
||||
}
|
||||
|
||||
int typeOrder = 0;
|
||||
if (readCount > 0)
|
||||
{
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = "Volume Reward",
|
||||
PaymentType = "Total TP & AD",
|
||||
Count = readCount,
|
||||
BasePrice = 0,
|
||||
PersonalAdditional = 0,
|
||||
TrialAdditional = 0,
|
||||
PaymentId = Guid.Empty,
|
||||
DoctorId = doctor,
|
||||
TrialId = Guid.Empty,
|
||||
ShowTypeOrder = typeOrder,
|
||||
ShowCodeOrder = (++codeOrder),
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = 0,
|
||||
PaymentCNY = 0
|
||||
});
|
||||
|
||||
foreach (var awardItem in volumeRewardPriceList)
|
||||
{
|
||||
++typeOrder;
|
||||
if ((readCount - awardItem.Min + 1) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (awardItem.Min == 0)
|
||||
{
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = "Volume Reward",
|
||||
PaymentType = awardItem.Min + "-" + awardItem.Max,
|
||||
Count = readCount >= awardItem.Max ?
|
||||
(awardItem.Max - awardItem.Min) : (readCount - awardItem.Min),
|
||||
BasePrice = awardItem.Price,
|
||||
PersonalAdditional = 0,
|
||||
TrialAdditional = 0,
|
||||
PaymentId = Guid.Empty,//result.Data,
|
||||
DoctorId = doctor,
|
||||
TrialId = Guid.Empty,
|
||||
ShowTypeOrder = typeOrder,
|
||||
ShowCodeOrder = (++codeOrder),
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = (readCount >= awardItem.Max ?
|
||||
(awardItem.Max - awardItem.Min) : (readCount - awardItem.Min)) * awardItem.Price,
|
||||
PaymentCNY = (readCount >= awardItem.Max ?
|
||||
(awardItem.Max - awardItem.Min) : (readCount - awardItem.Min)) * awardItem.Price * exchangeRate
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
paymentDetailList.Add(new PaymentDetailCommand
|
||||
{
|
||||
TrialCode = "Volume Reward",
|
||||
PaymentType = awardItem.Min + "-" + awardItem.Max,
|
||||
Count = readCount >= awardItem.Max ?
|
||||
(awardItem.Max - awardItem.Min + 1) : (readCount - awardItem.Min + 1),
|
||||
BasePrice = awardItem.Price,
|
||||
PersonalAdditional = 0,
|
||||
TrialAdditional = 0,
|
||||
PaymentId = Guid.Empty,
|
||||
DoctorId = doctor,
|
||||
TrialId = Guid.Empty,
|
||||
ShowTypeOrder = typeOrder,
|
||||
ShowCodeOrder = (++codeOrder),
|
||||
ExchangeRate = exchangeRate,
|
||||
YearMonth = yearMonth,
|
||||
PaymentUSD = (readCount >= awardItem.Max ?
|
||||
(awardItem.Max - awardItem.Min + 1) : (readCount - awardItem.Min + 1)) * awardItem.Price,
|
||||
PaymentCNY = (readCount >= awardItem.Max ?
|
||||
(awardItem.Max - awardItem.Min + 1) : (readCount - awardItem.Min + 1)) * awardItem.Price * exchangeRate
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
decimal award = 0;
|
||||
volumeRewardPriceList = volumeRewardPriceList.OrderBy(u => u.Min).ToList();
|
||||
|
||||
var levelTemp = -1; //用来计算属于哪一个挡位
|
||||
foreach (var awarPriceitem in volumeRewardPriceList)
|
||||
{
|
||||
if (awarPriceitem.Min == 0)
|
||||
{
|
||||
if (readCount > awarPriceitem.Max)
|
||||
{
|
||||
++levelTemp;
|
||||
award += (awarPriceitem.Max - awarPriceitem.Min) * awarPriceitem.Price;
|
||||
}
|
||||
if (awarPriceitem.Min < readCount && readCount < awarPriceitem.Max)
|
||||
{
|
||||
++levelTemp;
|
||||
award += (readCount - awarPriceitem.Min) * awarPriceitem.Price;
|
||||
break; ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (readCount > awarPriceitem.Max)
|
||||
{
|
||||
++levelTemp;
|
||||
award += (awarPriceitem.Max - awarPriceitem.Min + 1) * awarPriceitem.Price;
|
||||
}
|
||||
if (awarPriceitem.Min < readCount && readCount < awarPriceitem.Max)
|
||||
{
|
||||
++levelTemp;
|
||||
award += (readCount - awarPriceitem.Min + 1) * awarPriceitem.Price;
|
||||
break; ;
|
||||
}
|
||||
}
|
||||
}
|
||||
decimal totalUSD = award + totalNormal;//总费用
|
||||
|
||||
var result = await AddOrUpdateMonthlyPayment(new PaymentCommand
|
||||
{
|
||||
DoctorId = doctor,
|
||||
Year = param.CalculateMonth.Year,
|
||||
Month = param.CalculateMonth.Month,
|
||||
PaymentUSD = totalUSD,
|
||||
CalculateUser = token,
|
||||
CalculateTime = DateTime.Now,
|
||||
ExchangeRate = exchangeRate,
|
||||
PaymentCNY = exchangeRate * totalUSD,
|
||||
});
|
||||
|
||||
|
||||
reviewerPaymentUSDList.Add(new ReviewerPaymentUSD { DoctorId = doctor, PaymentUSD = totalUSD, RecordId = result.Data });
|
||||
foreach (var detail in paymentDetailList)
|
||||
{
|
||||
//var data = trialDoctorlist.FirstOrDefault(x => x.DoctorId == detail.DoctorId && x.TrialId == detail.TrialId && x.IsNewTrial == true && (x.AdjustmentMultiple??0) != 0);
|
||||
//if (data != null)
|
||||
//{
|
||||
// detail.BasePrice = data.AdjustmentMultiple??0;
|
||||
// detail.PersonalAdditional = 0;
|
||||
// detail.TrialAdditional = 0;
|
||||
//}
|
||||
|
||||
detail.PaymentId = result.Data;
|
||||
}
|
||||
await AddOrUpdateMonthlyPaymentDetail(paymentDetailList, result.Data);
|
||||
|
||||
await UpdatePaymentAdjustment(doctor, yearMonth);
|
||||
}
|
||||
return ResponseOutput.Ok(reviewerPaymentUSDList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 重新计算调整费用
|
||||
|
||||
private async Task UpdatePaymentAdjustment(Guid reviewerId, string yearMonth)
|
||||
{
|
||||
var adjustList = await _payAdjustmentRepository.Where(u => u.YearMonth == yearMonth &&
|
||||
!u.IsLock && u.ReviewerId == reviewerId).ToListAsync();
|
||||
|
||||
|
||||
var needUpdatePayment = adjustList.GroupBy(t => t.ReviewerId).Select(g => new
|
||||
{
|
||||
ReviewerId = g.Key,
|
||||
AdjustCNY = g.Sum(t => t.AdjustmentCNY),
|
||||
AdjustUSD = g.Sum(t => t.AdjustmentUSD)
|
||||
});
|
||||
|
||||
foreach (var reviewer in needUpdatePayment)
|
||||
{
|
||||
await _paymentRepository.UpdateFromQueryAsync(u => u.YearMonth == yearMonth &&
|
||||
!u.IsLock && u.DoctorId == reviewer.ReviewerId, t => new Payment()
|
||||
{
|
||||
AdjustmentUSD = reviewer.AdjustUSD,
|
||||
AdjustmentCNY = reviewer.AdjustCNY
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存费用计算的月度数据
|
||||
/// </summary>
|
||||
private async Task<IResponseOutput<Guid>> AddOrUpdateMonthlyPayment(PaymentCommand addOrUpdateModel)
|
||||
{
|
||||
var success = false;
|
||||
var paymentModel = await _paymentRepository.FirstOrDefaultAsync(t =>
|
||||
t.DoctorId == addOrUpdateModel.DoctorId && t.YearMonth == addOrUpdateModel.YearMonth);
|
||||
|
||||
|
||||
|
||||
//var taxCNY = GetTax(addOrUpdateModel.PaymentCNY);
|
||||
//var actuallyPaidCNY = addOrUpdateModel.PaymentCNY - taxCNY;
|
||||
//var bankTransferCNY = addOrUpdateModel.PaymentCNY - taxCNY;
|
||||
|
||||
if (paymentModel == null)
|
||||
{
|
||||
var payment = _mapper.Map<Payment>(addOrUpdateModel);
|
||||
|
||||
//payment.BankTransferCNY = bankTransferCNY;
|
||||
//payment.TaxCNY= taxCNY;
|
||||
//payment.BankTransferCNY = bankTransferCNY;
|
||||
payment.YearMonthDate = DateTime.Parse(payment.YearMonth);
|
||||
|
||||
payment =await _paymentRepository.AddAsync(payment);
|
||||
success =await _paymentRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(success, payment.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果是 当月计算的工作量费用 和 调整费用都为0,则删除该行记录
|
||||
if (addOrUpdateModel.PaymentUSD == 0 && paymentModel.AdjustmentUSD == 0)
|
||||
{
|
||||
success =await _paymentRepository.DeleteFromQueryAsync(u => u.Id == paymentModel.Id);
|
||||
//_paymentDetailRepository.Delete(u=>u.PaymentId==paymentModel.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = await _paymentRepository.UpdateFromQueryAsync(t => t.Id == paymentModel.Id, u => new Payment()
|
||||
{
|
||||
PaymentUSD = addOrUpdateModel.PaymentUSD,
|
||||
CalculateTime = addOrUpdateModel.CalculateTime,
|
||||
CalculateUser = addOrUpdateModel.CalculateUser,
|
||||
//TaxCNY = taxCNY,
|
||||
//ActuallyPaidCNY = actuallyPaidCNY,
|
||||
//BankTransferCNY = bankTransferCNY,
|
||||
PaymentCNY = addOrUpdateModel.PaymentCNY,
|
||||
ExchangeRate = addOrUpdateModel.ExchangeRate
|
||||
});
|
||||
}
|
||||
|
||||
return ResponseOutput.Result(success, paymentModel.Id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 保存费用计算的月度详情
|
||||
/// </summary>
|
||||
private async Task<bool> AddOrUpdateMonthlyPaymentDetail(List<PaymentDetailCommand> addOrUpdateList, Guid paymentId)
|
||||
{
|
||||
//var paymentDetailIds = addOrUpdateList.Select(t => t.PaymentId).ToList();
|
||||
await _paymentDetailRepository.DeleteFromQueryAsync(t => t.PaymentId == paymentId);
|
||||
await _paymentDetailRepository.AddRangeAsync(_mapper.Map<List<PaymentDetail>>(addOrUpdateList));
|
||||
return await _paymentDetailRepository.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取待计算费用的Reviewer对应的月份列表
|
||||
/// </summary>
|
||||
public async Task<List<CalculateNeededDTO>> GetNeedCalculateReviewerList(Guid reviewerId, string yearMonth)
|
||||
{
|
||||
Expression<Func<Payment, bool>> calculateLambda = u => !u.IsLock;
|
||||
if (reviewerId != Guid.Empty)
|
||||
{
|
||||
calculateLambda = calculateLambda.And(u => u.DoctorId == reviewerId);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(yearMonth))
|
||||
{
|
||||
calculateLambda = calculateLambda.And(u => u.YearMonth == yearMonth);
|
||||
}
|
||||
return await _paymentRepository.Where(calculateLambda).ProjectTo<CalculateNeededDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询Reviewer某个月的费用是否被锁定
|
||||
/// </summary>
|
||||
public async Task<bool> IsLock(Guid reviewerId, string yearMonth)
|
||||
{
|
||||
return await _paymentRepository.AnyAsync(u => u.DoctorId == reviewerId && u.YearMonth == yearMonth && u.IsLock);
|
||||
}
|
||||
|
||||
//public bool ResetMonthlyPayment(Guid reviewerId, Guid trialId, string yearMonth)
|
||||
//{
|
||||
// var payment = _paymentRepository.FindSingleOrDefault(u => u.DoctorId == reviewerId && u.YearMonth == yearMonth);
|
||||
// payment.PaymentCNY = 0;
|
||||
// payment.PaymentUSD = 0;
|
||||
// _paymentRepository.Update(payment);
|
||||
// _paymentDetailRepository.Delete(u=>u.DoctorId==reviewerId && u.TrialId==trial)
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public class AwardPriceDTO: AwardPriceCalculateDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
}
|
||||
|
||||
public class AwardPriceCalculateDTO
|
||||
{
|
||||
public decimal Price { get; set; }
|
||||
public int Max { get; set; }
|
||||
public int Min { get; set; }
|
||||
}
|
||||
|
||||
public class AwardPriceCommand
|
||||
{
|
||||
//public Guid Id { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
public int Min { get; set; }
|
||||
public int Max { get; set; }
|
||||
public Guid OptUserId { get; set; }
|
||||
}
|
||||
|
||||
public class AwardPriceQueryDTO : PageInput
|
||||
{
|
||||
}
|
||||
|
||||
public class ExchangeRateQueryDTO : PageInput
|
||||
{
|
||||
public DateTime? SearchMonth { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class CalculateNeededDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid DoctorId { get; set; }
|
||||
public string YearMonth { get; set; } = String.Empty;
|
||||
public bool IsLock { get; set; }
|
||||
}
|
||||
|
||||
public class DoctorPrice
|
||||
{
|
||||
public decimal? AdjustmentMultiple { get; set; }
|
||||
|
||||
public Guid? DoctorId { get; set; }
|
||||
|
||||
public Guid? TrialId { get; set; }
|
||||
|
||||
public bool? IsNewTrial { get; set; }
|
||||
|
||||
public int? Training { get; set; }
|
||||
|
||||
public int? RefresherTraining { get; set; }
|
||||
|
||||
public int? Timepoint { get; set; }
|
||||
|
||||
public int? Timepoint48H { get; set; }
|
||||
|
||||
public int? Timepoint24H { get; set; }
|
||||
|
||||
public int? Adjudication { get; set; }
|
||||
|
||||
public int? Adjudication48H { get; set; }
|
||||
|
||||
public int? Adjudication24H { get; set; }
|
||||
|
||||
public int? Global { get; set; }
|
||||
|
||||
|
||||
public int? Downtime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class ExchangeRateCommand
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string YearMonth { get; set; }=String.Empty;
|
||||
public decimal Rate { get; set; }
|
||||
|
||||
public DateTime UpdateTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Contracts.Pay
|
||||
{
|
||||
public class PaymentAdjustmentCommand
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public Guid ReviewerId { get; set; }
|
||||
public DateTime YearMonth { get; set; }
|
||||
public decimal AdjustPaymentUSD { get; set; }
|
||||
public decimal AdjustPaymentCNY { get; set; }
|
||||
public string Note { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class PaymentAdjustmentDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid ReviewerId { get; set; }
|
||||
public string YearMonth { get; set; }=String.Empty;
|
||||
public DateTime YearMonthDate { get; set; }
|
||||
public bool IsLock { get; set; }
|
||||
public decimal AdjustPaymentUSD { get; set; }
|
||||
public decimal AdjustPaymentCNY { get; set; }
|
||||
public string Note { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
public class PaymentAdjustmentDetailDTO: PaymentAdjustmentDTO
|
||||
{
|
||||
public string ReviewerCode { get; set; } = String.Empty;
|
||||
public string FirstName { get; set; } = String.Empty;
|
||||
public string LastName { get; set; } = String.Empty;
|
||||
public string FullName => LastName + " / " + FirstName;
|
||||
public string ChineseName { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
public class PaymentAdjustmentQueryDTO:PageInput
|
||||
{
|
||||
public string TrialCode { get; set; } = string.Empty;
|
||||
public string Reviewer { get; set; } = string.Empty;
|
||||
public DateTime BeginMonth { get; set; }
|
||||
public DateTime EndMonth { get; set; }
|
||||
}
|
||||
|
||||
public class DoctorSelectDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string FirstName { get; set; } = String.Empty;
|
||||
public string LastName { get; set; } = String.Empty;
|
||||
public string FullName => LastName + " / " + FirstName;
|
||||
public string ChineseName { get; set; } = String.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Contracts.Pay
|
||||
{
|
||||
public class PaymentDetailDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid PaymentId { get; set; }
|
||||
public string YearMonth { get; set; } = String.Empty;
|
||||
public Guid DoctorId { get; set; }
|
||||
public Guid TrialId { get; set; }
|
||||
public string TrialCode { get; set; } = String.Empty;
|
||||
public string PaymentType { get; set; } = String.Empty;
|
||||
public int Count { get; set; }
|
||||
public decimal BasePrice { get; set; }
|
||||
public decimal PersonalAdditional { get; set; }
|
||||
|
||||
public decimal? NewPersonalAdditional { get; set; }
|
||||
public decimal TrialAdditional { get; set; }
|
||||
public int ShowTypeOrder { get; set; }
|
||||
public int ShowCodeOrder { get; set; }
|
||||
|
||||
public decimal ExchangeRate { get; set; }
|
||||
|
||||
public decimal PaymentUSD { get; set; }
|
||||
public decimal PaymentCNY { get; set; }
|
||||
|
||||
public bool? IsNewTrial { get; set; }
|
||||
|
||||
public decimal TotalUnitPrice => BasePrice + PersonalAdditional + TrialAdditional;
|
||||
|
||||
public AdjustmentDTO AdjustmentView { get; set; } = new AdjustmentDTO();
|
||||
|
||||
}
|
||||
|
||||
public class AdjustmentDTO
|
||||
{
|
||||
public decimal AdjustPaymentUSD { get; set; }
|
||||
|
||||
public decimal AdjustPaymentCNY { get; set; }
|
||||
|
||||
public string AdjustType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (AdjustPaymentUSD > 0)
|
||||
{
|
||||
return "+";
|
||||
}
|
||||
else if (AdjustPaymentUSD < 0)
|
||||
{
|
||||
return "-";
|
||||
}
|
||||
else { return string.Empty; }
|
||||
}
|
||||
}
|
||||
public string Note { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
|
||||
public class PaymentDetailCommand : PaymentDetailDTO
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class PayDetailDTO
|
||||
{
|
||||
public IEnumerable<PaymentDetailDTO> DetailList { get; set; } = new List<PaymentDetailDTO>();
|
||||
public DoctorPayInfo DoctorInfo { get; set; } = new DoctorPayInfo();
|
||||
}
|
||||
|
||||
public class LockPaymentDTO
|
||||
{
|
||||
public List<Guid> ReviewerIdList { get; set; }=new List<Guid>();
|
||||
public DateTime Month { get; set; }
|
||||
|
||||
public bool IsLock { get; set; } = true;
|
||||
}
|
||||
|
||||
public class DoctorPayInfo
|
||||
{
|
||||
public Guid DoctorId { get; set; }
|
||||
public string ChineseName { get; set; } = String.Empty;
|
||||
public string FirstName { get; set; } = String.Empty;
|
||||
public string LastName { get; set; } = String.Empty;
|
||||
public string Phone { get; set; } = String.Empty;
|
||||
public string PayTitle { get; set; } = String.Empty;
|
||||
public string Code { get; set; } = String.Empty;
|
||||
public string YearMonth { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class ReviewerPaymentUSD
|
||||
{
|
||||
public Guid RecordId { get; set; }
|
||||
public Guid DoctorId { get; set; }
|
||||
public decimal PaymentUSD { get; set; }
|
||||
}
|
||||
|
||||
public class PaymentQueryDTO : PageInput
|
||||
{
|
||||
public string Reviewer { get; set; } = String.Empty;
|
||||
public DateTime BeginMonth { get; set; }
|
||||
public DateTime EndMonth { get; set; }
|
||||
public int? Nation { get; set; }
|
||||
}
|
||||
public class MonthlyPaymentDTO
|
||||
{
|
||||
public Guid ReviewerId { get; set; }
|
||||
public string ReviewerCode { get; set; } = String.Empty;
|
||||
public string ChineseName { get; set; } = String.Empty;
|
||||
public string FirstName { get; set; } = String.Empty;
|
||||
public string LastName { get; set; } = String.Empty;
|
||||
|
||||
public decimal AdjustmentUSD { get; set; }
|
||||
public decimal AdjustmentCNY { get; set; }
|
||||
public decimal PaymentUSD { get; set; }
|
||||
public decimal PaymentCNY { get; set; }
|
||||
|
||||
public decimal TotalUSD { get; set; }
|
||||
public decimal TotalCNY { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class VolumeStatisticsDTO
|
||||
{
|
||||
public Guid StatisticsId { get; set; }
|
||||
public string Month { get; set; } = String.Empty;
|
||||
public decimal VolumeReward { get; set; }
|
||||
public decimal ExchangeRate { get; set; }
|
||||
|
||||
public decimal AdjustmentUSD { get; set; }
|
||||
public decimal AdjustmentCNY { get; set; }
|
||||
public decimal PaymentUSD { get; set; }
|
||||
public decimal PaymentCNY { get; set; }
|
||||
public decimal TotalCNY => AdjustmentCNY + PaymentCNY;
|
||||
public decimal TotalUSD => AdjustmentUSD + PaymentUSD;
|
||||
|
||||
public List<TrialPaymentDTO> TrialPaymentList = new List<TrialPaymentDTO>();
|
||||
}
|
||||
|
||||
public class TrialPaymentDTO
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
public string TrialCode { get; set; } = String.Empty;
|
||||
public decimal TrialPayment { get; set; }
|
||||
|
||||
}
|
||||
public class VolumeQueryDTO
|
||||
{
|
||||
public DateTime BeginMonth { get; set; }
|
||||
public DateTime EndMonth { get; set; }
|
||||
public Guid ReviewerId { get; set; }
|
||||
}
|
||||
|
||||
public class RevenuesDTO
|
||||
{
|
||||
public List<string> MissingTrialCodes = new List<string>();
|
||||
public Guid Id { get; set; }
|
||||
public string TrialCode { get; set; } = String.Empty;
|
||||
public Guid TrialId { get; set; }
|
||||
public string Indication { get; set; } = String.Empty;
|
||||
public Guid? CroId { get; set; }
|
||||
public string Cro { get; set; } = string.Empty;
|
||||
|
||||
public int Expedited { get; set; }
|
||||
public string ChineseName { get; set; } = string.Empty;
|
||||
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
public string LastName { get; set; } = string.Empty;
|
||||
public string ReviewerCode { get; set; } = string.Empty;
|
||||
|
||||
public decimal Training { get; set; }
|
||||
public decimal Downtime { get; set; }
|
||||
public decimal Timepoint { get; set; }
|
||||
public decimal TimepointIn24H { get; set; }
|
||||
public decimal TimepointIn48H { get; set; }
|
||||
public decimal Adjudication { get; set; }
|
||||
public decimal AdjudicationIn24H { get; set; }
|
||||
public decimal AdjudicationIn48H { get; set; }
|
||||
public decimal Global { get; set; }
|
||||
public decimal Total { get; set; }
|
||||
|
||||
public string YearMonth { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class PaymentDTO
|
||||
{
|
||||
public PageOutput<PaymentModel> CostList { get; set; }=new PageOutput<PaymentModel>();
|
||||
public decimal ExchangeRate { get; set; }
|
||||
}
|
||||
public class PaymentModel
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string RankName { get; set; } = String.Empty;
|
||||
public Guid DoctorId { get; set; }
|
||||
public string YearMonth { get; set; } = String.Empty;
|
||||
public DateTime YearMonthDate { get; set; }
|
||||
public DateTime? CalculateTime { get; set; }
|
||||
public string CalculateUser { get; set; } = String.Empty;
|
||||
|
||||
//额外信息
|
||||
public string Code { get; set; } = String.Empty;
|
||||
public string FirstName { get; set; } = String.Empty;
|
||||
public string LastName { get; set; } = String.Empty;
|
||||
|
||||
public string ChineseName { get; set; } = String.Empty;
|
||||
public string Phone { get; set; } = String.Empty;
|
||||
public string DoctorNameInBank { get; set; } = String.Empty;
|
||||
public string IDCard { get; set; } = String.Empty;
|
||||
public string BankCardNumber { get; set; } = String.Empty;
|
||||
public string BankName { get; set; } = String.Empty;
|
||||
|
||||
public bool IsLock { get; set; } = false;
|
||||
|
||||
public decimal ExchangeRate { get; set; }
|
||||
|
||||
public decimal PaymentCNY { get; set; }
|
||||
|
||||
public decimal AdjustPaymentCNY { get; set; }
|
||||
public decimal TotalPaymentCNY { get; set; }
|
||||
public decimal PaymentUSD { get; set; }
|
||||
|
||||
public decimal AdjustPaymentUSD { get; set; }
|
||||
public decimal TotalPaymentUSD { get; set; }
|
||||
}
|
||||
|
||||
public class PaymentCommand
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid DoctorId { get; set; }
|
||||
public string YearMonth => new DateTime(Year, Month, 1).ToString("yyyy-MM");
|
||||
public int Year { get; set; }
|
||||
public int Month { get; set; }
|
||||
public decimal PaymentUSD { get; set; }
|
||||
public DateTime CalculateTime { get; set; }
|
||||
public decimal PaymentCNY { get; set; }
|
||||
public decimal ExchangeRate { get; set; }
|
||||
public string CalculateUser { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
public class MonthlyPaymentQueryDTO : PageInput
|
||||
{
|
||||
public DateTime StatisticsDate { get; set; }
|
||||
public string KeyWord { get; set; } = String.Empty;
|
||||
public int? Nation { get; set; }
|
||||
}
|
||||
|
||||
public class MonthlyPaymentDetailQuery
|
||||
{
|
||||
public Guid PaymentId { get; set; }
|
||||
public Guid ReviewerId { get; set; }
|
||||
|
||||
public DateTime YearMonth { get; set; }
|
||||
}
|
||||
|
||||
//public class LaborPaymentQuery
|
||||
//{
|
||||
// public Guid PaymentId { get; set; }
|
||||
// public Guid ReviewerId { get; set; }
|
||||
|
||||
// public DateTime YearMonth { get; set; }
|
||||
//}
|
||||
|
||||
|
||||
public class TrialAnalysisDTO
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
public string Indication { get; set; } = String.Empty;
|
||||
|
||||
public string TrialCode { get; set; } = String.Empty;
|
||||
public string Cro { get; set; } = string.Empty;
|
||||
|
||||
public int Expedited { get; set; }
|
||||
|
||||
public string Type { get; set; } = String.Empty;
|
||||
|
||||
public decimal PaymentUSD { get; set; }
|
||||
public decimal RevenusUSD { get; set; }
|
||||
public decimal GrossProfit => RevenusUSD - PaymentUSD;
|
||||
public decimal GrossProfitMargin
|
||||
{
|
||||
get {
|
||||
if (RevenusUSD == 0)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
return GrossProfit / RevenusUSD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class LaborPayment
|
||||
{
|
||||
public string ChineseName { get; set; } = String.Empty;
|
||||
public string FirstName { get; set; } = String.Empty;
|
||||
public string LastName { get; set; } = String.Empty;
|
||||
|
||||
public string ResidentId { get; set; } = String.Empty;
|
||||
|
||||
public string Phone { get; set; } = String.Empty;
|
||||
|
||||
public string AccountNumber { get; set; } = String.Empty;
|
||||
|
||||
public string Bank { get; set; } = String.Empty;
|
||||
public string YearMonth { get; set; } = String.Empty;
|
||||
|
||||
public decimal PaymentCNY { get; set; }
|
||||
public decimal TaxCNY { get; set; }
|
||||
public decimal ActuallyPaidCNY { get; set; }
|
||||
public decimal BankTransferCNY { get; set; }
|
||||
}
|
||||
public class ReviewerAnalysisDTO
|
||||
{
|
||||
public List<string> MissingTrialCodes = new List<string>();
|
||||
public string ChineseName { get; set; } = String.Empty;
|
||||
public string FirstName { get; set; } = String.Empty;
|
||||
public string LastName { get; set; } = String.Empty;
|
||||
|
||||
public Guid ReviewerId { get; set; }
|
||||
public string ReviewerCode { get; set; } = String.Empty;
|
||||
|
||||
public decimal PaymentUSD { get; set; }
|
||||
public decimal RevenusUSD { get; set; }
|
||||
public decimal GrossProfit => RevenusUSD - PaymentUSD;
|
||||
|
||||
public decimal GrossProfitMargin
|
||||
{
|
||||
get {
|
||||
if (RevenusUSD == 0)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
return GrossProfit / RevenusUSD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public class AnalysisQueryDTO
|
||||
{
|
||||
public string Reviewer { get; set; } = String.Empty;
|
||||
public DateTime BeginDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
|
||||
public int? Nation { get; set; }
|
||||
}
|
||||
|
||||
public class TrialAnalysisQueryDTO
|
||||
{
|
||||
public Guid? CroId { get; set; }
|
||||
public string TrialCode { get; set; } = String.Empty;
|
||||
public DateTime BeginDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
|
||||
public int? AttendedReviewerType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class RankPriceDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string RankName { get; set; } = string.Empty;
|
||||
public decimal Timepoint { get; set; }
|
||||
public decimal TimepointIn24H { get; set; }
|
||||
public decimal TimepointIn48H { get; set; }
|
||||
public decimal Adjudication { get; set; }
|
||||
public decimal AdjudicationIn24H { get; set; }
|
||||
public decimal AdjudicationIn48H { get; set; }
|
||||
public decimal Global { get; set; }
|
||||
public decimal Training { get; set; }
|
||||
public decimal Downtime { get; set; }
|
||||
|
||||
public decimal RefresherTraining { get; set; }
|
||||
public int ShowOrder { get; set; }
|
||||
}
|
||||
|
||||
public class RankDic
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string RankName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class RankPriceCommand
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string RankName { get; set; } = string.Empty;
|
||||
public decimal Timepoint { get; set; }
|
||||
public decimal TimepointIn24H { get; set; }
|
||||
public decimal TimepointIn48H { get; set; }
|
||||
public decimal Adjudication { get; set; }
|
||||
public decimal AdjudicationIn24H { get; set; }
|
||||
public decimal AdjudicationIn48H { get; set; }
|
||||
public decimal Global { get; set; }
|
||||
public decimal Training { get; set; }
|
||||
public decimal Downtime { get; set; }
|
||||
public decimal RefresherTraining { get; set; }
|
||||
|
||||
|
||||
}
|
||||
public class RankPriceQueryDTO : PageInput
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class ReviewerPayInfoQueryDTO
|
||||
{
|
||||
public Guid DoctorId { get; set; }
|
||||
public string FirstName { get; set; } = String.Empty;
|
||||
public string LastName { get; set; } = String.Empty;
|
||||
public string ChineseName { get; set; } = String.Empty;
|
||||
public string Code { get; set; } = String.Empty;
|
||||
public string Phone { get; set; } = String.Empty;
|
||||
public string DoctorNameInBank { get; set; } = String.Empty;
|
||||
public string IDCard { get; set; } = String.Empty;
|
||||
public string BankCardNumber { get; set; } = String.Empty;
|
||||
public string BankName { get; set; } = String.Empty;
|
||||
public Guid? RankId { get; set; }
|
||||
public decimal? Additional { get; set; }
|
||||
public DateTime? CreateTime { get; set; }
|
||||
}
|
||||
|
||||
public class DoctorPayInfoQueryListDTO : ReviewerPayInfoQueryDTO
|
||||
{
|
||||
public string Hospital { get; set; } = String.Empty;
|
||||
public string RankName { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
public class ReviewerPayInfoCommand
|
||||
{
|
||||
//public Guid Id { get; set; }
|
||||
public Guid DoctorId { get; set; }
|
||||
public string DoctorNameInBank { get; set; } = String.Empty;
|
||||
public string IDCard { get; set; } = String.Empty;
|
||||
public string BankCardNumber { get; set; } = String.Empty;
|
||||
public string BankName { get; set; } = String.Empty;
|
||||
public Guid RankId { get; set; }
|
||||
public decimal? Additional { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using System;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
|
||||
public class DtoDoctorList
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public class TrialPaymentPriceDTO
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
public string TrialCode { get; set; } = String.Empty;
|
||||
public string Indication { get; set; } = String.Empty;
|
||||
public string Cro { get; set; } = String.Empty;
|
||||
public int Expedited { get; set; }
|
||||
|
||||
public bool? IsNewTrial { get; set; }
|
||||
public decimal? TrialAdditional { get; set; }
|
||||
public DateTime? CreateTime { get; set; }
|
||||
public string SowName { get; set; } = String.Empty;
|
||||
public string SowPath { get; set; } = String.Empty;
|
||||
public string SowFullPath => SowPath;
|
||||
public decimal AdjustmentMultiple { get; set; } = 1;
|
||||
|
||||
public string DoctorsNames{ get; set; }=String.Empty;
|
||||
|
||||
public string ReviewMode { get; set; } = String.Empty;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class TrialPaymentPriceCommand
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
public decimal TrialAdditional { get; set; }
|
||||
public decimal AdjustmentMultiple { get; set; }
|
||||
|
||||
public bool? IsNewTrial { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Contracts
|
||||
{
|
||||
public class TrialRevenuesPriceDTO
|
||||
{
|
||||
|
||||
public Guid TrialId { get; set; }
|
||||
public decimal Timepoint { get; set; }
|
||||
public decimal TimepointIn24H { get; set; }
|
||||
public decimal TimepointIn48H { get; set; }
|
||||
public decimal Adjudication { get; set; }
|
||||
public decimal AdjudicationIn24H { get; set; }
|
||||
public decimal AdjudicationIn48H { get; set; }
|
||||
public decimal RefresherTraining { get; set; }
|
||||
|
||||
public decimal Global { get; set; }
|
||||
public decimal Training { get; set; }
|
||||
public decimal Downtime { get; set; }
|
||||
}
|
||||
|
||||
public class TrialRevenuesPriceDetialDTO : TrialRevenuesPriceDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string TrialCode { get; set; } = String.Empty;
|
||||
public string Indication { get; set; } = string.Empty;
|
||||
public int Expedited { get; set; }
|
||||
public string ReviewMode { get; set; } = String.Empty;
|
||||
public string Cro { get; set; } = String.Empty;
|
||||
}
|
||||
public class TrialRevenuesPriceQueryDTO : PageInput
|
||||
{
|
||||
public string KeyWord { get; set; } = String.Empty;
|
||||
public Guid? CroId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
public class RevenusVerifyQueryDTO
|
||||
{
|
||||
public DateTime BeginDate { get; set; } = DateTime.Now;
|
||||
public DateTime EndDate { get; set; } = DateTime.Now;
|
||||
|
||||
}
|
||||
|
||||
public class AnalysisVerifyQueryDTO
|
||||
{
|
||||
public DateTime BeginDate { get; set; } = DateTime.Now;
|
||||
public DateTime EndDate { get; set; } = DateTime.Now;
|
||||
}
|
||||
|
||||
|
||||
public class AnalysisNeedLockDTO
|
||||
{
|
||||
public string YearMonth { get; set; } = string.Empty;
|
||||
|
||||
public string ReviewerCode { get; set; } = string.Empty;
|
||||
|
||||
public string ReviewerName { get; set; } = string.Empty;
|
||||
|
||||
public string ReviewerNameCN { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class AnalysisVerifyResultDTO
|
||||
{
|
||||
public List<MonthlyResult> MonthVerifyResult = new List<MonthlyResult>();
|
||||
|
||||
public List<RevenusVerifyDTO> RevenuesVerifyList = new List<RevenusVerifyDTO>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class MonthlyResult
|
||||
{
|
||||
public string YearMonth { get; set; } = string.Empty;
|
||||
public List<string> ReviewerNameList = new List<string>();
|
||||
public List<string> ReviewerNameCNList = new List<string>();
|
||||
public List<string> ReviewerCodeList = new List<string>();
|
||||
}
|
||||
|
||||
|
||||
public class RevenusVerifyDTO
|
||||
{
|
||||
public string TrialCode { get; set; } = string.Empty;
|
||||
|
||||
public bool Training { get; set; } = false;
|
||||
|
||||
public bool Downtime { get; set; } = false;
|
||||
|
||||
public bool Global { get; set; } = false;
|
||||
|
||||
public bool Timepoint { get; set; } = false;
|
||||
|
||||
public bool TimepointIn24H { get; set; } = false;
|
||||
|
||||
public bool TimepointIn48H { get; set; } = false;
|
||||
|
||||
public bool Adjudication { get; set; } = false;
|
||||
|
||||
public bool AdjudicationIn24H { get; set; } = false;
|
||||
|
||||
public bool AdjudicationIn48H { get; set; } = false;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
|
||||
[ApiExplorerSettings(GroupName = "Financial")]
|
||||
public class ExchangeRateService : BaseService, IExchangeRateService
|
||||
{
|
||||
private readonly IRepository<ExchangeRate> _exchangeRateRepository;
|
||||
private readonly IRepository<Payment> _paymentRepository;
|
||||
|
||||
public ExchangeRateService(IRepository<ExchangeRate> exchangeRateRepository, IRepository<Payment> paymentRepository)
|
||||
{
|
||||
_exchangeRateRepository = exchangeRateRepository;
|
||||
_paymentRepository = paymentRepository;
|
||||
}
|
||||
|
||||
[NonDynamicMethod]
|
||||
public async Task<IResponseOutput> AddOrUpdateExchangeRate(ExchangeRateCommand model)
|
||||
{
|
||||
if (model.Id == Guid.Empty || model.Id == null)
|
||||
{
|
||||
var existItem = await _exchangeRateRepository.FirstOrDefaultAsync(u => u.YearMonth == model.YearMonth);
|
||||
if (existItem != null)
|
||||
{
|
||||
return ResponseOutput.NotOk("The exchange rate of the same month already existed.");
|
||||
}
|
||||
var rate = _mapper.Map<ExchangeRate>(model);
|
||||
rate = await _exchangeRateRepository.AddAsync(rate);
|
||||
if (await _exchangeRateRepository.SaveChangesAsync())
|
||||
{
|
||||
return ResponseOutput.Ok(rate.Id.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return ResponseOutput.NotOk();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var success = await _exchangeRateRepository.UpdateFromQueryAsync(t => t.Id == model.Id, u => new ExchangeRate()
|
||||
{
|
||||
//YearMonth = model.YearMonth,
|
||||
Rate = model.Rate,
|
||||
UpdateTime = DateTime.Now
|
||||
});
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据记录Id,删除汇率记录
|
||||
/// </summary>
|
||||
/// <param name="id">汇率记录Id</param>
|
||||
|
||||
[HttpDelete("{id:guid}")]
|
||||
public async Task<IResponseOutput> DeleteExchangeRate(Guid id)
|
||||
{
|
||||
var monthInfo = await _exchangeRateRepository.FirstOrDefaultAsync(t => t.Id == id);
|
||||
|
||||
if (await _paymentRepository.AnyAsync(t => t.YearMonth == monthInfo.YearMonth))
|
||||
{
|
||||
return ResponseOutput.NotOk("The exchange rate has been used in monthly payment");
|
||||
}
|
||||
|
||||
|
||||
var success = await _exchangeRateRepository.DeleteFromQueryAsync(t => t.Id == id);
|
||||
|
||||
return ResponseOutput.Ok(success);
|
||||
}
|
||||
|
||||
|
||||
[NonDynamicMethod]
|
||||
public async Task<decimal> GetExchangeRateByMonth(string month)
|
||||
{
|
||||
//var rate = _exchangeRateRepository.FindSingleOrDefault(u => u.YearMonth.Equals(month));
|
||||
//if (rate == null)
|
||||
//{
|
||||
// return 0;
|
||||
//}
|
||||
//return rate.Rate;
|
||||
|
||||
var rate = await _exchangeRateRepository.FirstOrDefaultAsync(t => t.YearMonth == month);
|
||||
if (rate == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return rate.Rate;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<ExchangeRateCommand>> GetExchangeRateList(ExchangeRateQueryDTO queryParam)
|
||||
{
|
||||
|
||||
var yearMonth = queryParam.SearchMonth?.ToString("yyyy-MM");
|
||||
|
||||
var exchangeRateQueryable = _exchangeRateRepository.AsQueryable()
|
||||
.WhereIf(queryParam.SearchMonth != null, o => o.YearMonth == yearMonth)
|
||||
.ProjectTo<ExchangeRateCommand>(_mapper.ConfigurationProvider);
|
||||
|
||||
return await exchangeRateQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, "YearMonth", false);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
using IRaCIS.Application.Contracts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface ICalculateService
|
||||
{
|
||||
Task<IResponseOutput> CalculateMonthlyPayment(CalculateDoctorAndMonthDTO param, string token);
|
||||
//IResponseOutput LockMonthlyPayment(LockPaymentDTO param);
|
||||
Task<List<CalculateNeededDTO>> GetNeedCalculateReviewerList(Guid reviewerId, string yearMonth);
|
||||
Task<bool> IsLock(Guid reviewerId, string yearMonth);
|
||||
//bool ResetMonthlyPayment(Guid reviewerId, Guid trialId,string yearMonth);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IReviewerPayInfoService
|
||||
{
|
||||
Task<IResponseOutput> AddOrUpdateReviewerPayInfo(ReviewerPayInfoCommand addOrUpdateModel, Guid userId);
|
||||
Task<PageOutput<DoctorPayInfoQueryListDTO>> GetReviewerPayInfoList(DoctorPaymentInfoQueryDTO queryParam);
|
||||
Task<DoctorPayInfoQueryListDTO> GetReviewerPayInfo(Guid doctorId);
|
||||
Task<List<Guid>> GetReviewerIdByRankId(Guid rankId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using IRaCIS.Application.Contracts;
|
||||
using System;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IExchangeRateService
|
||||
{
|
||||
Task<IResponseOutput> AddOrUpdateExchangeRate(ExchangeRateCommand model);
|
||||
Task<decimal> GetExchangeRateByMonth(string month);
|
||||
Task<PageOutput<ExchangeRateCommand>> GetExchangeRateList(ExchangeRateQueryDTO queryParam);
|
||||
|
||||
Task<IResponseOutput> DeleteExchangeRate(Guid id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using IRaCIS.Application.Contracts.Pay;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IPaymentAdjustmentService
|
||||
{
|
||||
Task<PageOutput<PaymentAdjustmentDetailDTO>> GetPaymentAdjustmentList(PaymentAdjustmentQueryDTO queryParam);
|
||||
Task<IResponseOutput> AddOrUpdatePaymentAdjustment(PaymentAdjustmentCommand addOrUpdateModel);
|
||||
Task<IResponseOutput> DeletePaymentAdjustment(Guid id);
|
||||
Task CalculateCNY(string yearMonth, decimal rate);
|
||||
Task<List<DoctorSelectDTO>> GetReviewerSelectList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Application.Contracts.Pay;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IPaymentService
|
||||
{
|
||||
Task<IResponseOutput> LockMonthlyPayment(LockPaymentDTO param);
|
||||
|
||||
Task<PageOutput<PaymentModel>> GetMonthlyPaymentList(MonthlyPaymentQueryDTO queryParam);
|
||||
Task<PayDetailDTO> GetMonthlyPaymentDetailList(Guid PaymentId, Guid doctorId, DateTime yearMonth);
|
||||
|
||||
Task<List<LaborPayment>> GetLaborPaymentList(List<Guid> paymentId);
|
||||
|
||||
//导出多个医生的付费详细
|
||||
Task<List<PayDetailDTO>> GetReviewersMonthlyPaymentDetail(List<MonthlyPaymentDetailQuery> manyReviewers);
|
||||
|
||||
Task<PageOutput<MonthlyPaymentDTO>> GetPaymentHistoryList(PaymentQueryDTO param);
|
||||
Task<List<VolumeStatisticsDTO>> GetPaymentHistoryDetailList(VolumeQueryDTO param);
|
||||
|
||||
Task<PageOutput<RevenuesDTO>> GetRevenuesStatistics(StatisticsQueryDTO param);
|
||||
Task<List<TrialAnalysisDTO>> GetTrialAnalysisList(TrialAnalysisQueryDTO param);
|
||||
Task<List<ReviewerAnalysisDTO>> GetReviewerAnalysisList(AnalysisQueryDTO param);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IRankPriceService
|
||||
{
|
||||
Task<IResponseOutput> AddOrUpdateRankPrice(RankPriceCommand addOrUpdateModel, Guid userId);
|
||||
|
||||
Task<PageOutput<RankPriceDTO>> GetRankPriceList(RankPriceQueryDTO queryParam);
|
||||
|
||||
Task<IResponseOutput> DeleteRankPrice( Guid id);
|
||||
|
||||
Task<List<RankDic>> GetRankDic();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface ITrialPaymentPriceService
|
||||
{
|
||||
Task<IResponseOutput> AddOrUpdateTrialPaymentPrice(TrialPaymentPriceCommand addOrUpdateModel);//新增也不需要返回Id,TrialId 也是唯一
|
||||
Task<PageOutput<TrialPaymentPriceDTO>> GetTrialPaymentPriceList(TrialPaymentPriceQueryDTO queryParam);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 上传入组后的Ack-SOW
|
||||
/// </summary>
|
||||
Task<IResponseOutput> UploadTrialSOW( TrialSOWPathDTO trialSowPath);
|
||||
|
||||
|
||||
|
||||
Task<IResponseOutput> DeleteTrialSOW( DeleteSowPathDTO trialSowPath);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using IRaCIS.Application.Contracts;
|
||||
using System;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface ITrialRevenuesPriceService
|
||||
{
|
||||
Task<IResponseOutput> AddOrUpdateTrialRevenuesPrice(TrialRevenuesPriceDTO model);
|
||||
Task<bool> DeleteTrialCost(Guid Id);
|
||||
Task<PageOutput<TrialRevenuesPriceDetialDTO>> GetTrialRevenuesPriceList(TrialRevenuesPriceQueryDTO param);
|
||||
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface ITrialRevenuesPriceVerificationService
|
||||
{
|
||||
//List<RevenusVerifyDTO> GetRevenuesVerifyResultList(RevenusVerifyQueryDTO param);
|
||||
|
||||
Task<AnalysisVerifyResultDTO> GetAnalysisVerifyList(RevenusVerifyQueryDTO param);
|
||||
|
||||
Task<List<RevenusVerifyDTO>> GetRevenuesVerifyList(RevenusVerifyQueryDTO param);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Application.Interfaces
|
||||
{
|
||||
public interface IVolumeRewardService
|
||||
{
|
||||
Task<IResponseOutput> AddOrUpdateVolumeRewardPriceList(IEnumerable<AwardPriceCommand> addOrUpdateModels);
|
||||
Task<PageOutput<AwardPriceDTO>> GetVolumeRewardPriceList(AwardPriceQueryDTO queryParam);
|
||||
Task<List<AwardPriceCalculateDTO>> GetVolumeRewardPriceList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
using AutoMapper;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts.Pay;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
[ApiExplorerSettings(GroupName = "Financial")]
|
||||
public class PaymentAdjustmentService : BaseService, IPaymentAdjustmentService
|
||||
{
|
||||
private readonly IRepository<PaymentAdjustment> _payAdjustmentRepository;
|
||||
private readonly IRepository<Doctor> _doctorRepository;
|
||||
private readonly IRepository<ExchangeRate> _exchangeRateRepository;
|
||||
private readonly IRepository<Payment> _paymentRepository;
|
||||
|
||||
|
||||
public PaymentAdjustmentService(IRepository<PaymentAdjustment> costAdjustmentRepository, IRepository<Doctor> doctorRepository,
|
||||
IRepository<ExchangeRate> exchangeRateRepository, IRepository<Payment> paymentRepository, IMapper mapper)
|
||||
{
|
||||
_payAdjustmentRepository = costAdjustmentRepository;
|
||||
_doctorRepository = doctorRepository;
|
||||
_exchangeRateRepository = exchangeRateRepository;
|
||||
_paymentRepository = paymentRepository;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加或更新费用调整[AUTH]
|
||||
/// </summary>
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> AddOrUpdatePaymentAdjustment(PaymentAdjustmentCommand addOrUpdateModel)
|
||||
{
|
||||
|
||||
var yearMonthDate = new DateTime(addOrUpdateModel.YearMonth.Year, addOrUpdateModel.YearMonth.Month, 1);
|
||||
var yearMonth = addOrUpdateModel.YearMonth.ToString("yyyy-MM");
|
||||
|
||||
var payment = await _paymentRepository.FirstOrDefaultAsync(u => u.DoctorId == addOrUpdateModel.ReviewerId
|
||||
&& u.YearMonth == yearMonth);
|
||||
|
||||
//判断付费表中是否有记录
|
||||
if (payment == null)
|
||||
{
|
||||
//没有 添加仅有的调整费用记录
|
||||
payment = new Payment
|
||||
{
|
||||
DoctorId = addOrUpdateModel.ReviewerId,
|
||||
YearMonth = yearMonth,
|
||||
YearMonthDate = yearMonthDate,
|
||||
PaymentCNY = 0,
|
||||
PaymentUSD = 0,
|
||||
AdjustmentCNY = 0,
|
||||
AdjustmentUSD = 0
|
||||
};
|
||||
await _paymentRepository.AddAsync(payment);
|
||||
await _paymentRepository.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (payment.IsLock)
|
||||
{
|
||||
return ResponseOutput.NotOk("Doctor payment has confirmed lock");
|
||||
}
|
||||
}
|
||||
|
||||
var exchangeRate = await _exchangeRateRepository.FirstOrDefaultAsync(t => t.YearMonth == yearMonth);
|
||||
if (addOrUpdateModel.Id == Guid.Empty || addOrUpdateModel.Id == null)
|
||||
{
|
||||
var costAdjustment = _mapper.Map<PaymentAdjustment>(addOrUpdateModel);
|
||||
|
||||
//视图模型和领域模型没对应 重新赋值
|
||||
costAdjustment.ExchangeRate = exchangeRate?.Rate ?? 0;
|
||||
costAdjustment.AdjustmentCNY = addOrUpdateModel.AdjustPaymentUSD * (exchangeRate?.Rate ?? 0);
|
||||
costAdjustment.AdjustmentUSD = addOrUpdateModel.AdjustPaymentUSD;
|
||||
|
||||
await _payAdjustmentRepository.AddAsync(costAdjustment);
|
||||
|
||||
//添加的时候,每个月调整汇总费用 需要加上本次调整的费用
|
||||
payment.AdjustmentCNY += costAdjustment.AdjustmentCNY;
|
||||
payment.AdjustmentUSD += costAdjustment.AdjustmentUSD;
|
||||
|
||||
await _paymentRepository.UpdateAsync(payment);
|
||||
|
||||
await _payAdjustmentRepository.SaveChangesAsync();
|
||||
|
||||
|
||||
return ResponseOutput.Ok(costAdjustment.Id.ToString());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// 更新的时候,先查出来,更新前的调整费用数据
|
||||
var paymentAdjust = await _payAdjustmentRepository.FirstOrDefaultAsync(t => t.Id == addOrUpdateModel.Id);
|
||||
|
||||
|
||||
_mapper.Map(addOrUpdateModel, paymentAdjust);
|
||||
|
||||
paymentAdjust.ExchangeRate = exchangeRate?.Rate ?? 0;
|
||||
paymentAdjust.AdjustmentUSD = addOrUpdateModel.AdjustPaymentUSD;
|
||||
paymentAdjust.AdjustmentCNY = addOrUpdateModel.AdjustPaymentUSD * (exchangeRate?.Rate ?? 0);
|
||||
|
||||
await _payAdjustmentRepository.UpdateAsync(paymentAdjust);
|
||||
var success = await _payAdjustmentRepository.SaveChangesAsync();
|
||||
|
||||
if (success)
|
||||
{
|
||||
|
||||
var adjustmentList = await _payAdjustmentRepository.Where(u => u.ReviewerId == addOrUpdateModel.ReviewerId && u.YearMonth == yearMonth).ToListAsync();
|
||||
|
||||
payment.AdjustmentCNY = adjustmentList.Sum(t => t.AdjustmentCNY);
|
||||
payment.AdjustmentUSD = adjustmentList.Sum(t => t.AdjustmentUSD);
|
||||
|
||||
|
||||
await _paymentRepository.UpdateAsync(payment);
|
||||
|
||||
await _paymentRepository.SaveChangesAsync();
|
||||
}
|
||||
|
||||
//查询得到历史汇总
|
||||
|
||||
|
||||
|
||||
return ResponseOutput.Ok(success);
|
||||
|
||||
#region 逻辑存在错误 问题待查
|
||||
|
||||
//// 更新的时候,先查出来,更新前的调整费用数据
|
||||
//var paymentAdjust = _payAdjustmentRepository.FindSingleOrDefault(t => t.Id == addOrUpdateModel.Id);
|
||||
|
||||
////减去数据库本条记录的值
|
||||
//payment.AdjustmentCNY = -paymentAdjust.AdjustmentCNY;
|
||||
//payment.AdjustmentUSD = -paymentAdjust.AdjustmentUSD;
|
||||
|
||||
//_mapper.Map(addOrUpdateModel, paymentAdjust);
|
||||
|
||||
//paymentAdjust.ExchangeRate = exchangeRate?.Rate ?? 0;
|
||||
//paymentAdjust.AdjustmentUSD = addOrUpdateModel.AdjustPaymentUSD;
|
||||
//paymentAdjust.AdjustmentCNY = addOrUpdateModel.AdjustPaymentUSD * (exchangeRate?.Rate ?? 0);
|
||||
|
||||
//_payAdjustmentRepository.Update(paymentAdjust);
|
||||
|
||||
////查询得到历史汇总
|
||||
//var adjustment = _payAdjustmentRepository.Find(u => u.ReviewerId == addOrUpdateModel.ReviewerId && u.YearMonth == yearMonth)
|
||||
// .GroupBy(u => new { u.ReviewerId, u.YearMonth }).Select(g => new
|
||||
// {
|
||||
// AdjustCNY = g.Sum(t => t.AdjustmentCNY),
|
||||
// AdjustUSD = g.Sum(t => t.AdjustmentUSD)
|
||||
// }).FirstOrDefault();
|
||||
|
||||
////最终的值 等于历史汇总 减去更新前的加上当前更新的值
|
||||
//payment.AdjustmentCNY += (adjustment.AdjustCNY + paymentAdjust.AdjustmentCNY);
|
||||
//payment.AdjustmentUSD += (adjustment.AdjustUSD + paymentAdjust.AdjustmentUSD);
|
||||
|
||||
//_paymentRepository.Update(payment);
|
||||
|
||||
//var success = _payAdjustmentRepository.SaveChanges();
|
||||
//return ResponseOutput.Result(success, success ? string.Empty : StaticData.UpdateFailed);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除费用调整记录
|
||||
/// </summary>
|
||||
|
||||
[HttpDelete("{id:guid}")]
|
||||
public async Task<IResponseOutput> DeletePaymentAdjustment(Guid id)
|
||||
{
|
||||
var adjustPayment = await _payAdjustmentRepository.FirstOrDefaultAsync(u => u.Id == id);
|
||||
|
||||
var monthPay = await _paymentRepository.FirstOrDefaultAsync(t =>
|
||||
t.DoctorId == adjustPayment.ReviewerId && t.YearMonth == adjustPayment.YearMonth);
|
||||
|
||||
await _payAdjustmentRepository.DeleteAsync(new PaymentAdjustment() { Id = id });
|
||||
|
||||
var success = await _payAdjustmentRepository.SaveChangesAsync();
|
||||
|
||||
if (success)
|
||||
{
|
||||
|
||||
var adjustmentList = await _payAdjustmentRepository.Where(u =>
|
||||
u.ReviewerId == adjustPayment.ReviewerId && u.YearMonth == adjustPayment.YearMonth).ToListAsync();
|
||||
|
||||
monthPay.AdjustmentCNY = adjustmentList.Sum(t => t.AdjustmentCNY);
|
||||
monthPay.AdjustmentUSD = adjustmentList.Sum(t => t.AdjustmentUSD);
|
||||
|
||||
|
||||
|
||||
await _paymentRepository.UpdateAsync(monthPay);
|
||||
|
||||
await _paymentRepository.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取费用调整列表
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<PaymentAdjustmentDetailDTO>> GetPaymentAdjustmentList(PaymentAdjustmentQueryDTO queryParam)
|
||||
{
|
||||
|
||||
var beginYearMonth = queryParam.BeginMonth.AddDays(1 - queryParam.BeginMonth.Day);
|
||||
var endYearMonth = queryParam.EndMonth.AddDays(1 - queryParam.EndMonth.Day).AddMonths(1).AddDays(-1);
|
||||
|
||||
var costAdjustmentQueryable = from costAdjustment in _payAdjustmentRepository
|
||||
.Where(t => t.YearMonthDate >= beginYearMonth && t.YearMonthDate <= endYearMonth)
|
||||
join doctor in _doctorRepository.AsQueryable().
|
||||
WhereIf(!string.IsNullOrWhiteSpace(queryParam.Reviewer),
|
||||
u => u.ChineseName.Contains(queryParam.Reviewer) ||
|
||||
(u.LastName + u.FirstName).Contains(queryParam.Reviewer) ||
|
||||
u.ReviewerCode.Contains(queryParam.Reviewer))
|
||||
on costAdjustment.ReviewerId equals doctor.Id
|
||||
|
||||
select new PaymentAdjustmentDetailDTO()
|
||||
{
|
||||
AdjustPaymentCNY = costAdjustment.AdjustmentCNY,
|
||||
AdjustPaymentUSD = costAdjustment.AdjustmentUSD,
|
||||
IsLock = costAdjustment.IsLock,
|
||||
Id = costAdjustment.Id,
|
||||
YearMonth = costAdjustment.YearMonth,
|
||||
YearMonthDate = costAdjustment.YearMonthDate,
|
||||
Note = costAdjustment.Note,
|
||||
ReviewerId = costAdjustment.ReviewerId,
|
||||
ReviewerCode = doctor.ReviewerCode,
|
||||
FirstName = doctor.FirstName,
|
||||
LastName = doctor.LastName,
|
||||
ChineseName = doctor.ChineseName
|
||||
};
|
||||
|
||||
return await costAdjustmentQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, string.IsNullOrWhiteSpace(queryParam.SortField) ? "YearMonthDate" : queryParam.SortField, queryParam.Asc);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async Task<List<DoctorSelectDTO>> GetReviewerSelectList()
|
||||
{
|
||||
return await _doctorRepository.Where(t => t.CooperateStatus == ContractorStatusEnum.Cooperation && t.ResumeStatus == ResumeStatusEnum.Pass).ProjectTo<DoctorSelectDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
[NonDynamicMethod]
|
||||
public async Task CalculateCNY(string yearMonth, decimal rate)
|
||||
{
|
||||
|
||||
//如果是double 不会保留两位小数
|
||||
await _payAdjustmentRepository.UpdateFromQueryAsync(u => u.YearMonth == yearMonth &&
|
||||
!u.IsLock, t => new PaymentAdjustment
|
||||
{
|
||||
AdjustmentCNY = t.AdjustmentUSD * rate,
|
||||
ExchangeRate = rate,
|
||||
UpdateTime = DateTime.Now
|
||||
});
|
||||
|
||||
var adjustList = await _payAdjustmentRepository.Where(u => u.YearMonth == yearMonth &&
|
||||
!u.IsLock).ToListAsync();
|
||||
|
||||
|
||||
|
||||
var needUpdatePayment = adjustList.GroupBy(t => t.ReviewerId).Select(g => new
|
||||
{
|
||||
ReviewerId = g.Key,
|
||||
AdjustCNY = g.Sum(t => t.AdjustmentCNY),
|
||||
AdjustUSD = g.Sum(t => t.AdjustmentUSD)
|
||||
});
|
||||
|
||||
foreach (var reviewer in needUpdatePayment)
|
||||
{
|
||||
await _paymentRepository.UpdateFromQueryAsync(u => u.YearMonth == yearMonth &&
|
||||
!u.IsLock && u.DoctorId == reviewer.ReviewerId, t => new Payment()
|
||||
{
|
||||
AdjustmentUSD = reviewer.AdjustUSD,
|
||||
AdjustmentCNY = reviewer.AdjustCNY
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using AutoMapper;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
[ ApiExplorerSettings(GroupName = "Financial")]
|
||||
public class RankPriceService : BaseService, IRankPriceService
|
||||
{
|
||||
private readonly IRepository<RankPrice> _rankPriceRepository;
|
||||
private readonly IRepository<ReviewerPayInformation> _reviewerPayInfoRepository;
|
||||
|
||||
|
||||
public RankPriceService(IRepository<RankPrice> rankPriceRepository, IRepository<ReviewerPayInformation> reviewerPayInfoRepository,IMapper mapper)
|
||||
{
|
||||
_rankPriceRepository = rankPriceRepository;
|
||||
_reviewerPayInfoRepository = reviewerPayInfoRepository;
|
||||
|
||||
}
|
||||
|
||||
[NonDynamicMethod]
|
||||
public async Task<IResponseOutput> AddOrUpdateRankPrice(RankPriceCommand addOrUpdateModel, Guid userId)
|
||||
{
|
||||
if (addOrUpdateModel.Id == Guid.Empty|| addOrUpdateModel.Id ==null)
|
||||
{
|
||||
var rankPrice = _mapper.Map<RankPrice>(addOrUpdateModel);
|
||||
rankPrice = await _rankPriceRepository.AddAsync(rankPrice);
|
||||
if (await _rankPriceRepository.SaveChangesAsync())
|
||||
{
|
||||
return ResponseOutput.Ok(rankPrice.Id.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return ResponseOutput.NotOk();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var success =await _rankPriceRepository.UpdateFromQueryAsync(t => t.Id == addOrUpdateModel.Id, u => new RankPrice()
|
||||
{
|
||||
UpdateUserId = userId,
|
||||
UpdateTime = DateTime.Now,
|
||||
RefresherTraining=addOrUpdateModel.RefresherTraining,
|
||||
RankName = addOrUpdateModel.RankName,
|
||||
Timepoint = addOrUpdateModel.Timepoint,
|
||||
TimepointIn24H = addOrUpdateModel.TimepointIn24H,
|
||||
TimepointIn48H = addOrUpdateModel.TimepointIn48H,
|
||||
Adjudication = addOrUpdateModel.Adjudication,
|
||||
AdjudicationIn24H = addOrUpdateModel.AdjudicationIn24H,
|
||||
AdjudicationIn48H = addOrUpdateModel.AdjudicationIn48H,
|
||||
Global = addOrUpdateModel.Global,
|
||||
Training = addOrUpdateModel.Training,
|
||||
Downtime = addOrUpdateModel.Downtime
|
||||
|
||||
});
|
||||
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete("{id:guid}")]
|
||||
public async Task<IResponseOutput> DeleteRankPrice(Guid id)
|
||||
{
|
||||
|
||||
if (await _reviewerPayInfoRepository.AnyAsync(t => t.RankId == id))
|
||||
{
|
||||
return ResponseOutput.NotOk("This title has been used by reviewer payment information");
|
||||
}
|
||||
|
||||
var success = await _rankPriceRepository.DeleteFromQueryAsync(t => t.Id == id);
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取职称单价列表
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<RankPriceDTO>> GetRankPriceList(RankPriceQueryDTO queryParam)
|
||||
{
|
||||
var rankPriceQueryable = _rankPriceRepository.ProjectTo<RankPriceDTO>(_mapper.ConfigurationProvider);
|
||||
return await rankPriceQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, "ShowOrder", queryParam.Asc);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public async Task<List<RankDic>> GetRankDic()
|
||||
{
|
||||
var rankQueryable = _rankPriceRepository.ProjectTo<RankDic>(_mapper.ConfigurationProvider);
|
||||
return await rankQueryable.ToListAsync();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
using AutoMapper;
|
||||
using IRaCIS.Core.Infrastructure.ExpressionExtend;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using System.Linq.Expressions;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
[ ApiExplorerSettings(GroupName = "Financial")]
|
||||
public class ReviewerPayInfoService : BaseService, IReviewerPayInfoService
|
||||
{
|
||||
private readonly IRepository<ReviewerPayInformation> _doctorPayInfoRepository;
|
||||
private readonly IRepository<Doctor> _doctorRepository;
|
||||
private readonly IRepository<RankPrice> _rankPriceRepository;
|
||||
private readonly IRepository<Hospital> _hospitalRepository;
|
||||
|
||||
|
||||
public ReviewerPayInfoService(IRepository<Doctor> doctorRepository, IRepository<ReviewerPayInformation> doctorPayInfoRepository,
|
||||
IRepository<RankPrice> rankPriceRepository, IRepository<Hospital> hospitalRepository, IMapper mapper)
|
||||
{
|
||||
_doctorPayInfoRepository = doctorPayInfoRepository;
|
||||
_doctorRepository = doctorRepository;
|
||||
_rankPriceRepository = rankPriceRepository;
|
||||
_hospitalRepository = hospitalRepository;
|
||||
|
||||
}
|
||||
[NonDynamicMethod]
|
||||
public async Task<IResponseOutput> AddOrUpdateReviewerPayInfo(ReviewerPayInfoCommand addOrUpdateModel, Guid userId)
|
||||
{
|
||||
var success = false;
|
||||
var doctorPayInfoExistedItem = await _doctorPayInfoRepository.FirstOrDefaultAsync(u => u.DoctorId == addOrUpdateModel.DoctorId);
|
||||
if (doctorPayInfoExistedItem == null)//insert
|
||||
{
|
||||
var doctorPayInfo = _mapper.Map<ReviewerPayInformation>(addOrUpdateModel);
|
||||
//doctorPayInfo.CreateTime = DateTime.Now;
|
||||
//doctorPayInfo.CreateUserId = userId;
|
||||
await _doctorPayInfoRepository.AddAsync(doctorPayInfo);
|
||||
|
||||
}
|
||||
else//update
|
||||
{
|
||||
await _doctorPayInfoRepository.UpdateAsync(_mapper.Map(addOrUpdateModel, doctorPayInfoExistedItem));
|
||||
|
||||
}
|
||||
success = await _doctorPayInfoRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取医生支付信息列表
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<DoctorPayInfoQueryListDTO>> GetReviewerPayInfoList(DoctorPaymentInfoQueryDTO queryParam)
|
||||
{
|
||||
|
||||
|
||||
var doctorQueryable = from doctor in _doctorRepository.AsQueryable()
|
||||
.WhereIf(queryParam.HospitalId != null, o => o.HospitalId == queryParam.HospitalId)
|
||||
.WhereIf(!string.IsNullOrEmpty(queryParam.SearchName),
|
||||
u => u.ChineseName.Contains(queryParam.SearchName)|| (u.LastName+ u.FirstName).Contains(queryParam.SearchName))
|
||||
join hospitalItem in _hospitalRepository.AsQueryable() on doctor.HospitalId equals hospitalItem.Id into gt
|
||||
from hospital in gt.DefaultIfEmpty()
|
||||
join trialPayInfo in _doctorPayInfoRepository.Where()
|
||||
on doctor.Id equals trialPayInfo.DoctorId into payInfo
|
||||
from doctorPayInfo in payInfo.DefaultIfEmpty()
|
||||
join rankPrice in _rankPriceRepository.Where()
|
||||
on doctorPayInfo.RankId equals rankPrice.Id into rankPriceInfo
|
||||
from rankPrice in rankPriceInfo.DefaultIfEmpty()
|
||||
select new DoctorPayInfoQueryListDTO
|
||||
{
|
||||
//Id = doctorPayInfo.Id,
|
||||
DoctorId = doctor.Id,
|
||||
Code = doctor.ReviewerCode,
|
||||
LastName = doctor.LastName,
|
||||
FirstName = doctor.FirstName,
|
||||
ChineseName = doctor.ChineseName,
|
||||
Phone = doctor.Phone,
|
||||
DoctorNameInBank = doctorPayInfo.DoctorNameInBank,
|
||||
IDCard = doctorPayInfo.IDCard,
|
||||
BankCardNumber = doctorPayInfo.BankCardNumber,
|
||||
BankName = doctorPayInfo.BankName,
|
||||
RankId = doctorPayInfo.RankId,
|
||||
RankName = rankPrice.RankName,
|
||||
Additional = doctorPayInfo.Additional,
|
||||
Hospital = hospital.HospitalName,
|
||||
CreateTime = doctor.CreateTime
|
||||
};
|
||||
|
||||
return await doctorQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, "Code", queryParam.Asc);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据医生Id获取支付信息
|
||||
/// </summary>
|
||||
/// <param name="doctorId">医生Id</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{doctorId:guid}")]
|
||||
public async Task<DoctorPayInfoQueryListDTO> GetReviewerPayInfo(Guid doctorId)
|
||||
{
|
||||
var doctorQueryable = from doctor in _doctorRepository.Where(u => u.Id == doctorId)
|
||||
join trialPayInfo in _doctorPayInfoRepository.Where()
|
||||
on doctor.Id equals trialPayInfo.DoctorId into payInfo
|
||||
from doctorPayInfo in payInfo.DefaultIfEmpty()
|
||||
join rankPrice in _rankPriceRepository.Where()
|
||||
on doctorPayInfo.RankId equals rankPrice.Id into rankPriceInfo
|
||||
from rankPrice in rankPriceInfo.DefaultIfEmpty()
|
||||
select new DoctorPayInfoQueryListDTO
|
||||
{
|
||||
//Id = doctorPayInfo.Id,
|
||||
DoctorId = doctor.Id,
|
||||
Code = doctor.ReviewerCode,
|
||||
LastName = doctor.LastName,
|
||||
FirstName = doctor.FirstName,
|
||||
ChineseName = doctor.ChineseName,
|
||||
Phone = doctor.Phone,
|
||||
DoctorNameInBank = doctorPayInfo.DoctorNameInBank,
|
||||
IDCard = doctorPayInfo.IDCard,
|
||||
BankCardNumber = doctorPayInfo.BankCardNumber,
|
||||
BankName = doctorPayInfo.BankName,
|
||||
RankId = doctorPayInfo.RankId,
|
||||
RankName = rankPrice.RankName,
|
||||
Additional = doctorPayInfo.Additional,
|
||||
CreateTime = doctor.CreateTime
|
||||
};
|
||||
|
||||
return (await doctorQueryable.FirstOrDefaultAsync()).IfNullThrowException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据rankId 获取ReviewerId,用于当Rank的单价信息改变时,触发费用计算
|
||||
/// </summary>
|
||||
/// <param name="rankId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<Guid>> GetReviewerIdByRankId(Guid rankId)
|
||||
{
|
||||
return await _doctorPayInfoRepository.Where(u => u.RankId == rankId).Select(u => u.DoctorId).ToListAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
using AutoMapper;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
[ApiExplorerSettings(GroupName = "Financial")]
|
||||
public class TrialPaymentPriceService : BaseService, ITrialPaymentPriceService
|
||||
{
|
||||
private readonly IRepository<TrialPaymentPrice> _trialExtRepository;
|
||||
private readonly IRepository<Enroll> _enrollRepository;
|
||||
private readonly IRepository<Doctor> _doctorRepository;
|
||||
private readonly IRepository<CRO> _croRepository;
|
||||
|
||||
|
||||
private readonly IRepository<Trial> _trialRepository;
|
||||
public TrialPaymentPriceService(IRepository<Trial> trialRepository, IRepository<TrialPaymentPrice> trialExtRepository,
|
||||
IRepository<Enroll> enrollRepository,
|
||||
IRepository<Doctor> doctorRepository,
|
||||
IRepository<CRO> croCompanyRepository, IMapper mapper)
|
||||
{
|
||||
_trialExtRepository = trialExtRepository;
|
||||
_croRepository = croCompanyRepository;
|
||||
_enrollRepository = enrollRepository;
|
||||
_doctorRepository = doctorRepository;
|
||||
|
||||
_trialRepository = trialRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加或更新项目支付价格信息
|
||||
/// </summary>
|
||||
[NonDynamicMethod]
|
||||
public async Task<IResponseOutput> AddOrUpdateTrialPaymentPrice(TrialPaymentPriceCommand addOrUpdateModel)
|
||||
{
|
||||
|
||||
var trialExistedItem = await _trialExtRepository.FirstOrDefaultAsync(u => u.TrialId == addOrUpdateModel.TrialId);
|
||||
if (trialExistedItem == null)//insert
|
||||
{
|
||||
var trialExt = _mapper.Map<TrialPaymentPrice>(addOrUpdateModel);
|
||||
|
||||
await _trialExtRepository.AddAsync(trialExt);
|
||||
|
||||
}
|
||||
else//update
|
||||
{
|
||||
await _trialExtRepository.UpdateAsync(_mapper.Map(addOrUpdateModel, trialExistedItem));
|
||||
|
||||
}
|
||||
var success = await _trialExtRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> UploadTrialSOW(TrialSOWPathDTO trialSowPath)
|
||||
{
|
||||
var trialPaymentPrice = await _trialExtRepository.FirstOrDefaultAsync(u => u.TrialId == trialSowPath.TrialId);
|
||||
|
||||
if (trialPaymentPrice == null)//添加
|
||||
{
|
||||
await _trialExtRepository.AddAsync(_mapper.Map<TrialPaymentPrice>(trialSowPath));
|
||||
}
|
||||
else//更新
|
||||
{
|
||||
await _trialExtRepository.UpdateAsync(_mapper.Map(trialSowPath, trialPaymentPrice));
|
||||
}
|
||||
|
||||
var success = await _trialExtRepository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> DeleteTrialSOW(DeleteSowPathDTO trialSowPath)
|
||||
{
|
||||
var success = await _trialExtRepository.UpdateFromQueryAsync(u => u.TrialId == trialSowPath.TrialId, s => new TrialPaymentPrice
|
||||
{
|
||||
SowPath = "",
|
||||
SowName = "",
|
||||
UpdateTime = DateTime.Now,
|
||||
UpdateUserId = _userInfo.Id
|
||||
});
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目支付价格信息列表
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<TrialPaymentPriceDTO>> GetTrialPaymentPriceList(TrialPaymentPriceQueryDTO queryParam)
|
||||
{
|
||||
#region hwt
|
||||
//var trialQueryable = from trial in _trialRepository.AsQueryable()
|
||||
// .WhereIf(queryParam.CroId != null, o => o.CROId == queryParam.CroId)
|
||||
// .WhereIf(!string.IsNullOrEmpty(queryParam.KeyWord), o => o.TrialCode.Contains(queryParam.KeyWord) || o.Indication.Contains(queryParam.KeyWord))
|
||||
// join cro in _croRepository.AsQueryable() on trial.CROId equals cro.Id into CRO
|
||||
// from croInfo in CRO.DefaultIfEmpty()
|
||||
// join trialExt in _trialExtRepository.Where()
|
||||
// on trial.Id equals trialExt.TrialId into trialInfo
|
||||
// from trialExt in trialInfo.DefaultIfEmpty()
|
||||
// select new TrialPaymentPriceDTO
|
||||
// {
|
||||
// //Id = trialExt.Id ,
|
||||
// IsNewTrial = trialExt.IsNewTrial,
|
||||
// TrialId = trial.Id,
|
||||
// TrialCode = trial.TrialCode,
|
||||
// Cro = croInfo.CROName,
|
||||
// Indication = trial.Indication,
|
||||
// Expedited = trial.Expedited,
|
||||
// TrialAdditional = trialExt.TrialAdditional,
|
||||
// AdjustmentMultiple = trialExt.AdjustmentMultiple,
|
||||
// SowName = trialExt.SowName,
|
||||
// SowPath = trialExt.SowPath,
|
||||
// CreateTime = trial.CreateTime,
|
||||
// };
|
||||
|
||||
//var namelist = (from enroll in _enrollRepository.AsQueryable()
|
||||
// join doctor in _doctorRepository.Where() on enroll.DoctorId equals doctor.Id
|
||||
// select new DtoDoctorList()
|
||||
// {
|
||||
// TrialId = enroll.TrialId,
|
||||
// Name = doctor.ChineseName
|
||||
// }).ToList().GroupBy(x => new { x.TrialId },
|
||||
//(key, lst) => new DtoDoctorList
|
||||
//{
|
||||
// TrialId = key.TrialId,
|
||||
// Name = string.Join(',', lst.Select(x => x.Name))
|
||||
//});
|
||||
|
||||
//var returndata = trialQueryable.ToPagedList(queryParam.PageIndex, queryParam.PageSize, "CreateTime", queryParam.Asc);
|
||||
|
||||
//returndata.CurrentPageData.ForEach(x => {
|
||||
// x.DoctorsNames = namelist.Where(y => y.TrialId == x.TrialId).Select(y => y.Name).FirstOrDefault() ?? string.Empty;
|
||||
//});
|
||||
//return returndata;
|
||||
|
||||
#endregion
|
||||
|
||||
#region byzhouhang 方式一
|
||||
|
||||
//var trialQueryable = _trialExtRepository.Where(t => t.Trial.IsDeleted == false)
|
||||
// .WhereIf(queryParam.CroId != null, o => o.Trial.CROId == queryParam.CroId)
|
||||
// .WhereIf(!string.IsNullOrEmpty(queryParam.KeyWord), o => o.Trial.TrialCode.Contains(queryParam.KeyWord) || o.Trial.Indication.Contains(queryParam.KeyWord))
|
||||
// .Select(trialExt => new TrialPaymentPriceDTO()
|
||||
// {
|
||||
// TrialCode = trialExt.Trial.TrialCode,
|
||||
// Cro = trialExt.Trial.CRO.CROName,
|
||||
// Indication = trialExt.Trial.Indication,
|
||||
// Expedited = trialExt.Trial.Expedited,
|
||||
|
||||
// TrialId = trialExt.TrialId,
|
||||
// IsNewTrial = trialExt.IsNewTrial,
|
||||
// SowName = trialExt.SowName,
|
||||
// SowPath = trialExt.SowPath,
|
||||
// TrialAdditional = trialExt.TrialAdditional,
|
||||
// AdjustmentMultiple = trialExt.AdjustmentMultiple,
|
||||
// CreateTime = trialExt.CreateTime,
|
||||
// DoctorsNames = string.Join(',', trialExt.Trial.EnrollList.Select(t => t.Doctor.ChineseName))
|
||||
// });
|
||||
|
||||
//return trialQueryable.ToPagedList(queryParam.PageIndex, queryParam.PageSize, string.IsNullOrEmpty(queryParam.SortField) ? "CreateTime" : queryParam.SortField, queryParam.Asc);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region byzhouhang 方式二
|
||||
|
||||
var trialQueryable2 = _trialExtRepository.Where(t => t.Trial.IsDeleted == false)
|
||||
.WhereIf(queryParam.CroId != null, o => o.Trial.CROId == queryParam.CroId)
|
||||
.WhereIf(!string.IsNullOrEmpty(queryParam.KeyWord), o => o.Trial.TrialCode.Contains(queryParam.KeyWord) || o.Trial.Indication.Contains(queryParam.KeyWord))
|
||||
.ProjectTo<TrialPaymentPriceDTO>(_mapper.ConfigurationProvider);
|
||||
|
||||
return await trialQueryable2.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, string.IsNullOrEmpty(queryParam.SortField) ? "CreateTime" : queryParam.SortField, queryParam.Asc);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
using AutoMapper;
|
||||
using IRaCIS.Core.Infrastructure.ExpressionExtend;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using System.Linq.Expressions;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
[ ApiExplorerSettings(GroupName = "Financial")]
|
||||
public class TrialRevenuesPriceService : BaseService, ITrialRevenuesPriceService
|
||||
{
|
||||
private readonly IRepository<Trial> _trialRepository;
|
||||
private readonly IRepository<TrialRevenuesPrice> _trialRevenuesPriceRepository;
|
||||
private readonly IRepository<CRO> _croRepository;
|
||||
private readonly IRepository<Dictionary> _dictionaryRepository;
|
||||
private readonly IRepository<TrialRevenuesPriceVerification> _trialRevenuesPriceVerificationRepository;
|
||||
|
||||
|
||||
public TrialRevenuesPriceService(IRepository<Trial> trialRepository, IRepository<TrialRevenuesPrice> trialCostRepository, IRepository<CRO> croCompanyRepository, IRepository<Dictionary> dictionaryRepository, IRepository<TrialRevenuesPriceVerification> trialRevenuesPriceVerificationRepository, IMapper mapper)
|
||||
{
|
||||
_trialRepository = trialRepository;
|
||||
_trialRevenuesPriceRepository = trialCostRepository;
|
||||
_croRepository = croCompanyRepository;
|
||||
_dictionaryRepository = dictionaryRepository;
|
||||
_trialRevenuesPriceVerificationRepository = trialRevenuesPriceVerificationRepository;
|
||||
|
||||
}
|
||||
|
||||
public async Task<IResponseOutput> AddOrUpdateTrialRevenuesPrice(TrialRevenuesPriceDTO model)
|
||||
{
|
||||
var count = model.Timepoint +
|
||||
model.TimepointIn24H +
|
||||
model.TimepointIn48H +
|
||||
model.Adjudication +
|
||||
model.AdjudicationIn24H +
|
||||
model.AdjudicationIn48H +
|
||||
model.Downtime +
|
||||
model.Global +
|
||||
model.Training;
|
||||
|
||||
if (count <= 0)
|
||||
{
|
||||
return ResponseOutput.NotOk("Please add meaningful data");
|
||||
}
|
||||
var trialExistedItem = await _trialRevenuesPriceRepository.FirstOrDefaultAsync(u => u.TrialId == model.TrialId);
|
||||
if (trialExistedItem == null)//insert
|
||||
{
|
||||
var trialCost = _mapper.Map<TrialRevenuesPrice>(model);
|
||||
await _trialRevenuesPriceRepository.AddAsync(trialCost);
|
||||
var success = await _trialRevenuesPriceRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(success, trialCost.Id.ToString());
|
||||
}
|
||||
else//update
|
||||
{
|
||||
var trialRevenuesPrice = (await _trialRevenuesPriceRepository.AsQueryable().FirstOrDefaultAsync(u => u.TrialId == model.TrialId)).IfNullThrowException();
|
||||
|
||||
await _trialRevenuesPriceRepository.UpdateAsync(_mapper.Map(model, trialRevenuesPrice));
|
||||
|
||||
// 完善价格的 将对应的列设置为true 变更为有价格了
|
||||
|
||||
var aaa = await _trialRevenuesPriceVerificationRepository.UpdateFromQueryAsync(t => t.TrialId == model.TrialId, u => new TrialRevenuesPriceVerification()
|
||||
{
|
||||
//有价格 则设置为true 否则 该列不变
|
||||
Timepoint = model.Timepoint > 0 || u.Timepoint,
|
||||
TimepointIn24H = model.TimepointIn24H > 0 || u.TimepointIn24H,
|
||||
TimepointIn48H = model.TimepointIn48H > 0 || u.TimepointIn48H,
|
||||
Adjudication = model.Adjudication > 0 || u.Adjudication,
|
||||
AdjudicationIn24H =
|
||||
model.AdjudicationIn24H > 0 || u.AdjudicationIn24H,
|
||||
AdjudicationIn48H =
|
||||
model.AdjudicationIn48H > 0 || u.AdjudicationIn48H,
|
||||
Global = model.Global > 0 || u.Global,
|
||||
Downtime = model.Downtime > 0 || u.Downtime,
|
||||
Training = model.Training > 0 || u.Training,
|
||||
RefresherTraining = model.RefresherTraining > 0 || u.RefresherTraining,
|
||||
});
|
||||
|
||||
//删除所有有价格的记录 为true 表示有价格或者不需要价格 缺价格的为false
|
||||
await _trialRevenuesPriceVerificationRepository.DeleteFromQueryAsync(t => t.TrialId == model.TrialId &&
|
||||
t.Timepoint&&
|
||||
t.TimepointIn24H&&
|
||||
t.TimepointIn48H &&
|
||||
t.Adjudication &&
|
||||
t.AdjudicationIn24H &&
|
||||
t.AdjudicationIn48H &&
|
||||
t.Global &&
|
||||
t.Training &&t.RefresherTraining);
|
||||
|
||||
|
||||
|
||||
var success = await _trialRevenuesPriceRepository.SaveChangesAsync();
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
}
|
||||
|
||||
[NonDynamicMethod]
|
||||
public async Task<bool> DeleteTrialCost(Guid id)
|
||||
{
|
||||
return await _trialRevenuesPriceRepository.DeleteFromQueryAsync(u => u.Id == id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目收入费用信息列表[New]
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<TrialRevenuesPriceDetialDTO>> GetTrialRevenuesPriceList(TrialRevenuesPriceQueryDTO queryParam)
|
||||
{
|
||||
|
||||
var trialQueryable = from trial in _trialRepository.AsQueryable()
|
||||
.Where(u => u.TrialCode.Contains(queryParam.KeyWord)|| u.Indication.Contains(queryParam.KeyWord))
|
||||
.WhereIf(queryParam.CroId != null, o => o.CROId == queryParam.CroId)
|
||||
join cro in _croRepository.AsQueryable() on trial.CROId equals cro.Id into CRO
|
||||
from croInfo in CRO.DefaultIfEmpty()
|
||||
join dic in _dictionaryRepository.AsQueryable() on trial.ReviewModeId equals dic.Id into dict
|
||||
from dic in dict.DefaultIfEmpty()
|
||||
join trialCost in _trialRevenuesPriceRepository.AsQueryable()
|
||||
on trial.Id equals trialCost.TrialId into trialInfo
|
||||
from trialCostItem in trialInfo.DefaultIfEmpty()
|
||||
select new TrialRevenuesPriceDetialDTO
|
||||
{
|
||||
Id = trialCostItem == null ? Guid.Empty : trialCostItem.Id,
|
||||
TrialId = trial.Id,
|
||||
TrialCode = trial.TrialCode,
|
||||
Indication = trial.Indication,
|
||||
Cro = croInfo == null ? string.Empty : croInfo.CROName,
|
||||
ReviewMode = dic == null ? string.Empty : dic.Value,
|
||||
Timepoint = trialCostItem == null ? 0 : trialCostItem.Timepoint,
|
||||
TimepointIn24H = trialCostItem == null ? 0 : trialCostItem.TimepointIn24H,
|
||||
TimepointIn48H = trialCostItem == null ? 0 : trialCostItem.TimepointIn48H,
|
||||
Adjudication = trialCostItem == null ? 0 : trialCostItem.Adjudication,
|
||||
AdjudicationIn24H = trialCostItem == null ? 0 : trialCostItem.AdjudicationIn24H,
|
||||
AdjudicationIn48H = trialCostItem == null ? 0 : trialCostItem.AdjudicationIn48H,
|
||||
Downtime = trialCostItem == null ? 0 : trialCostItem.Downtime,
|
||||
Global = trialCostItem == null ? 0 : trialCostItem.Global,
|
||||
Training = trialCostItem == null ? 0 : trialCostItem.Training,
|
||||
RefresherTraining= trialCostItem == null ? 0 : trialCostItem.RefresherTraining,
|
||||
Expedited = trial.Expedited
|
||||
|
||||
};
|
||||
|
||||
return await trialQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, "TrialCode", queryParam.Asc);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
|
||||
namespace IRaCIS.Core.Application.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Financial---项目收入价格验证
|
||||
/// </summary>
|
||||
[ ApiExplorerSettings(GroupName = "Financial")]
|
||||
public class TrialRevenuesPriceVerificationService : BaseService, ITrialRevenuesPriceVerificationService
|
||||
{
|
||||
private readonly IRepository<TrialRevenuesPriceVerification> _trialRevenuesPriceVerificationRepository;
|
||||
private readonly IRepository<Trial> _trialRepository;
|
||||
private readonly IRepository<Doctor> _doctorRepository;
|
||||
private readonly IRepository<Payment> _paymentRepository;
|
||||
|
||||
public TrialRevenuesPriceVerificationService(IRepository<TrialRevenuesPriceVerification> trialRevenuesPriceVerificationRepository,
|
||||
IRepository<Trial> trialRepository,IRepository<Doctor> doctorRepository,IRepository<Payment> paymentRepository)
|
||||
{
|
||||
_trialRevenuesPriceVerificationRepository = trialRevenuesPriceVerificationRepository;
|
||||
_trialRepository = trialRepository;
|
||||
_doctorRepository = doctorRepository;
|
||||
_paymentRepository = paymentRepository;
|
||||
}
|
||||
[HttpPost]
|
||||
public async Task<AnalysisVerifyResultDTO> GetAnalysisVerifyList(RevenusVerifyQueryDTO param)
|
||||
{
|
||||
AnalysisVerifyResultDTO result=new AnalysisVerifyResultDTO();
|
||||
result.RevenuesVerifyList = await GetRevenuesVerifyList(param);
|
||||
|
||||
|
||||
var bDate = new DateTime(param.BeginDate.Year, param.BeginDate.Month, 1);
|
||||
var eDate = new DateTime(param.EndDate.Year, param.EndDate.Month, 1);
|
||||
eDate = eDate.AddMonths(1).AddSeconds(-1);
|
||||
|
||||
Expression<Func<Payment, bool>> paymentLambda = x => x.YearMonthDate >= bDate && x.YearMonthDate <= eDate&&!x.IsLock;
|
||||
|
||||
var query = from payment in _paymentRepository.Where(paymentLambda)
|
||||
join doctor in _doctorRepository.AsQueryable() on payment.DoctorId equals doctor.Id
|
||||
select new AnalysisNeedLockDTO()
|
||||
{
|
||||
YearMonth = payment.YearMonth,
|
||||
ReviewerCode = doctor.ReviewerCode,
|
||||
ReviewerName = doctor.LastName + " / " + doctor.FirstName,
|
||||
ReviewerNameCN = doctor.ChineseName
|
||||
};
|
||||
|
||||
result.MonthVerifyResult = (await query.ToListAsync()).GroupBy(t => t.YearMonth).Select(g => new MonthlyResult
|
||||
{
|
||||
YearMonth = g.Key,
|
||||
ReviewerNameList = g.Select(t => t.ReviewerName).ToList(),
|
||||
ReviewerNameCNList = g.Select(t => t.ReviewerNameCN).ToList(),
|
||||
ReviewerCodeList = g.Select(t => t.ReviewerCode).ToList()
|
||||
|
||||
}).OrderBy(t=>t.YearMonth).ToList();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public async Task<List<RevenusVerifyDTO>> GetRevenuesVerifyList(RevenusVerifyQueryDTO param)
|
||||
{
|
||||
var bDate = new DateTime(param.BeginDate.Year, param.BeginDate.Month, 1);
|
||||
var eDate = new DateTime(param.EndDate.Year, param.EndDate.Month, 1);
|
||||
Expression<Func<TrialRevenuesPriceVerification, bool>> trialRevenuesPriceVerificationLambda = x => x.WorkLoadDate >= bDate && x.WorkLoadDate <= eDate;
|
||||
|
||||
var query = (from trialVerify in _trialRevenuesPriceVerificationRepository.Where(trialRevenuesPriceVerificationLambda)
|
||||
join trail in _trialRepository.AsQueryable() on trialVerify.TrialId equals trail.Id
|
||||
select new RevenusVerifyDTO
|
||||
{
|
||||
TrialCode = trail.TrialCode,
|
||||
Timepoint = trialVerify.Timepoint,
|
||||
TimepointIn24H = trialVerify.TimepointIn24H,
|
||||
TimepointIn48H = trialVerify.TimepointIn48H,
|
||||
Adjudication = trialVerify.Adjudication,
|
||||
AdjudicationIn24H = trialVerify.AdjudicationIn24H,
|
||||
AdjudicationIn48H = trialVerify.AdjudicationIn48H,
|
||||
Global = trialVerify.Global,
|
||||
Downtime = trialVerify.Downtime,
|
||||
Training = trialVerify.Training
|
||||
}).Distinct();
|
||||
|
||||
|
||||
return await query.ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//废弃
|
||||
[Obsolete]
|
||||
public async Task<List<RevenusVerifyDTO>> GetRevenuesVerifyResultList(RevenusVerifyQueryDTO param)
|
||||
{
|
||||
var bDate = new DateTime(param.BeginDate.Year, param.BeginDate.Month, 1);
|
||||
var eDate = new DateTime(param.EndDate.Year, param.EndDate.Month, 1);
|
||||
Expression<Func<TrialRevenuesPriceVerification, bool>> trialRevenuesPriceVerificationLambda = x => x.WorkLoadDate >= bDate && x.WorkLoadDate <= eDate;
|
||||
|
||||
var query = (from trialVerify in _trialRevenuesPriceVerificationRepository.Where(trialRevenuesPriceVerificationLambda)
|
||||
join trail in _trialRepository.AsQueryable() on trialVerify.TrialId equals trail.Id
|
||||
select new RevenusVerifyDTO
|
||||
{
|
||||
TrialCode = trail.TrialCode,
|
||||
Timepoint = trialVerify.Timepoint,
|
||||
TimepointIn24H = trialVerify.TimepointIn24H,
|
||||
TimepointIn48H = trialVerify.TimepointIn48H,
|
||||
Adjudication = trialVerify.Adjudication,
|
||||
AdjudicationIn24H = trialVerify.AdjudicationIn24H,
|
||||
AdjudicationIn48H = trialVerify.AdjudicationIn48H,
|
||||
Global = trialVerify.Global,
|
||||
Downtime = trialVerify.Downtime,
|
||||
Training = trialVerify.Training
|
||||
}).Distinct();
|
||||
|
||||
|
||||
return await query.ToListAsync();
|
||||
#region 提示 old
|
||||
//query = from trialVerify in _trialRevenuesPriceVerificationRepository.GetAll()
|
||||
// join trail in _trialRepository.GetAll() on trialVerify.TrialId equals trail.Id
|
||||
// join reviewer in _doctorRepository.GetAll() on trialVerify.ReviewerId equals reviewer.Id
|
||||
// select new RevenusVerifyDTO()
|
||||
// {
|
||||
// ReviewerCode = reviewer.Code,
|
||||
// TrialCode = trail.Code,
|
||||
// YearMonth = trialVerify.YearMonth
|
||||
// };
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////0是Detail 1是按照项目 2是按照人 3按照月份
|
||||
//if (param.StatType == 0)
|
||||
//{
|
||||
// query = from trialVerify in _trialRevenuesPriceVerificationRepository.GetAll()
|
||||
// join trail in _trialRepository.GetAll() on trialVerify.TrialId equals trail.Id
|
||||
// join reviewer in _doctorRepository.GetAll() on trialVerify.ReviewerId equals reviewer.Id
|
||||
// select new RevenusVerifyDTO()
|
||||
// {
|
||||
// ReviewerCode = reviewer.Code,
|
||||
// TrialCode = trail.Code,
|
||||
// YearMonth = trialVerify.YearMonth
|
||||
// };
|
||||
|
||||
//}
|
||||
//else if (param.StatType == 1)
|
||||
//{
|
||||
// query = (from trialVerify in _trialRevenuesPriceVerificationRepository.GetAll()
|
||||
// join trail in _trialRepository.GetAll() on trialVerify.TrialId equals trail.Id
|
||||
// select new RevenusVerifyDTO()
|
||||
// {
|
||||
// ReviewerCode = "",
|
||||
// TrialCode = trail.Code,
|
||||
// YearMonth = ""
|
||||
// }).Distinct();
|
||||
//}
|
||||
//else if (param.StatType == 2)
|
||||
//{
|
||||
// query = (from trialVerify in _trialRevenuesPriceVerificationRepository.GetAll()
|
||||
// join trail in _trialRepository.GetAll() on trialVerify.TrialId equals trail.Id
|
||||
// join reviewer in _doctorRepository.GetAll() on trialVerify.ReviewerId equals reviewer.Id
|
||||
// select new RevenusVerifyDTO()
|
||||
// {
|
||||
// ReviewerCode = reviewer.Code,
|
||||
// TrialCode = trail.Code,
|
||||
// YearMonth = ""
|
||||
// }).Distinct();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// query = from trialVerify in _trialRevenuesPriceVerificationRepository.GetAll()
|
||||
// join trail in _trialRepository.GetAll() on trialVerify.TrialId equals trail.Id
|
||||
// join reviewer in _doctorRepository.GetAll() on trialVerify.ReviewerId equals reviewer.Id
|
||||
// select new RevenusVerifyDTO()
|
||||
// {
|
||||
// ReviewerCode = reviewer.Code,
|
||||
// TrialCode = trail.Code,
|
||||
// YearMonth = trialVerify.YearMonth
|
||||
// };
|
||||
//}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using AutoMapper;
|
||||
using AutoMapper.QueryableExtensions;
|
||||
using IRaCIS.Core.Infrastructure.ExpressionExtend;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
[ ApiExplorerSettings(GroupName = "Financial")]
|
||||
public class VolumeRewardService : BaseService, IVolumeRewardService
|
||||
{
|
||||
private readonly IRepository<VolumeReward> _volumeRewardRepository;
|
||||
|
||||
|
||||
public VolumeRewardService(IRepository<VolumeReward> volumeRewardRepository,IMapper mapper)
|
||||
{
|
||||
_volumeRewardRepository = volumeRewardRepository;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 批量添加或更新奖励费用单价
|
||||
/// </summary>
|
||||
[NonDynamicMethod]
|
||||
public async Task<IResponseOutput> AddOrUpdateVolumeRewardPriceList(IEnumerable<AwardPriceCommand> addOrUpdateModel)
|
||||
{
|
||||
await _volumeRewardRepository.DeleteFromQueryAsync(t => t.Id != Guid.Empty);
|
||||
var temp = _mapper.Map<List<VolumeReward>>(addOrUpdateModel);
|
||||
|
||||
await _volumeRewardRepository.AddRangeAsync(temp);
|
||||
var success = await _volumeRewardRepository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有奖励单价列表-用于计算时,一次性获取所有
|
||||
/// </summary>
|
||||
[NonDynamicMethod]
|
||||
public async Task<List<AwardPriceCalculateDTO>> GetVolumeRewardPriceList()
|
||||
{
|
||||
return await _volumeRewardRepository.ProjectTo<AwardPriceCalculateDTO>(_mapper.ConfigurationProvider).OrderBy(t => t.Min).ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页获取奖励单价列表
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<PageOutput<AwardPriceDTO>> GetVolumeRewardPriceList(AwardPriceQueryDTO queryParam)
|
||||
{
|
||||
var awardPriceQueryable = _volumeRewardRepository.ProjectTo<AwardPriceDTO>(_mapper.ConfigurationProvider);
|
||||
|
||||
return await awardPriceQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, "Min");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using AutoMapper;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Application.Contracts.Pay;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
public class FinancialConfig : Profile
|
||||
{
|
||||
public FinancialConfig()
|
||||
{
|
||||
CreateMap<PaymentAdjustmentCommand, PaymentAdjustment>()
|
||||
.ForMember(t => t.YearMonthDate, u => u.MapFrom(t => t.YearMonth))
|
||||
.ForMember(t => t.YearMonth, u => u.MapFrom(t => t.YearMonth.ToString("yyyy-MM")));
|
||||
|
||||
CreateMap<TrialPaymentPriceCommand, TrialPaymentPrice>();
|
||||
CreateMap<ReviewerPayInfoCommand, ReviewerPayInformation>();
|
||||
|
||||
CreateMap<RankPriceCommand, RankPrice>();
|
||||
|
||||
CreateMap<AwardPriceCommand, VolumeReward>();
|
||||
|
||||
CreateMap<PaymentCommand, Payment>();
|
||||
|
||||
CreateMap<PaymentDetailCommand, PaymentDetail>();
|
||||
CreateMap<ExchangeRateCommand, ExchangeRate>();
|
||||
|
||||
CreateMap<AwardPriceCommand, VolumeReward>();
|
||||
|
||||
CreateMap<TrialRevenuesPriceDTO, TrialRevenuesPrice>();
|
||||
|
||||
CreateMap<TrialSOWPathDTO, TrialPaymentPrice>();
|
||||
|
||||
|
||||
CreateMap<RankPrice, RankPriceDTO>();
|
||||
CreateMap<VolumeReward, AwardPriceDTO>();
|
||||
CreateMap<RankPrice, RankDic>();
|
||||
CreateMap<ExchangeRate, ExchangeRateCommand>();
|
||||
CreateMap<Payment, CalculateNeededDTO>();
|
||||
|
||||
CreateMap<VolumeReward, AwardPriceCalculateDTO>();
|
||||
CreateMap<PaymentDetail, PaymentDetailDTO>();
|
||||
|
||||
CreateMap<TrialPaymentPrice, TrialSOWPathDTO>();
|
||||
|
||||
|
||||
CreateMap<TrialPaymentPrice, TrialPaymentPriceDTO>()
|
||||
.ForMember(t => t.TrialCode, u => u.MapFrom(t => t.Trial.Code))
|
||||
.ForMember(t => t.ReviewMode, u => u.MapFrom(t => t.Trial.ReviewMode.Value))
|
||||
.ForMember(t => t.Cro, u => u.MapFrom(t => t.Trial.CRO.CROName))
|
||||
.ForMember(t => t.Indication, u => u.MapFrom(t => t.Trial.Indication))
|
||||
.ForMember(t => t.Expedited, u => u.MapFrom(t => t.Trial.Expedited))
|
||||
.ForMember(t => t.DoctorsNames, u => u.MapFrom(t => string.Join(',', t.Trial.EnrollList.Select(t => t.Doctor.ChineseName))))
|
||||
|
||||
|
||||
;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts.Dicom.DTO
|
||||
{
|
||||
public sealed class DicomArchiveResult
|
||||
{
|
||||
public int ReceivedFileCount { get; set; }
|
||||
public ICollection<string> ErrorFiles { get; set; }
|
||||
public ICollection<DicomStudyBasicDTO> ArchivedDicomStudies { get; set; }
|
||||
|
||||
public Guid ReuploadNewStudyId { get; set; } = Guid.Empty;
|
||||
|
||||
public DicomArchiveResult()
|
||||
{
|
||||
ReceivedFileCount = 0;
|
||||
ErrorFiles = new List<string>();
|
||||
ArchivedDicomStudies = new List<DicomStudyBasicDTO>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
public class DicomInstanceDTO
|
||||
{
|
||||
public Guid Id { get; set;}
|
||||
public Guid StudyId { get; set; }
|
||||
public Guid SeriesId { get; set; }
|
||||
public string StudyInstanceUid { get; set; } = string.Empty;
|
||||
public string SeriesInstanceUid { get; set; } = string.Empty;
|
||||
public string SopInstanceUid { get; set; } = string.Empty;
|
||||
public int InstanceNumber { get; set; }
|
||||
public DateTime InstanceTime { get; set; }
|
||||
public bool CPIStatus { get; set; }
|
||||
public int ImageRows { get; set; }
|
||||
public int ImageColumns { get; set; }
|
||||
public int SliceLocation { get; set; }
|
||||
|
||||
public Guid TrialId { get; set; }
|
||||
public Guid SiteId { get; set; }
|
||||
public Guid SubjectId { get; set; }
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
|
||||
//public Guid CreateUserId { get; set; }
|
||||
//public DateTime CreateTime { get; set; }
|
||||
//public Guid UpdateUserId { get; set; }
|
||||
//public DateTime UpdateTime { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class DicomTrialSiteSubjectInfo
|
||||
{
|
||||
public string TrialSiteCode { get; set; } = string.Empty;
|
||||
public string SiteCode { get; set; } = string.Empty;
|
||||
public string SiteName { get; set; } = string.Empty;
|
||||
public string SubjectCode { get; set; } = string.Empty;
|
||||
public int? SubjectAge { get; set; }
|
||||
public string SubjectSex { get; set; } = string.Empty;
|
||||
public string TrialCode { get; set; } = string.Empty;
|
||||
public string ResearchProgramNo { get; set; } = string.Empty;
|
||||
public string TrialIndication { get; set; } = string.Empty;
|
||||
|
||||
|
||||
|
||||
public decimal VisitNum { get; set; }
|
||||
public string SVUPDES { get; set; } = string.Empty;
|
||||
public string VisitName { get; set; } = string.Empty;
|
||||
public string Sponsor { get; set; } = string.Empty;
|
||||
public Guid TrialId { get; set; }
|
||||
public Guid SiteId { get; set; }
|
||||
public Guid SubjectId { get; set; }
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
|
||||
//public string SubjectName => LastName + " / " + FirstName;
|
||||
//public string FirstName { get; set; } = string.Empty;
|
||||
//public string LastName { get; set; } = string.Empty;
|
||||
//public bool IsDoubleReview { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
namespace IRaCIS.Core.Application.Contracts.Dicom.DTO
|
||||
{
|
||||
public class DicomSeriesDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid StudyId { get; set; }
|
||||
public string StudyInstanceUid { get; set; } = String.Empty;
|
||||
public string SeriesInstanceUid { get; set; } = String.Empty;
|
||||
public int SeriesNumber { get; set; }
|
||||
public DateTime SeriesTime { get; set; }
|
||||
public string Modality { get; set; } = String.Empty;
|
||||
public string Description { get; set; }=String.Empty;
|
||||
public int InstanceCount { get; set; }
|
||||
public string SliceThickness { get; set; } = String.Empty;
|
||||
|
||||
public Guid TrialId { get; set; }
|
||||
public Guid SiteId { get; set; }
|
||||
public Guid SubjectId { get; set; }
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
|
||||
public Guid CreateUserId { get; set; }
|
||||
public DateTime CreateTime { get; set; }
|
||||
public Guid UpdateUserId { get; set; }
|
||||
public DateTime UpdateTime { get; set; }
|
||||
|
||||
public List<Guid> InstanceList { get; set; } = new List<Guid>();
|
||||
}
|
||||
|
||||
public class DicomSeriesWithLabelDTO : DicomSeriesDTO
|
||||
{
|
||||
public bool HasLabel { get; set; } = false;
|
||||
public bool KeySeries { get; set; } = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
public class DicomStudyBasicDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid TrialId { get; set; }
|
||||
public Guid SiteId { get; set; }
|
||||
|
||||
public Guid SubjectId { get; set; }
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
|
||||
public string StudyCode { get; set; } = string.Empty;
|
||||
|
||||
public DateTime StudyTime { get; set; }
|
||||
}
|
||||
|
||||
public class DicomStudyDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid TrialId { get; set; }
|
||||
public Guid SiteId { get; set; }
|
||||
|
||||
public Guid SubjectId { get; set; }
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
|
||||
public string StudyCode { get; set; } = string.Empty;
|
||||
|
||||
public int Status { get; set; } = 1;
|
||||
|
||||
public string StudyInstanceUid { get; set; } = string.Empty;
|
||||
public DateTime StudyTime { get; set; }
|
||||
public string Modalities { get; set; } = string.Empty;
|
||||
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public int SeriesCount { get; set; } = 0;
|
||||
public int InstanceCount { get; set; } = 0;
|
||||
|
||||
public bool SoftDelete { get; set; } = false;
|
||||
|
||||
public string InstitutionName { get; set; } = string.Empty;
|
||||
public string PatientId { get; set; } = string.Empty;
|
||||
public string PatientName { get; set; } = string.Empty;
|
||||
public string PatientAge { get; set; } = string.Empty;
|
||||
public string PatientSex { get; set; } = string.Empty;
|
||||
|
||||
public Guid UpdateUserId { get; set; }
|
||||
public DateTime UpdateTime { get; set; }
|
||||
public Guid CreateUserId { get; set; }
|
||||
public DateTime CreateTime { get; set; }
|
||||
}
|
||||
|
||||
public class RelationVisitDTO
|
||||
{
|
||||
public string VisitName { get; set; } = string.Empty;
|
||||
public string TpCode { get; set; } = string.Empty;
|
||||
public Guid StudyId { get; set; }
|
||||
}
|
||||
|
||||
public class RelationStudyDTO
|
||||
{
|
||||
public string VisitName { get; set; } = string.Empty;
|
||||
public string StudyCode { get; set; } = string.Empty;
|
||||
public Guid StudyId { get; set; }
|
||||
public int SeriesCount { get; set; }
|
||||
public string Modalities { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public class UploadViewInitDto
|
||||
{
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
|
||||
public Guid SubjectId { get; set; }
|
||||
|
||||
public Guid TrialId { get; set; }
|
||||
public Guid SiteId { get; set; }
|
||||
//public string SubjectName { get; set; }
|
||||
|
||||
public string SubjectCode { get; set; } = string.Empty;
|
||||
|
||||
public string TrialSiteCode { get; set; } = string.Empty;
|
||||
|
||||
public decimal VisitNum { get; set; }
|
||||
|
||||
public string VisitName { get; set; } = string.Empty;
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts.Dicom.DTO
|
||||
{
|
||||
public class ImageLabelDTO
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.Empty;
|
||||
public string TpCode { get; set; } = string.Empty;
|
||||
public Guid StudyId { get; set; } = Guid.Empty;
|
||||
public Guid SeriesId { get; set; } = Guid.Empty;
|
||||
public Guid InstanceId { get; set; } = Guid.Empty;
|
||||
public string LabelValue { get; set; } = string.Empty;
|
||||
}
|
||||
public class ImageLabelInfo
|
||||
{
|
||||
public Guid StudyId { get; set; } = Guid.Empty;
|
||||
public Guid SeriesId { get; set; } = Guid.Empty;
|
||||
public Guid InstanceId { get; set; } = Guid.Empty;
|
||||
public string LabelValue { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class ImageLabelCommand
|
||||
{
|
||||
public string TpCode { get; set; } = string.Empty;
|
||||
public List<ImageLabelInfo> ImageLabelList { get; set; } = new List<ImageLabelInfo>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts.Dicom.DTO
|
||||
{
|
||||
public class ImageShareCommand
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
public Guid SiteId { get; set; }
|
||||
public Guid SubjectId { get; set; }
|
||||
public Guid? StudyId { get; set; }
|
||||
|
||||
public DateTime? ExpireTime { get; set; }
|
||||
|
||||
public string Password { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class ResourceInfo
|
||||
{
|
||||
public Guid StudyId { get; set; }
|
||||
|
||||
public string Token { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace IRaCIS.Core.Application.Contracts.Dicom.DTO
|
||||
{
|
||||
public class StudyDTFDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid StudyId { get; set; }
|
||||
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
|
||||
public string Path { get; set; } = string.Empty;
|
||||
public Guid CreateUserId { get; set; }
|
||||
|
||||
public string UserName { get; set; } = string.Empty;
|
||||
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
|
||||
public string LastName { get; set; } = string.Empty;
|
||||
public DateTime CreateTime { get; set; }
|
||||
}
|
||||
|
||||
public class StudyDTFAddOrUpdateCommand
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public Guid StudyId { get; set; }
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
public string Path { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
namespace IRaCIS.Core.Application.Contracts.Dicom.DTO
|
||||
{
|
||||
public class StudyReviewerDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid StudyId { get; set; }
|
||||
public Guid ReviewerId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class StudyDistributeInfo
|
||||
{
|
||||
public Guid StudyId { get; set; }
|
||||
public int Status { get; set; }
|
||||
//public int ReviewerCount { get; set; }
|
||||
}
|
||||
|
||||
public class StudyReviewerCommand
|
||||
{
|
||||
public List<StudyDistributeInfo> StudyList { get; set; } = new List<StudyDistributeInfo>();
|
||||
//public List<Guid> StudyIdList { get; set; }
|
||||
public Guid ReviewerId { get; set; }
|
||||
//public int WorkloadType { get; set; }
|
||||
public Guid TrialId { get; set; }
|
||||
//public bool IsDoubleReview { get; set; }
|
||||
}
|
||||
|
||||
public class StudyReviewerEditCommand
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
public Guid StudyId { get; set; }
|
||||
public bool IsDoubleReview { get; set; }
|
||||
|
||||
public Guid? ReviewerId1 { get; set; }
|
||||
public Guid? ReviewerId2 { get; set; }
|
||||
public Guid? ReviewerIdForAD { get; set; }
|
||||
}
|
||||
|
||||
public class ReviewerDistributionDTO
|
||||
{
|
||||
public Guid ReviewerId { get; set; }
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
public string LastName { get; set; } = string.Empty;
|
||||
public string ReviewerCode { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts.Dicom.DTO
|
||||
{
|
||||
public class StudyStatusDetailDTO
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid StudyId { get; set; }
|
||||
public int Status { get; set; }
|
||||
public string OptUserName { get; set; }=string.Empty;
|
||||
public DateTime OptTime { get; set; }
|
||||
public string Note { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class StudyStatusDetailCommand
|
||||
{
|
||||
public Guid StudyId { get; set; }
|
||||
|
||||
public int Status { get; set; }
|
||||
|
||||
public DateTime? DeadlineTime { get; set; }
|
||||
public string Note { get; set; } = string.Empty;
|
||||
|
||||
//QA不通过的时候传递参数
|
||||
public string QAComment { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
//--------------------------------------------------------------------
|
||||
// 此代码由T4模板自动生成 byzhouhang 20210918
|
||||
// 生成时间 2022-03-03 15:28:20
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
namespace IRaCIS.Core.Application.ViewModel
|
||||
{
|
||||
/// <summary> SystemAnonymizationView 列表视图模型 </summary>
|
||||
public class SystemAnonymizationView: SystemAnonymizationAddOrEdit
|
||||
{
|
||||
|
||||
public Guid CreateUserId { get; set; }
|
||||
public DateTime UpdateTime { get; set; }
|
||||
public Guid UpdateUserId { get; set; }
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
}
|
||||
|
||||
///<summary>SystemAnonymizationQuery 列表查询参数模型</summary>
|
||||
public class SystemAnonymizationQuery:PageInput
|
||||
{
|
||||
public string Group { get; set; } = string.Empty;
|
||||
|
||||
public bool? IsAdd { get; set; }
|
||||
|
||||
public string Element { get; set; } = string.Empty;
|
||||
|
||||
public string TagDescription { get; set; } = string.Empty;
|
||||
|
||||
public string ValueRepresentation { get; set; } = string.Empty;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
///<summary> SystemAnonymizationAddOrEdit 列表查询参数模型</summary>
|
||||
public class SystemAnonymizationAddOrEdit
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string Group { get; set; } = String.Empty;
|
||||
public string Element { get; set; } = String.Empty;
|
||||
public string TagDescription { get; set; } = String.Empty;
|
||||
public string TagDescriptionCN { get; set; } = String.Empty;
|
||||
public string ReplaceValue { get; set; } = String.Empty;
|
||||
|
||||
public string ValueRepresentation { get; set; } = String.Empty;
|
||||
|
||||
public bool IsAdd { get; set; }
|
||||
|
||||
public bool IsEnable { get; set; }
|
||||
|
||||
public bool IsFixed { get; set; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
|
||||
public class UnionStudyBaseModel
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid SiteId { get; set; }
|
||||
|
||||
public Guid SubjectId { get; set; }
|
||||
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
|
||||
|
||||
public string SubjectCode { get; set; }
|
||||
|
||||
public string VisitName { get; set; } = string.Empty;
|
||||
|
||||
public decimal VisitNum { get; set; }
|
||||
|
||||
public string TrialSiteCode { get; set; } = string.Empty;
|
||||
|
||||
public string TrialSiteAliasName { get; set; } = string.Empty;
|
||||
|
||||
public string Uploader { get; set; } = string.Empty;
|
||||
|
||||
public DateTime UploadTime { get; set; }
|
||||
|
||||
public string StudyCode => IsDicom ? DicomStudyCode : "NST" + NoneDicomCode.ToString("D5");
|
||||
|
||||
|
||||
[JsonIgnore]
|
||||
public string DicomStudyCode { get; set; } = string.Empty;
|
||||
[JsonIgnore]
|
||||
public int NoneDicomCode { get; set; }
|
||||
|
||||
public bool IsDicom { get; set; }
|
||||
}
|
||||
|
||||
public class UnionStudyMonitorModel : UnionStudyBaseModel
|
||||
{
|
||||
public Guid StudyId { get; set; }
|
||||
|
||||
|
||||
public DateTime UploadStartTime { get; set; }
|
||||
|
||||
|
||||
public DateTime UploadFinishedTime { get; set; }
|
||||
|
||||
|
||||
public decimal FileSize { get; set; }
|
||||
|
||||
public string IP { get; set; }
|
||||
|
||||
|
||||
public bool IsDicomReUpload { get; set; }
|
||||
|
||||
public bool IsDicom { get; set; }
|
||||
|
||||
public int FileCount { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class UnionStudyViewModel:UnionStudyBaseModel
|
||||
{
|
||||
|
||||
public Guid Id { get; set; }
|
||||
|
||||
|
||||
|
||||
public int? Count { get; set; }
|
||||
|
||||
|
||||
public string Modalities { get; set; } = string.Empty;
|
||||
|
||||
public string Bodypart { get; set; } = string.Empty;
|
||||
|
||||
public DateTime? StudyTime { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class StudyQuery:PageInput
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
public Guid? SiteId { get; set; }
|
||||
public Guid? SubjectVisitId { get; set; }
|
||||
|
||||
public string SubjectInfo { get; set; } = String.Empty;
|
||||
|
||||
public string VisitPlanInfo { get; set; } = String.Empty;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,447 @@
|
||||
using Dicom;
|
||||
using Dicom.Imaging.Codec;
|
||||
using EasyCaching.Core;
|
||||
using IRaCIS.Core.Application.Contracts.Dicom;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System.Text;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
|
||||
namespace IRaCIS.Core.Application.Services
|
||||
{
|
||||
public class DicomArchiveService : IDicomArchiveService
|
||||
{
|
||||
private readonly IRepository<DicomStudy> _studyRepository;
|
||||
private readonly IRepository<DicomSeries> _seriesRepository;
|
||||
private readonly IRepository<DicomInstance> _instanceRepository;
|
||||
|
||||
private readonly IEasyCachingProvider _provider;
|
||||
private readonly DicomFileStoreHelper _dicomFileStoreHelper;
|
||||
|
||||
|
||||
private static object lockCodeGenerate = new object();
|
||||
|
||||
public DicomArchiveService(IRepository<DicomStudy> studyRepository,
|
||||
IRepository<DicomSeries> seriesRepository,
|
||||
IRepository<DicomInstance> instanceRepository,
|
||||
IHostEnvironment hostEnvironment,
|
||||
DicomFileStoreHelper dicomFileStoreHelper,
|
||||
IEasyCachingProvider provider)
|
||||
{
|
||||
_dicomFileStoreHelper = dicomFileStoreHelper;
|
||||
|
||||
_studyRepository = studyRepository;
|
||||
|
||||
_seriesRepository = seriesRepository;
|
||||
|
||||
_instanceRepository = instanceRepository;
|
||||
|
||||
_provider = provider;
|
||||
|
||||
}
|
||||
|
||||
public async Task<bool> DicomDBDataSaveChange()
|
||||
{
|
||||
var success = await _studyRepository.SaveChangesAsync();
|
||||
return success;
|
||||
}
|
||||
|
||||
public async Task<Guid> ArchiveDicomStreamAsync(Stream dicomStream,
|
||||
DicomTrialSiteSubjectInfo addtionalInfo, List<string> seriesInstanceUidList, List<string> instanceUidList)
|
||||
{
|
||||
|
||||
|
||||
DicomFile dicomFile = await DicomFile.OpenAsync(dicomStream, Encoding.Default);
|
||||
|
||||
DicomDataset dataset = dicomFile.Dataset;
|
||||
|
||||
//如果数据库存在该instance 记录 那么就不处理
|
||||
string sopInstanceUid = dataset.GetString(DicomTag.SOPInstanceUID);
|
||||
string studyInstanceUid = dataset.GetString(DicomTag.StudyInstanceUID);
|
||||
|
||||
if (instanceUidList.Any(t => t == sopInstanceUid))
|
||||
{
|
||||
return IdentifierHelper.CreateGuid(studyInstanceUid, addtionalInfo.TrialId.ToString());
|
||||
}
|
||||
|
||||
|
||||
var anonymize_AddFixedFiledList = _provider.Get<List<SystemAnonymization>>(StaticData.Anonymize_AddFixedFiled).Value;
|
||||
var anonymize_AddIRCInfoFiled = _provider.Get<List<SystemAnonymization>>(StaticData.Anonymize_AddIRCInfoFiled).Value;
|
||||
var anonymize_FixedField = _provider.Get<List<SystemAnonymization>>(StaticData.Anonymize_FixedField).Value;
|
||||
var anonymize_IRCInfoField = _provider.Get<List<SystemAnonymization>>(StaticData.Anonymize_IRCInfoField).Value;
|
||||
|
||||
|
||||
|
||||
foreach (var item in anonymize_AddFixedFiledList.Union(anonymize_FixedField))
|
||||
{
|
||||
|
||||
var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16));
|
||||
|
||||
dataset.AddOrUpdate(dicomTag, item.ReplaceValue);
|
||||
}
|
||||
|
||||
foreach (var item in anonymize_AddIRCInfoFiled.Union(anonymize_IRCInfoField))
|
||||
{
|
||||
|
||||
var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16));
|
||||
|
||||
if (dicomTag == DicomTag.ClinicalTrialProtocolID)
|
||||
{
|
||||
dataset.AddOrUpdate(dicomTag, addtionalInfo.TrialCode);
|
||||
|
||||
}
|
||||
if (dicomTag == DicomTag.ClinicalTrialSiteID)
|
||||
{
|
||||
dataset.AddOrUpdate(dicomTag, addtionalInfo.TrialSiteCode);
|
||||
|
||||
}
|
||||
if (dicomTag == DicomTag.ClinicalTrialSubjectID)
|
||||
{
|
||||
dataset.AddOrUpdate(dicomTag, addtionalInfo.SubjectCode);
|
||||
|
||||
}
|
||||
if (dicomTag == DicomTag.ClinicalTrialTimePointID)
|
||||
{
|
||||
dataset.AddOrUpdate(dicomTag, addtionalInfo.VisitNum.ToString());
|
||||
|
||||
}
|
||||
if (dicomTag == DicomTag.PatientID)
|
||||
{
|
||||
dataset.AddOrUpdate(dicomTag, addtionalInfo.TrialCode+"_"+ addtionalInfo.SubjectCode);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#region 调整废弃
|
||||
////按照配置文件 匿名化
|
||||
//foreach (var anonymizeItem in SystemConfig.AnonymizeTagList)
|
||||
//{
|
||||
// if (anonymizeItem.Enable)
|
||||
// {
|
||||
// ushort group = Convert.ToUInt16(anonymizeItem.Group, 16);
|
||||
// ushort element = Convert.ToUInt16(anonymizeItem.Element, 16);
|
||||
// dataset.AddOrUpdate(new DicomTag(group, element), anonymizeItem.ReplaceValue);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
//if (AppSettings.AddClinicalInfo) //是否需要写入临床信息
|
||||
//{
|
||||
// //Dicom 文件中写入临床信息
|
||||
// dataset.AddOrUpdate(DicomTag.ClinicalTrialProtocolID, addtionalInfo.TrialCode); //Trial
|
||||
// dataset.AddOrUpdate(DicomTag.ClinicalTrialProtocolName, addtionalInfo.TrialIndication); //indication
|
||||
// dataset.AddOrUpdate(DicomTag.ClinicalTrialSponsorName, addtionalInfo.Sponsor);//sponsor
|
||||
// dataset.AddOrUpdate(DicomTag.ClinicalTrialSiteID, addtionalInfo.SiteCode); //SiteId
|
||||
// dataset.AddOrUpdate(DicomTag.ClinicalTrialSiteName, addtionalInfo.SiteName);//SiteName
|
||||
// dataset.AddOrUpdate(DicomTag.ClinicalTrialSubjectID, addtionalInfo.SubjectCode + " " + addtionalInfo.SubjectSex);//SubjectId
|
||||
// dataset.AddOrUpdate(DicomTag.ClinicalTrialTimePointID, addtionalInfo.VisitNum.ToString()); // TimePoint
|
||||
// dataset.AddOrUpdate(DicomTag.ClinicalTrialTimePointDescription, addtionalInfo.VisitName + " " + addtionalInfo.SVUPDES);
|
||||
//}
|
||||
|
||||
//DicomStudy dicomStudy = null;
|
||||
//DicomSeries dicomSeries = null;
|
||||
//DicomInstance dicomInstance = null;
|
||||
|
||||
//lock (lockTest)
|
||||
//{
|
||||
// dicomStudy = CreateDicomStudy(dataset, addtionalInfo, out bool isStudyNeedAdd);
|
||||
// dicomSeries = CreateDicomSeries(dataset, dicomStudy, out bool isSeriesNeedAdd);
|
||||
// dicomInstance = CreateDicomInstance(dataset, dicomStudy, dicomSeries);
|
||||
|
||||
// if (isStudyNeedAdd) _studyRepository.Add(dicomStudy);
|
||||
// if (isSeriesNeedAdd) _seriesRepository.Add(dicomSeries);
|
||||
// _instanceRepository.Add(dicomInstance);
|
||||
//}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DicomStudy dicomStudy = CreateDicomStudy(dataset, addtionalInfo, out bool isStudyNeedAdd);
|
||||
DicomSeries dicomSeries = CreateDicomSeries(dataset, dicomStudy, out bool isSeriesNeedAdd);
|
||||
DicomInstance dicomInstance = CreateDicomInstance(dataset, dicomStudy, dicomSeries);
|
||||
|
||||
if (isStudyNeedAdd) await _studyRepository.AddAsync(dicomStudy);
|
||||
if (isSeriesNeedAdd) await _seriesRepository.AddAsync(dicomSeries);
|
||||
await _instanceRepository.AddAsync(dicomInstance);
|
||||
|
||||
|
||||
|
||||
string filePath = _dicomFileStoreHelper.CreateInstanceFilePath(dicomStudy, dicomSeries.Id, dicomInstance.Id);
|
||||
|
||||
var samplesPerPixel = dataset.GetSingleValueOrDefault(DicomTag.SamplesPerPixel, string.Empty);
|
||||
var photometricInterpretation = dataset.GetSingleValueOrDefault(DicomTag.PhotometricInterpretation, string.Empty);
|
||||
if (samplesPerPixel == "1" && (photometricInterpretation.ToUpper() == "MONOCHROME2" || photometricInterpretation.ToUpper() == "MONOCHROME1"))//MONOCHROME2
|
||||
{
|
||||
if (dataset.InternalTransferSyntax.IsEncapsulated)
|
||||
{
|
||||
await dicomFile.SaveAsync(filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
await dicomFile.Clone(DicomTransferSyntax.JPEGLSLossless).SaveAsync(filePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dataset.InternalTransferSyntax.IsEncapsulated) await dicomFile.SaveAsync(filePath);
|
||||
else await dicomFile.Clone(DicomTransferSyntax.RLELossless).SaveAsync(filePath); //RLELossless
|
||||
}
|
||||
return dicomInstance.StudyId;
|
||||
}
|
||||
|
||||
|
||||
private DicomStudy CreateDicomStudy(DicomDataset dataset, DicomTrialSiteSubjectInfo addtionalInfo, out bool isStudyNeedAdd)
|
||||
{
|
||||
|
||||
string studyInstanceUid = dataset.GetString(DicomTag.StudyInstanceUID);
|
||||
Guid studyId = IdentifierHelper.CreateGuid(studyInstanceUid, addtionalInfo.TrialId.ToString());
|
||||
|
||||
|
||||
|
||||
// 每个线程都查询数据库最大的,和缓存中最大的,取最大值为基数生成Code
|
||||
//var id = Thread.CurrentThread.ManagedThreadId.ToString("00");
|
||||
|
||||
//虽然每个文件都会进来,但是只要查询过,就会跟踪,不会再次查询数据库 这里线程并发会有问题,得加锁,不然生成Code 出错
|
||||
DicomStudy dicomStudy = _studyRepository.ImageFind(studyId, typeof(DicomStudy));
|
||||
|
||||
if (dicomStudy != null)
|
||||
{
|
||||
isStudyNeedAdd = false;
|
||||
return dicomStudy;
|
||||
}
|
||||
|
||||
//_logger.LogWarning($"Thread {id} ,studyUid{studyInstanceUid}, 生成StudyId:{studyId}");
|
||||
|
||||
isStudyNeedAdd = true;
|
||||
|
||||
dicomStudy = new DicomStudy
|
||||
{
|
||||
Id = studyId,
|
||||
StudyInstanceUid = studyInstanceUid,
|
||||
StudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, DateTime.Now).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, DateTime.Now).TimeOfDay),//dataset.GetDateTime(DicomTag.StudyDate, DicomTag.StudyTime),
|
||||
Modalities = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty),
|
||||
Description = dataset.GetSingleValueOrDefault(DicomTag.StudyDescription, string.Empty),
|
||||
InstitutionName = dataset.GetSingleValueOrDefault(DicomTag.InstitutionName, string.Empty),
|
||||
PatientId = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty),
|
||||
PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty),
|
||||
PatientAge = dataset.GetSingleValueOrDefault(DicomTag.PatientAge, string.Empty),
|
||||
PatientSex = dataset.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty),
|
||||
BodyPartExamined = dataset.GetSingleValueOrDefault(DicomTag.BodyPartExamined, string.Empty),
|
||||
|
||||
StudyId = dataset.GetSingleValueOrDefault(DicomTag.StudyID, string.Empty),
|
||||
AccessionNumber = dataset.GetSingleValueOrDefault(DicomTag.AccessionNumber, string.Empty),
|
||||
|
||||
//需要特殊处理
|
||||
PatientBirthDate = dataset.GetSingleValueOrDefault(DicomTag.PatientBirthDate, string.Empty),
|
||||
|
||||
|
||||
AcquisitionTime = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionTime, string.Empty),
|
||||
AcquisitionNumber = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionNumber, string.Empty),
|
||||
TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty),
|
||||
|
||||
|
||||
SiteId = addtionalInfo.SiteId,
|
||||
TrialId = addtionalInfo.TrialId,
|
||||
SubjectId = addtionalInfo.SubjectId,
|
||||
SubjectVisitId = addtionalInfo.SubjectVisitId,
|
||||
//IsDoubleReview = addtionalInfo.IsDoubleReview,
|
||||
SeriesCount = 0,
|
||||
InstanceCount = 0
|
||||
};
|
||||
|
||||
if (dicomStudy.PatientBirthDate.Length == 8)
|
||||
{
|
||||
dicomStudy.PatientBirthDate = $"{dicomStudy.PatientBirthDate[0]}{dicomStudy.PatientBirthDate[1]}{dicomStudy.PatientBirthDate[2]}{dicomStudy.PatientBirthDate[3]}-{dicomStudy.PatientBirthDate[4]}{dicomStudy.PatientBirthDate[5]}-{dicomStudy.PatientBirthDate[6]}{dicomStudy.PatientBirthDate[7]}";
|
||||
}
|
||||
|
||||
lock (lockCodeGenerate)
|
||||
{
|
||||
|
||||
//查询数据库获取最大的Code 没有记录则为0
|
||||
var dbStudyCodeIntMax = _studyRepository.Where(s => s.TrialId == addtionalInfo.TrialId).Select(t => t.Code).DefaultIfEmpty().Max();
|
||||
|
||||
//获取缓存中的值 并发的时候,需要记录,已被占用的值 这样其他线程在此占用的最大的值上递增
|
||||
var cacheMaxCodeInt = _provider.Get<int>($"{addtionalInfo.TrialId }_{ StaticData.StudyMaxCode}").Value;
|
||||
|
||||
int currentNextCodeInt = cacheMaxCodeInt > dbStudyCodeIntMax ? cacheMaxCodeInt + 1 : dbStudyCodeIntMax + 1;
|
||||
|
||||
dicomStudy.Code = currentNextCodeInt;
|
||||
|
||||
dicomStudy.StudyCode = "ST" + currentNextCodeInt.ToString("D5");
|
||||
|
||||
_provider.Set<int>($"{addtionalInfo.TrialId }_{ StaticData.StudyMaxCode}", dicomStudy.Code, TimeSpan.FromMinutes(30));
|
||||
|
||||
}
|
||||
|
||||
#region Setting Code old
|
||||
|
||||
//var studyCode = _studyRepository.Where(s => s.TrialId == addtionalInfo.TrialId).Select(t => t.StudyCode).OrderByDescending(c => c).FirstOrDefault();
|
||||
|
||||
//var cacheMaxCode = _provider.Get<string>($"{addtionalInfo.TrialId }_{ StaticData.StudyMaxCode}").Value;
|
||||
|
||||
//if (studyCode == null && string.IsNullOrEmpty(cacheMaxCode))
|
||||
//{
|
||||
// dicomStudy.StudyCode = "ST" + 1.ToString().PadLeft(5, '0');
|
||||
|
||||
// _logger.LogWarning($"Thread {id} DB:{studyCode} 生成{ dicomStudy.StudyCode}");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// int dbNum = 0;
|
||||
|
||||
// int cacheNum = 0;
|
||||
|
||||
// if (studyCode != null)
|
||||
// {
|
||||
// int.TryParse(studyCode.Substring(studyCode.Length - 5, 5), out dbNum);
|
||||
// }
|
||||
|
||||
// if (!string.IsNullOrEmpty(cacheMaxCode))
|
||||
// {
|
||||
// int.TryParse(cacheMaxCode.Substring(cacheMaxCode.Length - 5, 5), out cacheNum);
|
||||
// }
|
||||
|
||||
// dbNum = cacheNum > dbNum ? cacheNum : dbNum;
|
||||
|
||||
|
||||
// dicomStudy.StudyCode = "ST" + (++dbNum).ToString().PadLeft(5, '0');
|
||||
|
||||
// _logger.LogWarning($" Thread {id} DB:{studyCode} cache:{cacheNum} 生成{ dicomStudy.StudyCode}");
|
||||
//}
|
||||
|
||||
//_provider.Set<string>($"{addtionalInfo.TrialId }_{ StaticData.StudyMaxCode}", dicomStudy.StudyCode, TimeSpan.FromMinutes(30));
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
return dicomStudy;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private DicomSeries CreateDicomSeries(DicomDataset dataset, DicomStudy dicomStudy, out bool isSeriesNeedAdd)
|
||||
{
|
||||
string seriesInstanceUid = dataset.GetString(DicomTag.SeriesInstanceUID);
|
||||
Guid seriesId = IdentifierHelper.CreateGuid(dicomStudy.StudyInstanceUid, seriesInstanceUid, dicomStudy.TrialId.ToString());
|
||||
|
||||
//有几个序列会查询几次
|
||||
|
||||
DicomSeries dicomSeries = _seriesRepository.ImageFind(seriesId, typeof(DicomSeries));
|
||||
|
||||
if (dicomSeries != null)
|
||||
{
|
||||
isSeriesNeedAdd = false;
|
||||
return dicomSeries;
|
||||
}
|
||||
else
|
||||
{
|
||||
//var id = Thread.CurrentThread.ManagedThreadId.ToString("00");
|
||||
|
||||
isSeriesNeedAdd = true;
|
||||
dicomSeries = new DicomSeries
|
||||
{
|
||||
Id = seriesId,
|
||||
StudyId = dicomStudy.Id,
|
||||
|
||||
StudyInstanceUid = dicomStudy.StudyInstanceUid,
|
||||
SeriesInstanceUid = seriesInstanceUid,
|
||||
SeriesNumber = dataset.GetSingleValueOrDefault(DicomTag.SeriesNumber, 1),
|
||||
SeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, DateTime.Now).Add(dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, DateTime.Now).TimeOfDay), // dataset.GetDateTime(DicomTag.SeriesDate, DicomTag.SeriesTime),
|
||||
Modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty),
|
||||
Description = dataset.GetSingleValueOrDefault(DicomTag.SeriesDescription, string.Empty),
|
||||
SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty),
|
||||
|
||||
ImagePositionPatient = dataset.GetSingleValueOrDefault(DicomTag.ImagePositionPatient, string.Empty),
|
||||
ImageOrientationPatient = dataset.GetSingleValueOrDefault(DicomTag.ImageOrientationPatient, string.Empty),
|
||||
BodyPartExamined = dataset.GetSingleValueOrDefault(DicomTag.BodyPartExamined, string.Empty),
|
||||
SequenceName = dataset.GetSingleValueOrDefault(DicomTag.SequenceName, string.Empty),
|
||||
ProtocolName = dataset.GetSingleValueOrDefault(DicomTag.ProtocolName, string.Empty),
|
||||
ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
|
||||
|
||||
AcquisitionTime = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
|
||||
AcquisitionNumber = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
|
||||
TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
|
||||
|
||||
SiteId = dicomStudy.SiteId,
|
||||
TrialId = dicomStudy.TrialId,
|
||||
SubjectId = dicomStudy.SubjectId,
|
||||
SubjectVisitId = dicomStudy.SubjectVisitId,
|
||||
|
||||
InstanceCount = 0
|
||||
};
|
||||
|
||||
++dicomStudy.SeriesCount;
|
||||
|
||||
|
||||
//_logger.LogWarning($"线程:{id},sericeId:{seriesId},count:{SeriesDic.Keys.Count}");
|
||||
|
||||
return dicomSeries;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private DicomInstance CreateDicomInstance(DicomDataset dataset, DicomStudy dicomStudy, DicomSeries dicomSeries)
|
||||
{
|
||||
string sopInstanceUid = dataset.GetString(DicomTag.SOPInstanceUID);
|
||||
Guid instanceId = IdentifierHelper.CreateGuid(dicomStudy.StudyInstanceUid, dicomSeries.SeriesInstanceUid, sopInstanceUid, dicomStudy.TrialId.ToString());
|
||||
|
||||
DicomInstance dicomInstance = new DicomInstance
|
||||
{
|
||||
Id = instanceId,
|
||||
StudyId = dicomStudy.Id,
|
||||
SeriesId = dicomSeries.Id,
|
||||
|
||||
SiteId = dicomStudy.SiteId,
|
||||
TrialId = dicomStudy.TrialId,
|
||||
SubjectId = dicomStudy.SubjectId,
|
||||
SubjectVisitId = dicomStudy.SubjectVisitId,
|
||||
|
||||
StudyInstanceUid = dicomStudy.StudyInstanceUid,
|
||||
SeriesInstanceUid = dicomSeries.SeriesInstanceUid,
|
||||
SopInstanceUid = sopInstanceUid,
|
||||
InstanceNumber = dataset.GetSingleValueOrDefault(DicomTag.InstanceNumber, 1),
|
||||
InstanceTime = dataset.GetSingleValueOrDefault(DicomTag.ContentDate, DateTime.Now).Add(dataset.GetSingleValueOrDefault(DicomTag.ContentTime, DateTime.Now).TimeOfDay),
|
||||
//dataset.GetSingleValueOrDefault(DicomTag.ContentDate,DateTime.Now);//, DicomTag.ContentTime)
|
||||
CPIStatus = false,
|
||||
ImageRows = dataset.GetSingleValueOrDefault(DicomTag.Rows, 0),
|
||||
ImageColumns = dataset.GetSingleValueOrDefault(DicomTag.Columns, 0),
|
||||
SliceLocation = dataset.GetSingleValueOrDefault(DicomTag.SliceLocation, 0),
|
||||
|
||||
SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty),
|
||||
NumberOfFrames = dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 0),
|
||||
PixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.PixelSpacing, string.Empty),
|
||||
ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
|
||||
FrameOfReferenceUID = dataset.GetSingleValueOrDefault(DicomTag.FrameOfReferenceUID, string.Empty),
|
||||
WindowCenter = dataset.GetSingleValueOrDefault(DicomTag.WindowCenter, string.Empty),
|
||||
WindowWidth = dataset.GetSingleValueOrDefault(DicomTag.WindowWidth, string.Empty),
|
||||
};
|
||||
|
||||
++dicomStudy.InstanceCount;
|
||||
++dicomSeries.InstanceCount;
|
||||
|
||||
return dicomInstance;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System;
|
||||
using System.IO;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Core.Application
|
||||
{
|
||||
public class DicomFileStoreHelper
|
||||
{
|
||||
private readonly IWebHostEnvironment _hostEnvironment;
|
||||
private static string _fileStorePath = string.Empty;
|
||||
|
||||
private readonly ILogger<DicomFileStoreHelper> _logger;
|
||||
|
||||
public DicomFileStoreHelper(IWebHostEnvironment hostEnvironment, ILogger<DicomFileStoreHelper> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_hostEnvironment = hostEnvironment;
|
||||
var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).IfNullThrowException().FullName;
|
||||
|
||||
//上传根路径
|
||||
_fileStorePath = Path.Combine(rootPath, StaticData.TrialDataFolder);
|
||||
|
||||
}
|
||||
|
||||
public string GetInstanceFilePath(DicomStudy dicomStudy, Guid seriesId, string instanceId)
|
||||
{
|
||||
return Path.Combine(_fileStorePath, dicomStudy.TrialId.ToString(),
|
||||
dicomStudy.SiteId.ToString(), dicomStudy.SubjectId.ToString(), dicomStudy.SubjectVisitId.ToString(), StaticData.DicomFolder, dicomStudy.Id.ToString(), instanceId.ToString() + ".dcm");
|
||||
}
|
||||
|
||||
|
||||
public string CreateInstanceFilePath(DicomStudy dicomStudy, Guid seriesId, Guid instanceId)
|
||||
{
|
||||
|
||||
//加入访视层级 和Data
|
||||
var path = Path.Combine(_fileStorePath, dicomStudy.TrialId.ToString(),
|
||||
dicomStudy.SiteId.ToString(), dicomStudy.SubjectId.ToString(), dicomStudy.SubjectVisitId.ToString(), StaticData.DicomFolder, dicomStudy.Id.ToString());
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
return Path.Combine(path, instanceId.ToString() + ".dcm");
|
||||
}
|
||||
|
||||
|
||||
public string GetSubjectVisitPath(Guid trialId,Guid siteId,Guid subjectId, Guid subjectVisitId)
|
||||
{
|
||||
return Path.Combine(_fileStorePath, trialId.ToString(),
|
||||
siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.DicomFolder);
|
||||
}
|
||||
|
||||
//public static string CreateInstanceFilePath(DicomStudy dicomStudy, Guid seriesId, Guid instanceId)
|
||||
//{
|
||||
// string path = Path.Combine(_fileStorePath, "Dicom", dicomStudy.CreateTime.Year.ToString(), dicomStudy.TrialId.ToString(),
|
||||
// dicomStudy.SiteId.ToString(), dicomStudy.SubjectId.ToString(), dicomStudy.Id.ToString());
|
||||
// if (!Directory.Exists(path)) Directory.CreateDirectory(path);
|
||||
|
||||
// return Path.Combine(path, instanceId.ToString() + ".dcm");
|
||||
//}
|
||||
|
||||
//public static string GetInstanceFilePath(DicomStudy dicomStudy, Guid seriesId, Guid instanceId)
|
||||
//{
|
||||
// return Path.Combine(_fileStorePath, "Dicom", dicomStudy.CreateTime.Year.ToString(), dicomStudy.TrialId.ToString(),
|
||||
// dicomStudy.SiteId.ToString(), dicomStudy.SubjectId.ToString(), dicomStudy.Id.ToString(), instanceId.ToString() + ".dcm");
|
||||
//}
|
||||
|
||||
|
||||
//public static void RemoveStudyDirectory(DicomStudy dicomStudy)
|
||||
//{
|
||||
// string path = Path.Combine(_fileStorePath, "Dicom", dicomStudy.CreateTime.Year.ToString(), dicomStudy.TrialId.ToString(),
|
||||
// dicomStudy.SiteId.ToString(), dicomStudy.SubjectId.ToString(), dicomStudy.Id.ToString());
|
||||
// if (Directory.Exists(path)) Directory.Delete(path, true);
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using FellowOakDicom.Imaging;
|
||||
using SixLabors.ImageSharp.Formats.Jpeg;
|
||||
|
||||
namespace IRaCIS.Core.Application.Dicom
|
||||
{
|
||||
public static class DicomRenderingHelper
|
||||
{
|
||||
public static Stream RenderPreviewJpeg(string filePath)
|
||||
{
|
||||
string jpegPath = filePath + ".preview.jpg";
|
||||
|
||||
if (!File.Exists(jpegPath))
|
||||
{
|
||||
using (Stream stream = new FileStream(jpegPath, FileMode.Create))
|
||||
{
|
||||
DicomImage image = new DicomImage(filePath);
|
||||
//image.ShowOverlays = false;
|
||||
//image.Scale = Math.Min(Math.Min(128.0 / image.Width, 128.0 / image.Height), 1.0);
|
||||
//image.RenderImage().AsClonedBitmap().Save(stream, ImageFormat.Jpeg);
|
||||
|
||||
var sharpimage = image.RenderImage().AsSharpImage();
|
||||
|
||||
sharpimage.Save(stream, new JpegEncoder());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return new FileStream(jpegPath, FileMode.Open);
|
||||
}
|
||||
|
||||
public static void RemovePreviewJpeg(string filePath)
|
||||
{
|
||||
string jpegPath = filePath + ".preview.jpg";
|
||||
if (File.Exists(jpegPath)) File.Delete(jpegPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace IRaCIS.Core.Application.Services
|
||||
{
|
||||
static class IdentifierHelper
|
||||
{
|
||||
//private static MD5 md5 = new MD5CryptoServiceProvider
|
||||
//
|
||||
private static MD5 md5 = MD5.Create();
|
||||
|
||||
private static object lockObj =new object();
|
||||
|
||||
public static Guid CreateGuid(params string[] parts)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
return new Guid(md5.ComputeHash(Encoding.UTF8.GetBytes(string.Concat(parts))));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
using IRaCIS.Core.Application.Contracts.Dicom;
|
||||
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using IRaCIS.Core.Application.Auth;
|
||||
|
||||
namespace IRaCIS.Core.Application.Services
|
||||
{
|
||||
[AllowAnonymous, ApiExplorerSettings(GroupName = "Image")]
|
||||
public class ImageShareService : BaseService, IImageShareService
|
||||
{
|
||||
|
||||
private readonly IRepository<ImageShare> _imageShareRepository;
|
||||
private readonly IRepository<DicomStudy> _studyRepository;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly ITokenService _tokenService;
|
||||
|
||||
public ImageShareService(IRepository<ImageShare> imageShareRepository, IRepository<DicomStudy> studyRepository, IConfiguration configuration, ITokenService tokenService)
|
||||
{
|
||||
|
||||
_imageShareRepository = imageShareRepository;
|
||||
_studyRepository = studyRepository;
|
||||
_configuration = configuration;
|
||||
_tokenService = tokenService;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> CreateImageShare(ImageShareCommand imageShareCommand)
|
||||
{
|
||||
if (imageShareCommand.StudyId == null)
|
||||
{
|
||||
|
||||
#region 上传不按照访视上传,基线没传,数据可能出错
|
||||
|
||||
//var subjectVisit1 = _subjectVisitRepository.FirstOrDefault(t =>
|
||||
// t.TrialId == imageShareCommand.TrialId && t.SubjectId == imageShareCommand.SubjectId &&
|
||||
// t.VisitNum == 1);
|
||||
|
||||
//if (subjectVisit1 == null)
|
||||
//{
|
||||
// return ResponseOutput.NotOk("当前无影像数据,无法分享!");
|
||||
//}
|
||||
|
||||
//imageShareCommand.StudyId =
|
||||
// _studyRepository.GetAll().First(t => t.SubjectVisitId == subjectVisit1.Id&&t.Status != (int)StudyStatus.Abandon).Id;
|
||||
|
||||
#endregion
|
||||
|
||||
var studyIds = await _studyRepository.AsQueryable()
|
||||
.Where(t => t.TrialId == imageShareCommand.TrialId && t.SubjectId == imageShareCommand.SubjectId &&
|
||||
t.SiteId == imageShareCommand.SiteId)
|
||||
.Select(u => u.Id).ToListAsync();
|
||||
|
||||
if (!studyIds.Any())
|
||||
{
|
||||
return ResponseOutput.NotOk("There is no image in the current study and cannot be shared! ");
|
||||
}
|
||||
|
||||
imageShareCommand.StudyId = studyIds.First();
|
||||
|
||||
}
|
||||
|
||||
//验证码 4位
|
||||
int verificationPassWord = new Random().Next(1000, 10000);
|
||||
|
||||
imageShareCommand.Password = verificationPassWord.ToString();
|
||||
|
||||
//配置文件读取过期时间
|
||||
var days = int.Parse(_configuration.GetSection("imageShare:ExpireDays").Value);
|
||||
|
||||
imageShareCommand.ExpireTime = DateTime.Now.AddDays(days);
|
||||
|
||||
var imageShare = _mapper.Map<ImageShare>(imageShareCommand);
|
||||
|
||||
await _imageShareRepository.AddAsync(imageShare);
|
||||
|
||||
var success = await _imageShareRepository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Result(success, new { ResourceId = imageShare.Id, Password = verificationPassWord.ToString() });
|
||||
|
||||
|
||||
}
|
||||
|
||||
[HttpGet, Route("{resourceId:guid}/{password}")]
|
||||
public async Task<IResponseOutput> VerifyShareImage(Guid resourceId, string password)
|
||||
{
|
||||
var pWord = password.Trim();
|
||||
var imageShare = await _imageShareRepository.FirstOrDefaultAsync(t => t.Id == resourceId);
|
||||
|
||||
if (imageShare == null)
|
||||
{
|
||||
return ResponseOutput.NotOk("The resource does not exist! ");
|
||||
}
|
||||
|
||||
if (pWord != imageShare.Password.Trim())
|
||||
{
|
||||
return ResponseOutput.NotOk("Shared password error!");
|
||||
}
|
||||
|
||||
if (DateTime.Now > imageShare.ExpireTime)
|
||||
{
|
||||
return ResponseOutput.NotOk("Resource sharing has expired!");
|
||||
}
|
||||
|
||||
var resource = new ResourceInfo()
|
||||
{
|
||||
StudyId = imageShare.StudyId,
|
||||
Token = _tokenService.GetToken(IRaCISClaims.Create(new UserBasicInfo()
|
||||
{
|
||||
Id = Guid.Empty,
|
||||
IsReviewer = false,
|
||||
IsAdmin = false,
|
||||
RealName = "Share001",
|
||||
UserName = "Share001",
|
||||
Sex = 0,
|
||||
//UserType = "ShareType",
|
||||
UserTypeEnum = UserTypeEnum.ShareImage,
|
||||
Code = "ShareCode001",
|
||||
}))
|
||||
};
|
||||
|
||||
|
||||
return ResponseOutput.Ok(resource);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using IRaCIS.Core.Application.Contracts.Dicom;
|
||||
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Application.Dicom;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
|
||||
namespace IRaCIS.Core.Application.Services
|
||||
{
|
||||
[ApiExplorerSettings(GroupName = "Image")]
|
||||
[AllowAnonymous]
|
||||
public class InstanceService : BaseService, IInstanceService
|
||||
{
|
||||
private readonly IRepository<DicomInstance> _instanceRepository;
|
||||
private readonly IRepository<DicomStudy> _studyRepository;
|
||||
private readonly IRepository<KeyInstance> _keyInstanceRepository;
|
||||
private readonly DicomFileStoreHelper _dicomFileStoreHelper;
|
||||
public InstanceService(IRepository<DicomInstance> instanceRepository, IRepository<DicomStudy> studyRepository,
|
||||
IRepository<KeyInstance> keyInstanceRepository, DicomFileStoreHelper dicomFileStoreHelper)
|
||||
{
|
||||
_dicomFileStoreHelper = dicomFileStoreHelper;
|
||||
_instanceRepository = instanceRepository;
|
||||
_studyRepository = studyRepository;
|
||||
_keyInstanceRepository = keyInstanceRepository;
|
||||
}
|
||||
|
||||
/// <summary> 指定资源Id,获取Dicom序列所属的实例信息列表 </summary>
|
||||
/// <param name="seriesId"> Dicom序列的Id </param>
|
||||
[HttpGet("{seriesId:guid}")]
|
||||
public async Task<IEnumerable<DicomInstanceDTO>> List(Guid seriesId)
|
||||
{
|
||||
return await _instanceRepository.Where(s => s.SeriesId == seriesId).OrderBy(s => s.InstanceNumber).
|
||||
ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
|
||||
.ProjectTo<DicomInstanceDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
/// <summary> 指定资源Id,获取Dicom序列所属的实例Id列表 </summary>
|
||||
/// <param name="seriesId"> Dicom序列的Id </param>
|
||||
/// <param name="tpCode"></param>
|
||||
/// <param name="key"></param>
|
||||
[HttpGet, Route("{seriesId:guid}/{tpCode?}/{key?}")]
|
||||
public IEnumerable<Guid> List(Guid seriesId, string tpCode, bool? key)
|
||||
{
|
||||
if (key != null && key.HasValue && key.Value)
|
||||
{
|
||||
return _keyInstanceRepository.Where(s => s.TpCode == tpCode).Select(t => t.InstanceId).Distinct();
|
||||
}
|
||||
else
|
||||
return _instanceRepository.Where(s => s.SeriesId == seriesId).OrderBy(s => s.InstanceNumber).Select(t => t.Id);
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpGet, Route("{instanceId:guid}")]
|
||||
public async Task<FileContentResult> Preview(Guid instanceId)
|
||||
{
|
||||
var path = string.Empty;
|
||||
|
||||
DicomInstance dicomInstance = await _instanceRepository.FirstOrDefaultAsync(s => s.Id == instanceId).IfNullThrowException();
|
||||
|
||||
DicomStudy dicomStudy = await _studyRepository.FirstOrDefaultAsync(s => s.Id == dicomInstance.StudyId).IfNullThrowException();
|
||||
|
||||
path = _dicomFileStoreHelper.GetInstanceFilePath(dicomStudy, dicomInstance.SeriesId, dicomInstance.Id.ToString());
|
||||
|
||||
|
||||
|
||||
using (var sw = DicomRenderingHelper.RenderPreviewJpeg(path))
|
||||
{
|
||||
var bytes = new byte[sw.Length];
|
||||
sw.Read(bytes, 0, bytes.Length);
|
||||
sw.Close();
|
||||
return new FileContentResult(bytes, "image/jpeg");
|
||||
}
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpGet, Route("{instanceId:guid}")]
|
||||
public async Task<FileContentResult> Content(Guid instanceId)
|
||||
{
|
||||
var filePath = string.Empty;
|
||||
DicomInstance dicomInstance = await _instanceRepository.FirstOrDefaultAsync(s => s.Id == instanceId).IfNullThrowException();
|
||||
|
||||
DicomStudy dicomStudy = await _studyRepository.FirstOrDefaultAsync(s => s.Id == dicomInstance.StudyId).IfNullThrowException();
|
||||
|
||||
|
||||
if (dicomInstance.Anonymize) //被匿名化
|
||||
{
|
||||
filePath = _dicomFileStoreHelper.GetInstanceFilePath(dicomStudy, dicomInstance.SeriesId, dicomInstance.Id + ".Anonymize");
|
||||
}
|
||||
|
||||
else filePath = _dicomFileStoreHelper.GetInstanceFilePath(dicomStudy, dicomInstance.SeriesId, dicomInstance.Id.ToString());
|
||||
|
||||
|
||||
|
||||
using (var sw = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
var bytes = new byte[sw.Length];
|
||||
sw.Read(bytes, 0, bytes.Length);
|
||||
sw.Close();
|
||||
return new FileContentResult(bytes, "application/octet-stream");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
namespace IRaCIS.Core.Application.Contracts.Dicom
|
||||
{
|
||||
public interface IDicomArchiveService
|
||||
{
|
||||
Task<Guid> ArchiveDicomStreamAsync(Stream dicomStream, DicomTrialSiteSubjectInfo addtionalInfo, List<string> seriesInstanceUidList, List<string> instanceUidList);
|
||||
//ICollection<DicomStudyDTO> GetArchivedStudyList(List<Guid> archivedStudyIds);
|
||||
|
||||
Task<bool> DicomDBDataSaveChange();
|
||||
|
||||
|
||||
//[EasyCachingAble(Expiration = 6000)]
|
||||
|
||||
|
||||
|
||||
//IEnumerable<DicomSeriesDTO> GetSeriesList(Guid studyId);
|
||||
//IEnumerable<DicomSeriesWithLabelDTO> GetSeriesWithLabelList(Guid studyId,string tpCode);
|
||||
|
||||
////[EasyCachingAble(Expiration = 6000)]
|
||||
//string GetSeriesPreview(Guid seriesId);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user