You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

570 lines
23 KiB

using Dapper;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Npgsql;
using Shentun.Peis.ImportLisResults;
using Shentun.Peis.ImportPacsResults;
using Shentun.Peis.PlugIns.Extensions.ChargeRequests.YinHai;
using Shentun.Peis.PlugIns.Extensions.ChargeRequests.YinHai.FeeBacks;
using Shentun.Peis.PlugIns.Extensions.ImportLisResults.YinHai;
using Shentun.Peis.PlugIns.Extensions.ImportLisResults.YinHai.ResultCalls;
using Shentun.Peis.PlugIns.Extensions.ImportPacsResults.YinHai.ResultCalls;
using Shentun.Peis.PlugIns.Extensions.LisRequests.YinHai;
using Shentun.Peis.PlugIns.PatientRegisters;
using Shentun.Peis.ThirdInterfaces;
using Shentun.Utilities;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace Shentun.Peis.PlugIns.Extensions.ImportPacsResults.YinHai
{
public class ImportPacsResultPlugInsYinHai
{
protected IConfiguration? AppConfig;
private readonly string AppConnctionStr;
private readonly IConfiguration? InterfaceConfig;
private readonly ThirdInterfaceDto? _thirdInterfaceDto;
private readonly PluginLogger _logger; // 添加日志实例
private string? _appBaseAddress;
private static string? _accesToken;
protected string? AppUser;
protected string? AppPassword;
static ImportPacsResultPlugInsYinHai()
{
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
}
public ImportPacsResultPlugInsYinHai(Guid thirdInterfaceId)
{
_logger = new PluginLogger();
AppConfig = new ConfigurationBuilder()
.SetBasePath(DirectoryHelper.GetAppDirectory()) // 设置基础路径为当前目录
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.Build();
AppConnctionStr = AppConfig.GetSection("ConnectionStrings")
.GetSection("Default").Value;
using (DbConnection conn = new NpgsqlConnection(AppConnctionStr))
{
string sql;
sql = @"
SELECT *
from third_interface
where id =@ThirdInterfaceId
";
_thirdInterfaceDto = (conn.Query<ThirdInterfaceDto>(sql,
new { ThirdInterfaceId = thirdInterfaceId })).Single();
}
var configurationBuilder = new ConfigurationBuilder()
.AddJsonStream(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(_thirdInterfaceDto.ParmValue)));
InterfaceConfig = configurationBuilder.Build();
_appBaseAddress = AppConfig.GetSection("App")
.GetSection("SelfUrl").Value;
AppUser = AppConfig.GetSection("App")
.GetSection("SelfUser").Value;
AppPassword = AppConfig.GetSection("App")
.GetSection("SelfPassword").Value;
}
public ImportPacsResultPlugInsYinHai(string parmValue)
{
_logger = new PluginLogger();
AppConfig = new ConfigurationBuilder()
.SetBasePath(DirectoryHelper.GetAppDirectory()) // 设置基础路径为当前目录
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.Build();
AppConnctionStr = AppConfig.GetSection("ConnectionStrings")
.GetSection("Default").Value;
var configurationBuilder = new ConfigurationBuilder()
.AddJsonStream(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(parmValue)));
InterfaceConfig = configurationBuilder.Build();
_appBaseAddress = AppConfig.GetSection("App")
.GetSection("SelfUrl").Value;
AppUser = AppConfig.GetSection("App")
.GetSection("SelfUser").Value;
AppPassword = AppConfig.GetSection("App")
.GetSection("SelfPassword").Value;
}
/// <summary>
/// 接收Pacs检查结果
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task<CallBussinessResponseDetailDto> SendResultRequestAsync(InferfaceXmlDataDto input)
{
var res = new CallBussinessResponseDetailDto
{
msg = "失败",
status_code = "-1"
};
#region 解析xml
var pacsResultCallRequestData = GetPacsResultCallRequestData(input.message);
#endregion
_logger.LogResult("银海接收pacs检查结果", $"请求数据:{input.message}");
try
{
var execDoctorUser = InterfaceConfig.GetValue("Interface:ExecDoctorUser", "");
// var commonTableTypeId = InterfaceConfig.GetValue("Interface:CommonTableTypeId", "");
var execOrganizationUnitId = InterfaceConfig.GetValue("Interface:ExecOrganizationUnitId", "");
var checkDoctorName = InterfaceConfig.GetValue("Interface:CheckDoctorName", "");
string actionName = "result_call";
string codeName = "pacs_server";
var bodyData = pacsResultCallRequestData.body.data.request_details;
if (bodyData.detail.Any())
{
foreach (var item in bodyData.detail)
{
var createImportPacsResultDto = new CreateImportPacsResultDto()
{
CheckRequestNo = item.request_no,
PatientName = GetPatientNameByCheckRequsetNo(item.request_no).GetAwaiter().GetResult(),
Result = item.diag_result,
Summary = item.diag_result,
Suggestion = item.diag_suggest,
//CheckDate = checkDate,
CheckDoctorName = checkDoctorName,
Files = new List<CreateImportPacsResultPictureDto>()
{
new CreateImportPacsResultPictureDto()
{
IsPrint = 'Y',
FileTransMode = "1",//0-json,1-url
FileName = item.image_address,
FileFormat = "0",//0-图片,1-pdf
FileUrl = item.image_address
//FileBase64 = Shentun.Utilities.FileHelper.ToBase64(firstData.reportUrl)
}
}
};
var callResult = await CallAppServiceAsync<CreateImportPacsResultDto, object>("api/app/ImportPacsResult/ImportResult", createImportPacsResultDto);
_logger.LogResult("银海接收pacs检查结果", $"处理成功,pacs申请单号【{item.request_no}】");
var yinHaiSendInterfaceLogDto = new YinHaiSendInterfaceLogDto
{
LogName = "接收pacs检查结果",
ExecDoctorUser = Guid.Parse(execDoctorUser),
InterfaceName = $"{codeName}_{actionName}",
ParaValue = input.message,
RequestNo = item.request_no,
ReturnParaValue = ""
};
await AddSendLog(yinHaiSendInterfaceLogDto);
}
}
else
{
throw new Exception("无结果数据");
}
res = new CallBussinessResponseDetailDto
{
status_code = "1",
msg = "成功"
};
}
catch (Exception ex)
{
_logger.LogResult("银海接收pacs检查结果", ex, $"接收pacs检查结果异常");
}
return res;
}
/// <summary>
/// 根据检查单号获取病人姓名
/// </summary>
/// <param name="checkRequestNo"></param>
/// <returns></returns>
private async Task<string> GetPatientNameByCheckRequsetNo(string checkRequestNo)
{
string msg = "";
using (DbConnection conn = new NpgsqlConnection(AppConnctionStr))
{
string sql;
sql = $@"select a.patient_name from patient_register as a
left join register_check as b on a.id=b.patient_register_id
where b.check_request_no=@checkRequestNo ";
msg = await conn.QueryFirstOrDefaultAsync<string>(sql, new
{
checkRequestNo = checkRequestNo
});
}
return msg;
}
/// <summary>
/// 添加日志
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task AddSendLog(YinHaiSendInterfaceLogDto input)
{
using (DbConnection conn = new NpgsqlConnection(AppConnctionStr))
{
string sql;
sql = $@" insert into interface_send_log (id,log_name,request_no,interface_name,para_value,return_para_value,concurrency_stamp,
creation_time,creator_id,last_modification_time,last_modifier_id) values
(@id,@log_name,@request_no,@interface_name,@para_value,@return_para_value,@concurrency_stamp,
@creation_time,@creator_id,@last_modification_time,@last_modifier_id)
";
await conn.ExecuteAsync(sql,
new
{
id = Guid.NewGuid(),
log_name = input.LogName,
request_no = input.RequestNo,
interface_name = input.InterfaceName,
para_value = input.ParaValue,
return_para_value = input.ReturnParaValue,
concurrency_stamp = Guid.NewGuid().ToString("N"),
creation_time = DateTime.Now,
creator_id = input.ExecDoctorUser,
last_modification_time = DateTime.Now,
last_modifier_id = input.ExecDoctorUser
});
}
}
#region 解析xml
private PacsResultCallRequestDto GetPacsResultCallRequestData(string message)
{
try
{
var doc = new XmlDocument();
doc.LoadXml(message);
var request = new PacsResultCallRequestDto();
var root = doc.DocumentElement;
if (root == null) return null;
// 解析 head
var headNode = root.SelectSingleNode("head");
if (headNode != null)
{
request.head = new CallBussinessRequestHeadDto
{
version = GetNodeValue(headNode, "version"),
timestamp = GetNodeValue(headNode, "timestamp"),
sign = GetNodeValue(headNode, "sign"),
request_id = GetNodeValue(headNode, "request_id"),
source_system = GetNodeValue(headNode, "source_system"),
object_system = GetNodeValue(headNode, "object_system"),
action = GetNodeValue(headNode, "action"),
code = GetNodeValue(headNode, "code")
};
}
// 解析 body
var bodyNode = root.SelectSingleNode("body");
if (bodyNode != null)
{
request.body = new PacsResultCallRequestBodyDto();
var dataNode = bodyNode.SelectSingleNode("data");
if (dataNode != null)
{
request.body.data = new PacsResultCallRequestBodyDataDto();
var requestDetailsNode = dataNode.SelectSingleNode("request_details");
if (requestDetailsNode != null)
{
// 创建 detail 列表
request.body.data.request_details = new PacsResultCallRequestBodyDataRequestDetails
{
detail = new List<PacsResultCallRequestBodyDataRequestDetail>()
};
// 获取所有 detail 节点
var detailNodes = requestDetailsNode.SelectNodes("detail");
if (detailNodes != null)
{
foreach (XmlNode detailNode in detailNodes)
{
var detail = new PacsResultCallRequestBodyDataRequestDetail
{
hos_id = GetNodeValue(detailNode, "hos_id"),
request_no = GetNodeValue(detailNode, "request_no"),
patient_type = GetNodeValue(detailNode, "patient_type"),
report_serial_no = GetNodeValue(detailNode, "report_serial_no"),
org_code = GetNodeValue(detailNode, "org_code"),
system_source = GetNodeValue(detailNode, "system_source"),
org_name = GetNodeValue(detailNode, "org_name"),
patient_id = GetNodeValue(detailNode, "patient_id"),
visit_id = GetNodeValue(detailNode, "visit_id"),
order_id = GetNodeValue(detailNode, "order_id"),
remark = GetNodeValue(detailNode, "remark"),
check_no = GetNodeValue(detailNode, "check_no"),
conform_reality = GetNodeValue(detailNode, "conform_reality"),
diag_result = GetNodeValue(detailNode, "diag_result"),
diag_suggest = GetNodeValue(detailNode, "diag_suggest"),
image_address = GetNodeValue(detailNode, "image_address"),
image_generation_time = GetNodeValue(detailNode, "image_generation_time"),
image_report_index = GetNodeValue(detailNode, "image_report_index"),
item_serial_no = GetNodeValue(detailNode, "item_serial_no"),
positive_flag = GetNodeValue(detailNode, "positive_flag"),
report_quality = GetNodeValue(detailNode, "report_quality"),
study_uuid = GetNodeValue(detailNode, "study_uuid")
};
request.body.data.request_details.detail.Add(detail);
}
}
}
}
}
return request;
}
catch (Exception ex)
{
//_logger.LogError(ex, "解析 XML 失败");
return null;
}
}
private string GetNodeValue(XmlNode parent, string nodeName)
{
var node = parent.SelectSingleNode(nodeName);
return node?.InnerText ?? "";
}
#endregion
/// <summary>
/// 发起api请求
/// </summary>
/// <typeparam name="TInput"></typeparam>
/// <typeparam name="TOut"></typeparam>
/// <param name="url"></param>
/// <param name="data"></param>
/// <param name="method"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
private async Task<TOut> CallAppServiceAsync<TInput, TOut>(string url, TInput data, string method = "post")
{
if (string.IsNullOrWhiteSpace(_appBaseAddress))
{
throw new Exception("_appBaseAddress不能为空");
}
string baseAddress = _appBaseAddress;
await CheckLoginAsync();
using (var httpClientHandler = new HttpClientHandler())
{
using (var httpClient = new HttpClient(httpClientHandler))
{
httpClient.BaseAddress = new Uri(baseAddress);
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));//设置accept标头,告诉JSON是可接受的响应类型
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accesToken);
IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
var sendData = JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.Indented, timeFormat);
using (HttpContent httpContent = new StringContent(sendData))
{
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpResponseMessage response = null;
if (method == "post")
{
response = await httpClient.PostAsync(url, httpContent);
}
else
{
response = await httpClient.GetAsync(url);
}
string result;
if (!response.IsSuccessStatusCode)
{
result = response.Content.ReadAsStringAsync().Result;
throw new Exception("http通信错误:" + response.StatusCode + ",结果:" + result);
}
result = await response.Content.ReadAsStringAsync();
var resultDto = JsonConvert.DeserializeObject<WebApiOutDto<TOut>>(result);
if (resultDto.Code == -1)
{
throw new Exception($"调用WebApi失败,返回-1,消息:" + resultDto.Message);
}
return resultDto.Data;
}
}
}
}
#region 获取token
private async Task<WebApiOutDto<LoginOutDataDto>> LoginAsync(string userId, string password)
{
if (string.IsNullOrWhiteSpace(userId))
{
throw new Exception("用户ID不能为空");
}
if (string.IsNullOrWhiteSpace(password))
{
throw new Exception("密码不能为空");
}
using (var httpClientHandler = new HttpClientHandler())
{
using (var httpClient = new HttpClient(httpClientHandler))
{
httpClient.BaseAddress = new Uri(_appBaseAddress);
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));//设置accept标头,告诉JSON是可接受的响应类型
var url = "api/identity/users/login";
var loginUser = new LoginInputDto()
{
UserName = userId,
Password = password
};
var sendData = JsonConvert.SerializeObject(loginUser);
using (HttpContent httpContent = new StringContent(sendData))
{
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpResponseMessage response = await httpClient.PostAsync(url, httpContent);
string result;
if (!response.IsSuccessStatusCode)
{
result = response.Content.ReadAsStringAsync().Result;
throw new Exception("http通信错误:" + response.StatusCode + ",结果:" + result);
}
result = await response.Content.ReadAsStringAsync();
var restultDto = JsonConvert.DeserializeObject<WebApiOutDto<LoginOutDataDto>>(result);
if (restultDto == null)
{
throw new Exception("返回结果是空");
}
if (restultDto.Code != 1)
{
throw new Exception($"登录失败{restultDto.Message}");
}
_accesToken = restultDto.Data.access_token;
return restultDto;
}
}
}
}
private async Task CheckLoginAsync()
{
if (string.IsNullOrWhiteSpace(_accesToken))
{
await LoginAsync();
}
else
{
var handler = new JwtSecurityTokenHandler();
var payload = handler.ReadJwtToken(_accesToken).Payload;
var claims = payload.Claims;
var exp = claims.First(claim => claim.Type == "exp").Value;
if (exp == null)
{
await LoginAsync();
}
else
{
if (long.TryParse(exp, out var expires))
{
var expireTime = DateTimeOffset.FromUnixTimeSeconds(expires).LocalDateTime;
if (expireTime <= DateTime.Now)
{
await LoginAsync();
}
}
else
{
await LoginAsync();
}
}
}
}
private async Task<WebApiOutDto<LoginOutDataDto>> LoginAsync()
{
if (string.IsNullOrWhiteSpace(AppUser))
{
throw new Exception("SelfUser不能为空");
}
if (string.IsNullOrWhiteSpace(AppPassword))
{
throw new Exception("SelfPassword不能为空");
}
var relult = await LoginAsync(AppUser, AppPassword);
return relult;
}
#endregion
}
}