标题 | 基于微信公众平台的医院预约挂号服务系统实现 |
范文 | 于浩佳++陈波 摘要:为方便患者挂号就医并缓解医院排队挂号的拥挤问题,设计并实现了基于微信平台的医院信息动态查询与挂号系统。介绍了基于微信平台的网页开发,基于PHP实现的动态网页生成和网页信息抓取和以Web代理为核心的网页移植技术。建立了一个微信公众号开放给患者进行方便的查询和挂号等操作,同时考虑到移动端设备的多样性将系统设计成响应式布局。该服务系统具有灵活性高、适应性强、时效性强等特点。 关键词:微信平台;Web代理;挂号预约;动态网页 中图分类号:TP319 文献标识码:A DOI: 10.3969/j.issn.1003-6970.2015.10.025 引言 手机即时通讯应用“微信”给我们带来了一种全新的“微生活”方式。2012年8月推出的微信公众平台,由于提供多媒体信息大规模推送、定向推送(可按性别、地区、分组等指标定向推送)、一对一互动、多样化开发和智能回复等功能,成为继微博之后又一重要的运营平台。当前,微信公众平台有3万认证账号,其中超过七成的账号为企业账号,主要服务于媒体、营销、客服、公共服务等应用。目前国内也有许多学者和企业在进行微信方面的研究和开发。 随着移动设备的普及,近年来移动医疗产业也日渐发达,市场规模已从2012年的不到2亿元发展到了如今的28亿元,甚至有望在2017年突破125亿元,移动医疗具有广阔的发展前景。基于微信实现移动医疗服务,能够拓展微信平台应用领域,使其服务大众、便利大众。 南京12320卫生网2012年开始提供网上在线预约挂号服务,本文工作是基于微信官方为公众号提供的相关接口和服务,设计与开发面向移动端用户的医院预约挂号系统,使用户可以在移动端通过关注微信号就能便捷的实现预约挂号等操作,并通过微信公众号的群发功能为用户推送最新的可预约专家信息以及第一手健康咨询。 接下来本文首先介绍预约挂号服务与功能设计,然后再详细介绍各个功能模块实现的技术细节。 1 系统设计 我们首先进行了调研分析,确定用户挂号流程。南京卫生网站www.nj12320.org提供的挂号方式比较灵活,用户可以从网站上医院、科室、医生等任一浏览位置开始选择挂号。但这种方式并不便捷,而且也不符合移动端用户的操作习惯,因此我们决定采用一种适用于移动端的固定挂号流程:让用户首先选择医院,然后选择该医院的具体科室,再选择医生,最后再选择看病具体时间,用户在最终决定选择预约挂号后才需要登录完成整个预约挂号操作。 由此确定系统功能模块如图1所示。在公众号中有两个菜单选项,预约挂号和用户管理。在预约挂号功能下,共有6个核心功能模块。索引模块提供不同页面的索引,作为主页;选择医院、科室、医生模块分别是进行对应项的选择,全部选择完毕后进入登录模块进行登录,登录成功后确认预约,完成全部操作。在用户管理菜单中,可以查询预约结果,或者取消已完成的预约,其中具体取消规则要按照卫生网相关协议进行。 如图2所示,预约挂号服务系统由4部分构成,分别是用户微信客户端、微信公众平台服务器、南京卫生网服务器和预约挂号服务系统所在服务器。4部分之间按照箭头关系分别进行消息交互。用户发出的信息请求部分交由微信官方服务器处理,例如用户发送的文字信息会通过微信官方服务器传输,经过上传部署好的本服务系统代码进行处理进行相应的自动回复;还有部分信息直接交由本预约服务系统处理,例如用户选择预约服务菜单发出的请求。本服务系统提供给用户的所有信息都来自于南京12320卫生网,从而确保用户获取信息的实时性。另外,整个预约挂号服务过程中的消息交互对用户都是透明的。 本服务系统各模块之间的工作流程如图3所示。用户通过点击菜单向微信服务器发起访问请求,微信服务器把请求转交给系统服务器,系统服务器把请求网页返回给用户,用户在网页上进行相关查询操作,系统服务器则动态响应这些操作,从卫生网服务器请求用户所需信息并予以返回。最后,用户确认预约请求,卫生网服务器接受到请求后如预约成功,则直接向用户手机发送短信进行通知。 2 系统开发 2.1 系统开发环境 (1)硬件环境 服务器端:英特尔酷睿I5处理器,WIN7专业版64位,4G内存,500G硬盘。 客户端设备:装有微信5.0以上版本的智能手机。 (2)软件环境 服务器端:装有IIS的Windows操作系统;装有PHP5。 客户端:装有微信5.0以上版本。 2.2 微信公众平台对用户文字消息的处理 为了把挂号系统移植到微信平台,首先要注册一个微信公众号。微信提供了服务号、订阅号、企业号和测试号给用户使用,其中测试号可以免费试用所有的接口和功能,本文为了叙述清晰和开发过程重现,选择注册微信测试号。注册完成后会需要填写URL和Token,验证开发者是否拥有自己的服务器资源,并进行Token的验证,此处填写的URL需要正确响应微信发送的Token验证。具体操作是从微信官方网站下载wx_sample.php文件,用Dreamweaver打开编辑,将代码中的define(”TOKEN”,”weixin”);中的”weixm”改成白定义Token值,要注意在“修改”一“页面设置”中将代码的编码改为UTF-8,勾选“不包括BOM”,否则Token无法验证。代码修改完成后将其部署到SAE,把代码部署位置的路径填写到URL处,并点击进行验证。 完成上述操作后,首先编写代码实现基本文字消息的处理。接口配置已经完成,对刚才使用的验证代码进行修改,来实现一些简单的消息回复功能。 将“$wechatObj->valid();改成$wechatObj->responseMsg();”然后对responseMsg()函数进行修改。在“$msgType=”text”;”后添加一个switch语句,通过对$keyword的匹配来进行关键词回复。例如: case”你好”; $contentStr=”你好!”; break: 除此之外,微信公众号还能自动回复类型丰富的消息类型,例如:图片消息、语音消息、视频消息、音乐消息、图文消息等等。微信的官方文档为不同的消息类型提供了对应格式,按照官方格式在代码中修改$textTpl变量即可回复对应消息类型。 2.3 用户端菜单设计与实现 除了各种类型消息的处理,本系统要求公众号必须拥有白定义菜单来为用户提供进入系统的方便的入口。 根据微信官方提供的文档,目前自定义菜单最多包括三个一级菜单,每个一级菜单最多包含5个二级菜单。一级菜单最多4个汉字,二级菜单最多7个汉字,多出部分将以”……”代替。创建白定义菜单后,微信客户端将延迟一段时间后才展现出来。用户创建自定义菜单时,用注册帐号时系统分配的appID和appsecret同微信服务器以POST方式发送一个HTTP请求,从而获得一个ACCESS—TOKEN值,获得这个值后就能根据官方文档提供的创建自定义菜单的格式创建属于自己的白定义菜单了。发起第一次请求的代码如下: $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false): curl_setopt($ch,CURLOPT_SSL_VERIFYHOST.false): curl_setopt($ch,CURLOPT_RETURNTRANSFER.1): $a=curl_exec($ch); $strjson=json_decode($a); $token=$strjson->access_token; 至此完成一次POST请求并保存获得的ACCESS_TOKEN值。完成验证后,就可以创建自己的自定义菜单了。创建白定义菜单的代码格式由微信官方给出,此处不再赘述,但要注意在用PHP写这段代码时要在引号前加转义符,例如\”button\”,否则在发送这个创建请求时服务器将不会识别,并返回一个错误码。还要注意编码必须为UTF-8,否则也会报错。在写完自定义菜单的代码后,再次调用cURL函数发送一次POST请求,代码如下: $url=”https://api.weixin.qq.com/cgi-bin/menu/create?access_token={$token)”; $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS,$post): curl_exec($ch); curl_close($ch); 当返回{”errcode”:0,”errmsg”:”ok”}时候,证明请求成功,在等待一段时间后即可在微信客户端看到白定义菜单的效果。如图4所示。 2.4 系统各主要模块实现 (1)索引模块 索引模块就是默认主页index,本系统的主页是一个静态网页,提供进入各个模块的链接,是一个导航页面。因为这是系统开发过程中的第一个网页,因此要先进行网页设计,把样式表CSS做好,以实现响应式布局。此处的网页设计是下载了开源的CSS框架进行修改,之后的各个模块都将采用这个框架。 其中,各个链接都设置成标题hl,并居中: (2)医院选择模块 在前期的调研分析中发现,南京卫生网提供的信息是经常更新的,并且未来可能会有更多的医院加入这个系统,因此这个模块要设计成动态更新的网页。用户每次打开网页前,后台运行一段程序,向南京12320网发起一次http请求,并通过正则表达式匹配获得当前所有医院信息。获得这些信息后再生成网页展示给用户,如此避免用户选择一个无法挂号的医院或用户找不到想要去的医院。 获得医院信息的重点在于正则表达式的匹配,此处为: preg_match_all(/HospitalDesc\(\(\d+)\\)\”\>(\W+)\ 其中(\d+)是要匹配的医院名,(\W+)是要匹配的医院id,这个id是下一步选择科室模块要发起http请求的目的url地址的重要元素。将医院名和医院id分别保存在两个数组中,然后将医院名展示在网页上,医院id则作为option标签的值保留下来。 在具体实现时,还发现了一个问题。在获得医院信息的url地址中,一个地址只显示10个医院的信息,要更多的医院信息则需要访问更多的url地址。如果一个个的枚举显然效率太过低下。在观察url地址后发现,url地址中有一个“start={}”,只要修改大括号中的数字就能实现对不同地址的访问并得到所有医院信息。由于具体医院数量是未知的,因此调用foreach函数遍历一下即可,主要代码如下:
for($n=0;$n<=50;$n+=10){ $url=”http://www.nj12320.org/weixin/wx/qdefault.php?__op=oho_online&i_f_djklfe_d=s6057240&show_num=lO&start= {$n)”; preg_match_all(/HospitalDesc\(\(\d+)\\)\”\>(\W+)\ foreach($matches as $hid){$a口=$hid;) foreach($matches as $hname){$b口=$11name;}} for($i_0;$i print””;}/*用于动态生成网页信息*/ (3)科室选择模块 科室选择模块中,若把所有可挂号的科室全部显示出来显然太多了,不利于用户选择,因此本系统的科室选择模块做在医院选择模块之后,在用户选好医院后,再根据这个医院的id向对应url地址发送一次http请求,获得当前该医院可挂号科室的信息并展示给用户。 具体代码实现和医院选择相似,此处的正则表达式为: preg_match_all(/onclick\=\“keshi\((\d+),\(\W+)\\)\”\>/i,$f,$matches); 同样的既要保存科室名显示,也要保存科室id做下一步工作。 $hos=$_POST[”hospital”]; $ke=$_POST[”zjzk”]; $url=”http://www.nj12320.org/weixin/wx/qdefault.php?mod=yy_{$ke}&id={$hos}&hospital=”; $f=fle_get_contents($url); preg_match_all(/onclick\=\”keshi\((\d+),\(\W+)\\)\”\>/i,$f,$matches); foreach($matches as $keid){$a口=$keid;) foreach($matches as $kename){$b口=$kename;, for( $i=0; $i (4)医生选择模块 此模块仅展示医生的名字,并不显示具体就诊时间和挂号费,主要是为了给寻找特定专家的用户提供服务,对普通用户的意义并不太大。具体代码实现和医院选择相似。此处匹配所用的正则表达式为: preg_match_all(/data-docid\=\”(\d+)\”\sdata-docname\=\”(\W+)\”/i,$f,$matches); (5)登录模块 南京12320卫生网的登录功能是通过javascript函数实现的,由于本系统的代码不是部署在其服务器上,因此如果也采用javascript函数进行登录会出现跨域访问的问题,根据互联网相关安全协议,无法发出登录的http请求,所以本系统采用的方法是用PHP重写登录函数,进行第三方登。 首先用Wireshark抓取了官方网站的登录报文,如图6所示。可以看到此处的帐号、密码和验证码是明文传输的。再记录下http数据包的其他头部信息,用PHP构造一个完全相同的数据包。 $data=”username=$u&password=$p&verifyCode=$v”;/*用户名,密码,验证码*/ $time=number_format(microtime(true),3,”,”);/*时间戳*/ $url=”http://www.nj12320.org/njres/indexjson/login.do?timestamp=$time&ajax=true”; curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_HTTPHEADER,array(/*头部信息*/). curl_setopt($ch,CURLOPT_POSTFIELDS,$data): curl_setopt($ch,CURLOPT_COOKIEFILE,$cookie_jar); 代码中的$cookiejar是在验证码获取时服务器返回的一个cookie值,这个cookie必须保存下来,然后在向服务器递交用户名密码和验证码时把这个cookie添加到http请求的头部才能成功登录。因为把验证码从服务器下载后展示给用户,而直接在验证码所在的img处添加url地址无法保存cookie,为了解决这个问题,本系统采用的方法是先发起请求将验证码和cookie保存在系统服务器上,然后在显示验证码时将img标签的src属性填写成本地地址。 $cookiejar=tempnam(”./temp”,”cookie”);/*创建临时文件,保存cookie*/ $f=fopen(”yzm.jpg”,”w”);/*创建图片文件,之后把验证码图片以数据流写入其中*/ $url=http://www.nj12320.org/njres/authhng.do:
curl_setopt($ch,CURLOPT_FILE, $f);/*在选项中加入CURLOPT_FILE来将验证码写入*/ (6)确认预约模块 预约模块是本系统的重中之重。首先,预约界面的显示和前面几个模块一样是实时更新、动态生成的,此处用了三个正则表达式: preg_match_all(/javascript\:toconfirm\((\d+)\)\”i,$f,$matches0); preg_match_all(/出诊时间:([\W\W]*?)/,$f,$matchesl): preg_match_all(/挂号费:([\w\W]*?)n>/, $f,$matches2): 分别用于匹配本次预约的代号,出诊时间和挂号费。如果没有匹配到任何信息,则输出“对不起,暂无可预约时间。” 在用户点击确认预约后,系统跳转到登录界面进行登录,登录成功后系统会自动开始预约操作,若挂号成功则用户会在一段时间内收到12320的短信通知。如果登录失败,则提示失败信息并3秒后返回登录界面。 此处实现登录和实现预约的程序分属不同文件,而在这两个功能之间需要进行cookie的传递,故涉及到了PHP中超级全局变量的问题。本系统采用session来进行文件间的变量传递。首先,在登录处用session—start函数初始化session,然后创建一个临时文件用于保存之后产生的cookie,把指向这个文件的变量$cookiejar保存到session中,最后在完成预约的文件中用session start初始化session后就能访问这个跨文件变量了。 由于是第三方访问,因此稍有不慎就会被官方服务器判定为不安全行为,所以必须把http请求模拟的和官方自己发送的请求一模一样才行。实现Web代理的同时存在着一定的安全隐患,但由于本系统无法获得南京卫生网的服务器资源,且仅作学习研究用,因此这些安全问题暂不予考虑。 3 系统运行实例 图7a是系统登录界面,对于没有帐号的用户还可点击注册新账号进入帐号注册界面,如图7b所示。这两个界面运用了大量的htm15+css3的新特性,力求做到简洁美观。 图8是医院选择界面,此处要同时选择医院和专家/专科后再进入下一步,若不选择专家/专科,系统将自动默认选择专家号,因为绝大多数用户都会选择专家号。选好医院并点击选择科室后,系统会提交此表单。 在选择医院后,还要分别选择科室和医生。选择科室列表中出现的信息是根据用户选择的医院来显示的,同样,医生信息也是根据科室来显示的,这样就避免了用户接受不需要的冗余信息。实际效果如图9a和9b所示。 在所有选项都选择完成后,会显示可预约的医生信息,包括可预约时间和挂号费。(其余信息都是用户自己选择的,因此不再显示)如图10所示。如果当前用户选择的医生没有可预约的时间,则会显示“对不起,暂无可预约时间”。用户需返回重新选择别的医生。 4 结论 本文设计实现的基于微信平台的医院预约挂号系统能够为用户就医带来极大的方便。首先基于微信平台,用户不需要再去下载额外的APP占用手机资源;其次,通过手机预约,可以做到真正的随时、随地;最后,微信发展速度快,扩展性强,方便未来随时升级此系统。 本系统还可以扩展许多功能,例如:自动识别验证码,在线支付挂号费,预约时间闹钟提醒,医院查询,医生查询和电子病历等,可以此为用户提供一整套的移动端医疗服务。 |
随便看 |
|
科学优质学术资源、百科知识分享平台,免费提供知识科普、生活经验分享、中外学术论文、各类范文、学术文献、教学资料、学术期刊、会议、报纸、杂志、工具书等各类资源检索、在线阅读和软件app下载服务。