基于JSP的网上处方跟踪系统(完整资料)_第1页
基于JSP的网上处方跟踪系统(完整资料)_第2页
基于JSP的网上处方跟踪系统(完整资料)_第3页
基于JSP的网上处方跟踪系统(完整资料)_第4页
基于JSP的网上处方跟踪系统(完整资料)_第5页
已阅读5页,还剩143页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于JSP的网上处方跟踪系统(完整资料)(可以直接使用,可编辑优秀版资料,欢迎下载)

基于JSP的网上处方跟踪系统(完整资料)(可以直接使用,可编辑优秀版资料,欢迎下载)长沙理工大学《软件工程综合课程设计》报告基于JSP的网上处方跟踪系统专业:软件工程班级:姓名:报告日期:2016年6月30日目录1背景与意义ﻩ1。1背景与现状 1。2趋势与前景ﻩ1。3工作基础、条件与优势 2需求分析ﻩ2.1功能与性能需求 2.2其它需求 3内容和目标 3.1主要内容 3.2预期目标ﻩ4技术路线 4.1总体功能 4。2运行平台具 4。2.1网络环境ﻩ4.2.2设备情况 4.2。3支撑软件ﻩ4。3程序语言与开发工具 4.4关键技术ﻩ5进度计划 6条件、假定和限制ﻩ7系统设计与原型UI(或系统设计与实现) 7.1数据库表设计 7.2关键算法与实现技术 7。3主要原型UI(或主要功能实现)ﻩ7.4测试方案与测试用例 7。5安装与运行情况 7.5。1安装与配置 7。5.2运行情况图 8总结ﻩ参考文献ﻩ附件:主要功能的源代码1背景与意义1。1背景与现状随着互联网不断的发展,计算机已经深入到了各行各业,计算机不再局限于对科学技术的研究,当今时代,计算机可以决解大部分的具体问题,而且有利于人们的控制,这大大方便了人们的需求。当今的中小型医院中一般还没有全面采用信息技术来进行管理,所以建议一套计算机辅助经营管理系统是必不可少的。本系统是专门为处方专门设计的,我们知道,传统的记录使用手工的方式来记录数据,但是如果用手工的方式记录数据,如果数据量很大,那么结果往往就很容易出错;而且,随着时间的积累,数据变得越来越多,且容易丢失,传统的手工管理极大的浪费了人力和财力,不能满足医师和医院之间的需求。ﻩ总的来说,使用一个高效率的系统来处理这些繁杂的流程是必须的,所以我们有必要建立一个处方跟踪系统来处理这一系列的问题,让医师可以通过系统方便的记录病史症状,开处方,查阅历史处方,保存。通过这样,这些数据能被即使、准确、有效的处理。这不仅可以提高工作效率还可以确保信息的安全和准确。1。2趋势与前景目前,国内的大多数医院均不同程度的将计算机技术应用于医院管理.该系统对软件没有太高的要求,市场上已存在各式各样的软件足以满足各方面的要求.但是不同软件之间由于需求的不一致或者是根据不同的政策标准难以实现软件统一化,现在医疗行业飞速发展,国家政策不断的推陈出新也使软件的开发出现多样化,模块的多样化造成了维护原有系统上的困难,传统的软件业务有的已经也不符合当今的要求,所以开发一款符合当今社会需求的软件是有必要的。1。3工作基础、条件和优势(1)技术可行性该系统对软件没有太高的要求,但是开发人员必须具有该软件开发的专业知识,已经开发过相关的医学管理系统,在熟悉业务的情况下进行开发,完善更多的功能业务。(2)经济可行性该软件的开发成本较低,在有前人开发的经验中开发风险小,系统投入运行后会给医院带来可观的经济效益:一方面提高了工作效率,增加了市场竞争力。另一方面,所需要的人员减少也提高了经济效益.(3)人才设备可行性对于针对医疗行业软件开发的人员是相当多的,在设备方面同样比较容易进行,所以在人才设备上是可行的。2需求分析2。1功能和性能需求功能需求:处方管理系统的构建是以医师处方为中心,实时录入病人信息,开处方,生成处方,进行数据的统计,简化了传统处方信息处理的过程。本系统的重点是跟踪处方的信息数据并处理数据,处理数据时相关的数据对象有如下有以下:(1)系统跟踪每位顾客的以下信息:ﻩ顾客姓名、电话号码、出生日期、承保公司、保险号、处方历史记录(2)每位顾客的服药史将记录下列每次处方信息:ﻩ由药房给出的唯一的处方ID号、处方开出的药物、开处方的医生姓名和电话号码、处方日期、处方终止日期、有效购药次数、配药“单位”数量(此处的“单位”可能是片、匙和毫升等-—-见后面关于药品的讨论)、如果有其它替代品,是否可以向顾客提供替代品。(3)对于药房存货的每种药品,系统应跟踪的如下:ﻩ药品名称,药品“单位”(片、匙和毫升等),哪些其它药品可以作为另一种这种药品的替代品,服用药品可能引起的副作用。(4)系统所支持的查询功能:服药史,即给定顾客的所有处方历史记录—根据顾客的要求提供的报告,某种给定药品的副作用报告,随处方一起提供某种给定药品的可替换药品列表一份给定处方是否还有购药许可:即,是否还可以凭处方购药,以及处方是否已经过期。性能需求:ﻩ(1)时间特性要求ﻩ服务器启动时间不超过1分钟;系统响应时间:用户在使用软件的过程中对各个功能模块中的鼠标点击、键盘输入等操作响应的时间不操作1秒。ﻩ(2)数据精度 要按照严格的数据格式输入,对符合数据格式要求的输入进行提示。ﻩ(3)服务器并发和可伸缩性ﻩ软件应采用界面层、应用程、数据层三层架构,若以后用户数量增多,只需要增加应用层的服务器数量,实现可裁减、可扩充和可移植等不同方面的要求.采用模块化的应用软件结构,确保系统可以灵活的扩充其业务功能,并可与其他业务系统进行无缝连接。 (4)系统安全性 数据库设计阐明使用何种方式保证系统的安全.2.2其它需求可靠性和可用性需求:出错处理需求:接口需求:Mysql、Soap、约束需求:暂无逆向需求:暂无将来可能的需求:3内容和目标3.1主要内容(1)用户信息维护,实现用户信息的录入、查询、修改以及删除等功能。(2)处方信息处理,针对不同的用户记录用户的处方信息,其中处方信息中记录处方开出的药物、开处方的医生姓名和电话号码、处方日期、处方终止日期、有效购药次数、配药“单位”数量(此处的“单位”可能是片、匙和毫升等-——见后面关于药品的讨论)、如果有其它替代品,是否可以向顾客提供替代品等信息,并可对该处方进行修改以及删除等操作.(3)处方历史查询,查询所有的处方信息,或者根据用户的信息模糊查询到该用户的处方信息。(4)处方药物信息处理,药方根据处方信息处理药物并确认处理。3.2预期目标系统必须根据需求实现核心业务上的需求内容,系统必须严格按照说明书上来开发,最终的系统必须达到需求说明书上的要求,实现一个可靠的、易用的处方跟踪系统,该系统实现了对用户信息、处方信息的一体化处理。4技术路线4。1总体功能图4。-1—1总体功能结构图图4.—1-3系统数据流图4.2运行平台4。2。1网络环境局域网网络环境以及私有的IP地址该局域网的网拓扑结构如图4-2-1-1所示:图4-2—1-1网络拓扑图4。2.2设备情况服务器端:处理器主频1000MHz内存容量64GB主机型号与数量PA—8800/2外存容量16GB设备型号与数量惠普9000rp7420/2输入及输出设备型号与数量L455有线多媒体键盘/1、S22B360HW显示器/1、N215鼠标/1数据通信设备型号与数量交换机华为S1724G/1其他专用硬件设备与数量无客户端:处理器主频不限定设备的型号与数量不限定主机型号与数量不限定外存容量不限定设备型号与数量无输入及输出设备型号与数量交换机华为S1724G/1数据通信设备型号与数量无其他专用硬件设备与数量无4。2.3支撑软件支撑软件软件版本操作系统Linuxlinuxredhat5.6以上,内核版本kernel—2.6.18-238。el5数据库管理系统Mysql5.1Web服务器Tomcat7。0浏览器Chrome46.0。2490。86其他软件JVM1.74.3程序语言与开发工具程序语言:HTML/CSS、JavaScript、Jquery、Java、Jsp、Jstl、Spring、SpringMVC、Hibernate、SpringDataJpa、Mysql开发工具:SpringToolSuit3.7、Maven3.3、Mysql5.1、Tomcat7。0、JavaRuntimeEnviroment1.7、Git项目管理工具4。4关键技术(1)HTML5WebSocketAPI客户端与服务器端进行全双工通讯,WebSocket的出现是基于Web应用的实时性需要而产生的,它允许客户端和服务器在任意时刻互相推送消息。WebSocket是下一代客户端-服务器异步通讯的方法,它本事上任然是一个基于TCP的协议,它使用ws或wss协议,可用于任意的客户端和服务器。为了建立一个WebSocket连接,客户端浏览器首先要向服务器发起一个HTTP请求,这个请求和通常的HTTP请求不同,包含了一些附加头信息,其中附加头信息”Upgrade:WebSocket”(”Upgrade:WebSocket"表示这是一个特殊的HTTP请求,请求的目的就是要将客户端和服务器端的通讯协议从HTTP协议升级到WebSocket协议。)表明这是一个申请协议升级的HTTP请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的WebSocket连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。它的通讯方式如下:图4-4—1客户端和服务器websocket通讯。图4-4—1客户端和服务器websocket通讯(2)HighChats一套由纯Javascript写的表现层框架,它提供曲线、面积、柱形图、条形图、饼图、散点图、区域范围图、气泡、漏斗等等一系列的图形表现形式。HighChars不需要像Flash和Java那样需要插件才可以运行,而且运行速度快,它是轻量级的JavaScript脚本,它使用的是json数据格式,数据传输更加方便,而且它的数据是在客户端解析的,减轻了服务器的压力,所以它比JFreeChart更方便(JFreeChart是JAVA平台上的一个开放的图表绘制类库。它完全使用JAVA语言编写在我看来JFreeChart有点笨重了,而且它生成的图形也比HighChart少,并且好像是收费的)。另外HighCharts还有很好的兼容性,能够完美支持当前大多数浏览器。(3)SpringDataJPA提供了一整套数据访问层(DAO)的解决方案,致力于减少数据访问层的开发量,并支持云服务的开源框架。SpringData作为SpringSource的其中一个父项目,旨在统一和简化对各类型持久化存储,而不拘泥于是关系型数据库还是NoSQL数据存储.无论是哪种持久化存储,数据访问对象(或称作为DAO,即DataAccessObjects)通常都会提供对单一域对象的CRUD(创建、读取、更新、删除)操作、查询方法、排序和分页方法等。SpringData则提供了基于这些层面的统一接口(Repository、CrudRepository、PagingAndSortingRepository、JpaRepository)以及对持久化存储的实现。JPA(JavaPersistenceAPI,Java持久化API)是sun提出的一个对象持久化规范,各JavaEE应用服务器自主选择实现,JPA的底层实现是一些流行的开源ORM(对象关系映射)框架(如Hibernate、OpenJPA、TopLink、Ibatis等等),因此JPA其实也就是java实体对象和关系型数据库建立起映射关系,通过面向对象编程的思想操作关系型数据库的规范。JPA,定义了对象-关系映射以及实体对象持久化的标准接口.如下图:图4-4-2JPA在应用程序中的位置:图4-4—2JPA在应用程序中的位置SpringDataJpa是SpringData对JPA提供的一套解决方案。SpringDataJpa实现了大部分的持久层的逻辑代码,你需要做的只是声明持久层的接口,其他的都交给SpringDataJpa完成。SpringDataJpa中Repository是一个空接口,CrudRepository:继承Repository,实现了一组CRUD相关的方法,PagingAndSortingRepository:继承CrudRepository,实现了一组分页排序相关的方法,JpaRepository:继承PagingAndSortingRepository,实现一组JPA规范相关的方法。相关技术方案参考SpringData实战的书籍[2]。SpringDataJpa提供的接口如下图4-4-3SpringDataJpa提供的接口图:图4—4-3SpringDataJpa提供的接口图(4)SpringMVC,SpringWebMVC是一种基于Java的实现了WebMVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求—响应模型,框架的目的就是帮助我们简化开发,SpringWebMVC也是要简化我们日常Web开发的。它的请求处理流程图如下:图4—4—2springMVC请求处理流程图前端控制器首先接收到用户的请求,前端控制器根据接收的请求信息把请求委托给页面控制器来处理。处理器接收请求后调用相应的业务对象处理请求,如果有数据库操作会向数据库请求数据,并返回一个模型视图(一般是ModelAndView),返回的模型经过视图解析器把,模型数据解析到页面中并返回给客户端。SpringMVC充分对模型、视图、控制器进行充分的解耦,并利用SpringIOC的功能更加方便管理。相关技术方案参考SpringMVC学习指南的书籍[1]。(5)REST风格URL,REST架构风格是全新的针对Web应用的开发风格,是当今世界最成功的互联网超媒体分布式系统架构,它使得人们真正理解了Http协议本来面貌.随着REST架构成为主流技术,一种全新的互联网网络应用开发的思维方式开始流行.REST是基于Http协议的,任何对资源的操作行为都是通过Http协议来实现。以往的Web开发大多数用的都是Http协议中的GET和POST方法,对其他方法很少使用,这实际上是因为对Http协议认识片面的理解造成的。Http不仅仅是一个简单的运载数据的协议,而是一个具有丰富内涵的网络软件的协议。他不仅仅能对互联网资源进行唯一定位,而且还能告诉我们如何对该资源进行操作。Http把对一个资源的操作限制在4个方法以内:GET,POST,PUT和DELETE,这正是对资源CRUD操作的实现。由于资源和URI是一一对应的,执行这些操作的时候URI是没有变化的,这和以往的Web开发有很大的区别.正由于这一点,极大的简化了Web开发,也使得URI可以被设计成更为直观的反映资源的结构,这种URI的设计被称作RESTful的URI.基于RESTURL风格的请求方式如下:图4-4-2基于RESTURL风格的请求5进度计划说明本项目的进度要求,参照软件工程的三个时期中的八个阶段时间安排问题定义3日可行性分析2日需求分析5日总体设计5日详细设计10日编码和单元测试15日综合测试5日软件维护5日操作培训3日验收测试2日项目验收2日总计为57天6条件、假定和限制(1)建议开发软件开发投入的时间:两个月(2)经费来源及限制:由需求方提供(3)软件的预期寿命:两年(4)网络环境:局域网(5)运行环境:mysql5。1,JavaRuntimeEnviroment1.7及以上版本(6)客户端环境:InternetExplorer8。0及以上的版本(7)硬件设备:处理器InterPentinm3或者更高,内存至少256M以上,硬盘至少2G(8)平台:linuxredhat5.6以上,内核版本kernel-2.6.18—238.el5(9)法律和政策:遵守相关的法律法规,以保护用户的隐私为前提开发软件7系统设计与原型UI(或系统设计与实现)7.1数据库表设计数据库名:Prescription数据库管理者账号:root密码:root账号操作权限:CREATE、DROP、DELETE、INSERT、UPDATE、SELECT、ALTERUser表:记录用户的基本信息。表User(用户表)用于保存用户的基本信息字段名数据类型长度主键描述IdInt11是用户编号NameVarchar64否用户姓名TelephoneVarchar20否电话号码BirthdayData10否出生日期insurance_companyVarchar32否承保公司Policy_numberVarchar64否保单号表7-1-1User表Department表:部门表,医师所属部门。表Department(部门表)用于保存医师的部门字段名数据类型长度主键描述IdInt11是部门编号NameVarchar64否部门名称表7—1—2Department表Position表:医师所属职位.表Position(职位表)用于保存医师的职位信息字段名数据类型长度主键描述IdInt11是职位编号NameVarchar64否职位名称表7-1—3Department表Doctor表:医师基本信息,包括两个外键,表示医师所属的部门和职位。表Doctor(医师表)用于保存医师的基本信息字段名数据类型长度主键描述IdInt11是医师编号NameVarchar64否医师姓名TelephoneVarchar20否电话号码DidInt11否医师所属部门PidInt11否医师所属职位表7—1-4Doctor表Prescription表:处方信息表,记录处方基本信息以及两个外键,一个是该处方所属的用户,另一个是处方所属医师。表Prescription(处方信息表)用于保存处方的基本信息字段名数据类型长度主键描述IdInt11是处方编号UidInt11否该处方所属用户DidInt11否该处方所属医师BeginDateDate16否处方日期EndDateDate16否处方终止日期CrawlAgainstInt4否再次抓药的次数表7-1-5Prescription表PrescriptionDetail表:处方详细信息表,记录一个处方中多个处方详细信息记录,两个外键,一个表示该处方详细所属的处方,另一个表示该处方详细中具体的药物信息。表PrescriptionDetail(处方详细信息表)用于保存处方的具体的信息字段名数据类型长度主键描述IdInt11是处方详细编号CountInt4否数量CanuseString16否是否可用替代药品Take_methodString255否服用的方式UnitString16否单位MidInt11否药物的编号PidInt11否处方的编号表7-1-6PrescriptionDetail表Medicine表:记录药物的基本信息。表Medicine(药物信息表)用于保存药物的信息字段名数据类型长度主键描述IdInt11是药物的编号NameString64否药物的名称SideeffectString255否副作用表7-1-7Medicine表Subtitute表:药物可替代的药品表,每个药物如果有可替代的药物,那么该药物将会维持一份药物替代表,其中两个字段都是外间,一个是指向具体的某个药物,另外一个是指向可替代药物的id编号。表Subtitute(药物替代表)用于保存药物的可替代药物的信息字段名数据类型长度主键描述M_idInt11是药物的编号S_idInt11是药物的标号表7-1-8Subtitute表数据库总体UML如下图7—1-9数据库UML图7—1—9数据库UML数据库设计相关技术方案参考据库设计与关系理论[4]与数据库设计与应用开发实践[5].无,由于使用了springdatajpa操作数据库,springdatajpa简化了数据库访问的操作.7。2关键算法与实现技术1。系统难点:添加一个处方信息可一次性提交多个处方详细信息(相当于每次开药方包含多种药物,每种药物的数量也不一致),每个处方详细信息中又包含了基本信息以及药品对象。为了解决该问题,每次选择和填好一种药物后都实用ajax保存到服务器上的session中,当然,在服务器上建立了两个类来暂时存放这些数据,分别是PrescriptionDetailOperator和PrescriptionOperator两个类。classPrescriptionDetailOperator{ﻩprivacount;//每个药品的数量 privateStringunit;//每个药品的单位ﻩprivateMedicinemedicine;//该药品的对象ﻩprivateStringtakeMethod;//服用方法ﻩprivateStringcanuse;//是否可以实用替代药品 //省略getter和setter方法}classPrescriptionOperator{ //声明一个map来保存多个PrescriptionDetailOperator对象,实用药品的id作为主键ﻩprivateMap<Integer,PrescriptionDetailOperator>map= ﻩﻩnewLinkedHashMap<Integer,PrescriptionDetailOperator〉();ﻩpublicCollection<PrescriptionDetailOperator>getPreDetail(){ ﻩreturnmap.values();ﻩ} //每次添加的时候都检查是否存在药物,存在则在原来的数量上增加 publicvoidaddPrescriptionDetail(PrescriptionDetailOperatorpreDetail){ ﻩIntegerid=preDetail。getMedicine()。getId();ﻩ if(map。containsKey(id)){ﻩ ﻩPrescriptionDetailOperator_preDetail=map。get(id);ﻩﻩﻩ_preDetail。setCount(_preDetail.getCount()+preDetail。getCount()); }else{ﻩ map.put(id,preDetail); }ﻩ}ﻩ//可以移除处方详细信息ﻩpublicvoidremovePreDetail(Integerpid){ﻩﻩif(map。containsKey(pid)){ ﻩﻩ ﻩmap。remove(pid);ﻩ }ﻩ}}前台使用ajax发送数据保存到服务器端:varpdid;//保存处方详细的idvar$tmp;//用于保存当前删除的对象的引用//保存更新处方详细信息functionsaveDetail(item){ﻩvarpdid=$(item)。attr(”lang”)。trim();//处方详细唯一编号ﻩvar$count;//数量ﻩvarcanuse;//是否可用替代药品ﻩvarunit;//实用药品单位 vartake_method;//服用方法 //遍历找到一个处方详细的信息 $(item)。parent()。parent()。find(".modal—body”).each(function(index){ﻩ $count=$(this).find(”#count");ﻩﻩcanuse=$(this).find(”#canuse")。find("option:selected").val().trim();ﻩﻩunit=$(this).find("#unit”).val().trim(); take_method=$(this).find(”#take_method").val().trim();ﻩ}); if(!/^\+?[1-9][0-9]*$/.test($count.val().trim())){ ﻩ$.tooltip('请输入正确的数字,该数字不能小于1!’,2000,false); ﻩ$count.val("1")。focus(); return; } //发送ajax保存处方详细信息ﻩ$.ajax({type:”POST", data:{"id”:pdid,"count":$count。val().trim(),"canuse":canuse,"unit”:unit,”takemethod”:take_method},url:window.location.pathname.substring(0,25)+"saveUpdateDetail”,ﻩsuccess:function(data){ﻩif(data){$.tooltip(’保存成功成功!’,2000,true);}else{$.tooltip(’删除失败,请检查服务器或网络状态!',2000,false);}ﻩ}, error:function(){$。tooltip('删除失败,请检查服务器或网络状态!',2000,false);}ﻩ});}2.关键SQL:(1)查询存在处方数据的用户以及处方的数量:Selectu。name,u.policy_number,u.telephone,u.insurance_company,u.uid,count(*)fromprescriptionpinnerjoinuseruwhereu。id=p.uidgroupbyp.uid;(2)。全表扫描user表查询用户对象fromUseruwhereconcat(u.name,u。birthday,u.telephone,u.insuranceCompany,u。policyNumber)likeCONCAT('%’,:search,'%');(HQL语法)(3).根据不同的年龄段统计用户的数量selectcount(*),left(birthday,4)fromusergroupbyleft(birthday,4);(4).查询所有用户的出生年份,月份,日期分布selectleft(birthday,4),substring(birthday,6,2),substring(birthday,9,2)fromuser;3.核心算法:(1)WebSocket存储和分发消息代码,基于WebSocket服务器与客户端通讯的问题,医师每添加一条处方记录或者对处方记录执行删除修改等操作时会及时通知客户端服务器数据状态的改变并及时更新获取最新的数据。针对以上的问题,我首先针对需要及时处理消息的页面与服务器建立WebSocket连接,服务器端使用一个Map保存客户端的连接,如下:privatestaticMap〈String,Session〉sessions=newHashMap<String,Session>();,每次请求时就根据session的id进行存储,对每个医师处方信息操作的页面每个在页面初始化时都与服务器(与上面处理的请求是同一个)也建立一个WebScoket连接(多个WebSocket连接到同一个请求),医师每次操作成功时立即就发送WebScoket消息到服务器,服务器根据接受到的消息遍历Map中客户端中的多个连接循环发送消息到客户端,客户端根据接受到的消息以根据消息的内容重新请求服务器上的数据。7.3主要原型UI(或主要功能实现)(1)系统登录和主界面图7—3-1系统登录界面功能作用:实现医师的登录功能图7—3-2系统主界面功能作用:介绍系统以及显示不同年龄或者部门人数占有的比率(2)用户信息管理图7-3-3所有用户的基本信息功能作用:实用highcharts像是所有的用户信息,可进行搜索图7-3-4分页显示用户信息以及操作功能作用:对用户信息进行分页处理以及显示操作图7-3—5弹出层显示可编辑的用户修改(3)处方信息管理功能作用:实现对用户信息的修改图7-3-6添加处方信息功能作用:实现添加处方信息图7-3—7弹出层选择药品功能作用:实现添加处方信息中具体的一个药品图7-3-8可搜索药品功能作用:实现药品的搜索图7—3-8添加多个药品功能作用:实用ajax保存数据,一次性可添加多个药品的信息,即一个处方中可添加多个药品信息,每个药品信息中有不同的单位,数量,服用方式和是否可用替代的药品。(3)处方记录管理图7-3-9处方历史记录的显示功能作用:实用时间轴显示每个用户开过的处方记录,该记录上记录正医师的姓名和电话,以及每个处方中多个处方详细信息,如果该药品是可实用替代药品,则列出可替代药品的药品名称.图7-3-9处方信息的修改界面功能作用:每个处方信息中都有多个处方详细,即每个处方中有多个药品信息,在该页面中可对每个药品进行修改和删除。图7—3-10弹出确认删除的模态框(4)用户处方查询图7-3—11查询所有处方记录图7-3-12实用关键字姓名搜索图7—3-13实用关键字出生年份搜索图7-3-14实用关键字电话号码搜索(5)取药信息查询管理图7—3—15实用承保单号唯一搜索图7-3—16药物管理主页功能作用:使用WebSocket实时处理处方数据,显示登记的处方信息。图7-3—16药物处理(6)系统出错管理图7-3-16处理404错误页面图7-3-17处理500错误页面7.4测试方案与测试用例制定测试计划:(1)确定测试需求(2)制定测试策略(3)建立测试通过准则(4)确定资源和进度(5)评审测试计划(6)更新测试计划设计测试:设计测试用例针对每一个测试需求,确定其需要的测试用例对每个测试用例,确定其输入的预期结果确定测试用例文档的测试环境配置对测试用例进行评审开发测试过程根据界面原型为每一个测试用例定义详细的测试步骤为每一个格式步骤定义详细的测试结果验证方法为测试用例准备输入数据在实施测试时对测试过程进行更改1.单元测试首先在项目开发中使用单元测试,如:Junit、SpringJUnit4ClassRunner进行单元测试,按照测试过程手工执行单元测试或运行测试脚本自动执行单元测试,如下:@RunWith(SpringJUnit4ClassRunner。class)@ContextConfiguration(locations={"applicationContext.xml"})@Transactional@TransactionConfiguration(transactionManager="transactionManager”)publicclassTestModule{@Testpublicvoidtest(){}}2.集成测试:使用回归测试方法,对软件的新版本测试时,验证是否解决了软件缺陷,而且保证以前所有运行正常的功能依旧保持正常,而不会影响本次的修改。按照测试过程手工执行集成测试或运行测试脚本自动执行集成测试将集成测试结果作详细记录,并评审测试结果对修改后的工作版本执行回归测试,或者对增量集成后的版本执行回归测试2。验收测试:以用户为主,前提是已经通过系统测试的软件系统,根据需求规格说明书或者概要设计文档验证需求的合理性和正确性,包括文档资料是否完整、正确,人机界面和其他方面(如,可移植性、兼容性、错误回复能力和可维护性等)是否令用户满意.7.5安装与运行情况(1)JDK1.7首先系统必须有JRE的支持,为了能够完成在该环境下的编译,最好能够安装下完整的JDK环境,JDK选用1.7或者更高的版本。(2)Maven3.3或更高的版本,本系统添加对Maven的支持,方便在不同类型的机器上完成编译工作。(3)MYSQL5。1或更高的版本,与系统集成.(4)WEB服务器,Tomcat17.0或更高的版本,为了支持WebSocket,Tomcat只有在7.0或者更高的版本中才添加了对WebScoket的支持。7。5.1安装与配置描述服务器端运行环境的配置情况,包括:安装与初始化数据库、安装与配置服务器安装、安装支撑软件、配置系统运行参数,等等。1.JDK环境配置:(1)如果系统中存在JDK1。7或更高的版本则这一步可以省略,可以实用java-version查看当前系统JDK的版本,如下图所示。首先到Oracle官网下载下载JDK,官网地址如下:www。oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html,假设当前的文件名称为jdk-7u67-linux-x64.tar.gz,进入到该文件的目录下。ﻩ(2)使用命令tar—zxvfjdk-7u67-linux-x64。tar.gz-Cpath解压到path路径下,path为你想要放置JDK的本地位置,假设我放在/home/silence/software/jdk1。7.0_67就要执行命令tar-zxvfjdk—7u67—linux-x64。tar。gz/home/silence/software/ (3)配置环境变量,在/etc/profile,这个是系统核心文件,对所有的用户都起作用,你需要以root用户才能修改,实用命令sudo—i,提示输入密码,输入密码,当前用户变为root用户,实用命令gedit/etc/profile打开profile文件,在该文件的末尾写入 JAVA_HOME=/home/silence/software/jdk1。7。0_67ﻩexportCLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/libﻩexportJRE_HOME=${JAVA_HOME}/jre exportPATH=${JAVA_HOME}/bin:$PATH命令source/etc/profile使其立即生效,cat/etc/profile可以看到如下:ﻩ(4)运行javac或者java命令可以看到即可ﻩ2.Maven安装ﻩ(1)软件下载,到apache官网地址http://apache。f/maven/maven—3/3。3.3/binaries/apache-maven—3。3。3-bin-tar-gz到本地目录下。 (2)软件解压,进入到该文件的目录,使用tar-zxvfapache-maven-3.3.3—bin。tar.gz-Cpath解压到path目录下,假设我的地址为:/home/silence/software/maven3.3则使用tar—zxvfapache—maven-3。3。3-bin.tar.gz-Chome/silence/software/maven3.3 (3)环境变量配置,到gedit/etc/profile打开全局配置文件,在上面的JDK后添加上exportMAVEN_HOME=/home/silence/software/maven3.3,最后变为 (4)执行命令mvn-v可以看见maven版本和jre版本(4)修改本地仓库地址,进入到maven目录下的conf目录,打开settings.xml,在<settingsxmlns="http://maven.apache。org/SETTINGS/1。0。0"xmlns:xsi="http://www.w3。org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache。org/SETTINGS/1.0.0http://maven。apache。org/xsd/settings—1。0.0.xsd">下添加〈localRepository>/home/silence/data/repository</localRepository>其中/home/silence/data/repository是本地文件夹路径,用来存放第三方jar包。 3。Mysql安装ﻩ(1)mysql可以在线安装,mysql服务器的安装apt—getinstallmysql—server,安装过程提示输入root密码 (2)mysql客户端安装apt-getinstallmysql-client (3)apt-getinstalllibmysqlclient-dev,实用mysql—uroot—p,输入密码,如下4.Tomcat安装 (1)到apache官网地址下载Tomcat7,地址为:http://mirrors。cnn/apache/tomcat/tomcat-7/v7.0。70/bin/apache-tomcat-7。0.70-deploye.tar.gzﻩ(2)实用命令tar-zxvfapache—tomcat-7.0.70-deploye.tar.gz-Cpath,path同上ﻩ(3)同样的,你也可以把tomcat下的bin目录添加到profile全局域中,进入到bin目录下执行./startup。sh并在浏览器中查看,如下:ﻩ5.项目编译与项目放置及服务器启动ﻩ(1)文件信息修改,数据库ip,用户名以及密码的修改,项目文件接下的src/main/resources下,找到dperties,其中jdbc。user=root//用户名ﻩjdbc.password=root//密码 jdbc。jdbcUrl=jdbc:mysql:///url地址,修改为当前服务器的ip地址 进入项目的主目录,本系统的PrescriptionTrackSystem下,执行mvnclean命令清除旧版本的编译文件。ﻩ(2)实用mvncomplier进行编译下,如果你是首次进行编译,那么系统将会下载pom.xml中需要的jar文件进行一起编译,这将需要一定的时间.ﻩ编译完成 (3)运行命令mvnpackage进行项目的打包工作,打包过的项目可以直接移植到tomcat中直接运行。(4)在当前文件夹下的target文件夹下可以找到PrescriptionTrackSystem.war(5)把上图中的PrescriptionTrackSystem.war放置在Tomcat目录下的webapps目录下,进入Tomcat文件夹下的bin文件夹,执行./startup.sh文件启动服务器。(6)访问ip+/PrescriptionTrackSystem/login.html可以访问到如下内容:7.5。2运行情况图图7—5-2—1所有用户的基本信息功能作用:查询在库的所有用户的信息记录。图7-5-2—2分页显示用户信息以及操作功能作用:对用户信息进行分页处理以及显示操作,并可对用户进行一定的操作。图7-5—2—3弹出层显示可编辑的用户修改功能作用:实现对用户信息的修改。图7-5-2-4添加处方信息功能作用:实现添加处方信息。图7-5-2-5弹出层选择药品功能作用:实现添加处方信息中具体的一个药品及一些额外信息。图7-5-2—6可搜索药品功能作用:实现药品的搜索。图7—5—2-7添加多个药品功能作用:实用ajax保存数据,一次性可添加多个药品的信息,即一个处方中可添加多个药品信息,每个药品信息中有不同的单位,数量,服用方式和是否可用替代的药品。图7—5—2-8处方历史记录的显示功能作用:实用时间轴显示每个用户开过的处方记录,该记录上记录正医师的姓名和电话,以及每个处方中多个处方详细信息,如果该药品是可实用替代药品,则列出可替代药品的药品名称。图7-5-2—9处方信息的修改界面功能作用:每个处方信息中都有多个处方详细,即每个处方中有多个药品信息,在该页面中可对每个药品进行修改和删除。图7—5—2—10查询所有处方记录功能作用:查询在库的所有的处方记录。图7-5—2-11实用关键字搜索图7-5-2—12药物管理主页功能作用:使用WebSocket实时处理处方数据,显示登记的处方信息。图7-3-16药物处理8总结本项目实现了需求中的大部分内容,实现对用户信息和处方信息维护等等一系列的功能,本项目的难点主要是数据结构比较复杂,表与表之间的关系比较复杂,处理起来比较麻烦,由于本人的设计水平有限,实现的功能比较简单,还有一些功能没有具体实现,比如权限的管理,整套系统对WebSocket的支持,没有用户方面的操作.另外,遗憾的是本项目默认的药物的数据量是不大的,确切的说应该对这些药物进行分类或者分药房管理,如果药物数据量太大的话执行起来是比较耗时间的。还有一点就是本项目没有考虑到系统的并发性,没有考虑到多个医师处理同一个处方信息的情况,当然这种情况可以添加权限来进行管理。参考资料PaulDeck著,SpringMVC学习指南。美:人民邮电出版社,20015MarkPollack,SpringData实战.美:人民邮电出版社,2014C.J。Date,数据库设计与关系理论.北京,机械工业出版社,2013SoftwareDocumentation。http://www。literatep/documentation.pdf,2001StrategiesforAgileSoftwareDevelopment.www.agliemodeling.http://www。agilemodeling.com/essays/agileDocumentation.htm,2012附件(主要功能源代码)1。实体对象(1)@Entity@Table(name=”user")publicclassUser{ @Id@GeneratedValue(strategy=GenerationType.AUTO)ﻩprivateintid;//用户id @Column(length=32) privateStringname;//用户姓名 privateStringtelephone;//用户电话@DateTimeFormat(pattern=”MM/dd/yyyy")//用户出生日期 @Temporal(TemporalType.DATE) privateDatebirthday; @Column(length=32)//承保公司ﻩprivateStringinsuranceCompany;ﻩ@Column(length=32)//保单号ﻩprivateStringpolicyNumber; @OneToMany(fetch=FetchType.LAZY,mappedBy="user",cascade=CascadeType.ALL)ﻩprivateSet<Prescription>prescriptions;ﻩ publicSet<Prescription>getPrescriptions(){ returnprescriptions; }ﻩ//省略setter和getter}(2)@Table(name=”department")@EntitypublicclassDepartment{ﻩ@Id@GeneratedValue(strategy=GenerationType.AUTO)ﻩprivateintid; @Column(length=32,nullable=false) privateStringname;//部门的名字ﻩ@OneToMany(fetch=FetchType。LAZY,mappedBy="department",cascade=CascadeType.ALL)ﻩprivateSet〈Doctor>doctors=newHashSet<Doctor>();//该部门下的医生//省略setter和getter}(3)@Table(name="position")@EntitypublicclassPosition{ @Id@GeneratedValue(strategy=GenerationType.AUTO) privateintid; @Column(length=32,nullable=false)ﻩprivateStringname;//职位的名称ﻩ@OneToMany(fetch=FetchType.LAZY,mappedBy=”position”,cascade=CascadeType。ALL) @OrderBy(value=”idASC") privateSet<Doctor>doctors=newHashSet<Doctor〉();//该职位下的医生//省略setter和getter}(4)@Entity@Table(name="doctor")publicclassDoctor{ﻩ@Id@GeneratedValue(strategy=GenerationType.AUTO)ﻩprivateintid;@Column(length=32,nullable=false)ﻩprivateStringname;//医师姓名ﻩ@Column(length=32,nullable=false)ﻩprivateStringtelephone;//医师电话@Column(length=32,nullable=false) privateStringpassword;//登录密码@ManyToOne(fetch=FetchType.EAGER,targetEntity=Department.class,optional=false) @JoinColumn(name="did")ﻩprivateDepartmentdepartment;//医师所属的部门 @ManyToOne(fetch=FetchType.EAGER,targetEntity=Position.class,optional=false)ﻩ@JoinColumn(name="pid")ﻩprivatePositionposition;//医师的职位 @OneToMany(fetch=FetchType.LAZY,mappedBy=”doctor”,cascade=CascadeType.ALL) privateSet<Prescription>prescriptions;//该医生的处方//省略setter和getter}(5)@Entity@Table(name="prescription")publicclassPrescription{ﻩ@Id@GeneratedValue(strategy=GenerationType.AUTO) privateintid; @DateTimeFormat(pattern="MM/dd/yyyy”) @Temporal(TemporalType。DATE)privateDatebegindate;//处方开始日期ﻩ@DateTimeFormat(pattern="MM/dd/yyyy”)ﻩ@Temporal(TemporalType.DATE)ﻩprivateDateenddate;//处方终止日期ﻩ@Column(length=4) privateintcrawlagainst;//有效抓要次数@ManyToOne(fetch=FetchType.LAZY,targetEntity=User.class,optional=false)ﻩ@JoinColumn(name=”uid") privateUseruser;//处方所属用户 @ManyToOne(fetch=FetchType.LAZY,targetEntity=Doctor。class,optional=false) @JoinColumn(name=”did") privateDoctordoctor;//处方所属医生ﻩ@OneToMany(fetch=FetchType。EAGER,mappedBy="prescription",cascade=CascadeType。ALL)ﻩprivateSet<PrescriptionDetail〉prescriptionDetails=newHashSet〈PrescriptionDetail〉();//省略setter和getter}(6)@Table(name="prescriptiondetail”)@EntitypublicclassPrescriptionDetail{ﻩ@Id@GeneratedValue(strategy=GenerationType.AUTO) privateintid;@Column(length=4,columnDefinition="INTdefault1”)ﻩprivateintcount;//该药的数量@Column(length=16) privateStringunit;//该药的单位 @Column(length=128,columnDefinition=”Stringdefault无建议的服用方式”) privateStringtakemethod;//服用方式ﻩ@Column(length=16,columnDefinition=”Stringdefault否") privateStringcanuse;//是否可用替代药品ﻩ@ManyToOne(fetch=FetchType.LAZY,targetEntity=Prescription.class,optional=false)ﻩ@JoinColumn(name="pid")ﻩprivatePrescriptionprescription;//该处方详细所属的处方 @ManyToOne(fetch=FetchType。LAZY,targetEntity=Medicine.class,optional=false) @JoinColumn(name=”mid") privateMedicinemedicine;//药物信息//省略setter和getter}(7)@Entity@Table(name="medicine")publicclassMedicine{ @Id@GeneratedValue(strategy=GenerationType.AUTO)ﻩprivateintid;ﻩ@Column(length=64,nullable=false) privateStringname;//药物名称ﻩ@Column(length=128)ﻩprivateStringsideeffect;//副作用ﻩ@OneToMany(fetch=FetchType.LAZY,mappedBy="medicine",cascade=CascadeType.ALL,targetEntity=PrescriptionDetail.class)ﻩprivateSet<PrescriptionDetail>prescriptionDetails=newHashSet〈PrescriptionDetail>();ﻩﻩ@OneToMany(cascade=CascadeType.ALL,fetch=FetchType。LAZY) @JoinTable(name="subtitute",joinColumns={@JoinColumn(name="m_id”)},inverseJoinColumns ={@JoinColumn(name="s_id")}) privateSet〈Medicine>substitutes=newHashSet<Medicine〉();//可替代的药品列表//省略setter和getter}2。数据访问接口(1)DoctoryRepository@Repository(value="doctoryDao")@Transactional(readOnly=true)publicinterfaceDoctorRepositoryextendsJpaRepository<Doctor,Integer>{@Modifying@Query("updateDoctordsetd.name=:name,d.telephone=:telephonewhered。id=:id")publicvoidupdate(@Param("name”)Stringname,@Param("telephone")Stringtelephone,@Param("id")Integerid); publicDoctorfindByNameAndPassword(Stringname,Stringpassword);}(2)MedicineRepository@Repository(value=”medicineDao")@Transactional(readOnly=true)publicinterfaceMedicineRepositoryextendsJpaRepository<Medicine,Integer>{}(3)PrescriptionRepository@Transactional@Repository("prescriptionDao”)publicinterfacePrescriptionRepositoryextendsJpaRepository<Prescription,Integer〉{ //根据用户id号查询处方记录 publicList<Prescription〉findPrescriptionsByUserId(Integerid); @Query("fromPrescriptionpreorderbypre。idDESC”) publicList<Prescription>find(); //更新处方,减少处方可取次数ﻩ@Modifying @Query(value="updateprescriptionsetcrawlagainst=crawlagainst-1whereid=:id",nativeQuery=true)ﻩpublicvoiddecreasePrescription(@Param("id”)Integerid);ﻩ//更新处方信息 @Modifying @Query(value=”updatePrescriptionpresetpre.enddate=:enddate,pre.crawlagainst=:crawlagainstwherepre.id=:id”) publicvoidupdate(@Param("enddate”)Dateenddate,@Param("crawlagainst")Integercrawlagainst,@Param(”id”)Integerid); @Query(value=”select,u。policy_number,u.telephone,u。insurance_company,count(*),u.idfromprescriptionpinnerjoinuseruwhereu.id=p。uidgroupbyp。uid",nativeQuery=true)ﻩpublicList〈Object[]〉showUPrescriptionCount(); @Query(value="select*fromprescriptionorderbyiddesclimit1",nativeQuer=true) publicPrescriptionfindLastPrescription();}(4)PrescriptionDetailRepository@Repository(value="prescriptionDetailDao")publicinterfacePrescriptionDetailRepositoryextendsJpaRepository〈PrescriptionDetail,Integer〉{ //更新处方详细信息 @Transactional@Modifying @Query(value=”updatePrescriptionDetaildetailsetdetail.count=:count,detail.unit=:unit,detail。takemethod=:takemethod,detail。canuse=:canusewheredetail.id=:id")ﻩpublicvoidupdateDetail(@Param("count”)Integercount,@Param("unit")Stringunit,@Param("takemethod”)Stringtakemethod,@Param(”canuse")Stringcanuse,@Param("id”)Integerid);}(5)UserRepository@Transactional@Repository("userDao”)publicinterfaceUserRepositoryextendsJpaRepository〈User,Integer>{ﻩ@Modifying @Query("updateUserusetu。name=:name,u。birthday=:birthday,u.telephone=:telephone,u.insuranceCompany=:insuranceCompany,u.policyNumber=:policyNumberwhereu.id=:id”) publicvoidupdate(@Param(”name")Stringname,@Param(”birthday")Datebirthday,@Param(”telephone”)Stringtelephone,@Param(”insuranceCompany")StringinsuranceCompany,@Param(”policyNumber")StringpolicyNumber,@Param("id")Integerid); //根据搜索关键字查询用户ﻩ@Query(”fromUseruwhereconcat(u。name,u.birthday,u。telephone,u。insuranceCompany,u。policyNumber)likeCONCAT('%',:search,’%')”)ﻩpublicList<User>findUserByAll(@Param("search")Stringsearch);//根据承保公司计算用户的数量 ﻩ@Query("selectcount(*),insuranceCompanyfromUserugroupbyu。insuranceCompany")ﻩpublicList〈Object[]〉countUser();ﻩ//根据不同的年龄段统计用户的数量 @Query(value="selectcount(*),left(birthday,4)fromusergroupbyleft(birthday,4)”,nativeQuery=true)ﻩpublicList<Object[]〉findByAgeCount();ﻩ//查询用户的出生年份,月份,日期ﻩ@Query(value="selectleft(birthday,4),substring(birthday,6,2),substring(birthday,9,2)fromuser",nativeQuery=true) publicList<Object[]>findByYearMonthdayDay();ﻩ//根据用户的电话号码判断是否存在ﻩ@Query(”fromUseruwhereu.telephone=:telephone")ﻩpublicUserexist(@Param("telephone")Stringtelephone);}3.业务层接口和类(1)publicinterfaceBaseService〈T〉{ publicvoidadd(Tt);ﻩpublicTsearch();ﻩpublicTfind(Integerid); publicList<T〉find(String[]Param); publicList〈T〉get(Integerid); publicTfind(Tt); publicList〈T>find(); publicvoiddelete(Tt);publicvoiddelete(Integerid);ﻩpublicList<Object[]>get(); publicList<Object[]>get(Tt); publicvoidupdate(Tt);publicvoidupdate(Integerid); publicLongcount();ﻩpublicList〈T〉findPage(intpage,intpageSize); publicTexist(Tt);}(2)publicclassBaseServiceImpl<T>implementsBaseService〈T〉{ @AutowiredﻩprivateJpaRepository〈T,Integer>dao; publicvoidadd(Tt){dao。save(t);} publicTfind(Integerid){returndao。findOne(id);}ﻩpublicTfind(Tt){returnnull;} publicList〈T>find(){returndao.findAll();}ﻩpublicvoiddelete(Tt){dao.delete(t);} publicvoiddelete(Integerid){dao。delete(id);}ﻩpublicvoidupdate(Tt){}ﻩpublicLongcount(){returndao。count();} publicList〈T>findPage(intpage,intpageSize){ﻩ if(page〈1){page=1;} if(pageSize<1){pageSize=16;}ﻩﻩPageablepageable=newPageRequest(page-1,pageSize); ﻩreturndao。findAll(pageable).getContent(); } publicList〈T>find(String[]Param){returnnull;}ﻩpublicList〈T>get(Integerid){returnnull;} publicList〈Object[]>get(){returnnull;} publicList<Object[]>get(Tt){returnnull;}ﻩpublicTexist(Tt){returnnull;}ﻩpublicTsearch(){returnnull;} publicvoidupdate(Integerid){}}(3)@ServicepublicclassDoctorServiceextendsBaseServiceImpl<Doctor〉{ﻩ@Autowired privateDoctorRepositorydoctorDao;ﻩ@Override publicDoctorfind(Doctort){ﻩ returndoctorDao.findByNameAndPassword(t。getName(),t.getPassword());ﻩ}}(4)@ServicepublicclassMedicineServiceexte

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论