毕业设计之微信小程序

0x00 微信小程序简介

  上文介绍了站牌部分的实现以及整个系统的设计思路,本文介绍微信小程序客户端和服务端功能的实现,客户端主要实现GPS数据上传和主界面公交数据显示,服务端主要实现站牌和小程序客户端之间的数据交换。微信小程序是腾讯在2017年推出的一个运行在微信上的应用,在微信中打开小程序类似于在浏览器中打开网站(电脑版微信不行)。它们的主要区别是小程序除了可以实现类似浏览器的功能以外,还可以借助微信的用户数据、腾讯云和手机等终端中的硬件实现更多更灵活的应用。
  微信小程序一般由逻辑层和视图层构成。逻辑层负责请求数据,处理数据,响应视图层产生的事件,逻辑层使用JavaScript编写;视图层负责渲染画面,刷新数据,视图层使用WXML(微信标签语言,用于描述页面结构)和WXSS(微信样式语言,用于描述页面样式),此处的WXML和WXSS类似于网页中的HTML和CSS,更加详细的介绍及特性见官网,这里的简介仅为方便理解后文。

0x01 一些基础概念

  我的毕设小程序是以腾讯官方提供的Node.js小程序Dome程序为基础,Dome地址:https://github.com/tencentyun/wafer2-quickstart-nodejs。下图是Node.js Dome解压后的目录说明。当然此Dome也有PHP版:https://github.com/tencentyun/wafer2-quickstart-php,它们的主要区别是后端运行环境不同。

小程序目录

0x02 客户端部分

注:因为微信开发者工具和API升级的原因,最新的客户端编译运行可能会报错。
使用的微信开发者工具版本:V1.02.1806120
调试基础库版本:1.9.94

  客户端的设计思路是定义两个界面,一个界面显示公交信息及传感器数据,面向所有人。另一个界面需输入账号密码才可能看见,只面向模拟公交车的人,因为专门的定位数据采集并支持上传服务器的模块比较贵,所以选择使用手机实现定位数据上传功能,进入此界面后,小程序每隔两秒向后台发送当前手机经纬度和速度。客户端代码地址:/WeChat_demo/client

  为了最终实现客户端的功能,每个页面都需要编辑上面4个文件。腾讯官方有小程序详细教程:https://developers.weixin.qq.com/miniprogram/dev/。不过前提是需了解JavaScript语法及基本特性,当时自学大概一个月,勉强会用,所以微信小程序这部分代码里有很多写法可能不对。

  • .js 文件:小程序逻辑文件,由JavaScript编写,实现小程序的处理逻辑。
  • .json 文件:小程序配置文件。
  • .wxml 文件:小程序页面结构描述文件。
  • .wxss 文件:小程序页面样式文件。

2.1 小程序配置文件

  • project.config.json:工程全局配置文件,包括appID,客户端和服务端代码存放路径等。
  • app.json:客户端配置文件,定义小程序的页面排列,背景颜色,页面名称等。
  • config.js:客户端后台接口配置文件,定义后台接口地址,微信登录接口等,如下图所示。

客户端配置

2.2 定位及经纬度上传功能的实现

  定位功能页面:/WeChat_demo/client/pages/location。微信提供读取当前手机所在经纬度、发起网络请求和在小程序内打开地图等很多API,所以只需正确并适合的调用API即可实现。

  • 读取经纬度API:wx.getLocation;
  • 打开地图API:wx.openLocation;
  • 发起网络请求API:wx.request;

  为达到功能主要实现了3个函数,分别绑定小程序界面上的3个按钮,其中 “openlocation”函数绑定方式稍有不同,该函数由 submit 事件触发,此事件和其他两个函数触发事件的区别是 submit 事件会传入绑定的表单数据,在这里的表单数据时经纬度和速度。当点击按钮后产生事件触发函数开始循环执行并向后台系统上传数据。界面如下图所示。

定位界面

2.3 首页主界面的实现

  根据设计思路,需要设计一个面向所有人的主界面,显示公交信息和传感器数据。主要用到的API是网络请求:wx.request;因为数据处理,状态更新等全在后台,所以只需请求数据显示即可。在实现的时候引用了一个开源项目:wxSearch,帮助我实现站点搜索功能,在此感谢“wxSearch”的作者:icindy。首页代码:/WeChat_demo/client/pages/view。效果图如下所示。

主界面

  主界面实现的主要难度是wxSearch模块和自己页面的结合,包括向后台请求的数据需和搜索输入的站台一致,还有页面布局等。此界面主要实现以下几个函数:

  • bindPickerChange:绑定站台选择按钮,使用微信的滚动列表样式实现站台的滚动选择。
  • usrcloud:实现向后台自动请求站台数据功能。
  • Click:绑定主界面 查询 按钮,在第一次点击按钮时调用usrcloud函数,因为多次调用小程序会向后台频繁请求数据。
  • 其他就是wxSearch模块需要的函数。

  目前主界面定位界面中还存在的bug:

  • 当模拟公交车的定位手机距离主界面选择的站台很近时,会出现距离显示出现很多位小数的情况,直接挤乱布局。
  • 所有站台的传感器数据都是一样的。
  • 定位界面可能会上传速度为-1的错误数据。
  • 定位界面定位时GPS信号可能受高楼影响,导致定位点跳动。

0x03 服务端部分

  服务端算是整个系统的大脑,接收数据,处理数据,下发数据。腾讯云提供的Node.js Demo中的后台部分程序基于Koa2框架(什么是Koa2?),Demo基本架构已经具备,只需实现网络请求和数据处理逻辑即可。服务端代码:/WeChat_demo/server,整个后台大致可分为控制器(controllers)、中间件(middlewares)、路由(middlewares)和主程序(app.js)四个部分,其他还有一些配置文件和node.js模块文件。一个请求进入Koa2框架到返回响应的完整大致流程是:主程序收到请求 -> 路由分发请求 ->控制器执行相应处理逻辑 -> 响应中间件调用控制器 -> 主程序向客户端返回响应。这是一个请求的完整执行流程,Koa2的中间件类似于堆栈机制,一层一层的执行直到最后一个中间件或者业务已执行完毕再反向一层一层的返回,并且这些中间件的执行是异步的,之后的中间件不会被之前的阻塞。

3.1 主程序

  主程序主要初始化整个服务并监听端口等待客户端请求,这里监听的端口是5757,至于客户端请求的是一个url,而url到后台ip之间的解析过程腾讯云已经做好,所以直接使用即可,如下图所示。

主界面

3.2 路由

  路由的作用是把不同请求定向到响应的逻辑函数,比如请求的url都是:https://xkmg9m2k.qcloud.la/weapp/location;可能有GET请求和POST请求,需要分别定位到不同的响应函数,这里主要定义3个路由,小程序有一个GET和一个POST请求,公交站台有一个GET,如下图所示。
示例:router.post(‘/location’,controllers.location.post);意思是如果服务器收到对url:https://xkmg9m2k.qcloud.la/weapp/location 的post请求,则调用控制器中location对象的post函数处理请求。

主界面

3.3 中间件

  其实路由也是个中间件,不过框架已经封装过,可作为一个独立模块使用。这里只使用一个叫 response 的响应中间件,它的作用是控制器各函数处理完各种请求或者请求超时返回错误时向客户端返回响应,包括响应状态和数据等。通过中间件可以灵活实现多样化的业务逻辑,中间件也是Koa2框架最典型的特点之一。

3.4 控制器

  控制器主要处理路由分发的客户端请求。这里主要实现站台数据、定位小程序数据和小程序主界面请求的处理。location控制器负责处理定位小程序和小程序主界面数据请求;usrcloud控制器负责站台数据请求。使用global属性可两个控制器之间的数据共用,类似于全局变量。

3.4.1 location控制器

  有post和get两个函数,post函数处理定位小程序数据,大概逻辑如下:收到定位经纬度数据后,计算当前定位点到规划站点(已提前测量记录站点经纬度)之间的距离,规划站点如下图,储存距离定位点最短的两个点,下一次定位数据刷新的时候再次计算,比较两次与两个点之间的距离变化,就能判断出当前定位点的运动方向和位置(本该是用电子地图判断位置,但是我没有,所以采用这个粗略的方法处理),知道方向和位置就可计算出到各个站点的距离,再除以数据速度即可得出到达各个站点的预测时间;get函数处理小程序主界面请求,大致逻辑如下:收到小程序主界面请求后,更具请求的站点编号,读取当前系统的状态和数据,如果系统正常,返回模拟公交车(定位点)到达请求站点的预测时间和距离,还有站点的温湿度数据,如果系统异常,则返回公交系统未准备好。

站点规划

  AB两个经纬度坐标点间距离计算公式如下,A点经纬度(WA,JA),B点经纬度(WB,JB),使用前需把经纬度角度值转换为弧度值。

距离计算

  公交车行驶方向计算方法如下,核心思路是比较两次公交车定位点经度差值和维度差值,比较经纬度差值和公交车靠近的站可得出公交车方向,示意图如下,比较BC和BD大小,同时和公交车正在靠近的站点一起即可得出公交车方向。因为靠近站点和远离站点都可能距离站点最短(还有公交线路的正反两个行驶方向,代码里写了但是未使用。),所以还需结合两个经纬度的差值才能判断方向。例如:图中的A点为第一次定位,B点为第二次定位,BF小于AF,公交车靠近F(明理楼站),若AC大于AD,则公交车在经度线方向,否则公交车在纬度线方向,图中AC大于AD,所以公交车方向为23(院士林到艺术楼站方向)。

方向计算

3.4.2 usrcloud控制器

  js文件中post和get函数都有,但是最后只使用get函数,响应站台的get请求,get函数并不复杂,大致逻辑如下:收到站台的get请求后,读取站台的状态和传感器数据,如果公交系统再运行,则返回公交状态和公交到达站点的时间和距离,否则返回系统未准备好;站台的时间更新也是从服务器获取的,单片机获取时间后,再用定时器更新。

0x04 其他

  小程序中的admin.js,mqttwsWx31.js和usrCloudWx.js文件是配合有人科技哪个串口转GPRS模块使用的,有人科技提供了一个后台服务API和微信小程序实例,它们的后台接口使用mqtt消息协议,通过此接口可读取GPRS模块的数据,但是我想在小程序的后台上读取到GPRS模块数据,没有找到koa2框架下的mqtt消息读取模块。所以在小程序中写了个admin.js,实现从有人科技的后台API读取数据,再上传到小程序后台的一个数据中转。usrcloud中的post函数就是为中转函数而设计的,但是后来实现了GPRS模块直接向微信后台发数据,所以弃用数据中转的方式。

-------------本文结束感谢您的阅读-------------