通过FHIR和EPIC进行对接

news2024/11/23 13:26:58

说明

Epic是全美最大电子病历供应商。

FHIR (Fast Health Interoperability Resources)旨在实现医疗健康信息的交换。其中包括了临床数据和健康相关的行政管理数据、公共卫生和临床研究数据。既包括了人类和兽医,又适合大多数应用场景——住院、慢病管理、社区护理、健康联盟等。

在https://fhir.epic.com/ 中有详细的文档

这里有详细的注册测试账号和沙箱使用的说明。

生成token

调用get_token函数生成token。 

        public static string make_jwt(Option option)
        {
            Dictionary<string, object> h = new Dictionary<string, object>();
            h["alg"] = "RS384";
            h["typ"] = "JWT";
            h["kid"] = option.kid ;
            string header = Newtonsoft.Json.JsonConvert.SerializeObject(h);
            DateTime d1 = DateTime.UtcNow.AddSeconds(60 * 4);
            //1970-01-01T00:00:00Z UTC)
            DateTime d0 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            int exp = ((int)(d1 - d0).TotalSeconds);
            Dictionary<string, object> p = new Dictionary<string, object>();
            p["iss"] = option.client_id;
            p["sub"] = option.client_id;
            p["aud"] = option.oauth_url;
            p["jti"] = Guid.NewGuid().ToString("N");
            p["exp"] = exp;
            string payload = Newtonsoft.Json.JsonConvert.SerializeObject(p);

            //signature = RSA-SHA384(base64urlEncoding(header) + '.' + base64urlEncoding(payload), privatekey)
            byte[] signature_buff = RSASha384Signature.SignData(Base64UrlEncoder.base64urlEncoding(header) + '.' + Base64UrlEncoder.base64urlEncoding(payload), option.privatekey_pem);

            string jwt = Base64UrlEncoder.base64urlEncoding(header) + '.' + Base64UrlEncoder.base64urlEncoding(payload) + '.' + Base64UrlEncoder.Encode(signature_buff);
            return jwt;
        }

        public static string get_token(Option option)
        {
            string jwt = make_jwt(option);
            Dictionary<string, string> postParameters = new Dictionary<string, string>();
            postParameters["grant_type"] = "client_credentials";
            postParameters["client_assertion_type"] = "urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer";
            postParameters["client_assertion"] = jwt;
            Dictionary<string, string> Headers = new Dictionary<string, string>();
            StringBuilder paraStrBuilder = new StringBuilder();
            foreach (string key in postParameters.Keys)
            {
                paraStrBuilder.AppendFormat("{0}={1}&", key, postParameters[key]);
            }
            string para = paraStrBuilder.ToString();
            if (para.EndsWith("&"))
                para = para.Remove(para.Length - 1, 1);
            string result;
            HttpUtils.HttpPostBuff(option.oauth_url, Headers, para, out result, option.proxy_url, option.proxy_port); 
            return result;
        }

使用了RSASha384

    public class RSASha384Signature
    {
        public static byte[] SignData(string data, string privatekey_pem)
        {
            using (var rsa = new RSACryptoServiceProvider())
            {

                RsaPrivateCrtKeyParameters privateKeyParams = ReadPrivateKey(privatekey_pem);
                RSAParameters rsaParams = new RSAParameters();
                rsaParams.Modulus = privateKeyParams.Modulus.ToByteArrayUnsigned();
                rsaParams.Exponent = privateKeyParams.PublicExponent.ToByteArrayUnsigned();
                rsaParams.D = privateKeyParams.Exponent.ToByteArrayUnsigned();
                rsaParams.P = privateKeyParams.P.ToByteArrayUnsigned();
                rsaParams.Q = privateKeyParams.Q.ToByteArrayUnsigned();
                rsaParams.DP = privateKeyParams.DP.ToByteArrayUnsigned();
                rsaParams.DQ = privateKeyParams.DQ.ToByteArrayUnsigned();
                rsaParams.InverseQ = privateKeyParams.QInv.ToByteArrayUnsigned();
                rsa.ImportParameters(rsaParams);
                // 使用SHA384进行签名
                byte[] dataBytes = Encoding.UTF8.GetBytes(data);
                byte[] signature = rsa.SignData(dataBytes, CryptoConfig.MapNameToOID("SHA384"));
                return signature;
            }
        }
        public static RsaPrivateCrtKeyParameters ReadPrivateKey(string privatekey_pem)
        {
            using (TextReader reader = new StringReader(privatekey_pem))
            {
                var pemReader = new PemReader(reader);
                var keyPair = pemReader.ReadObject() as RsaPrivateCrtKeyParameters;
                if (keyPair != null)
                {
                    return keyPair;
                }

                throw new InvalidDataException("Private key not found in file.");
            }
        }
    }

查询病人

查询病人可以使用 Hl7.Fhir.Rest (主要EPIC的有些接口 使用Hl7.Fhir.Rest  会报错,主要是日期格式)

            try
            {
                FhirClient client = Pub.get_FhirClient();
                SearchParams param = new SearchParams();
                if (textBox_given.Text.Trim() != "")
                    param.Add("given", textBox_given.Text.Trim());
                if (textBox_identifier.Text.Trim() != "")
                    param.Add("identifier", textBox_identifier.Text.Trim());
                if (textBox_family.Text.Trim() != "")
                    param.Add("family", textBox_family.Text.Trim()); 
                
                param.Count = 10; 
                Bundle b = client.Search<Patient>(param);
                display_patient(b);
            }
            catch (Exception err)
            {
                textBox_result.Text = err.Message;
            } 

病人数据

search_by_patient("Appointment"); 

search_by_patient("Condition");

 search_by_patient("Coverage");

 search_by_patient("DiagnosticReport");

search_by_patient("DocumentReference");

search_by_patient("Encounter");

search_by_patient("Immunization");

search_by_patient("InsurancePlan");

search_by_patient("MedicationRequest");

search_by_patient("MedicationStatement");

 search_by_patient("Observation");

search_by_patient("Procedure");

search_by_patient("QuestionnaireResponse");

search_by_patient("ServiceRequest");

search_by_patient("Slot");

private void search_by_patient(string type)
        {
            if (PatientId == "")
            {
                MessageBox.Show("Please select patient");
                return;
            }
            try
            {
               // Pub.get_FhirClient().Get(type + "?patient=" + PatientId);
                string json = Pub.get_RestClient(type + "?patient=" + PatientId);
                json = Pub.check_date(json);
                FhirJsonParser fp = new FhirJsonParser();
                Hl7.Fhir.Model.Bundle b = fp.Parse<Hl7.Fhir.Model.Bundle>(json);
                Form_List frm = new Form_List();
                frm.show_list(b);
                frm.ShowDialog();
                frm.Dispose();
            }
            catch (Exception err)
            {

                textBox_result.Text = err.Message;
            }
           
        }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2059256.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

windows平台的postgresql主从数据库流备份

主: 操作系统:windows10 数据库版本&#xff1a;postgresql-16.2 ip&#xff1a;192.168.3.254 从: 操作系统&#xff1a;windows10 数据库版本&#xff1a;postgresql-16.2 ip&#xff1a;192.168.3.253 配置主库 配置 pg_hba.conf 文件 在 pg 的安装目录下&#xff0c;找到 …

算法_字符串专题---持续更新

文章目录 前言最长公共前缀题目要求题目解析代码如下 最长回文子串题目要求题目解析代码如下 二进制求和题目要求题目解析 字符串相乘题目要求题目解析代码如下 前言 本文将会向你介绍有关字符串的相关题目&#xff1a;最长公共前缀、最长回文子串、二进制求和、字符串相乘。本…

CISAW安全集成和别的类型有什么区别

信息安全人员认证&#xff08;Certified Information Security Assurance Worker, CISAW&#xff09;是由中国网络安全审查技术认证中心依据信息安全领域的不同专业、技术和应用方向以及安全岗位需求&#xff0c;按照ISO/IEC 17024标准建立的多层次认证体系。 CISAW分为三个主…

web前端之选项卡的实现、动态添加类名、动态移除类名、动态添加样式、激活、tabBar

MENU 原生vue 原生 效果图 html 代码 <div class"card"><div class"tab_bar"><div class"item" onclick"handleTabBar(this)">tabBar1</div><div class"item" onclick"handleTabBar(this…

哈佛大学年中回顾2024年ESG发展近况

--- 兼谈新能源企业出海之ESG营销战略 2024年上半年&#xff0c;环境、社会和治理&#xff08;ESG&#xff09;问题以及对方法的不同意见继续成为全球头条新闻。今年年初&#xff0c;公司及其利益相关者在ESG的支持者和批评者之间进行了权衡&#xff0c;虽然近几个月ESG的势头…

cesium添加弹窗,跟随实体移动

先看效果&#xff0c;弹窗会跟随实体移动 1、首先我们先写一个弹窗样式&#xff0c;如果是vue开发&#xff0c;css最好写到公共引入的css &#xff0c;组件内css会编译后会加hash值 2、然后我们 开启 cesium的监听事件&#xff0c; 注意的是 initBubbleWindow方法在地球加载后…

控制阶段在DMAIC中的主要目标是什么?

在探讨DMAIC&#xff08;定义Define、测量Measure、分析Analyze、改进Improve、控制Control&#xff09;这一持续改进流程时&#xff0c;控制阶段作为整个循环的尾声&#xff0c;其重要性不言而喻。控制阶段的主要目标不仅在于巩固前期努力所取得的成果&#xff0c;更在于确保这…

EXCEL 分段排序--Excel难题#86

Excel某表格有3列。 ABC1A1B1512A2B27213A3B33824A4B495A5B5736A6B65777A7B7918A13B131509A14B144910A17B1770211A18B1870512A34B343313A35B3540914A36B3657915A37B3710 现在要求对表格按照第3列进行分段排序&#xff0c;由小到大排列。第1段&#xff1a;第3列小于等于50&…

UE5 datetime 创建日期时间节点 进行加法减法。个人理解

以下均为个人实验和个人理解&#xff0c;仅供参考。 目录 目标节点&#xff1a; 年月日 时分秒毫秒 目标节点&#xff1a; 年月日 年月日以1 为基底。若填的数字<0&#xff0c;该节点会失效。 试验&#xff1a; year基底为1&#xff0c;正常 year基底为0&#xff0c;异…

主流AI绘画工具StableDiffusion最新模型sd3本地部署方法(附工作流)

前言/introduction Stable Diffusion 3&#xff08;简称SD3&#xff09;是Stability AI最新推出的文本到图像生成模型。相比前代模型&#xff0c;SD3在生成质量、细节表现以及运行效率上有了显著提升&#xff0c;尤其在细腻的图像渲染和复杂的场景构建方面表现出色。SD3模型提…

【Harmony OS 4.0】页面路由跳转代码示例

ets/pages/Index.ets import router from ohos.router;Entry Component struct Index {State title: string Index Page;State message: string onPageShow(): void { // 页面每次显示时触发。使用aboutToAppear页面没反应。let record router.getParams() as Record<st…

微服务多个模块启动,端口被占用,yml配置文件读不到

刚刚提交到gitee自己的仓库&#xff0c;拉下来还是报错&#xff0c;然后看到一个解决方法&#xff1a; <build><resources><resource><directory>src/main/java</directory><includes><include>**/*.yml</include><includ…

医院信息管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图详细视频演示技术栈系统测试为什么选择我官方认证玩家&#xff0c;服务很多代码文档&#xff0c;百分百好评&#xff0c;战绩可查&#xff01;&#xff01;入职于互联网大厂&#xff0c;可以交流&#xff0c;共同进步。有保障的售后 代码参考数据库参…

神经重建在自动驾驶模拟中的应用

验证自动驾驶软件需要数百万公里的测试。这不仅意味着系统开发周期长&#xff0c;而且系统的复杂度也会不断增加&#xff0c;同时&#xff0c;大规模的实车测试也会耗费巨量的资源并且可能会面临未知的安全问题。aiSim这样的虚拟仿真工具可以减轻真实世界测试的负担。 AD和ADA…

学习ComfyUI的一个不错网站:www.comflowy.com/basics

学习ComfyUI&#xff0c;不仅仅是照搬别人的工作流来使用&#xff0c;重要的是能自己搭建工作流&#xff0c;而要能够熟练搭建&#xff0c;离不开对工作流中节点&#xff08;特别是重要节点&#xff09;的透彻理解。比如我自己&#xff0c;原来对 Lora 就十分陌生&#xff0c;不…

一款好看的WordPress REST API 主题

介绍&#xff1a; 主题特色&#xff1a; 使用Nuxtjs WordPress Rest Api 实现前后端分离&#xff0c;可完成多端部署&#xff1b; 主题支持自动切换黑夜模式。 使用说明&#xff1a; service 目录为wordpress主题文件&#xff0c;需要拷贝到wordpress主题目录下&#xff0…

创建uni-app项目(vue3+ts+vite)

npx degit dcloudio/uni-preset-vue#vite-ts m-uni-demo1 跳转到对应目录&#xff0c;装包&#xff0c;运行 cd m-uni-demo1 yarn yarn dev:h5 tsconfig.json: {"extends": "vue/tsconfig/tsconfig.json","compilerOptions": {"ignoreDepr…

项目实战--SpringBoot整合EasyExcel实现数据导入导出

SpringBoot整合EasyExcel实现数据导入导出 一、前言二、实践2.1 实体类注解方式2.2 动态参数化导出导入 一、前言 在公司业务系统开发过程中&#xff0c;操作 Excel 实现数据的导入导出是个非常常见的需求。 最近公司的项目采用EasyPoi来实现的&#xff0c;但是在数据量大的情…

用git指令别名,解决unity环境问题

文章目录 背景问题解决尝试1尝试2尝试3 背景 unity 项目开发时&#xff0c;由于我本机的配置和项目组其他小伙伴的配置不一样&#xff0c;使用统一的配置打开项目会出现花屏的现象&#xff0c;经过摸索尝试&#xff0c;需要修改 unity 的Project Settings。修改之后&#xff0…

骑行耳机品牌前五名排行榜:5大优质骑行耳机闭眼入都不踩雷!

近年来&#xff0c;骨传导耳机市场迅速崛起&#xff0c;但伴随着这股热潮&#xff0c;市场上也出现了诸多鱼龙混杂的杂牌品牌&#xff0c;有不少非专业的产品趁机涌入市场。这些骑行耳机在骨传导技术、防水性能、稳定性及音效调校等上百项关键指标上缺乏深入研发与优化&#xf…