123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 |
- 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 解构入参
-
- /// <summary>
- /// 异步下载,会造成压缩时文件还没生成,导致压缩包内容与实际文件夹内容不符
- /// </summary>
- /// <param name="url"></param>
- /// <param name="filePath"></param>
- /// <returns></returns>
- private async Task<bool> 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;
- }
- }
- /// <summary>
- /// 同步下载
- /// </summary>
- /// <param name="url"></param>
- /// <param name="filePath"></param>
- /// <returns></returns>
- 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;
- }
- }
- /// <summary>
- /// 保存XML文件
- /// </summary>
- /// <param name="jaXML"></param>
- 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);
- }
- }
-
-
- /// <summary>
- /// 压缩指定的文件夹及其内容到ZIP文件中。
- /// </summary>
- /// <param name="sourceFolderPath">源文件夹路径。</param>
- /// <param name="zipFilePath">输出的ZIP文件路径。</param>
- 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}");
- }
- }
- /// <summary>
- /// 递归地将文件夹添加到ZIP存档中。
- /// </summary>
- /// <param name="archive">ZIP存档对象。</param>
- /// <param name="folderPath">当前处理的文件夹路径。</param>
- /// <param name="basePath">基础路径,用于构建ZIP内的相对路径。</param>
- 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);
- }
- }
- /// <summary>
- /// 转换位Base64
- /// </summary>
- /// <param name="path"></param>
- /// <returns></returns>
- 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");
- }
- /// <summary>
- /// 根据当天0点计算当前时刻的5位时间戳,然后加上当前日期,组成序号。要求每个上传时间需要超过1秒,否则会有重复问题
- /// </summary>
- /// <returns></returns>
- 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
- }
- /// <summary>
- /// 正式解构HIS返回的入参,包括医保编码转换,PDF下载,XML文件保存,ZIP压缩,zip转Base64,业务编号命名等
- /// </summary>
- /// <param name="joSource"></param>
- /// <returns></returns>
- 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 查询,反写数据库
- /// <summary>
- /// 查询患者电子发票
- /// </summary>
- /// <param name="joIn"></param>
- /// <returns></returns>
- 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;
- }
- /// <summary>
- /// 查询患者电子发票
- /// </summary>
- /// <param name="joIn"></param>
- /// <returns></returns>
- public JObject MatchUploadRecord(JObject joIn)
- {
- //JoIn包含 起止时间,医院ID,接口ID,患者姓名,患者数电号
- JObject joRtn = invoker.invokeHISService(JsonHelper.setIrisInpar("05110040", joIn).ToString(), "查询某时间段内或某患者电子结算凭证清单");
- return joRtn;
- }
- /// <summary>
- /// 成功后更新记录表
- /// </summary>
- /// <param name="joIn"></param>
- /// <returns></returns>
- 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 具体功能点封装
- /// <summary>
- /// 上传
- /// </summary>
- /// <param name="joIn"></param>
- /// <returns></returns>
- public JObject Upload(JObject joIn)
- {
- JObject joRtn = invoker.invokeCenterService("4901", JsonHelper.setCenterInpar("4901",joIn));
- return joRtn;
- }
- /// <summary>
- /// 重新上传
- /// </summary>
- /// <param name="joIn"></param>
- /// <returns></returns>
- public JObject ReUpload(JObject joIn)
- {
- JObject joRtn = invoker.invokeCenterService("4905", JsonHelper.setCenterInpar("4905", joIn));
- return joRtn;
- }
- /// <summary>
- /// 查询上传结果
- /// </summary>
- /// <param name="joIn"></param>
- /// <returns></returns>
- public JObject QueryUploadResult(JObject joIn)
- {
- JObject joRtn = invoker.invokeCenterService("4902", JsonHelper.setCenterInpar("4902", joIn));
- return joRtn;
- }
- /// <summary>
- /// 查询电子凭证上传状态
- /// </summary>
- /// <param name="joIn"></param>
- /// <returns></returns>
- public JObject QueryUploadStatus(JObject joIn)
- {
- JObject joRtn = invoker.invokeCenterService("5501", JsonHelper.setCenterInpar("5501", joIn));
- return joRtn;
- }
- #endregion
- #region 具体流程封装
- #endregion
- }
- }
|