干预现场问题排查及解决方案
2024-02-22 15:46:14 21 举报
AI智能生成
在干预现场问题排查及解决方案过程中,首先需要对问题进行全面、深入的了解和分析。通过收集现场数据、观察现象、询问相关人员等方式,找出问题的根本原因。然后,根据问题的性质和严重程度,制定相应的解决策略。这可能包括技术改进、流程优化、人员培训等多种手段。在实施解决方案时,需要密切关注效果,及时调整策略,确保问题得到有效解决。同时,也要总结经验教训,防止类似问题的再次发生。整个过程需要团队协作,各司其职,共同推动问题的解决。
作者其他创作
大纲/内容
干预模块问题排查流程图
确定干预原因后 check list
1.规则跑的不正确
1)查看比对关系,规则图是否已审核,系统配置项‘干预’、‘引擎’
2)检查用户中心的用药提醒配置,或者直接在干预的数据查看页面点‘审’
3)查看干预的intervene_error.log,是否有报错导致干预异常
4)查看干预的intervene_trace.log,检查干预入参是否正确 grep “跑引擎”
5)查看引擎的engine_trace_request.log,检查预处理结果是否正确
一般来讲,在排除了1-3后规则跑不出来,可通过4-5来确定是干预的入参问题,还是引擎预处理的问题
2.数据查不到
1)查看干预的intervene_error.log,是否有报错导致干预数据入不了库
2)医院单日处方量是多少,可能因为请求量大导致数据入库慢,记录从发请求到入库耗时,上报到研发部门
3)查看redis日志,是否redis满了
切割是干预还是接口问题
https://shimo.im/docs/DhcQgdqtPVc8k6rY/ 《接口事中数据主要处理逻辑》
有逻辑改动的注明了版本。早一点的,重点关注检验时间、诊断时间、过敏时间这些
有逻辑改动的注明了版本。早一点的,重点关注检验时间、诊断时间、过敏时间这些
如果是干预问题,基本步骤:点审/界面取xml拿到处方评估测/看接口转的数据
常见问题汇总
后台报错相关处理
药品跑不出警示信息
查看后台报错,是否有提示:lsu和axaiu等单位问题 会造成但凡有这批药的患者所有干预跑不出
解决方案:升级到0930fix最新版本
或者:修改tb_product相关表中问题药品的单位,并重启知识建设和引擎服务(问题药品搜集并反馈给知识部进行修改,否则下次更新知识包后,问题仍然会出现)
或者:修改tb_product相关表中问题药品的单位,并重启知识建设和引擎服务(问题药品搜集并反馈给知识部进行修改,否则下次更新知识包后,问题仍然会出现)
干预数据查看和效果分析的统计结果不一致
排查思路:查看后台报错信息,是否存在字段超长等影响入库的信息
解决方案:将相关his数据提交研发进行分析,库表结构调整
页面报错相关处理
干预、分析出现检索报错现象
排查 询问时请根据:
【个别还是全部、点击报还是等了一段时间】
【个别还是全部、点击报还是等了一段时间】
关键词带%检索-已处理
手动修改过科室表数据(包括增删改查 导致管理科室获取报错-warn日志里会有特征报错
930开启了安全漏洞配置时出现 - 系统bug已处理,十一月后干预包都包含这一修复
个别页面报错:入库失败,关联查询明细为空-)干预历史版本出厂不是所有sql报错都打error,所以没日志不说明就不是入库失败。可以直接查表 根据列表的ipt/opt_id关联其他表
干预,页面进警示信息汇总菜单就马上报错,其他查看正常的,且干预error无内容的
可以看下tomcat日志catalina,有相关服务节点调用不到的,重启下知识建设(即使知识建设进程在)因为警示信息汇总一进就查知识建设dubbo接口
页面提示:您可能没有该路径的访问权限!
查看干预日志
查看干预日志:error、warn、tomcat
/data/soft/apache-tomcat/logs目录下查看catalina.out或者localhost-当天日期.out,如:localhost-2022-07-15.out
查看是否用户中心报错少short_name,配置角色权限菜单 少某些报表和规则模块,一般是漏了用户中心630增量脚本(见过几次)补刷下就行
干预打开药品明细提示错误(0630已修复)
查看入参是否增加了无法识别的字样、特殊字符
如:检验结果是阴性、阳性、异常结果、>10 、<0.9
规则审查相关处理
给药剂量单位选择iu,会跑否 RED4-7315
问题原因:知识部定的返回标准单位是u,所以引擎返回是u,跑否
解决方案:iu和u不一样,用匹配画规则,会取原始值
合并历史处方排查思路(推荐使用接口配置跨就诊模式,干预自身合并逻辑问题较多)
4.0支持 门诊对一个患者,跨就诊处方合并审查功能
场景一:his把历史处方合并好给我们(正常场景)开启方式
业务系统-用户中心-参数设置-干预部分-门诊干预规则警示适用对象:配置“3:按跨就诊“
场景二:如需要我们来合并,开启步骤
step1:开启【缓存历史处方数据】,开启后,历史数据会按照病历号patientId缓存。所以在功能使用前需提前开启
step2:开启【是否合并历史处方数据】 并同时确认:业务系统-用户中心-参数设置-干预部分-门诊干预规则警示适用对象:配置“3:按跨就诊”,接口开启同时业务系统用户中心也需开启并同时生效,单独开启一个会造成错误
step3:设置【门诊干预合并几天历史处方数据】注意这里天数实际作用还受到 公共部分及患教配置 - 第8条 - redis缓存失效时间 配置项影响,该配置项默认值已改为7天。
查看统一接口给干预的历史药嘱打标记是否正确
根据原有统一接口-干预配置项-第15条,干预增量需要处理的数据类型 这一项的启用/禁用情况。
启用:接口程序配置处方增量,会直接合并redis中所有数据。
禁用:接口程序配置处方全量。会合并缓存中前几天的的数据
启用:接口程序配置处方增量,会直接合并redis中所有数据。
禁用:接口程序配置处方全量。会合并缓存中前几天的的数据
合并审查相关日志文件路径:logs/merge_debug.log。
是否怀孕、是否哺乳、是否透析等入库跑引擎点审原因定位
页面展示的有的“false”有的“否”场景确认
入参怀孕/哺乳传的false时,点审跑引擎存在给反了情况
如果库里是false,去跑也应该是false 比如kf_opt表(改成空就不跑了 false的话 跑的true)
(现在是库里如果不包含“否”字就算true意思吗。有时候第一次引擎返回异常 会存false)
疗程问题
按照患者查看,大包装1盒的药品,自己算的疗程,跑出疗程的规则
问题原因:现场为干预按患者模式,也就是干预合并缓存里。那么,会把前一张处方 跑出来的疗程6.67天当做传入值
第二次跑时直接疗程天数传入值大于3天,不会走不超过一个包装逻辑。只有无传入值,采用引擎计算值才有这个
第二次跑时直接疗程天数传入值大于3天,不会走不超过一个包装逻辑。只有无传入值,采用引擎计算值才有这个
解决方案:需要把配置改为按统一接口合并 跨就诊 合并0天即当天,这样也是合并当天处方的效果
his没传疗程字段,合理用药没有自动计算出疗程(疗程没有计算)
排查流程:查看引擎trace日志中疗程字段“duration”是否有返回,字典中给药频率是否正确比对
原因:给药频率字典导入时,code和dict_value不一致,导致引擎取不到比对后的标准值,疗程就不计算了
解决方案是:将base_dictionary表中category_code=sys_route_freq字典的code赋值给dict_value,
然后重启知识建设和引擎服务
然后重启知识建设和引擎服务
配伍问题
干预同组配伍/溶媒问题
主药和副药干预界面上点开的primary字段,一个是true一个false这样有问题
如果两个都改true测试不会提示
正常一组肯定是两个都true的,虽然现在这样引擎跑也不算合理,但同组一个主审一个非主审不在引擎设计范围内
接口1210起加了同组一定同时true或false的一层
换最新接口可以解决
干预溶酶多余报/重复用药等问题 看下跑出来数据同组是否一个true一个false,这样跑引擎有问题,解决换个1210以后接口程序
事中跑没跑出溶媒或配伍提示有疑问
1)事中没跑出,事后跑出了,发药数量作为关键字段没传会导致接口报错 —— 看入参despensing_num,如果his该字段无意义则固定传1,传0或传空干预审方都跑不了
2)干预对溶酶和主要打的是否主审标记不同导致没有正常跑 —— 看干预3.0xml的primary字段
3)审方切片原因导致没有同组一起跑 —— 溶酶和主药组号是否相同,生效失效时间是否相同
4)溶媒和主药是否同个xml传入,是否存在单药调用了删除 —— 看接口入参文件
干预门诊-按患者-当天处方没有跑出重复用药
门诊患者查看页面,处方是否合并
患者查看页面合并了没有跑出重复用药规则,排查是否规则绘制有问题
患者查看页面没有合并
查看是否第一张处方已经失效
第一张处方没有失效
查看第一张处方是否在缓存中存在
不跑或多跑
住院临时医嘱跑规则有警示信息,长期医嘱不跑警示信息
1、查看xml中医嘱失效时间“order_invalid_time”是否在当前时间之前,已经失效。短期医嘱不受失效时间影响,长期医嘱失效后,数据会给干预,valid会显示flase
2、若已经失效,则更改order_invalid_time失效时间,需要晚于当前时间,或者不填
干预跑出了过去多余的医嘱或警示信息
step1 确认接口系统里,干预相关配置是否正确(参见接口专项文档之合并历史相关操作)
step2 根据患者号和时间,找到接口给到干预的那份数据详情xml里,是否包含了多余数据。该数据和接口配置项是否一致
在审方/干预中该跑出来的警示信息没跑出来、跑出了多余警示信息
step1 根据患者号和时间,处方/医嘱号,在校验工具里检索到对应接口给到审方/干预的数据
step2 找到药品对应的规则,结合上述xml数据 确认是否确实当前审核组,应该跑出该信息
step3 如果确认数据和规则都正确,作为审方/干预问题上报
step4 如果数据本身缺失或错误,进一步查看接口收到的外部调用;如果规则问题,调整规则或和药学老师确认;如果对规则具体运行逻辑,请咨询知识建设和引擎的产品
干预和审方审查结果不一致
通用排查思路
step1 根据患者号、处方/医嘱号和时间,查找接口校验工具(2.5接口的话后台看接口日志、备份文件)对应数据是否同时有正常给到干预和审方,并确认相关配置。包括相应明细内容是否有发过删除接口、数据有效接口等
step2 点击详情,查看具体给到干预和审方xml是否在有疑问的数据项上完全一致
step3 如不一致(一般不会),结合接口配置情况后还有疑问的可作为接口支持问题上报;
step4 如接口给到审方和干预的入参一致,查看审方和干预界面显示数据是否和入参一致
(这一步也可以去取审方、干预 跑引擎日志(双方关键词都是“引擎”),日志的跑引擎入参和出参打印的都很清楚。将其放到格式化工具去对比,哪些字段不同,是否能解释具体的警示信息不同原因【这里需要结合该药品规则】。通常可能是一个字段,传了同个含义但不同的值)
step5 校验工具展示的内部调用数据和干预/审方里数据项显示不同、则可作为相应干预或审方问题上报(这种,基本没有在我了解到的所有排查最终结果出现过)
干预接口存在药品合并跑出警示信息,审方这个药品已停不合并
排查思路:检查下统一接口-干预-长期医嘱有效时间范围配置 和审方-用户中心-搜“预停”配置是否绝对值一样
干预漏8级问题排查(审方发现8级)
step1 根据患者号和时间,查找干预里是否有这条数据,对应警示信息等级是否正确
step2 如果干预没有,根据患者号和时间,在校验工具(2.5接口的话后台看接口日志、备份文件)查找对应对数据是否内部给到了干预
step3 点击详情,具体查看xml内容和是否有已明确打印出的报错原因
step4 如果校验工具(2.5接口的话后台看接口日志、备份文件)展示了内部没有给到干预,在确认没有相关配置项影响到后,再作为接口问题上报;
【如果校验工具展示了已正常给到干预,进一步查看干预和审方日志】
【如果校验工具展示了已正常给到干预,进一步查看干预和审方日志】
step5 日志里,grep出对应患者去跑引擎的入参:分别在干预、审方日志里找
重点看:1.分别合并了几个药去跑,2.分别有没有报错,3.去跑的检验诊断等是否相同
step 6 根据找到的原因,解释给院方,对确实是我们问题的再上报干预/审方bug
(注:不经过以上步骤,提供日志、xml等信息,单纯一个截图,测试可以退回oa单)
干预住院没跑出适应症规则(审方跑了)
1)诊断数据发的GY_SF_V4,但干预发审方数据没有勾选ipt_diagnoses导致审方没收到
看审方库诊断表sf_ipt_diagnoses里有没有这一数据,和接口的审方配置 打通启用和发送类型
2)下诊断时间是否比开药时间迟,或者诊断时间这一字段传值格式有问题,历史版本对不是在处方时间前开的诊断不转给干预,但对审方不受影响 —— 看入参diag_date和order_time
3)数据干预和审方都收到了,界面显示也都本次去跑了,干预是名称和编码分开跑,审方一起跑引擎预处理 —— 看his发的诊断名称和诊断编码,比对信息是否指向同一个
4)his诊断增量传(只传本次新增或删除),和接口配置不符 —— 确认接口-干预-增量数据类型没选诊断,以及接口的审方全量转增量配置没开诊断
引擎报错导致干预审方跑的不一致
草药疗程duration 数量herb_packet_count 对接不要传“x付” 直接n
干预警示信息正常返回,但干预页面查不到记录(部分表没存进去)
日志grep "insert into" *.log
干预,Pay_Type容易报超长(接口文档和代码里都是32位)但很多现场早期装的实际是8位,很容易超。
干预是先返回再异步入库,尽量都检查下,干预处方明细表
干预效果分析相关处理
3.3干预效果分析没数据
日志位置:/data/yysoft/workspace/logs
查看cluster-name配置是否一致
170服务器为例:1、进浏览器查看cluster_name10.1.1.170:9201【es内部端口是9301,不用改9201
】
】
2、看配置的是不是一致:位置/data/yysoft/elasticsearch-5.1.1/config【或者/data/elasticsearch-5.1.1/config】
3、进入elasticsearch.yml查看cluster_name
需要一致
文件导出功能异常
排查思路:minio进程是否存在;minio版本是否正确;后台是否有报错
点评、干预下载文件,稍大的,导出失败,网络错误
(不管日志报错哪种) 试试nginx改配置,client_max_body_size 20m; 后面的20M可以调整大小,改完要重启nginx
vim /data/soft/nginx/conf/nginx.conf
找到 http { …… client_max_body_size 20M; …… //没有的加上(如果出厂原默认值看到是1024M的,也不行,要改小成10m或20m的)
/data/soft/nginx/sbin ./nginx -s reload重启
干预数据不入库
情况1:入库失败
看error日志和检查入参看校验,例如pay_type、处方号等字段超长
情况2:干预是先跑规则返回警示流程走完(临时存放redis),再从redis把数据异步入库到mysql(不入库也不影响返回)
可以看warn日志提示,如果超过同一时间最大线程数,为不卡业务,那部分数据作丢弃处理(原来1000,930最新包是5000)正常大医院业务高峰也不会超
情况3:统一接口配置的干预地址不正确
运营平台菜单漏加载
若通过运营平台已经勾选的菜单,通过激活工具激活后,仍然没有加载功能菜单
可以先进入运营平台取消对应菜单前的勾选,然后保存后勾选指定的功能菜单
重新导入激活包后再重新启动用户中心程序
升级少菜单重激活也不行的(主要少报表、知识建设增值规则的),看是不是漏脚本,补刷下
跨就诊疗程问题
跨就诊 合并 历史处方疗程没有算出来导致没过滤多余合并跑重复用药类问题检查:
0.如果是221228fix,先换到最新包 再观察;
1.看历史处方单张,在当时的门诊处方查看里,是否有算出疗程——如没有。疗程计算问题。检查疗程计算参数:包装 数量 剂量 规格等
例如 标准产品规格是否无法计算(规格里是否特殊 多个单位 成分,复方字样 等)
2.确认转换规格维护正确(如果是出厂带的,没问题;如果是自己额外维护的,因代码bug只在230626、0928会导致无效 无法计算。这一问题仅在231222fix有修复 换包或升级)
3.确认频次、药品比对;不存在带括号的数量、一次性等特殊频次;确认药品剂型对应疗程公式
4.排除以上所有情况:进入 http://10.1.1.184:9999/helper/ 页面 查询对应产品缓存 找出为什么没计算,使用方式参见 http://confluence.ipharmacare.net/pages/viewpage.action?pageId=49255829
5.如有疗程——提供第二次有问题的,多余合并的,干预页面上拿的3.0 xml数据提oa。提oa时除了干预3.0入参数据 最好附跑引擎日志,获取方式教程:http://confluence.ipharmacare.net/pages/viewpage.action?pageId=28378076
6.增加 检查干预error日志、引擎error日志
7.只根据计算疗程进行历史医嘱过滤,不取疗程原始值(240329修复)
0.如果是221228fix,先换到最新包 再观察;
1.看历史处方单张,在当时的门诊处方查看里,是否有算出疗程——如没有。疗程计算问题。检查疗程计算参数:包装 数量 剂量 规格等
例如 标准产品规格是否无法计算(规格里是否特殊 多个单位 成分,复方字样 等)
2.确认转换规格维护正确(如果是出厂带的,没问题;如果是自己额外维护的,因代码bug只在230626、0928会导致无效 无法计算。这一问题仅在231222fix有修复 换包或升级)
3.确认频次、药品比对;不存在带括号的数量、一次性等特殊频次;确认药品剂型对应疗程公式
4.排除以上所有情况:进入 http://10.1.1.184:9999/helper/ 页面 查询对应产品缓存 找出为什么没计算,使用方式参见 http://confluence.ipharmacare.net/pages/viewpage.action?pageId=49255829
5.如有疗程——提供第二次有问题的,多余合并的,干预页面上拿的3.0 xml数据提oa。提oa时除了干预3.0入参数据 最好附跑引擎日志,获取方式教程:http://confluence.ipharmacare.net/pages/viewpage.action?pageId=28378076
6.增加 检查干预error日志、引擎error日志
7.只根据计算疗程进行历史医嘱过滤,不取疗程原始值(240329修复)
辅助测试or现场应急临时修改调整相关
处方评估里,医院自己测试时,需要添加多条检验信息的
<exams><exam_item><exam_km></exam_km><sample_name>血液</sample_name><exam_item_name>CYP2C19*2(681G>A)</exam_item_name><exam_item_result>AA</exam_item_result><exam_item_std></exam_item_std><exam_item_unit></exam_item_unit></exam_item><exam_item><exam_km></exam_km><sample_name>血液</sample_name><exam_item_name>CYP2C19*3(636G>A)</exam_item_name><exam_item_result>GG</exam_item_result><exam_item_std></exam_item_std><exam_item_unit></exam_item_unit></exam_item><exam_item><exam_km></exam_km><sample_name>血液</sample_name><exam_item_name>CYP2C19*17(-806C>T)</exam_item_name><exam_item_result>CC</exam_item_result><exam_item_std></exam_item_std><exam_item_unit></exam_item_unit></exam_item></exams>
干预去掉弹框
“查看当日处方/data/soft/apache-tomcat/webapps/intervene/page/zlcx/returnInfo_v2.jsp
定时删非关键数据
对个别大医院,医嘱处方和警示信息需要全保留 但又要控制存储的,可以设置干预/审方每天凌晨定时清理任务。这些确认过页面不会报错
USE ipharmacare_intervene;DROP EVENT IF EXISTS delete_gy_data;DELIMITER //CREATE EVENT delete_gy_dataON SCHEDULE EVERY 1 DAY STARTS DATE_ADD(DATE(CURDATE()+1),INTERVAL 1 HOUR)ON COMPLETION PRESERVEDO BEGINdelete from kf_opt_xml where key_time < DATE_ADD(NOW(),INTERVAL -30 DAY); -- 删一个月前入参xml备份表delete from kf_ipt_exam_item where key_time < DATE_ADD(NOW(),INTERVAL -180 DAY); delete from kf_ipt_exam where key_time < DATE_ADD(NOW(),INTERVAL -180 DAY);delete from kf_opt_exam_item where key_time < DATE_ADD(NOW(),INTERVAL -180 DAY);delete from kf_opt_exam where key_time < DATE_ADD(NOW(),INTERVAL -180 DAY); -- 删半年前门诊住院检验 只删明细也行delete from kf_ipt_diag where key_time < DATE_ADD(NOW(),INTERVAL -180 DAY); END//DELIMITER ;
USE ipharmacare_auditcenter_full;DROP EVENT IF EXISTS delete_sf_data;DELIMITER //CREATE EVENT delete_sf_dataON SCHEDULE EVERY 1 DAY STARTS DATE_ADD(DATE(CURDATE()+1),INTERVAL 3 HOUR)ON COMPLETION PRESERVEDO BEGINdelete from sf_xml where key_date < DATE_ADD(NOW(),INTERVAL -30 DAY); -- 删入参xml备份表(本就是冗余数据)delete from sf_ipt_exam_item where key_date < DATE_ADD(NOW(),INTERVAL -180 DAY); delete from sf_ipt_exam where key_date < DATE_ADD(NOW(),INTERVAL -180 DAY);delete from sf_opt_exam_item where key_date < DATE_ADD(NOW(),INTERVAL -180 DAY);delete from sf_opt_exam where key_date < DATE_ADD(NOW(),INTERVAL -180 DAY); -- 删半年前门诊住院检验 只删明细也行delete from sf_ipt_vital_sign where key_date < DATE_ADD(NOW(),INTERVAL -180 DAY); -- 删半年前住院生命体征delete from sf_ipt_diagnose where key_date < DATE_ADD(NOW(),INTERVAL -180 DAY); END//DELIMITER ;
干预数据量大查不动
干预库里带的有迁移几个月前数据定时任务,确认下有没有开(数据库 定时任务 开关)-现象:明细页打不开
换nextcloud上930或331最新包,都有处理。可以在demo4体验下,跨一段时间都 不会出现查询超时报错了
干预-查看明细-查询超时报错的,数据库对门诊处方 门诊患者 住院添加如下索引 -现象:按药品查不动
CREATE INDEX opt_group_no ON kf_opt_summary(opt_group_no);
CREATE INDEX opt_patient_group_no ON kf_opt_patient_summary(opt_group_patient_no);//门诊患者
CREATE INDEX ipt_group_no ON kf_ipt_summary(ipt_group_no);
CREATE INDEX opt_group_no ON kf_opt_summary(opt_group_no);
CREATE INDEX opt_patient_group_no ON kf_opt_patient_summary(opt_group_patient_no);//门诊患者
CREATE INDEX ipt_group_no ON kf_ipt_summary(ipt_group_no);
干预老版本门诊患者查询超时
可以加下面索引。按处方正常,20年9月以后版本默认已加
/**给患者处方表,患者号字段添加索引*/USE ipharmacare_intervene; 3.3的3话ALTER TABLE `fy_opt_patient_recipes` ADD INDEX `idx_opt_patient_id` (`opt_patient_id`);ALTER TABLE `gh_opt_patient_recipes` ADD INDEX `idx_opt_patient_id` (`opt_patient_id`);ALTER TABLE `kf_opt_patient_recipes` ADD INDEX `idx_opt_patient_id` (`opt_patient_id`);ALTER TABLE `pz_opt_patient_recipes` ADD INDEX `idx_opt_patient_id` (`opt_patient_id`);ALTER TABLE `sf_opt_patient_recipes` ADD INDEX `idx_opt_patient_id` (`opt_patient_id`);ALTER TABLE `tx_opt_patient_recipes` ADD INDEX `idx_opt_patient_id` (`opt_patient_id`);ALTER TABLE `zx_opt_patient_recipes` ADD INDEX `idx_opt_patient_id` (`opt_patient_id`);
门诊患者不合并
干预redis存在脏数据,清理redis脏数据后恢复正常
接口发干预耗时较长
排查思路:查看接口调用日志;查看内存使用情况;关swap
干预除了 error日志,warn日志看过没有,引擎的error日志有没有,warn日志有没有看,Tomcat请求日志access有没有,catalina.out有没有
也可以看看data/logs/gc/engine
data/logs/gc/tomcat
data/logs/gc/tomcat
接口干预返回超过5秒还正常返回了警示信息
在其他常规排查基础上可以看看是不是接口cpu高
首先显示线程列表
ps -mp pid -o THREAD,tid,time
其次将需要的线程ID转换为16进制格式
printf "%x\n" 31606
最后打印线程的堆栈信息
jstack 31212 |grep 31606-A 30
cpu一直高,一般就是出现了死循环 —— 开发
干预是否有一个患者药过多sql
干预查询sqlselect patient_id,recipe_time,recipe_doc_name,count(1) from kf_opt_recipe where key_time = '2021-01-19' group by patient_id having count(1) > 15
历史项目满了,临时降100%恢复处理
干预、审方 带“ipt/opt_xml”表最大,且无任何业务影响!可直接整表删 trancate table就行正常表数据清理后空间没释放的:可以执行
OPTIMIZE NO_WRITE_TO_BINLOG TABLE 表名
临时不换包 解决干预带药品条件查询慢
(原因 sql跨库):知识建设库base_product表增加product_id和product_name联合索引,alter table `ipharmacare_knowledge`.`base_product` add index `chaxun` (`product_id`,`product_name`) 能提高不少 至少不止能查几天 要是还不行的话,可以看现场版本 具体沟通换包
安装升级问题汇总
21年版本(推荐升级到210930fix最新版本再排查)
所有210630、210930医院,如果干预数据是从3.3、3.5升过来的,看下干预包的具体时间点或医院有过数据迁移的,都需要换成21年10月份之后的(nextcloud上有)避免干预数据误删
升级到0930版本干预页面报500,210930-fix版本xssfilter 业务逻辑报错,干预需要更换重新打包 210930-fix4.RELEASE
干预启动,界面显示启动不了
缺少es的 host配置
单干预项目,只激活了干预没有激活点评,干预启动不成功
解决方案:tomcat webapp下点评包移出去
22年版本(推荐升级到221228fix最新版本再排查)
0331版本干预启动异常
1、先检查一下tomcat服务是否正常,若查看tomcat进程异常时,查看一下catalina.out的权限是yyuser 权限还是root权限。若后台服务显示的为root权限,则将root权限改为yyuser权限。
2、执行命令:chown R yyuser:yyuser /data/soft/apachetomcate/logs
23年版本(推荐升级到231222fix最新版本再排查)
升级到4.0230330/4.0.230630,干预打开报404,tomcat日志报错提示Unable to complete the scan for annotations for web application [/intervene] due to a StackOverflowError. Possible root causes include a too low setting for -Xss and illegal cyclic inheritance dependencies. The class hierarchy being processed was [org.bouncycastle.asn1.ASN1EncodableVector->org.bouncycastle.asn1.DEREncodableVector->org.bouncycastle.asn1.ASN1EncodableVector
解决方案:根据百度在tomcat的conf目录里面catalina.properties的文件中vim conf/catalina.properties 在tomcat.util.scan.StandardJarScanFilter.jarsToSkip=里面加bcprov*.jar 过滤忽略,就不报这个错了
redis查看和数据删除
soft/redis/bin
./redis-cli -h {{ip}} -p 6379 -n 13 -a ipharmacare
./redis-cli -h {{ip}} -p 6379 -n 13 -a ipharmacare
(这里ip是 redis所在ip,也就是应用服务所在的 一般写127.0.0.1也可以 连不上的话要写ip如果审方和其他应用分开部署,这个ip指的是其他应用的)
redis的库13是接口 3是审方(审方一般查权限 应用问题 没事别删)干预和用户中心在0,清干预的话,0库清了,最好重启下用户中心-a 后面是密码 一般是ipharmacare
soft/redis/bin
./redis-cli -h 10.1.1.173 -p 6379 -n 13 -a ipharmacare
./redis-cli -h 10.1.1.173 -p 6379 -n 13 -a ipharmacare
select 0
flushdb
ES问题汇总
从4.0.221020版本开始已经去ES,若还是21年的版本,统一建议先升级到210930fix,再进行复现和排查(22年只维护4.0.221228fix)
ES通用排思路
es常用操作(没有这些解决不了的es报错)
看进程在不 浏览器输入 http://ip:9201/
如果查看到有red的 建议删除 red无法访问
查询某一个索引 curl 'http://10.1.1.110:9201/_cat/indices/sf_opt_result_202108'
删除干预或审方某月索引 curl -XDELETE 'http://10.1.1.110:9201/kf_stat_opt_202205'
模糊删除(全删完要恢复工具恢复)curl -XDELETE 'http://10.1.1.110:9201/kf_*'
或 重启es
检查名称是否和配置文件对 cluster_name
查看审方 curl 'http://ip:9201/_cat/indices/sf*'
查看干预 curl 'http://ip:9201/_cat/indices/kf*'
查看干预 curl 'http://ip:9201/_cat/indices/kf*'
es数据处理
(干预效果分析 首页数据 审方报表统计 旧版事后报表)
(只要没有想象不到的异常操作,是不需要搞这些的!)
(只要没有想象不到的异常操作,是不需要搞这些的!)
es数据保存在/data/data/es-data 想备份的可以先备份下
浏览器进9201端口 会显示使用的是否这台服务器上es
查看索引 curl http://ip:9201/_cat/indices 双机部署注意ip
删除索引 curl -XDELETE 'http://ip:9201/要删除的索引名称,支持带*模糊匹配
比如干预的话一般是curl -XDELETE 'http://ip:9201/kf*
es导致启动报错处理
医院不对历史统计过分较真的,GY*全删了算了
如果非要保留数据,更改字段类型参考思路:
新建索引 给新索引mapping设定字段类型 旧索引数据 -> 新索引 删除旧索引,新建删掉的原名称索引,设置新的字段类型 把刚才索引的数据->原名称索引 删掉过渡索引具体操作百度或https://blog.csdn.net/weixin_43508544/article/details/104052231
(0326版本)干预统计为0,es数据问题
【干预概要统计无数据】
【干预概要统计无数据】
1.问题原因:代码是由于0202版本需求增加引入偶现bug,所以0326出现较多
2.现场处理:产生问题期间数据必须删除,即使问题修复升级后,包含错误数据也要删
3.操作:服务器任意目录:注意时间月份,opt/ipt 自己换下
curl -XDELETE 'http://10.1.1.120:9201/kf_stat_opt_202107'
4.操作影响:删除索引数据是按月的,可以先删7月,等数据更新后还有问题或还有报错(日志如下图),再往前面月份删除,注意门诊和住院都要删。
干预效果分析,对应月份数据删除后就没有了。但干预效果分析数据原始来自数据库,都在的,所以如果后面医院必须要,既可以单月份的sql从数据查一下,也有干预报表恢复工具,所以不用非备份几十g的es_data数据,也不用太担心这个操作把干预统计没了
5.处理后,首页数据为按小时更新,干预里面概要等数据,按天更新,所以不是实时出来的
6.在630正式外发版,这一问题已处理,不会再出现。如果0326,删了后面还有可能出来
干预报表重新生成工具
http://confluence.ipharmacare.net/pages/viewpage.action?pageId=23694570
干预效果分析统计sql汇总
http://confluence.ipharmacare.net/download/attachments/23694570/%E5%B9%B2%E9%A2%84%E6%95%88%E6%9E%9C%E5%88%86%E6%9E%90%E6%9F%A5%E8%AF%A2sql%E6%B1%87%E6%80%BB.sql?api=v2
检查应急时直接修改干预审方es(索引)统计数据方法
查看索引数据(就跟想直接看数据库里一样)
浏览器输入 http://ip:9201/索引名称/_search
查看 某个索引中指定数据 postman请求
GET /ipt_efficiency_analysis_202205/_search
body里json填入 {“size":{"size":0,"aggs": {"auditTime": {"stats": {"field":"auditTime"}}}}}
删除. 例如批量操作所有 <0的审核时间
POST http://ip:9201/索引名_可带*模糊/_delete_by_query 请求body里填
{"query":{"range": {"auditTime": {"lte": 0} } } }
查询 例如小于0的 取回参的index和_type,id
GET /ipt_efficiency_analysis_*/_search
{"query":{"range": {"auditTime": {"lte": 0}}}}
修改 es索引中指定某个数据的值
POST :9201/索引名/opt_analysis/123/_update
{"doc":{"auditTime": 0}} //中间123就是取的id
即:/索引名后/类型:/{{_type}}/{{id}}/_操作
干预次数占比超100%(这种情况应该很少)
出现原因:干预效果分析-概要统计-住院-因为如果是和非主审组跑出相互作用,在审查次数算1,干预次数算2
为es稳定,统计逻辑一般不动,有遇到的可以换下文件,前端展示处理了
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<script type="text/javascript" src="<c:url value="/uistyle/echarts/2.2.7/build/dist/echarts.js"/>"></script>
<style>
.targ-btns {
height: 30px;
margin: 10px;
}
.targ-btns span {
display: block;
width: 60px;
height: 28px;
border: 1px solid #ccc;
float: left;
text-align: center;
line-height: 28px;
cursor: pointer;
}
.targ-btns .btn-l {
border-right: 0;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.targ-btns .btn-l._checked {
border-color: #2db8f7;
border-right: 1px solid #2db8f7;
color: #2db8f7;
}
.targ-btns .btn-r {
border-left: 0;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
.targ-btns .btn-r._checked {
border-color: #2db8f7;
border-left: 1px solid #2db8f7;
color: #2db8f7;
}
input[type=radio]{
margin-left:20px;
margin-right:2px;
}
</style>
<div id="${jsns}quickMenu"></div>
<div id="${jsns}maingrid" style="margin:0; padding:0"></div>
<div class="targ-btns">
<span class="btn-l _checked">柱状图</span>
<span class="btn-r">趋势图</span>
</div>
<div style="display: none; text-align:center;color:#669;font-size:12px;font-weight:bold;font-family:微软雅黑 黑体 Arial;" id="${jsns}divPerType">
<input name="${jsns}perType" type="radio" value="0" checked/><span>${('num' eq pageType ) ? '医生修改处方占比' : '更换药物占比'}</span>
<input name="${jsns}perType" type="radio" value="1"/><span>${('num' eq pageType ) ? '干预占比' : '修正错误占比'}</span>
<input name="${jsns}perType" type="radio" value="2"/><span>${('num' eq pageType ) ? '拦截占比' : '忽略错误占比'}</span>
<input name="${jsns}perType" type="radio" value="3"/><span>${('num' eq pageType ) ? '无问题处方占比' : '删除处方占比'}</span>
</div>
<div style="display: none; text-align:center;color:#669;font-size:12px;font-weight:bold;font-family:微软雅黑 黑体 Arial;" id="${jsns}divIptPerType">
<input name="${jsns}perIptType" type="radio" value="1" checked/><span>${('num' eq pageType ) ? '干预占比' : '修正错误占比'}</span>
<input name="${jsns}perIptType" type="radio" value="2"/><span>${('num' eq pageType ) ? '拦截占比' : '忽略错误占比'}</span>
<input name="${jsns}perIptType" type="radio" value="3"/><span>${('num' eq pageType ) ? '无问题占比' : '删除占比'}</span>
</div>
<div id="${jsns}main" style="height: 450px;width:95%; "></div>
<div id="${jsns}main_line" style="height: 450px;width:95%;display: none; "></div>
<script type="text/javascript">
$(function () {
var qm = new quickMenu("${jsns}quickMenu").init();
var summaryRow = {test: '123'};
var pageTypeSet = {
handle: {
url: '<c:url value="/module/gy/recipeAnalysisRecipeHandle.action"/>',
columns: [
{display: '处方总数', name: 'total', minWidth: 80, width: 80},
// {display: '审查总人次', name: 'patientNum', minWidth: 80, width: 80},
{
display: '更换药物',
columns: [
{display: '处方数', name: 'recipeChangeDrugNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeChangeDrugNumPer', minWidth: 80, width: 80}
]
},
{
display: '修正错误',
columns: [
{display: '处方数', name: 'recipeCorrectNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeCorrectNumPer', minWidth: 80, width: 80}
]
},
{
display: '忽略错误',
columns: [
{display: '处方数', name: 'recipeIgnoreNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeIgnoreNumPer', minWidth: 80, width: 80}
]
},
{
display: '删除处方',
columns: [
{display: '处方数', name: 'recipeDeleteNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeDeleteNumPer', minWidth: 80, width: 80}
]
}/* ,{
display: '双签名确认',
columns: [
{ display: '处方数', name: 'recipeSignNum',minWidth:80,width:80 },
{ display: '占比', name: 'recipeSignNumPer',minWidth:80,width:80 }
]
} */]
},
optNum: {
url: '<c:url value="/module/gy/recipeAnalysisRecipeNum.action"/>',
columns: [
{display: '处方总数', name: 'total', minWidth: 80, width: 80},
{display: '审查次数',minWidth: 80, width: 80, name: 'reviewCount'},
{
display: '干预',
columns: [
{display: '干预处方数', name: 'recipeGyNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeGyPer', minWidth: 80, width: 80},
{display: '总金额(万元)', name: 'infoFeeTotal', minWidth: 80, width: 90},
{display: '干预次数', name: 'recipeGyCount', minWidth: 80, width: 80},
{display: '占比', name: 'recipeGyCountPer', minWidth: 80, width: 80},
]
},
{
display: '拦截',
columns: [
{display: '拦截处方数', name: 'recipeInterceptNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeInterceptPer', minWidth: 80, width: 80},
{display: '总金额(万元)', name: 'nosaveFeeTotal', minWidth: 80, width: 90},
{display: '拦截次数', name: 'recipeInterceptCount', minWidth: 80, width: 80},
{display: '占比', name: 'recipeInterceptCountPer', minWidth: 80, width: 80},
]
},
{
display: '医生修改处方',
columns: [
{display: '修改处方数', name: 'recipeModifyNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeModifyPer', minWidth: 80, width: 80},
{display: '修改次数', name: 'recipeModifyCount', minWidth: 80, width: 80},
{display: '修改占比', name: 'recipeModifyCountPer', minWidth: 80, width: 80},
]
},
{
display: '无问题处方',
columns: [
{display: '无问题处方数', name: 'recipeNormalNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeNormalPer', minWidth: 80, width: 80}
]
}
]
},
iptNum: {
url: '<c:url value="/module/gy/recipeAnalysisRecipeNum.action"/>',
columns: [
{display: '患者总数', name: 'total', minWidth: 80, width: 80},
{display: '审查次数',name:'reviewCount', minWidth: 80, width: 80},
{
display: '干预',
columns: [
{display: '患者数', name: 'recipeGyNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeGyPer', minWidth: 80, width: 80},
{display: '总金额(万元)', name: 'infoFeeTotal', minWidth: 80, width: 90},
{display: '组数', name: 'recipeGyCount', minWidth: 80, width: 80},
/* {display: '占比', name: 'recipeGyCountPer', minWidth: 80, width: 80},*/
]
},
{
display: '拦截',
columns: [
{display: '患者数', name: 'recipeInterceptNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeInterceptPer', minWidth: 80, width: 80},
{display: '总金额(万元)', name: 'nosaveFeeTotal', minWidth: 80, width: 90},
{display: '组数', name: 'recipeInterceptCount', minWidth: 80, width: 80},
/*{display: '占比', name: 'recipeInterceptCountPer', minWidth: 80, width: 80},*/
]
},
{
display: '无问题',
columns: [
{display: '患者数', name: 'recipeNormalNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeNormalPer', minWidth: 80, width: 80}
]
}
]
}
};
var $panel = navTab.getCurrentPanel();
var recipeSource = '门急诊';
function getPageType(){
var pageType = "${pageType}";
var type = recipeSource;
if (pageType == 'num') {
if (type == '住院') {
pageType = 'iptNum';
} else {
pageType = 'optNum';
}
}
return pageType;
}
function getColumns(pageType){
var columns = [{
display: '医院/科室/医生', name: 'titleName', minWidth: 200, width: 200, render: function (row) {
if (
(pageType == 'handle' && row.viewMode && row.viewMode != -1 )
||(pageType == 'optNum' && row.viewMode && row.viewMode != -1)
|| (pageType == 'iptNum' && row.viewMode && row.viewMode != 3)
) {
return '<a href="javascript:void(0)" prevViewModeIsHospital ="'+ row.prevViewModeIsHospital+'" rel="' + row.titleCode + '" viewMode="' + row.viewMode
+ '" style="line-height: 22px;" class="hdhClick">' + row.titleName + '</a>';
} else {
return row.titleName;
}
}
}];
if (pageType == 'iptNum') {
columns[0].display = '医院/科室';
} else {
columns[0].display = '医院/科室/医生';
}
var url = pageTypeSet[pageType].url;
var columnsSet = pageTypeSet[pageType].columns;
var count = columnsSet.length;
for (var i = 0; i < count; i++) {
columns.push(columnsSet[i]);
}
return columns;
}
var searhViewMode;
function initGrid() {
recipeSource = $panel.find("#${jsns}recipeSource").val();
return $("#${jsns}maingrid").ligerGrid({
columns: getColumns(getPageType()),
})
}
var searchLock = false;
var grid = $("#${jsns}maingrid").ligerGrid({
columns: getColumns(getPageType()),
delayLoad: true,
checkbox: false,
height: $(window).height() - 242,
allowHideColumn: false,
pageSize: 20,
pageSizeOptions: [20],
url: pageTypeSet[getPageType()].url,
parms: [],
onSuccess: function (ligerGridData, grid) {
drawEchartsBar(ligerGridData);
/* 趋势图数据获取 */
$.ajax({
type: 'post',
/* async: false, */
url: urlLine,
data: getUrlParam(),
success: function (data) {
lineData = data;
var index = navTab.getCurrentPanel().find(".targ-btns span._checked").index();
if (index == 0) {
return ;
}
var pageType = getPageType();
$('#${jsns}divPerType').hide();
$('#${jsns}divIptPerType').hide();
if (pageType == 'iptNum') {
$('#${jsns}divIptPerType').show();
var checkedRadio = $("input:radio[name=${jsns}perIptType]:checked");
optionLine.title.text= checkedRadio.next().text();
lineDataHandle(checkedRadio.val());
} else {
$('#${jsns}divPerType').show();
var checkedRadio = $("input:radio[name=${jsns}perType]:checked");
optionLine.title.text= checkedRadio.next().text();
lineDataHandle(checkedRadio.val());
}
}
});
},
onBeforeShowData: function (currentData) {
var dataRows = currentData.rows;
var sumRow = currentData.sum;
if (sumRow) {
sumRow.titleName = '汇总';
dataRows.push(sumRow);
}
for(var index in dataRows){
var dataRow = dataRows[index];
for(var i=2;i<grid.columns.length;i++){
var columnName = grid.columns[i].columnname;
if(!dataRow[columnName]){
dataRow[columnName]=0;
}
}
}
},
onAfterShowData: function (currentData) {
searchLock = false;
$panel.find(".hdhClick").bind('click', function (e) {
if (searchLock) {
return;
}
searchLock = true;
var $this = $(this);
var viewMode = $this.attr("viewMode");
var selectTitleCode = $this.attr("rel");
var prevViewModeIsHospital = $this.attr("prevViewModeIsHospital");
if (qm.setting.menus.length == 0) {
var titleValue ;
if (searhViewMode == 0) {
titleValue = "所有机构";
} else {
titleValue = "所有科室";
}
var oneM = {title: titleValue, data: {viewMode: searhViewMode}, func: searchData};
qm.add(oneM);
}
var data = {selectTitleCode: selectTitleCode, viewMode: viewMode, prevViewModeIsHospital : prevViewModeIsHospital};
qm.add({title: $this.text(), data: data, func: searchData});
searchData(data);
});
}
});;
var lineData;
var myChartLine;
/* 趋势图数据 */
var urlLine = '<c:url value="/module/gy/recipeAnalysisLine.action"/>'
function searchData(data) {
if (${jsns}CheckSubmit()) {
return false;
}
if (data) {
if (data.selectTitleCode) {
grid.setParm('query.selectTitleCode', data.selectTitleCode);
grid.setParm('query.prevViewModeIsHospital', data.prevViewModeIsHospital);
} else {
grid.removeParm('query.prevViewModeIsHospital');
grid.removeParm("query.selectTitleCode");
}
grid.setParm('query.viewMode', data.viewMode);
} else {
grid.removeParm('query.prevViewModeIsHospital');
grid.removeParm("query.selectTitleCode");
}
grid.changePage("first");
/* 载入数据 */
grid.loadData();
}
/* 拼接URL的参数 */
function getUrlParam() {
var urlParam = '';
var parms = grid.get('parms');
var len = parms.length;
for (var i = 0; i < len; i++) {
var param = parms[i];
if (param && param.name) {
urlParam += param.name;
urlParam += '=';
urlParam += param.value;
urlParam += '&';
}
}
/* 分页参数组装 */
urlParam += 'pagesize=';
urlParam += grid.options.pageSize;
urlParam += '&page=';
urlParam += grid.options.newPage;
return urlParam;
}
/* 绑定导出按钮 */
$("#${jsns}export").click(function () {
var exportUrl;
if ('num' == '${pageType}') {
exportUrl = '<c:url value="/module/gy/recipeAnalysisNumExport.action"/>';
} else {
exportUrl = '<c:url value="/module/gy/recipeAnalysisHandleExport.action"/>';
}
$(this).attr('href', exportUrl + '?' + getUrlParam());
});
/* 绑定【检索】按钮 */
$('#${jsns}doSearchBtn').click(function () {
/* 设置参数 */
searhViewMode = $('#${jsns}checkModeSelect').val();
grid = initGrid();
grid.setParm('query.phase', $('#${jsns}phase').val());
grid.setParm('query.startDate', $panel.find('[name="query.startDate"]').val());
grid.setParm('query.endDate', $panel.find('[name="query.endDate"]').val());
grid.setParm('query.recipeSource', $('#${jsns}recipeSource').val());
grid.setParm('query.viewMode', searhViewMode);
grid.setParm('hdd.hospitalCode', $('#${jsns}hospitalCode').val());
grid.setParm('hdd.hosDeptId', $('#${jsns}hosDeptId').val());
grid.setParm('hdd.userId', $('#${jsns}userId').val());
grid.setParm('hdd.type', $('#${jsns}type').val());
grid.setParm('pageType', '${pageType}');
if (${jsns}CheckSubmit()){
return false;
}
qm.clearMenus();
searchData();
});
/* 绑定占比类型数据点击事件 */
$("input:radio[name=${jsns}perType]").change(function () {
lineDataHandle($(this).attr('value'));
var name = $(this).next().text();
optionLine.title.text=name;
myChartLine.setOption(optionLine);
});
$("input:radio[name=${jsns}perIptType]").change(function () {
lineDataHandle($(this).attr('value'));
var name = $(this).next().text();
optionLine.title.text=name;
myChartLine.setOption(optionLine);
});
/**
* 趋势图数据构建
* @param perType
* 0:医生修改处方占比1:干预占比2:拦截占比3:无问题处方占比 --处方数量
* 0:更换药物占比1:修正警示占比2:忽略警示占比3:删除处方占比 --处方处理
*/
function lineDataHandle(perType) {
optionLine.xAxis[0].data = lineData.months||[];
/* 需要展示的月份 */
optionLine.legend.data = lineData.titleNames||[];
/* 需要展示的机构/科室/医生 */
optionLine.series = lineData['perType' + perType]||[{}];
for(var i in optionLine.series){
var seriesData = optionLine.series[i];
seriesData.itemStyle={normal: {
label : {
show: true,position:'right'
}
}};
}
drawEchartsLine();
/* 展示趋势图 */
}
/* 展示趋势图 */
function drawEchartsLine() {
// 使用
require(
[
'echarts',
'echarts/chart/line'
],
function (ec) {
// 基于准备好的dom,初始化echarts图表
myChartLine = ec.init(document.getElementById('${jsns}main_line'));
// 为echarts对象加载数据
myChartLine.setOption(optionLine);
}
);
}
var pageType = getPageType();
var pageData = {
handle: [{
titleName: "更换药物",
name: "recipeChangeDrugNumPer",
selected: true
}, {
titleName: "修正错误",
name: "recipeCorrectNumPer",
selected: false
}, {
titleName: "忽略错误",
name: "recipeIgnoreNumPer",
selected: false
}, {
titleName: "删除处方",
name: "recipeDeleteNumPer",
selected: false
}/* ,{
titleName:"双签名确认",
name:"recipeSignNumPer",
selected:false
} */],
optNum: [
{
titleName: "医生修改处方",
name: "recipeModifyPer",
selected: true
}, {
titleName: "干预",
name: "recipeGyPer",
selected: false
}, {
titleName: "拦截",
name: "recipeInterceptPer",
selected: false
}, {
titleName: "无问题处方",
name: "recipeNormalPer",
selected: false
}
],
iptNum: [
{
titleName: "干预",
name: "recipeGyPer",
selected: true
}, {
titleName: "拦截",
name: "recipeInterceptPer",
selected: false
}, {
titleName: "无问题处方",
name: "recipeNormalPer",
selected: false
}
]
};
var demoData = pageData[pageType];
require.config({
paths: {
echarts: '<c:url value="/uistyle/echarts/2.2.7/build/dist"/>'
}
});
/* 柱状图结构数据 */
var option = {
title: {
padding:[20,0,0,25],
itemGap:0,
text: '占比',
textStyle:{
fontSize:14
}
},
tooltip: {
trigger: 'axis'
},
legend: {
selectedMode: "single"
},
toolbox: {
show: true,
feature: {
magicType: {show: false, type: ['bar']},
saveAsImage: {show: true}
}
},
xAxis: [
{
name:'医院/\n科室/\n医生',
nameGap:30,
type: 'category',
axisLabel: {
interval: 0, rotate: 10
}
}
],
yAxis: [
{type: 'value'}
],
noDataLoadingOption :{
text: '暂无数据',
effect:'bubble',
effectOption : {
effect: {
n: 0 //气泡个数为0
}
}
}
};
/* 趋势图数据结构 */
var optionLine = {
title: {
padding:[20,0,0,25],
itemGap:0,
text: $("input:radio[name=${jsns}perType]:checked").next().text(),
textStyle:{
fontSize:14
}
},
tooltip: {
trigger: 'axis'
},
legend: {
orient: 'horizontal',
x:'center',
y:'top',
padding:[5,160,5,160],
itemGap:20,
textStyle:{fontWeight:'normal',fontWeight:'bold'},
data: []/* 数据后台获取 */
},
toolbox: {
show: true,
feature: {
magicType: {show: false, type: ['line']},
saveAsImage: {show: true}
}
},
xAxis: [
{
name:'月份',
type: 'category',
data: []/* 数据后台获取 */
}
],
yAxis: [
{
type: 'value'
}
],
series: [],/* 数据后台获取 */
noDataLoadingOption :{
text: '暂无数据',
effect:'bubble',
effectOption : {
effect: {
n: 0 //气泡个数为0
}
}
}
};
var barDatas=[];
function drawEchartsBar(ligerGridData) {
demoData = pageData[getPageType()];
if (null == ligerGridData) {
return;
}
/* start convertTo bar*/
var option_legend_data = new Array();
var series_data = new Array();
var legend_selected = {};
/* 医院/科室/医生 */
//for (var i = 0; i < ligerGridData.rows.length; i++) {
// xAxis_data[i] = ligerGridData.rows[i].titleName;
//}
/* 【医院/科室/医生】的[干预/拦截/修改/正常]占比 */
for (var i = 0; i < demoData.length; i++) {
var demo = demoData[i];
var titleName = demo["titleName"];
option_legend_data[i] = demo["titleName"];
legend_selected[titleName] = demo["selected"];
var name = demo["name"];
var xAxis_data = new Array();
var barData = new Array();
var data = new Array();
for (var y = 0; y < ligerGridData.rows.length; y++) {
barData[y]={name:ligerGridData.rows[y].titleName,data:ligerGridData.rows[y][name]};
}
barData.sort(function(self,other){
return other.data-self.data;
});
for(var x in barData){
xAxis_data[x] = barData[x].name;
data[x]=barData[x].data;
}
barDatas[i] = {titleName:titleName,xAxisData:xAxis_data,data:data};
series_data[i] = {name: titleName, type: 'bar', barWidth: 15, data: data};
}
/* 柱状图数据组合 */
option.legend.selected = legend_selected;
option.legend.data = option_legend_data;
option.series = series_data;
for(var i in option.series){
var seriesData = option.series[i];
seriesData.itemStyle={normal: {
color: 'tomato',
barBorderColor: 'tomato',
barBorderWidth: 6,
barBorderRadius:0,
label : {
show: true
}
}};
}
option.xAxis[0].data = barDatas[0].xAxisData;
var type = $panel.find("#${jsns}recipeSource").val();
if (type == '住院') {
option.title.text = '患者数占比';
} else {
option.title.text = '处方数占比';
}
/* end convertTo bar*/
drawEchartsBar1();
}
function drawEchartsBar1() {
// 使用
require(
[
'echarts',
'echarts/chart/bar'
],
function (ec) {
// 基于准备好的dom,初始化echarts图表
var myChart = ec.init(document.getElementById('${jsns}main'));
// 为echarts对象加载数据
myChart.setOption(option);
var ecConfig = require('echarts/config');
myChart.on(ecConfig.EVENT.LEGEND_SELECTED, function (params) {
var titleName = params.target;
for(var i in barDatas){
var barData = barDatas[i];
if(titleName==barData.titleName){
option.xAxis[0].data = barData.xAxisData;
break;
}
}
myChart.setOption(option);
});
}
);
}
navTab.getCurrentPanel().find(".targ-btns span").click(function () {
$(this).addClass("_checked").siblings().removeClass("_checked");
var idx = $(this).index();
if (idx == 0) {
$("#${jsns}main_line").hide();
$("#${jsns}main").show();
$('#${jsns}divPerType').hide();
$('#${jsns}divIptPerType').hide();
drawEchartsBar1();
} else if (idx == 1) {
$("#${jsns}main_line").show();
$("#${jsns}main").hide();
$('#${jsns}divPerType').hide();
$('#${jsns}divIptPerType').hide();
var pageType = getPageType();
if (pageType == 'iptNum') {
$('#${jsns}divIptPerType').show();
lineDataHandle($("input:radio[name=${jsns}perIptType]:checked").val());
} else {
$('#${jsns}divPerType').show();
lineDataHandle($("input:radio[name=${jsns}perType]:checked").val());
}
drawEchartsLine();
}
});
$('#${jsns}doSearchBtn').trigger("click");
});
</script>
<script type="text/javascript" src="<c:url value="/uistyle/echarts/2.2.7/build/dist/echarts.js"/>"></script>
<style>
.targ-btns {
height: 30px;
margin: 10px;
}
.targ-btns span {
display: block;
width: 60px;
height: 28px;
border: 1px solid #ccc;
float: left;
text-align: center;
line-height: 28px;
cursor: pointer;
}
.targ-btns .btn-l {
border-right: 0;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.targ-btns .btn-l._checked {
border-color: #2db8f7;
border-right: 1px solid #2db8f7;
color: #2db8f7;
}
.targ-btns .btn-r {
border-left: 0;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
.targ-btns .btn-r._checked {
border-color: #2db8f7;
border-left: 1px solid #2db8f7;
color: #2db8f7;
}
input[type=radio]{
margin-left:20px;
margin-right:2px;
}
</style>
<div id="${jsns}quickMenu"></div>
<div id="${jsns}maingrid" style="margin:0; padding:0"></div>
<div class="targ-btns">
<span class="btn-l _checked">柱状图</span>
<span class="btn-r">趋势图</span>
</div>
<div style="display: none; text-align:center;color:#669;font-size:12px;font-weight:bold;font-family:微软雅黑 黑体 Arial;" id="${jsns}divPerType">
<input name="${jsns}perType" type="radio" value="0" checked/><span>${('num' eq pageType ) ? '医生修改处方占比' : '更换药物占比'}</span>
<input name="${jsns}perType" type="radio" value="1"/><span>${('num' eq pageType ) ? '干预占比' : '修正错误占比'}</span>
<input name="${jsns}perType" type="radio" value="2"/><span>${('num' eq pageType ) ? '拦截占比' : '忽略错误占比'}</span>
<input name="${jsns}perType" type="radio" value="3"/><span>${('num' eq pageType ) ? '无问题处方占比' : '删除处方占比'}</span>
</div>
<div style="display: none; text-align:center;color:#669;font-size:12px;font-weight:bold;font-family:微软雅黑 黑体 Arial;" id="${jsns}divIptPerType">
<input name="${jsns}perIptType" type="radio" value="1" checked/><span>${('num' eq pageType ) ? '干预占比' : '修正错误占比'}</span>
<input name="${jsns}perIptType" type="radio" value="2"/><span>${('num' eq pageType ) ? '拦截占比' : '忽略错误占比'}</span>
<input name="${jsns}perIptType" type="radio" value="3"/><span>${('num' eq pageType ) ? '无问题占比' : '删除占比'}</span>
</div>
<div id="${jsns}main" style="height: 450px;width:95%; "></div>
<div id="${jsns}main_line" style="height: 450px;width:95%;display: none; "></div>
<script type="text/javascript">
$(function () {
var qm = new quickMenu("${jsns}quickMenu").init();
var summaryRow = {test: '123'};
var pageTypeSet = {
handle: {
url: '<c:url value="/module/gy/recipeAnalysisRecipeHandle.action"/>',
columns: [
{display: '处方总数', name: 'total', minWidth: 80, width: 80},
// {display: '审查总人次', name: 'patientNum', minWidth: 80, width: 80},
{
display: '更换药物',
columns: [
{display: '处方数', name: 'recipeChangeDrugNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeChangeDrugNumPer', minWidth: 80, width: 80}
]
},
{
display: '修正错误',
columns: [
{display: '处方数', name: 'recipeCorrectNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeCorrectNumPer', minWidth: 80, width: 80}
]
},
{
display: '忽略错误',
columns: [
{display: '处方数', name: 'recipeIgnoreNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeIgnoreNumPer', minWidth: 80, width: 80}
]
},
{
display: '删除处方',
columns: [
{display: '处方数', name: 'recipeDeleteNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeDeleteNumPer', minWidth: 80, width: 80}
]
}/* ,{
display: '双签名确认',
columns: [
{ display: '处方数', name: 'recipeSignNum',minWidth:80,width:80 },
{ display: '占比', name: 'recipeSignNumPer',minWidth:80,width:80 }
]
} */]
},
optNum: {
url: '<c:url value="/module/gy/recipeAnalysisRecipeNum.action"/>',
columns: [
{display: '处方总数', name: 'total', minWidth: 80, width: 80},
{display: '审查次数',minWidth: 80, width: 80, name: 'reviewCount'},
{
display: '干预',
columns: [
{display: '干预处方数', name: 'recipeGyNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeGyPer', minWidth: 80, width: 80},
{display: '总金额(万元)', name: 'infoFeeTotal', minWidth: 80, width: 90},
{display: '干预次数', name: 'recipeGyCount', minWidth: 80, width: 80},
{display: '占比', name: 'recipeGyCountPer', minWidth: 80, width: 80},
]
},
{
display: '拦截',
columns: [
{display: '拦截处方数', name: 'recipeInterceptNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeInterceptPer', minWidth: 80, width: 80},
{display: '总金额(万元)', name: 'nosaveFeeTotal', minWidth: 80, width: 90},
{display: '拦截次数', name: 'recipeInterceptCount', minWidth: 80, width: 80},
{display: '占比', name: 'recipeInterceptCountPer', minWidth: 80, width: 80},
]
},
{
display: '医生修改处方',
columns: [
{display: '修改处方数', name: 'recipeModifyNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeModifyPer', minWidth: 80, width: 80},
{display: '修改次数', name: 'recipeModifyCount', minWidth: 80, width: 80},
{display: '修改占比', name: 'recipeModifyCountPer', minWidth: 80, width: 80},
]
},
{
display: '无问题处方',
columns: [
{display: '无问题处方数', name: 'recipeNormalNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeNormalPer', minWidth: 80, width: 80}
]
}
]
},
iptNum: {
url: '<c:url value="/module/gy/recipeAnalysisRecipeNum.action"/>',
columns: [
{display: '患者总数', name: 'total', minWidth: 80, width: 80},
{display: '审查次数',name:'reviewCount', minWidth: 80, width: 80},
{
display: '干预',
columns: [
{display: '患者数', name: 'recipeGyNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeGyPer', minWidth: 80, width: 80},
{display: '总金额(万元)', name: 'infoFeeTotal', minWidth: 80, width: 90},
{display: '组数', name: 'recipeGyCount', minWidth: 80, width: 80},
/* {display: '占比', name: 'recipeGyCountPer', minWidth: 80, width: 80},*/
]
},
{
display: '拦截',
columns: [
{display: '患者数', name: 'recipeInterceptNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeInterceptPer', minWidth: 80, width: 80},
{display: '总金额(万元)', name: 'nosaveFeeTotal', minWidth: 80, width: 90},
{display: '组数', name: 'recipeInterceptCount', minWidth: 80, width: 80},
/*{display: '占比', name: 'recipeInterceptCountPer', minWidth: 80, width: 80},*/
]
},
{
display: '无问题',
columns: [
{display: '患者数', name: 'recipeNormalNum', minWidth: 80, width: 80},
{display: '占比', name: 'recipeNormalPer', minWidth: 80, width: 80}
]
}
]
}
};
var $panel = navTab.getCurrentPanel();
var recipeSource = '门急诊';
function getPageType(){
var pageType = "${pageType}";
var type = recipeSource;
if (pageType == 'num') {
if (type == '住院') {
pageType = 'iptNum';
} else {
pageType = 'optNum';
}
}
return pageType;
}
function getColumns(pageType){
var columns = [{
display: '医院/科室/医生', name: 'titleName', minWidth: 200, width: 200, render: function (row) {
if (
(pageType == 'handle' && row.viewMode && row.viewMode != -1 )
||(pageType == 'optNum' && row.viewMode && row.viewMode != -1)
|| (pageType == 'iptNum' && row.viewMode && row.viewMode != 3)
) {
return '<a href="javascript:void(0)" prevViewModeIsHospital ="'+ row.prevViewModeIsHospital+'" rel="' + row.titleCode + '" viewMode="' + row.viewMode
+ '" style="line-height: 22px;" class="hdhClick">' + row.titleName + '</a>';
} else {
return row.titleName;
}
}
}];
if (pageType == 'iptNum') {
columns[0].display = '医院/科室';
} else {
columns[0].display = '医院/科室/医生';
}
var url = pageTypeSet[pageType].url;
var columnsSet = pageTypeSet[pageType].columns;
var count = columnsSet.length;
for (var i = 0; i < count; i++) {
columns.push(columnsSet[i]);
}
return columns;
}
var searhViewMode;
function initGrid() {
recipeSource = $panel.find("#${jsns}recipeSource").val();
return $("#${jsns}maingrid").ligerGrid({
columns: getColumns(getPageType()),
})
}
var searchLock = false;
var grid = $("#${jsns}maingrid").ligerGrid({
columns: getColumns(getPageType()),
delayLoad: true,
checkbox: false,
height: $(window).height() - 242,
allowHideColumn: false,
pageSize: 20,
pageSizeOptions: [20],
url: pageTypeSet[getPageType()].url,
parms: [],
onSuccess: function (ligerGridData, grid) {
drawEchartsBar(ligerGridData);
/* 趋势图数据获取 */
$.ajax({
type: 'post',
/* async: false, */
url: urlLine,
data: getUrlParam(),
success: function (data) {
lineData = data;
var index = navTab.getCurrentPanel().find(".targ-btns span._checked").index();
if (index == 0) {
return ;
}
var pageType = getPageType();
$('#${jsns}divPerType').hide();
$('#${jsns}divIptPerType').hide();
if (pageType == 'iptNum') {
$('#${jsns}divIptPerType').show();
var checkedRadio = $("input:radio[name=${jsns}perIptType]:checked");
optionLine.title.text= checkedRadio.next().text();
lineDataHandle(checkedRadio.val());
} else {
$('#${jsns}divPerType').show();
var checkedRadio = $("input:radio[name=${jsns}perType]:checked");
optionLine.title.text= checkedRadio.next().text();
lineDataHandle(checkedRadio.val());
}
}
});
},
onBeforeShowData: function (currentData) {
var dataRows = currentData.rows;
var sumRow = currentData.sum;
if (sumRow) {
sumRow.titleName = '汇总';
dataRows.push(sumRow);
}
for(var index in dataRows){
var dataRow = dataRows[index];
for(var i=2;i<grid.columns.length;i++){
var columnName = grid.columns[i].columnname;
if(!dataRow[columnName]){
dataRow[columnName]=0;
}
}
}
},
onAfterShowData: function (currentData) {
searchLock = false;
$panel.find(".hdhClick").bind('click', function (e) {
if (searchLock) {
return;
}
searchLock = true;
var $this = $(this);
var viewMode = $this.attr("viewMode");
var selectTitleCode = $this.attr("rel");
var prevViewModeIsHospital = $this.attr("prevViewModeIsHospital");
if (qm.setting.menus.length == 0) {
var titleValue ;
if (searhViewMode == 0) {
titleValue = "所有机构";
} else {
titleValue = "所有科室";
}
var oneM = {title: titleValue, data: {viewMode: searhViewMode}, func: searchData};
qm.add(oneM);
}
var data = {selectTitleCode: selectTitleCode, viewMode: viewMode, prevViewModeIsHospital : prevViewModeIsHospital};
qm.add({title: $this.text(), data: data, func: searchData});
searchData(data);
});
}
});;
var lineData;
var myChartLine;
/* 趋势图数据 */
var urlLine = '<c:url value="/module/gy/recipeAnalysisLine.action"/>'
function searchData(data) {
if (${jsns}CheckSubmit()) {
return false;
}
if (data) {
if (data.selectTitleCode) {
grid.setParm('query.selectTitleCode', data.selectTitleCode);
grid.setParm('query.prevViewModeIsHospital', data.prevViewModeIsHospital);
} else {
grid.removeParm('query.prevViewModeIsHospital');
grid.removeParm("query.selectTitleCode");
}
grid.setParm('query.viewMode', data.viewMode);
} else {
grid.removeParm('query.prevViewModeIsHospital');
grid.removeParm("query.selectTitleCode");
}
grid.changePage("first");
/* 载入数据 */
grid.loadData();
}
/* 拼接URL的参数 */
function getUrlParam() {
var urlParam = '';
var parms = grid.get('parms');
var len = parms.length;
for (var i = 0; i < len; i++) {
var param = parms[i];
if (param && param.name) {
urlParam += param.name;
urlParam += '=';
urlParam += param.value;
urlParam += '&';
}
}
/* 分页参数组装 */
urlParam += 'pagesize=';
urlParam += grid.options.pageSize;
urlParam += '&page=';
urlParam += grid.options.newPage;
return urlParam;
}
/* 绑定导出按钮 */
$("#${jsns}export").click(function () {
var exportUrl;
if ('num' == '${pageType}') {
exportUrl = '<c:url value="/module/gy/recipeAnalysisNumExport.action"/>';
} else {
exportUrl = '<c:url value="/module/gy/recipeAnalysisHandleExport.action"/>';
}
$(this).attr('href', exportUrl + '?' + getUrlParam());
});
/* 绑定【检索】按钮 */
$('#${jsns}doSearchBtn').click(function () {
/* 设置参数 */
searhViewMode = $('#${jsns}checkModeSelect').val();
grid = initGrid();
grid.setParm('query.phase', $('#${jsns}phase').val());
grid.setParm('query.startDate', $panel.find('[name="query.startDate"]').val());
grid.setParm('query.endDate', $panel.find('[name="query.endDate"]').val());
grid.setParm('query.recipeSource', $('#${jsns}recipeSource').val());
grid.setParm('query.viewMode', searhViewMode);
grid.setParm('hdd.hospitalCode', $('#${jsns}hospitalCode').val());
grid.setParm('hdd.hosDeptId', $('#${jsns}hosDeptId').val());
grid.setParm('hdd.userId', $('#${jsns}userId').val());
grid.setParm('hdd.type', $('#${jsns}type').val());
grid.setParm('pageType', '${pageType}');
if (${jsns}CheckSubmit()){
return false;
}
qm.clearMenus();
searchData();
});
/* 绑定占比类型数据点击事件 */
$("input:radio[name=${jsns}perType]").change(function () {
lineDataHandle($(this).attr('value'));
var name = $(this).next().text();
optionLine.title.text=name;
myChartLine.setOption(optionLine);
});
$("input:radio[name=${jsns}perIptType]").change(function () {
lineDataHandle($(this).attr('value'));
var name = $(this).next().text();
optionLine.title.text=name;
myChartLine.setOption(optionLine);
});
/**
* 趋势图数据构建
* @param perType
* 0:医生修改处方占比1:干预占比2:拦截占比3:无问题处方占比 --处方数量
* 0:更换药物占比1:修正警示占比2:忽略警示占比3:删除处方占比 --处方处理
*/
function lineDataHandle(perType) {
optionLine.xAxis[0].data = lineData.months||[];
/* 需要展示的月份 */
optionLine.legend.data = lineData.titleNames||[];
/* 需要展示的机构/科室/医生 */
optionLine.series = lineData['perType' + perType]||[{}];
for(var i in optionLine.series){
var seriesData = optionLine.series[i];
seriesData.itemStyle={normal: {
label : {
show: true,position:'right'
}
}};
}
drawEchartsLine();
/* 展示趋势图 */
}
/* 展示趋势图 */
function drawEchartsLine() {
// 使用
require(
[
'echarts',
'echarts/chart/line'
],
function (ec) {
// 基于准备好的dom,初始化echarts图表
myChartLine = ec.init(document.getElementById('${jsns}main_line'));
// 为echarts对象加载数据
myChartLine.setOption(optionLine);
}
);
}
var pageType = getPageType();
var pageData = {
handle: [{
titleName: "更换药物",
name: "recipeChangeDrugNumPer",
selected: true
}, {
titleName: "修正错误",
name: "recipeCorrectNumPer",
selected: false
}, {
titleName: "忽略错误",
name: "recipeIgnoreNumPer",
selected: false
}, {
titleName: "删除处方",
name: "recipeDeleteNumPer",
selected: false
}/* ,{
titleName:"双签名确认",
name:"recipeSignNumPer",
selected:false
} */],
optNum: [
{
titleName: "医生修改处方",
name: "recipeModifyPer",
selected: true
}, {
titleName: "干预",
name: "recipeGyPer",
selected: false
}, {
titleName: "拦截",
name: "recipeInterceptPer",
selected: false
}, {
titleName: "无问题处方",
name: "recipeNormalPer",
selected: false
}
],
iptNum: [
{
titleName: "干预",
name: "recipeGyPer",
selected: true
}, {
titleName: "拦截",
name: "recipeInterceptPer",
selected: false
}, {
titleName: "无问题处方",
name: "recipeNormalPer",
selected: false
}
]
};
var demoData = pageData[pageType];
require.config({
paths: {
echarts: '<c:url value="/uistyle/echarts/2.2.7/build/dist"/>'
}
});
/* 柱状图结构数据 */
var option = {
title: {
padding:[20,0,0,25],
itemGap:0,
text: '占比',
textStyle:{
fontSize:14
}
},
tooltip: {
trigger: 'axis'
},
legend: {
selectedMode: "single"
},
toolbox: {
show: true,
feature: {
magicType: {show: false, type: ['bar']},
saveAsImage: {show: true}
}
},
xAxis: [
{
name:'医院/\n科室/\n医生',
nameGap:30,
type: 'category',
axisLabel: {
interval: 0, rotate: 10
}
}
],
yAxis: [
{type: 'value'}
],
noDataLoadingOption :{
text: '暂无数据',
effect:'bubble',
effectOption : {
effect: {
n: 0 //气泡个数为0
}
}
}
};
/* 趋势图数据结构 */
var optionLine = {
title: {
padding:[20,0,0,25],
itemGap:0,
text: $("input:radio[name=${jsns}perType]:checked").next().text(),
textStyle:{
fontSize:14
}
},
tooltip: {
trigger: 'axis'
},
legend: {
orient: 'horizontal',
x:'center',
y:'top',
padding:[5,160,5,160],
itemGap:20,
textStyle:{fontWeight:'normal',fontWeight:'bold'},
data: []/* 数据后台获取 */
},
toolbox: {
show: true,
feature: {
magicType: {show: false, type: ['line']},
saveAsImage: {show: true}
}
},
xAxis: [
{
name:'月份',
type: 'category',
data: []/* 数据后台获取 */
}
],
yAxis: [
{
type: 'value'
}
],
series: [],/* 数据后台获取 */
noDataLoadingOption :{
text: '暂无数据',
effect:'bubble',
effectOption : {
effect: {
n: 0 //气泡个数为0
}
}
}
};
var barDatas=[];
function drawEchartsBar(ligerGridData) {
demoData = pageData[getPageType()];
if (null == ligerGridData) {
return;
}
/* start convertTo bar*/
var option_legend_data = new Array();
var series_data = new Array();
var legend_selected = {};
/* 医院/科室/医生 */
//for (var i = 0; i < ligerGridData.rows.length; i++) {
// xAxis_data[i] = ligerGridData.rows[i].titleName;
//}
/* 【医院/科室/医生】的[干预/拦截/修改/正常]占比 */
for (var i = 0; i < demoData.length; i++) {
var demo = demoData[i];
var titleName = demo["titleName"];
option_legend_data[i] = demo["titleName"];
legend_selected[titleName] = demo["selected"];
var name = demo["name"];
var xAxis_data = new Array();
var barData = new Array();
var data = new Array();
for (var y = 0; y < ligerGridData.rows.length; y++) {
barData[y]={name:ligerGridData.rows[y].titleName,data:ligerGridData.rows[y][name]};
}
barData.sort(function(self,other){
return other.data-self.data;
});
for(var x in barData){
xAxis_data[x] = barData[x].name;
data[x]=barData[x].data;
}
barDatas[i] = {titleName:titleName,xAxisData:xAxis_data,data:data};
series_data[i] = {name: titleName, type: 'bar', barWidth: 15, data: data};
}
/* 柱状图数据组合 */
option.legend.selected = legend_selected;
option.legend.data = option_legend_data;
option.series = series_data;
for(var i in option.series){
var seriesData = option.series[i];
seriesData.itemStyle={normal: {
color: 'tomato',
barBorderColor: 'tomato',
barBorderWidth: 6,
barBorderRadius:0,
label : {
show: true
}
}};
}
option.xAxis[0].data = barDatas[0].xAxisData;
var type = $panel.find("#${jsns}recipeSource").val();
if (type == '住院') {
option.title.text = '患者数占比';
} else {
option.title.text = '处方数占比';
}
/* end convertTo bar*/
drawEchartsBar1();
}
function drawEchartsBar1() {
// 使用
require(
[
'echarts',
'echarts/chart/bar'
],
function (ec) {
// 基于准备好的dom,初始化echarts图表
var myChart = ec.init(document.getElementById('${jsns}main'));
// 为echarts对象加载数据
myChart.setOption(option);
var ecConfig = require('echarts/config');
myChart.on(ecConfig.EVENT.LEGEND_SELECTED, function (params) {
var titleName = params.target;
for(var i in barDatas){
var barData = barDatas[i];
if(titleName==barData.titleName){
option.xAxis[0].data = barData.xAxisData;
break;
}
}
myChart.setOption(option);
});
}
);
}
navTab.getCurrentPanel().find(".targ-btns span").click(function () {
$(this).addClass("_checked").siblings().removeClass("_checked");
var idx = $(this).index();
if (idx == 0) {
$("#${jsns}main_line").hide();
$("#${jsns}main").show();
$('#${jsns}divPerType').hide();
$('#${jsns}divIptPerType').hide();
drawEchartsBar1();
} else if (idx == 1) {
$("#${jsns}main_line").show();
$("#${jsns}main").hide();
$('#${jsns}divPerType').hide();
$('#${jsns}divIptPerType').hide();
var pageType = getPageType();
if (pageType == 'iptNum') {
$('#${jsns}divIptPerType').show();
lineDataHandle($("input:radio[name=${jsns}perIptType]:checked").val());
} else {
$('#${jsns}divPerType').show();
lineDataHandle($("input:radio[name=${jsns}perType]:checked").val());
}
drawEchartsLine();
}
});
$('#${jsns}doSearchBtn').trigger("click");
});
</script>
产品业务逻辑咨询相关
【干预3.5】药品信息增加配置不从干预生成 (3.5_201127、4.0_201210)
用户中心增加配置项:
干预是否上报药品信息到知识建设:0 / 1
配置说明:配1时不上报,只从事后上报药品数据如批准文号等到知识建设。
干预是否上报药品信息到知识建设:0 / 1
配置说明:配1时不上报,只从事后上报药品数据如批准文号等到知识建设。
干预(点评应该也是),药嘱明细里,医生信息是否空
取决于用户中心-系统配置-搜”医生”有两个!配置,一个是否保存,一个是否展示
检验数据展示不全,上下限箭头没有展示
排查思路:1. 排序问题:之前提需求过属于遗漏处理,会再改下,相同的排一起 https://jira.ipharmacare.net/browse/RED4-7426
2.少展示问题:干预检验全部是统一接口缓存合并的。接口在必要字段完整下不会少给,样本name和code要传,建议自定义配置 空值转“血液”(同时需要告知his,检验样本,来自血液或尿液是检验指标比对和识别的重要字段,肯定是有值要给的)
3.箭头上下限问题:看下入参,参考值给的是分开的字段,还是参考范围字段,注意分隔符。如果传不对,要么通过自定义转换,部分替换转一下,要么直接这个参考范围字段置空,删了。这样会采用指标知识建设的参考范围 RED4-2943
2.少展示问题:干预检验全部是统一接口缓存合并的。接口在必要字段完整下不会少给,样本name和code要传,建议自定义配置 空值转“血液”(同时需要告知his,检验样本,来自血液或尿液是检验指标比对和识别的重要字段,肯定是有值要给的)
3.箭头上下限问题:看下入参,参考值给的是分开的字段,还是参考范围字段,注意分隔符。如果传不对,要么通过自定义转换,部分替换转一下,要么直接这个参考范围字段置空,删了。这样会采用指标知识建设的参考范围 RED4-2943
跨就诊模式数据入库检索不到
跑引擎正常的 回参也正常。实施疑问点只是入库查询
930,或者说4.0在221228对这里有改之前,从一开始有跨就诊模式,实现的,多跑的那次引擎,数据就没有做入库要求。跨就诊就没有说提供干预页面查询,当然没有异常。
要看就校验工具能查出入参是靠谱的,跨就诊别管页面。页面只有按患者当天的
930,或者说4.0在221228对这里有改之前,从一开始有跨就诊模式,实现的,多跑的那次引擎,数据就没有做入库要求。跨就诊就没有说提供干预页面查询,当然没有异常。
要看就校验工具能查出入参是靠谱的,跨就诊别管页面。页面只有按患者当天的
用药警示管理中医生信息不展示
问题原因:干预根据医生工号从缓存中获取用户唯一标识失败导致 干预数据库中没有存储关联关系导致
解决方案:待产品规划
住院给药时机传值后不显示
标准4.0事中接口文档,草药标签中不存在 给药时机 字段,所以即便用户自己添加了这个字段,程序也不会处理
住院检验数据干预,白蛋白是不同项目下面的,查出两个同名称的指标code不一致,导致人血白蛋白规则错误弹框,但是点干预进去审框又正常无提示内容。点“审”逻辑可能与弹框不一致
现象原因及现场处理:
这个患者,不同检验报告里,存在样本、名称、code等都不同的两个,实际在引擎又是比对到同一个指标的:例如动脉钾 钾离子;以及这个oa上的 白蛋白这个指标也常见
引擎那边 都会跑或者说随机跑了。如果遇到医院很纠结的话。可以从入参接口自定义把指标名称code样本那些改改一样,就不会出现这一问题了
程序上暂不作调整,原因为:
如果在上游就识别为同一个指标,那接口都会取时间最新的给干预,但是在接口数据层面,它就是两个完全不同的指标,怎么去重的了。
?只有到引擎才知道比对后是同一个。所以干预自己存库肯定是都存了 跑引擎时都给了。入参和点审都是两个指标都跑。实际跑的可能随机了 导致不一样
本质原因还是干预3.0本身结构在那,没有时间。如果以后干预重构4.0了 就不会有这个问题
3.0结构下,即使当前程序去改,即使确保了 干预给引擎的两个 在引擎都跑。那只能保证入参和点审,跑的一致。并不能保证,是正确的最新的那个去跑。依然不完善
这个患者,不同检验报告里,存在样本、名称、code等都不同的两个,实际在引擎又是比对到同一个指标的:例如动脉钾 钾离子;以及这个oa上的 白蛋白这个指标也常见
引擎那边 都会跑或者说随机跑了。如果遇到医院很纠结的话。可以从入参接口自定义把指标名称code样本那些改改一样,就不会出现这一问题了
程序上暂不作调整,原因为:
如果在上游就识别为同一个指标,那接口都会取时间最新的给干预,但是在接口数据层面,它就是两个完全不同的指标,怎么去重的了。
?只有到引擎才知道比对后是同一个。所以干预自己存库肯定是都存了 跑引擎时都给了。入参和点审都是两个指标都跑。实际跑的可能随机了 导致不一样
本质原因还是干预3.0本身结构在那,没有时间。如果以后干预重构4.0了 就不会有这个问题
3.0结构下,即使当前程序去改,即使确保了 干预给引擎的两个 在引擎都跑。那只能保证入参和点审,跑的一致。并不能保证,是正确的最新的那个去跑。依然不完善
判断是接口还是业务系统问题
4.0 —— 看校验工具,上游(his)调用数据,和转给内部的例如3.0是否转换和合并正确
3.5/3.3 —— 看接口备份文件xml_bak 如果是接口转3.0时就少了那接口问题非干预
门诊患者查看,发送一次xml请求显示了多条数据【RED4-6346】
确认是不是发送的多处方,如一个xm中包含了多条处方数
按处方
按患者
his直接调干预接口的,干预接收
历史原因 默认就gbk,让his用utf-8直接调干预反而有问题
能改的最好也可以改成调统一接口免得后面万一干预升级有影响。统一接口4.0也都支持3.0入参的,接口接收都是统一utf-8,不支持其他
接口门诊单药删除
4.0门诊主线支持单药删除(3.5没)入参格式(也是调用正常删除接口)
<root><base><hospital_code><![CDATA[医院Code(必填)]]></hospital_code><patient_id><![CDATA[病人号(需要病人唯一标识)]]></patient_id><event_no><![CDATA[就诊流水号]]></event_no><source><![CDATA[来源]]></source></base><doc_id><![CDATA[医生工号]]></doc_id><doc_name><![CDATA[医生姓名]]></doc_name><opt_prescriptions><opt_prescription><opt_prescription_info><recipe_id><![CDATA[处方id]]></recipe_id><recipe_no><![CDATA[处方号]]></recipe_no></opt_prescription_info><opt_prescription_item><recipe_item_id><![CDATA[5656]]></recipe_item_id></opt_prescription_item>一个<opt_prescription_item>是一个药明细<opt_prescription_item>……</opt_prescription_item></opt_prescription></opt_prescriptions></root>
住院如果单药删除审方里会把这组删掉(目前设计如此),如果只上了干预也可以。
单药删除本质是吧那个药去掉,其他药发给干预 所以也会调干预内部的开方接口
但这样干预这个处方就剩下药 警示信息不会返回
一份诊断/检验/手术怎么样会给干预 或在审方显示出来
看看patient_id和event_no对不对的上(如果分开接的event_no很容易对不上)
看看检验时间report_time,报告时间sample_collect_time,是不是在当前时间之前5天内,默认是这天数(详细见审方和接口逻辑文档)在当前时间之后就更假了不是正常数据
看看时间,0730版本以前diag_date为空的不会给干预 会给审方 0904前手术时间也一样
独立发过来,不带医嘱和处方的诊断/检验数据不会发干预,正常的,会发审方
看看检验报告id/项目代码等关键的,有哪项为空这数据就不会发了;项目ID项目名称空有其他影响
看看诊断状态是不是作废的,检验是不是没明细或没检验头……这些基础的
合理用药(干预)系统不稳定 数据原因排查(过程举例)
1. 因系统集成测试单患者数据量过大(测试患者当日有效处方共42张798个药品),超出系统负载最大值,致使系统服务崩溃
2. 由于处方号取值(未能实现同处方修改id不变逻辑)原因,造成合理用药与his实际测试处方数差异较大
如处方号:hlyy201911131047263500(2019.11.13 10:47:26开的处方),取值于当前系统保存时间。
His点击一次保存调用一次接口,合理用药就会认为是一张有效处方。比如10:01:01保存一次,10:01:02无任何修改再保存一次,his可能只查询到一张处方,合理用药查询两张处方,呈现出合理用药系统有42张及大量重复药品数据。
干预结果不返回处方itemid
interface_unified/etc/xml_transform_conf/gy4/result
vim 999_nodeName_delete.json
[{ "operType": "2", "listPathRemove": [ "root/result/message/infos/info/recipe_item_id" ]}]
引擎一般是怎么跑死的(简述)
引擎逻辑:根据患者号会跑出同一天内所有处方的规则(不管是处方干预还是患者干预)
如第一张处方,20个药品能1000+规则;第二张处方(累加第一张处方药品),40个药品跑出3000+规则;第三张处方(累加第一、第二张处方药品数),60个药品跑出9000+规则;第25张处方(前面累加药品数),500个药品跑出3w+规则,服务以及假死了;…………….;第42张处方,前面服务已经崩溃了,导致后面的处方(及院内正常处方)请求都没有警示信息提醒。
干预转发患教nginx配置
干预直接转发患教数据,修改nginx配置
cd /data/soft/nginx/conf/conf.d/intervene.conf
干预里增加 mirror /hjmirror;
已有的下面 增加
location /hjmirror {
internal;
proxy_pass http://hjserver/hj/api/v2/saveByGyServlet; }
internal;
proxy_pass http://hjserver/hj/api/v2/saveByGyServlet; }
4.0可以 3.5也支持
这里的hjserver在conf上层的upstream文件定义,如果不跨服务器不用改
这里的hjserver在conf上层的upstream文件定义,如果不跨服务器不用改
0 条评论
下一页