using Newtonsoft.Json.Linq;
using PTMedicalInsurance.Helper;
using PTMedicalInsurance.Variables;
using System;
using System.IO;
using System.IO.Compression;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace PTMedicalInsurance.Business
{
public class ElectronicSettlementCertificate
{
public string ecSettlCertNo;
public string upldBchno;
private string xmlPath;
private string folderPath;
private string xmlName;
private string pdfName;
private string savePath; //保存路径
private InvokeHelper invoker = new InvokeHelper();
private MIIrisServices mIs = new MIIrisServices();
public ElectronicSettlementCertificate()
{
}
// 路径属性
public string SavePath
{
get { return savePath; } // 获取
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("路径不能为空", nameof(value));
}
savePath = value; // 设置
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
}
}
#region 获取入参
public JObject Get4901Input(JObject joIn)
{
//JoIn包含 患者数电号
JObject joRtn = invoker.invokeHISService(JsonHelper.setIrisInpar("05110041", joIn).ToString(), "获取该数电号对应的数电入参"); //测试服05110039
return joRtn;
}
#endregion
#region 解构入参
///
/// 异步下载,会造成压缩时文件还没生成,导致压缩包内容与实际文件夹内容不符
///
///
///
///
private async Task DownloadPdfFileAsync(string url, string filePath)
{
try
{
using (var httpClient = new HttpClient())
{
// 发送GET请求获取内容
HttpResponseMessage response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
// 读取内容到字节数组
byte[] fileBytes = await response.Content.ReadAsByteArrayAsync();
// 将字节数组写入文件
File.WriteAllBytes(filePath, fileBytes);
return true;
}
else
{
Console.WriteLine($"无法下载文件,状态码:{response.StatusCode}");
return false;
}
}
}
catch (Exception ex)
{
Console.WriteLine($"下载过程中发生错误:{ex.Message}");
return false;
}
}
///
/// 同步下载
///
///
///
///
private bool DownloadPdfFile(string url, string filePath)
{
try
{
using (var httpClient = new HttpClient())
{
// 发送GET请求获取内容
HttpResponseMessage response = httpClient.GetAsync(url).Result;
if (response.IsSuccessStatusCode)
{
// 读取内容到字节数组
byte[] fileBytes = response.Content.ReadAsByteArrayAsync().Result;
// 将字节数组写入文件
File.WriteAllBytes(filePath, fileBytes);
return true;
}
else
{
Console.WriteLine($"无法下载文件,状态码:{response.StatusCode}");
return false;
}
}
}
catch (Exception ex)
{
Console.WriteLine($"下载过程中发生错误:{ex.Message}");
return false;
}
}
///
/// 保存XML文件
///
///
private void SaveXML(JArray jaXML)
{
foreach (JObject jo in jaXML)
{
//税务数电票结构化数据文件(xml),命名规则为:电子结算凭证号码-extinfo ,因可能存在多条结算信息, 命名规则为:电子结算凭证号码-结算ID-extinfo
ecSettlCertNo = JsonHelper.getDestValue(jo, "tktextinfo.billInfo.elecSetlCertNo");
string setlId = JsonHelper.getDestValue(jo, "tktextinfo.mdtrtInfo.setlId");
//xmlName = $"{ecSettlCertNo}-{setlId}-extinfo.xml";
xmlName = $"{ecSettlCertNo}-extinfo.xml";
pdfName = $"{ecSettlCertNo}.pdf";
// 创建临时XML文件
folderPath = $@"{savePath}\ElecXml\{ecSettlCertNo}";
xmlPath = $@"{savePath}\ElecXml\{ecSettlCertNo}\{xmlName}";
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
XmlHelper xmler = new XmlHelper();
string xmlContent = xmler.ToXML(jo.ToString());
XElement xe = XElement.Parse(xmlContent);
string xml = xmler.setInput(xe);
File.WriteAllText(xmlPath, xml, Encoding.UTF8);
}
}
///
/// 压缩指定的文件夹及其内容到ZIP文件中。
///
/// 源文件夹路径。
/// 输出的ZIP文件路径。
private void CompressFolderToZIP(string sourceFolderPath, string zipFilePath)
{
if (!Directory.Exists(sourceFolderPath))
{
throw new DirectoryNotFoundException($"源文件夹不存在: {sourceFolderPath}");
}
try
{
using (FileStream fileStream = new FileStream(zipFilePath, FileMode.Create))
{
using (ZipArchive archive = new ZipArchive(fileStream, ZipArchiveMode.Create, true))
{
//AddFolderToZip(archive, sourceFolderPath, Path.GetFileName(sourceFolderPath));
AddFolderToZip(archive, sourceFolderPath, ""); //相对路径,为空则表示ZIP无第一层
}
}
}
catch (Exception ex)
{
throw new Exception($"压缩文件夹时发生错误: {ex.Message}");
}
}
///
/// 递归地将文件夹添加到ZIP存档中。
///
/// ZIP存档对象。
/// 当前处理的文件夹路径。
/// 基础路径,用于构建ZIP内的相对路径。
private static void AddFolderToZip(ZipArchive archive, string folderPath, string basePath)
{
DirectoryInfo directoryInfo = new DirectoryInfo(folderPath);
// 添加当前文件夹中的所有文件到ZIP存档
foreach (FileInfo fileInfo in directoryInfo.GetFiles())
{
string entryPath = Path.Combine(basePath, fileInfo.Name);
ZipArchiveEntry entry = archive.CreateEntry(entryPath);
using (FileStream stream = fileInfo.OpenRead())
{
using (Stream entryStream = entry.Open())
{
stream.CopyTo(entryStream);
}
}
}
// 递归地处理所有子文件夹
foreach (DirectoryInfo subDirInfo in directoryInfo.GetDirectories())
{
string subFolderPath = Path.Combine(folderPath, subDirInfo.Name);
string subBasePath = Path.Combine(basePath, subDirInfo.Name);
AddFolderToZip(archive, subFolderPath, subBasePath);
}
}
///
/// 转换位Base64
///
///
///
private string ZipTobase64(string path)
{
byte[] zipBytes = File.ReadAllBytes(path);
return Convert.ToBase64String(zipBytes);
}
private string FormatToFiveDigits(int seconds)
{
// 确保秒数不会超过五位数的最大值
if (seconds > 86400)
throw new ArgumentOutOfRangeException("秒", "一天的秒数不能超过86400");
// 使用格式化字符串将秒数转换为五位数的字符串
return seconds.ToString("D5");
}
///
/// 根据当天0点计算当前时刻的5位时间戳,然后加上当前日期,组成序号。要求每个上传时间需要超过1秒,否则会有重复问题
///
///
private string GetSeqNoBySecondStamp()
{
// 获取当天零点的时间
DateTime todayMidnight = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day);
// 计算从当天零点到现在的时间差(秒)
TimeSpan timeSinceMidnight = DateTime.Now - todayMidnight;
int secondsSinceMidnight = (int)timeSinceMidnight.TotalSeconds;
// 将秒数转换为5位时间戳
return DateTime.Now.ToString("yyyyMMdd") + FormatToFiveDigits(secondsSinceMidnight); //2024102168281
//return DateTime.Now.ToString("yyyyMMdd") + "68282"; // 68281
}
///
/// 正式解构HIS返回的入参,包括医保编码转换,PDF下载,XML文件保存,ZIP压缩,zip转Base64,业务编号命名等
///
///
///
public JObject Convert4901Input(JObject joSource)
{
//调用医保服务开始转换为医保对应的编码 09010127
JObject joConvertRtn = mIs.convertEcSettlUploadInpar(joSource);
JObject joData = JObject.Parse(JsonHelper.getDestValue(joConvertRtn,"data"));
//指定PDF,xml文件,xml文件夹路径
//保存xml ,保存过程中给路径等私有变量赋值
SaveXML(JArray.Parse(JsonHelper.getDestValue(joData, "xml")));
//保存PDF
string pdfUrl = JsonHelper.getDestValue(joData, "pdfUrl");
//DownloadPdfFileAsync(pdfUrl,$@"{folderPath}\{pdfName}");
DownloadPdfFile(pdfUrl, $@"{folderPath}\{pdfName}");
//压缩文件为ZIP,并保存到文件夹同级
CompressFolderToZIP(folderPath, $@"{savePath}\ElecXml\{ecSettlCertNo}.zip");
//转换ZIP为Base64
string base64 = ZipTobase64($@"{savePath}\ElecXml\{ecSettlCertNo}.zip");
joData["ftfileCompac"] = base64;
joData["filename"] = $@"{ecSettlCertNo}.zip";
joData["elecSetlCertCnt"] = int.Parse(joData["elecSetlCertCnt"].ToString()) + 1;
upldBchno = GetSeqNoBySecondStamp();
joData["upldBchno"] = upldBchno;//上传日期年月日加5位顺序号
//移除PDF和xml节点
joData.Remove("xml");
joData.Remove("pdfUrl");
return joData;
}
#endregion
#region 查询,反写数据库
///
/// 查询患者电子发票
///
///
///
public JObject QueryEcSettlCertList(JObject joIn)
{
//JoIn包含 起止时间,医院ID,接口ID,患者姓名,患者数电号
JObject joHisRtn = invoker.invokeHISService(JsonHelper.setIrisInpar("05110040", joIn).ToString(), "查询某时间段内或某患者电子结算凭证清单"); //测试服为05110038
string errMsg;
if (JsonHelper.parseIrisRtnValue(joHisRtn, out errMsg) != 0)
{
return joHisRtn;
}
JArray jaData = JArray.Parse(JsonHelper.getDestValue(joHisRtn,"data"));
JObject joInsuRtn = invoker.invokeInsuService(JsonHelper.setIrisInpar("09010128", jaData).ToString(), "根据传入的电子凭证记录匹配上传记录表");
return joInsuRtn;
}
///
/// 查询患者电子发票
///
///
///
public JObject MatchUploadRecord(JObject joIn)
{
//JoIn包含 起止时间,医院ID,接口ID,患者姓名,患者数电号
JObject joRtn = invoker.invokeHISService(JsonHelper.setIrisInpar("05110040", joIn).ToString(), "查询某时间段内或某患者电子结算凭证清单");
return joRtn;
}
///
/// 成功后更新记录表
///
///
///
public JObject Update(JObject joIn)
{
//JoIn包含 起止时间,医院ID,接口ID,患者姓名,患者数电号
JObject joInTmp = JsonHelper.setIrisInpar("02020007", joIn);
joInTmp["session"][0]["userID"] = "166";
joInTmp["session"][0]["hospID"] = Global.inf.hospitalDr;
JObject joRtn = invoker.invokeInsuService(joInTmp.ToString(),"更新通用记录表");
return joRtn;
}
#endregion
#region 具体功能点封装
///
/// 上传
///
///
///
public JObject Upload(JObject joIn)
{
JObject joRtn = invoker.invokeCenterService("4901", JsonHelper.setCenterInpar("4901",joIn));
return joRtn;
}
///
/// 重新上传
///
///
///
public JObject ReUpload(JObject joIn)
{
JObject joRtn = invoker.invokeCenterService("4905", JsonHelper.setCenterInpar("4905", joIn));
return joRtn;
}
///
/// 查询上传结果
///
///
///
public JObject QueryUploadResult(JObject joIn)
{
JObject joRtn = invoker.invokeCenterService("4902", JsonHelper.setCenterInpar("4902", joIn));
return joRtn;
}
///
/// 查询电子凭证上传状态
///
///
///
public JObject QueryUploadStatus(JObject joIn)
{
JObject joRtn = invoker.invokeCenterService("5501", JsonHelper.setCenterInpar("5501", joIn));
return joRtn;
}
#endregion
#region 具体流程封装
#endregion
}
}