1、HIS 医保接口设计规范一、导言BSHIS 在两年前就开始涉及医保软件接口的设计和实施了。随着时间的推移,越来越多的新签医院工程也要求实施医保;而一些以前上的老工程,也开始在实施各地的医保政策。可以说,医保的实施已经成为 HIS 软件在医院实施中一个很重要的组成部分。从某种意义上讲,医保实施的好坏也已经直接影响了工程实施的进度和效果。由于医保政策的复杂性,再加上政策有很大的地区差异。在实施过程中,软件设计人员遇到了很多比较复杂也或者很难于解决的问题。另外,由于医保政策一般都是刚刚指定出来不久的。所以,在实施的过程中,经常会遇到修改政策的过程。这在一定程度上给软件设计和实施增加了不少的难度。同时
2、,也会导致医保接口软件设计上的不确定性,直接的后果是可能导致很多的重复劳动。结合前面很多人医保实施成功和失败的教训,对在医保接口设计过程中的,好的方法进行了归纳,并尽量给出一种比较完善和完美的设计解决方法和规范,可帮助医保实施和软件接口设计人员比较好地实施医保。当然,现在只是个草稿,需要医保实施实践不断地扩充此规范,以至形成一种比较固定的综合解决方案。二、关于医保政策软件和应对方案我们通过对北京安宁盈科、创智公司、东大阿儿派、杭州新世纪、建达电子、万达公司等各个医保险政策软件提供商提供的接口方案进行了分析,总计出他们之间的共性如下:1、 一般都提供 DOS 和 WINDOWS 两套方案,DOS
3、 下一般用文件形式传递数据,WINDOWS 下一般以 WIN32 API 的形式在 HIS 和医保前置机之间调用和传递数据(DLL 提供了政策函数)。我们以后者为重点说明问题。2、 政策函数一般分为两类:单个函数和多个函数两种类型设计多个函数是指每中业务或者比较相似的业务为一个函数,这样组成结算、登记、退费等多个函数。如:杭州新世纪、东大阿儿派单个函数是指所有的业务都用一个函数实现。参数一般用结构字符串实现。如:上海万达公司。3、 明细数据一般都和结算时必要的项目数据分开传递到医保中心服务器。这样做的目的是为了减少网络阻塞。如果是同时要传的,一般在结算准备阶段就已经将数据计算好了。4、 平时发
4、生费用时,一般分成两种方式处理:1) 平时的自负比例按 HIS 中设置的算,也不需要审批如:万达公司2) 平时的自负比例不按 HIS 中设置的算,需要审批;需要维护标准的HIS 药品/项目的对照表,并在对照表中设置比例。如:东大阿儿派,记费代码需修改。5、 结算前一般都要刷卡,有些允许只在登记或者挂号的时候刷卡,结算时不刷卡,只要将必要的个人信息从 HIS 端保存的档中取即可。6、结算分计算(准备)阶段和确认结算阶段两部分。计算(准备)阶段:处理结算数据的上传或者调用结算计算函数获得医保支付信息,并获得自负金额,HIS 端可据此结算和打印发票。确认结算阶段:执行结算处理,和医保政策软件进行结算
5、交易。基于上面的分析和考虑,我们希望能够利用各个医保政策软件的共性,屏蔽其个性和特殊性、隔离 HIS 端业务和医保端业务。这样,对 HIS 端调用来说,调用的方式和接口是相同,有利于批量的实施和迎合医保险业务的多变性;减少 HIS 端程序的频繁修改和很大的后期维护量。所以,我们总的原则是:1) 隔离 HIS 端业务和医保端业务:HIS 端窗口和模块中,不要加入医保的处理过程,但可以加入对象方法的数据准备和方法调用。这样可减少 HIS 端业务和医保端业务的关联性,可适合批量医院上医保、各家医院程序又有客户化的情况。2) 利用共性,屏蔽个性:尽量将 HIS 端该调用医保处理的位置、函数名称和步骤明
6、确化,规范化,避免不必要的重复劳动和差异程序维护。3) 尽量减少调用医保的地方,或者在一个事件或者函数中集中处理,利于维护。4) 调用方法参数用结构体或者 DATAWINDOW,避免很多的参数。5) 函数返回值类型单一化,就成功或者失败两种情况,其他的返回信息放在医保接口对象的实例结构体变量或者实例变量中。三、医保接口规范1、医保病人结算的一般流程入院或者挂号(需要验证身份) 发生费用 结算发生费用时处理:有些医保需要个别项目进行审批,有些需要统一按标准目录取比例这时需要 HIS 药品/项目和医保之间有个对照如杭州医保就需要按上面的方法处理有些医保则不需在发生费用时和医保有关,只是在结算时发送
7、相关的大项目结算金额就可以了。 如上海医保,无对单个项目的处理结算的流程:先身份验证 计算请求:结算前先获得费用支付结构 确认结算:发送确认交易命令,调用医保软件实现结算退款的流程:先身份验证 由 HIS 向医保政策软件发送退款需要的数据和请求命令 获得医保政策软件响应处理 HIS 业务退款补结算的流程(指不是退全部款,而是新增或者退一部分):先身份验证 由 HIS 向医保政策软件发送退款和重新结算的数据和请求命令 获得医保政策软件响应处理 HIS 业务门诊挂号(住院入院登记)处理:在正式保存数据前,先调用医保政策提供商提供的函数验证,成功后,才保存正式的挂号或者已登记人员(在返回时一般可从函
8、数的返回值中获得病人的基本信息,该信息保存在医保中心)2、在程序设计中应该遵循的原则1)保证医保处理业务和 HIS 处理业务隔离开新增 yb_ybcl.pbl 放医保公用对象和数据;以后,只要替换此文件即实现医保变化。新增医保处理基对象 u_ybcl_base(基础类,负责和医保的业务调用),医保处理对象 u_ybcl(业务类,负责从 HIS 端获得和准备数据,以及与 HIS 端的交互操作)。HIS 端调用对象 u_ybcl 的方法(函数和事件),并提供必要的参数信息。2)若有医院和标准业务不同,请从 u_ybcl 对象继承3)需要修改 u_nbcl 对象和 yb_ybcl.pbl,请在修改后
9、,覆盖所有使用该 PBL 的地方,保持版本的统一,避免不必要的版本不相同而导致不能充分地共享代码。4)要书写上了医保后的表结构变化记录和字段变化记录。建议写成能直接执行的 SQL 语句,这样实施医保险的人,直接执行即可。避免让实施的人到 DBMS 上去修改。如,宁波医保的 SQL 如下:字段添加请参考 bshis2.x 宁波新医保_新增字段 适用于 Sybase or MsSql表的添加请参考 bshis2.x 宁波新医保_新增表 sybase 适用于 Sybase 11 or later或者 bshis2.x 宁波新医保 _新增表 sql70 适用于 Microsoft Sql Server
10、5)需要书写必要的注意事项,以便实施。可让工程技术人员阅读,知道其上医保系统。最主要的是说明“需要设置的基础数据”(包括了执行表结构修改和新增表的SQL 语句)如,可看bshis2.x 宁波新医保 _若干注意事项.txt6)代码中,对象的函数和事件命名要统一和规范化。如:事件的命名规范为:ue_mzgh_xxxx 门诊挂号相关的事件ue_mzsf_xxxx 门诊收费相关的事件ue_mztf_xxxx 门诊退费相关的事件ue_zydj_xxxx 住院(入院)登记相关的事件ue_zysf_xxxx 住院收费相关的事件ue_zytf_xxxx 住院退费相关的事件7)医保对象中,提供结算结果、个人信息
11、结构体等必要的实例变量(即对象属性)。可让 HIS 端在计算自负金额和打印用,以及其他处理的时候用。结算结果结构体中的信息有:自理金额、现金金额(就是自理金额+医保的现金支付部分)、本次结算总费用、结算后的帐户余额、其他必要的结算信息(如当前结算的类型等)、医保支付信息子结构体、各项目金额组成子机构体、个人信息子结构体等。具体需要多少信息可根据实际情况而定。下面是医保的结构体实例变量的说明:/=/ s_his_ybjsxx isu_ybjsxx 结算信息(可供 HIS 端打印发票是用)/=integer ghsf 结算类型 1 挂号 2 门诊 3 住院-2 门诊退费-3 住院退费integer
12、 jsbz 结算方式 0 普通 1 特病 2 家床string jzbz 普通/急诊 1 普通 2 急诊yb_ybfymx fymx 项目费用信息(在预结算时产生)decimal 2 zjje 当前结算费用总额decimal 2 fyje100 按医保归并得到的项目金额. 其他需要的项目费用数据yb_ybzfxx zfmx 支付结构(预结算后得到)子结构体(因为各个地区医保不同,内部项目具体命名可到时候实施的时候再修改)decimal 2 grzhzf 个人帐户支付decimal 2 gbjjzf 公补基金支付decimal 2 tczf 统筹支付decimal 2 jzzf 救助支付deci
13、mal 2 xjzf 医保现金支付decimal 2 qfdzhzf 起付段帐户支付decimal 2 qfdgbzf 起付段公补支付decimal 2 qfdxjzf 起付段现金支付decimal 2 tcdzhzf 统筹段帐户支付decimal 2 tcdgbzf 统筹段公补支付decimal 2 tcdxjzf 统筹段现金支付decimal 2 jzdzhzf 救助段帐户支付decimal 2 jzdgbzf 救助段公补支付decimal 2 jzdxjzf 救助段现金支付 decimal 2 xjzfa 现金支付 Adecimal 2 xjzfb 现金支付 Bdecimal 2 xjz
14、fc 现金支付 Cdecimal 2 grzhye 进行了当前结算后的帐户余额decimal 2 tfxjje 退费现金(0 补交),退费时用;一般不建议退费,而用隔日作废后重新结算decimal 2 zjje 当前结算的总计金额decimal 2 qzlje 当前结算的全自理金额decimal 2 xjzf 当前结算的医保现金金额decimal 2 xjje 当前结算的全部现金金额 = 当前结算的全自理金额 + 当前结算的医保现金金额decimal 2 zhye 进行了当前结算后的帐户余额string tsbbm 特病代码(不是特病结算无意义)string zcyydm 转目标医院代码(不是
15、转院结算无意义)/=/ s_his_jbxx isu_jbxx 病人基本信息(刷卡后获得)/=string knxx 卡内信息string brkh 病人卡号string bxhm 保险号码yb_ybgrxx grxx 个人信息子结构体string brxm 病人姓名string sfzh 身份证号string zhbz 帐户标志string dwdm 单位编码string qxdm 区县代码integer brnl 年龄integer brxb 性别string djbz 冻结状态 0 未冻结 1 已冻结datetime csny 出生年月decimal 2 zhye 帐户余额. 其他项目可
16、根据实际情况添加integer bz -1 表示刷卡未成功 否则成功8)调用方法参数用结构体或者 DATAWINDOW,避免很多的参数。若返回值有很多的信息,建议放在对象的结构体实例变量中。HIS 端要用的时候,再访问这个结构体实例变量即可。9)函数返回值类型单一化。成功/失败两种情况,其他的返回信息放在医保接口对象的实例结构体变量或者实例变量中。如:return integer = 1 成功 1 失败,对象的 is_errortext 变量保存了错误信息。10)对象内部之间调用,一般用对象的函数实现;供外部调用的,一般用对象事件实现。这样避免不必要的看到很多的函数或者事件,也搞不清楚哪些是内
17、部调用的,哪些是外部调用的,不易于程序维护和代码修改。11)代码书写风格请参考公司相关的开发文档。另外,注释一定要写的详细,注释的风格请参考 BHIS2.2 住院系统的风格。主要是代码中,要做阶段性的注释。每个块做写什么。这样,有利于整理看懂代码。12)一般不直接在原来的 HIS 代码上嵌入医保,需要定义事件和使用对象继承。需要继承的窗口有:结算确认窗口:w_hjsf_jscl (门诊确认)w_ghcl_jkcl (门诊挂号确认)w_zy_jsgl_jscl (住院结算确认)窗口命名方法,一般以: w_yb_xx_xxxx 或者: w_xx_xxxx_yb一般在祖先窗口中定义事件的调用次序,而
18、在继承的医保的窗口中,重载该事件。如果是 HIS2.21 或者以后的版本,住院系统一般用原来系统中的医保预留事件的定义。门诊系统到现在为止,一直没有医保预留事件,需要按下面的方式定义:下面的事件都是窗口事件,不是按钮或者是 DATAWINDOW 的事件。事件:ue_Pre_Dispose(), RETURN BOOLEAN预结算事件,用于医保结算请求费用计算事件:ue_Before_Dispose(),RETURN BOOLEAN在 HIS 的 gf_begin_transaction(sqlca)前做的工作事件:ue_On_Dispose(),RETURN BOOLEAN在 HIS 的 gf
19、_begin_transaction(sqlca)后在 gf_commit_transaction(sqlca)前做的工作事件:ue_After_Dispose() ,RETURN BOOLEAN在 HIS 的 gf_commit_transaction(sqlca)后做的工作至于到底是在 ue_Before_Dispose(),还是在 ue_On_Dispose(),还是在ue_After_Dispose()中处理医保代码,一般需要根据实际情况而定。以上三个事件,祖先的初始代码是:RETURN TRUE在继承的医保的窗口中,才实现具体的代码。下面已 BHIS2.21 的门诊系统的门诊收费确认
20、窗口的修改说明:门诊系统:w_hjsf_jscl:结算确认窗口修改1)新增实例变量 string is_errortext2)新增窗口事件 ue_Pre_Dispose、ue_Before_Dispose、ue_On_Dispose,return boolean三个事件的中,都增加 RETURN TRUE3)EVENT:OPEN:修改如下:。IF NOT event ue_Pre_Dispose() thenmessagebox(提示, is_errortext)gs_exchange.longparm1=-1close(this)returnend if id_yshj=iw_hjsf.id
21、_prefyhj+round(id_qtje,iw_hjsf.ii_decnum) /应收合计= 上次未收+本次合计sle_zjje.text=string(id_zjje,“0.00“)。3)EVENT:cb_ok.chicked 修改如下:。IF NOT event ue_Before_Dispose() thenmessagebox(提示, is_errortext)returnend if if not iw_hjsf.wf_save(il_jkfs,id_zhje,id_qtje) then /保存单据gf_rollback_transaction(sqlca)iw_hjsf.id_
22、fyhj = iw_hjsf.id_prefyhjmessagebox(“提示“,“保存数据出错,本次收费无效!“)elseIF NOT event ue_On_Dispose() thengf_rollback_transaction(sqlca)messagebox(提示, is_errortext)returnend if gf_commit_transaction(sqlca)IF NOT event ue_After_Dispose() thenmessagebox(提示, is_errortext)returnend if iw_hjsf.wf_ResetUpdate()debug
23、break()wf_create_fp() /生成发票信息并打印end if sle_pay.setfocus()门诊系统:继承 w_hjsf_jscl 得 w_yb_hjsf_jscl,存在 mz_ybcl.pbl 中,然后做后面的修改1)在界面中,新增 DATAWINDOW DW_YBJSXX,DATAOBJECT = “d_yb_jsxx”并调整界面为下面的样子:2)重载窗口 EVENT ue_Pre_Dispose,增下面的代码:/ Script - ue_pre_dispose for w_yb_hjsf_jscl inherited from w_hjsf_jscl/ Descri
24、ption: 医保预结算/ Returns: (BOOLEAN)/ Author: LIQW Date: 2002.03.14ib_ifyb = gu_ybcl.uf_ifyb(iw_hjsf.is_mzxx.id, 1)IF NOT ib_ifyb THEN RETURN TRUE/=/预结算数据准备/=gsu_mzjsxx.jsrq = gf_server_date() / 结算日期gsu_mzjsxx.czgh = base_info.userid / 操作工号gsu_mzjsxx.brid = iw_hjsf.is_mzxx.id / 病人的 ID 编号gsu_mzjsxx.mzhm
25、= iw_hjsf.is_mzxx.mzhm / 病人的门诊号码gsu_mzjsxx.fphm = iw_hjsf.st_fphm.text / 发票号码gsu_mzjsxx.dw_cf02 = iw_hjsf.dw_cf02 / 处方数据源gsu_mzjsxx.dw_yj02 = iw_hjsf.dw_yj02 / 检查单数据源gsu_mzjsxx.dw_sfxm = iw_hjsf.dw_sfmx / HIS 中的项目金额gsu_mzjsxx.dw_ybjsxx = dw_ybjsxx / 医保结算信息返回gsu_mzjsxx.ghgl = iw_hjsf.is_mzxx.ghgl / 挂
26、号关联/=/调用医保支持对象预结算函数/=if gu_ybcl.trigger event ue_mzsf_yjs(gsu_mzjsxx) 1 thengf_rollback_transaction(sqlca)is_errortext = gu_ybcl.is_errortextreturn FALSEend if end if RETURN TRUE13)务必保持两个事务的一致性。以前,很多地方的医保在开始做的时候,没有认真考虑此问题。很有可能导致到时候做报表的时候,数据不一致。一般将医保的业务放在 HIS 业务最后一条即 commit 之前。先做好 HIS 所有的业务,再做医保的业务。这样有个好处,万一医保失败了我们可以回滚 HIS 业务。如果医保的业务可能需要很长的时间,我们不能用两个事务一致的控制方法。一般先做好 HIS 的所有的业务并提交。然后在打发票前处理医保的业务,若失败则自动作废 HIS 业务,而不是回滚事务(这时 HIS 业务已提交)。湖州医保就是这样做的,可参考。