项目编号:BS-YL-022
一,项目简介
随着人们的生活水平不断提高,健康也越来越受到家庭的关注。2009 年2 月27 日,我国卫生部公布的第四次国家卫生服务调查结果显示,截止至2008 年,我国居民脑血栓,糖尿病,高血压等慢性病病例数达到2.6亿,占全国总人数的20%,其中高血压病人对自身疾病的知晓率只有30%,同时这些病人中的治疗率只有25%,控制率仅为6%,糖尿病病人中,能坚持做到规范治疗的也只有33%。由此我们可以看出,建立科学、规范、高质量的慢性病管理策略,实现对人体慢性病的监护具有重大的意义。通过慢性病的早期诊断和监护,不仅能提前预防和控制各种疾病,还能帮助他们合理用药,减少医药开支。另一方面,我国公共医疗卫生资源紧缺,城乡医疗卫生资源的差距比较大,城市人口平均拥有的医疗卫生资源是农村人口的2.5倍以上,比如,占全国总人口近70%的农村拥有全国医疗卫生资源的30%,而占全国总人口30%的城市却占有全国医疗卫生资源的70%,优质的医疗卫生资源集中分布在城市,尤其是大城市。因此,实现城乡之间的医疗卫生资源共享成为丞待解决的重要问题。
同时,随着国家积极倡导“3521”医疗系统建设,我国医疗领域信息化程度得到了很大的提高,预计在全国会出现上百个医疗数据中心,每个数据中心都将承载近1000 万人口的医疗数据,数量多、更新快且类型繁杂,使医院数据库的信息容量不断膨胀,这就产生了医疗资源大大不够。医疗平台通常具有以下特征:
(1) 数据大量化: 区域医疗数据通常是来自于拥有上百万人口和上百家医疗机构的区域,并且数据呈持续增长的趋势。依照医疗行业的相关规定,患者的数据通常至少需要保留50 年。
(2) 服务实时性: 医疗信息服务中会存在大量在线或实时数据分析处理的需求。例如: 临床中的诊断和用药建议、健康指标预警等。
(3) 存储形式多样化: 医疗数据的存储形式多种多样,例如各种结构化数据表、非( 半) 结构化文本文档、医疗影像等。
(4) 高价值性: 医疗数据对国家乃至全球的疾病防控、新药研发和顽疾攻克都有着巨大的作用。
因此,如何在海量的医疗大数据中提取信息的能力正快速成为战略性发展的方向,通过大数据分析挖掘出有价值的信息,将对疾病的管理、控制和医疗研究都有着非常高的价值。
目前,java、云计算是已经普及并成为IT 行业的主流技术。国内外都已经进入了大数据、云计算的研究热潮,同时大数据、云计算技术也逐渐成熟,大规模区域医疗信息系统和大型数据中心的建立也在同时进行。而云计算是大数据成长的驱动力,与此同时,由于医药医疗大数据越来越多,对云计算的需求日益增长,所以二者是相辅相成的。随着医疗数据的急剧增长,如何充分利用这些数据,运用大数据、云计算技术,搭建合理先进的数据云服务平台,为广大患者、医务人员、科研人员提供服务和协助,必将成为未来信息化工作的重要方向。
“大数据时代”已经降临,“大数据”正在对每个领域都造成影响。在商业、经济及其他领域中,决策行为将日益基于数据和分析的结果,而非基于经验和直觉;而在公共卫生、经济发展和经济预测等领域中,“大数据”的预见能力也已经崭露头角。2012年3月,美国政府公布了“大数据研发计划”(Big Data Research and Development Initiative)。该计划的目标是改进人们从现有的海量和复杂的数据中获取知识的能力。其中,与医疗卫生领域相关的有生物传感2.0、虚拟实验室环境(VLE)、癌症基因组图谱(TCGA)、神经科学信息框架(NIF)、患者报告结果测量信息系统(PROMIS) 等10 余项。2014年美国的公共数据开放项目OpenFDA上线之后,先导项目开放了“300万份药物不良反应报告”,这些数据是2004至2013年间被提交给FDA的药物不良反应和医疗过失记录。对医疗机构来说,不良反应和医疗过失记录起到的是长远的贡献作用,能减少医疗悲剧的重现。
根据我国居民第三次死因调查报告显示,脑血管病已成为居民的第一死因。脑卒中发病率正以每年8.7%的速率上升,我国每年用于治疗脑血管病的费用约在100亿元以上。2014年,GE医疗中国联合国家卫生计生委脑卒中防治工程委员会(脑防委)启动了“脑卒中行动”合作战略。GE医疗“脑卒中行动”的法宝之一就是大数据。尤其是GE构建的三级筛查网络,对双侧内膜增厚的高危人群检出率提升了近10%。GE搭建的脑卒中信息管理系统可以与医院Lis和His系统全面对接,记录患者的基本信息、初筛信息、复筛信息、用药信息、实验室检查、体格检查信息及其随访信息等,全面跟踪患者的诊治流程。还可以与PACS系统对接,全面记录患者的影像学信息,实现患者影像信息的共享。同时,可对患者全流程疾病影像信息回顾,减少患者重复检查的负担,协助医生对患者疾病信息的全面判断。
在上述这些大背景下,本公司提出并计划研发“医疗大数据分析应用平台”(以下简称“本平台”)产品,以期为我国医疗卫生实现数字医疗、智慧医疗、健康医疗发挥重要作用。从而达到:服务模式(以患者为中心,形成居民健康全过程服务),从被动到主动;医疗模式(以预防为主,人人享有基本医疗卫生服务,将医疗卫生工作重点由后治前移到预防保健),从治病到防病;诊疗模式(避免各自为政,实行上下联合,专业分工),从排斥到联动;数据模式(从业务系统数据向整体数据转变,改变过去的数据不统一、不互通、不共享),从隔离到整体;技术模式(采用各种新技术手段,包括大数据、云计算、物联网、移动互联等,形成技术合力),从简单到综合的转变
二,环境介绍
语言环境:Java: jdk1.8
数据库:Mysql: mysql5.7
应用服务器:Tomcat: tomcat8.5.31
开发工具:IDEA或eclipse
前端:LayUI、JQuery
三,系统展示
首页登录
注册功能
忘记密码功能
登录成功首页图表
病人诊断处方
处方保存打印
诊疗记录
查看病人档案
医案库
中药库
添加药物
四,核心代码展示
MeRecordServiceImpl 诊疗记录功能代码
package com.medicalsys.platform.service.impl; import com.google.gson.Gson; import com.medicalsys.platform.bean.MeRecord; import com.medicalsys.platform.bean.User; import com.medicalsys.platform.dao.MeRecordDao; import com.medicalsys.platform.service.MeRecordService; import com.medicalsys.platform.util.PageUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import javax.servlet.http.HttpSession; import javax.sound.midi.Soundbank; import java.util.ArrayList; import java.util.List; /* 诊疗记录服务层 */ @Service public class MeRecordServiceImpl implements MeRecordService { @Autowired private MeRecordDao meRecordDao; @Autowired private PageUtil pageUtil; @Autowired private Gson gson; //检索记录 @Override public String findAllMeRecord(String page, String limit, String name, String time) { int count=0; List<MeRecord> meRecordList=new ArrayList<>(); //调用脚标算法 Integer[] pageindex=pageUtil.pageindex(page, limit); //检索方式判断 if((name==null || StringUtils.isEmpty(name)) && (time==null || StringUtils.isEmpty(time))){ count=meRecordDao.meRecordCount(); meRecordList=meRecordDao.findAllMeRecord(pageindex[0],pageindex[1]); }else{ if(name!=null && !StringUtils.isEmpty(name)) name="%"+name+"%"; else {name=new String(); name="%";} if(time!=null && !StringUtils.isEmpty(time)) time="%"+time.split("\\s+")[0]+"%"; else {time=new String();time="%";} count=meRecordDao.meRecordSearchCount(name, time); meRecordList=meRecordDao.findAllSearch(pageindex[0],pageindex[1],name,time); } String meRecordjson = gson.toJson(meRecordList); return "{\n" + " \"code\": 0,\n" + " \"count\": " + String.valueOf(count) + ",\n" + " \"data\": " +meRecordjson + "}"; } //今日诊疗记录 @Override public String findAllMeRecordID(String page, String limit, String name, String time, HttpSession session) { List<MeRecord> meRecordList=new ArrayList<>(); //调用脚标算法 Integer[] pageindex=pageUtil.pageindex(page, limit); //检索方式判断 if((name==null || StringUtils.isEmpty(name)) && (time==null || StringUtils.isEmpty(time))){ meRecordList=meRecordDao.findAllMeRecord(pageindex[0],pageindex[1]); }else{ if(name!=null && !StringUtils.isEmpty(name)) name="%"+name+"%"; else {name=new String(); name="%";} if(time!=null && !StringUtils.isEmpty(time)) time="%"+time.split("\\s+")[0]+"%"; else {time=new String();time="%";} meRecordList=meRecordDao.findAllSearch(pageindex[0],pageindex[1],name,time); } User user = (User) session.getAttribute("user"); List<MeRecord> meRecordListID=new ArrayList<>(); //过滤其它医生记录 for (MeRecord meRecord : meRecordList) { if(user.getId()==meRecord.getUserid()){ meRecordListID.add(meRecord); } } String meRecordjson = gson.toJson(meRecordListID); return "{\n" + " \"code\": 0,\n" + " \"count\": " + String.valueOf(meRecordListID.size()) + ",\n" + " \"data\": " +meRecordjson + "}"; } //返回指定记录 @Override public MeRecord findMeRecordById(String id) { return meRecordDao.findMeRecordById(Integer.valueOf(id)); } //添加诊疗记录 @Override public String addMeRecord(MeRecord meRecord,HttpSession session) { User user= (User) session.getAttribute("user"); meRecord.setUserid(user.getId()); int addflag=meRecordDao.addMeRecord(meRecord); if(addflag==1){ return "{\n" + " \"code\": 200,\n" + " \"msg\": \"添加记录成功\",\n" + " \"data\": {\n" + " }\n" + "}"; }else { return "{\n" + " \"code\": 1,\n" + " \"msg\": \"添加失败\",\n" + " \"data\": {\n" + " }\n" + "}"; } } //更新诊疗记录 @Override public String updateMeRecord(MeRecord meRecord) { int addflag=meRecordDao.updateMeRecord(meRecord); if(addflag==1){ return "{\n" + " \"code\": 200,\n" + " \"msg\": \"更新记录成功\",\n" + " \"data\": {\n" + " }\n" + "}"; }else { return "{\n" + " \"code\": 1,\n" + " \"msg\": \"更新失败\",\n" + " \"data\": {\n" + " }\n" + "}"; } } //删除诊疗记录 @Override public String deleteMeRecord(String[] idsStr) { int count=0; String notdelet=""; int length=0; for (String s : idsStr) { if(StringUtils.isEmpty(s)==false&&s!=null){ int deleteflag=meRecordDao.deleteMeRecord(Integer.valueOf(s)); count=count+deleteflag; length++; if(deleteflag==0) notdelet=notdelet+s; } } if(count==length){ return "{\n" + " \"code\": 0,\n" + " \"msg\": \"删除成功\",\n" + " \"data\": {\n" + " }\n" + "}"; }else { return "{\n" + " \"code\": 1,\n" + " \"msg\": \"删除"+notdelet+"失败\",\n" + " \"data\": {\n" + " }\n" + "}"; } } }
FamRecordServiceImpl医案服务功能代码
package com.medicalsys.platform.service.impl; import com.google.gson.Gson; import com.medicalsys.platform.bean.FamRecord; import com.medicalsys.platform.bean.MeRecord; import com.medicalsys.platform.dao.FamRecordDao; import com.medicalsys.platform.service.FamRecordService; import com.medicalsys.platform.util.MdFileCompare; import com.medicalsys.platform.util.PageUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.stereotype.Service; import org.springframework.ui.Model; import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.List; /* 医案服务层 */ @Service public class FamRecordServiceImpl implements FamRecordService { @Autowired private FamRecordDao famRecordDao; @Autowired private PageUtil pageUtil; @Autowired private MdFileCompare mdFileCompare; @Autowired private Gson gson; //检索医案 @Override public String findAllFamRecord(String page, String limit, String zdiagnosis, String dialetype) { int count=0; List<FamRecord> famRecordList=new ArrayList<>(); //调用脚标算法 Integer[] pageindex=pageUtil.pageindex(page, limit); //检索方式判断 if((zdiagnosis==null || StringUtils.isEmpty(zdiagnosis)) && (dialetype==null || StringUtils.isEmpty(dialetype))){ count=famRecordDao.famRecordCount(); famRecordList=famRecordDao.findAllFamRecord(pageindex[0],pageindex[1]); }else{ if(zdiagnosis!=null && !StringUtils.isEmpty(zdiagnosis)) zdiagnosis="%"+zdiagnosis+"%"; else {zdiagnosis=new String(); zdiagnosis="%";} if(dialetype!=null && !StringUtils.isEmpty(dialetype)) dialetype="%"+dialetype+"%"; else {dialetype=new String();dialetype="%";} count=famRecordDao.famRecordSearchCount(zdiagnosis,dialetype); famRecordList=famRecordDao.findAllSearch(pageindex[0],pageindex[1],zdiagnosis,dialetype); } String famRecordjson = gson.toJson(famRecordList); return "{\n" + " \"code\": 0,\n" + " \"count\": " + String.valueOf(count) + ",\n" + " \"data\": " +famRecordjson + "}"; } @Override public FamRecord findFamRecordById(String id) { return famRecordDao.findFamRecordById(Integer.valueOf(id)); } //添加医案 @Override public String addFamRecord(FamRecord famRecord) { int addflag=famRecordDao.addFamRecord(famRecord); if(addflag==1){ return "{\n" + " \"code\": 200,\n" + " \"msg\": \"添加医案成功\",\n" + " \"data\": {\n" + " }\n" + "}"; }else { return "{\n" + " \"code\": 1,\n" + " \"msg\": \"添加医案失败\",\n" + " \"data\": {\n" + " }\n" + "}"; } } //更新医案 @Override public String updateFamRecord(FamRecord famRecord) { int addflag=famRecordDao.updateFamRecord(famRecord); if(addflag==1){ return "{\n" + " \"code\": 200,\n" + " \"msg\": \"更新医案成功\",\n" + " \"data\": {\n" + " }\n" + "}"; }else { return "{\n" + " \"code\": 1,\n" + " \"msg\": \"更新失败\",\n" + " \"data\": {\n" + " }\n" + "}"; } } //删除医案 @Override public String deleteFamRecord(String[] idsStr) { int count=0; String notdelet=""; int length=0; for (String s : idsStr) { if(StringUtils.isEmpty(s)==false&&s!=null){ int deleteflag=famRecordDao.deleteFamRecord(Integer.valueOf(s)); count=count+deleteflag; length++; if(deleteflag==0) notdelet=notdelet+s; } } if(count==length){ return "{\n" + " \"code\": 0,\n" + " \"msg\": \"删除成功\",\n" + " \"data\": {\n" + " }\n" + "}"; }else { return "{\n" + " \"code\": 1,\n" + " \"msg\": \"删除"+notdelet+"失败\",\n" + " \"data\": {\n" + " }\n" + "}"; } } //处方比对 @Override public FamRecord findCompare(String zdiagnosis, String dialetype, String drugs, String page, Model model) { int count=0; List<FamRecord> famRecordList=new ArrayList<>(); //调用脚标算法 Integer[] pageindex=pageUtil.pageindex(page, "1"); //检索方式判断 if((zdiagnosis==null || StringUtils.isEmpty(zdiagnosis)) && (dialetype==null || StringUtils.isEmpty(dialetype))){ count=famRecordDao.famRecordCount(); famRecordList=famRecordDao.findAllFamRecord(pageindex[0],pageindex[1]); }else{ if(zdiagnosis!=null && !StringUtils.isEmpty(zdiagnosis)) zdiagnosis="%"+zdiagnosis+"%"; else {zdiagnosis=new String(); zdiagnosis="%";} if(dialetype!=null && !StringUtils.isEmpty(dialetype)) dialetype="%"+dialetype+"%"; else {dialetype=new String();dialetype="%";} count=famRecordDao.famRecordSearchCount(zdiagnosis,dialetype); famRecordList=famRecordDao.findAllSearch(pageindex[0],pageindex[1],zdiagnosis,dialetype); } //处方比对 if(famRecordList.size()==0){ model.addAttribute("countnum", "0"); model.addAttribute("pagenum", "0"); model.addAttribute("drugs", drugs); return null; }else { String[] strings=mdFileCompare.compare(famRecordList.get(0), drugs); famRecordList.get(0).setDrugs(strings[0]); model.addAttribute("countnum", count); model.addAttribute("pagenum", pageindex[0]+1); model.addAttribute("drugs", strings[1]); return famRecordList.get(0); } } }