智能停——基于云计算的停车服务平台

目 录
1.系统功能概述 3
2.系统设计 3
2.1系统总体架构 3
2.2收费规则设计 5
2.3核心功能模块 1
3.系统功能操作说明 1
3.1用户操作 1
3.1.1 登录 1
3.1.2 注册 3
3.1.3 忘记密码 4
3.2停车场管理员 6
3.2.1 首页 6
3.2.2 停车场管理 8
3.2.3 设备管理 19
3.2.4 车辆管理 21
3.2.5 报表管理 23
3.2.6 公告发布 29
3.3系统管理员 31
3.3.1 首页 31
3.3.2 停车场管理 32
3.3.3 统计分析 33
3.3.4 用户数据 43
4.源代码 46
4.1服务端 46
Service实现层 213
POJO类 297
Fare收费规则模块 396
Constant常量 430
Utils工具类 434
程序入口 488
Mapper层 491
Mapper Xml编写 512
配置文件 614
config 框架配置 619
conf 项目配置 634
项目依赖 638
4.2客户端 642
4.2.1 用户界面UI 642
4.2.2 组件 651
4.2.3 页面 668
4.2.4 路由配置 668
4.2.5项目总配置 674
4.2.6项目入口文件 677

1.系统概述
利用物联网、移动互联网通信技术和云计算技术,建设一体化的停车服务平台,实现的主要功能包括:通过扫车牌,实现车辆的自动入场、计(时)费,以及自动收费和出场功能,全程.实现停车场的无人值守,降低运营成本;借助云端服务,通过集中托管各停车场的位置、停车位数量等信息,并实时采集各停车场的可用停车位的数量等信息,为移动终端用户实时查询并推荐可用的停车位,且基于位置服务,为移动终端用户导航到所预约或预定停车位所在的停车场,这在一定程度上缓解停车难的问题;基于大数据分析,统计并发布区域内各个停车场的使用状况,含使用效率、繁忙时段等信息,移动终端用户可根据查询到的停车场使用状况,有助于满足其合理出行的需要,以及引导停车场的配套建设和规划的有效性。

2.系统设计
2.1系统总体架构
系统架构如图2-1所示,主要分为三层,分别为:客户层、应用层、数据层。
图2-1 系统结构图
(1)客户层
主要实现协议为HTTP和Socket,HTTP是实现App与服务器的交互,Socket主要是实现传输芯片(硬件端)与服务器的实时交互。
(2)应用层
会话层:主要用Nginx来进行路由控制以及转发服务:主要是置于TOMCAT中得java程序提供的RestApi和WebService。
业务逻辑:主要由Java编写的逻辑代码,包括数据查询,报表管理,数据监听,收费规则管理等其他的一些公共的逻辑。
(3)数据层
数据访问:主要是利用Spring jdbc/Redis来进行数据访问。
数据存储:Redis缓存+Mysql存储,Redis主要是存放停车场实时更新的数据信息。Mysql主要存储,实时性不太强的信息。

应用层执行架构:
服务器操作系统为Centos6.2,
Nginx:负载均衡,路由分发。
Tomcat:运行Java后台服务程序
数据执行架构:
服务器操作系统为Centos6.2,以及Redis缓存,Mysql数据库。

2.2收费规则设计
利用停车场现有设备(摄像头),获取到车辆信息进行处理,对车辆进行自动识别,识别到车辆信息和停车动作后,调用云端服务功能,验证该车辆订单,完成自动扣费,收费系统架构图如图2-2所示。
图2-2 收费系统架构图

扣费的方式:支付宝、微信、银行卡均可。(根据默认扣费方式自动收费)
时长收费规则:按照停车时间长度收费。
前N小时收费:该规则包含免费收费段(免费段),和优惠收费段,停车场可自定义该两端的收费段,可以通过调节收费段只需要“免费段”,“优惠段”
阶梯收费段:停车场可在该段细粒度定义时间间隔及间隔的收费标准
超过阶梯收费区域:用户的停车时间超过阶梯收费规则可按该段收费规则收费

时制收费规则:
对于每天可以划分不同时间段进行收费,大致分为“凌晨”,“早上”,“中午”,“下午”,“傍晚”,“深夜”,停车场可根据需要,在各个时段指定收费规则
收费规则折扣指定:各个阶段的收费规则都可以定义,“折扣”,“额定优惠”,“单元收费”,“阶段最大收费”,几个指标来组合制定出“活动价”,“高峰期时段价”,等等
额定优惠:指一次性优惠一定的金额。
单元收费:指定计费单元,N元/U小时中U的大小。
阶段最大收费:指定阶梯收费阶段中最多的费用。

停车场可以综合上述收费标准,可以制定出满足各自需求的收费标准,特别是在不同的时段(“高峰期”,“低潮区”,“正常区”),以及推出各种活动(“活动价”)等上打造更方便,灵活,快速,高效的收费系统。

2.3核心功能模块
主要由停车场用户模块和网站管理模块
停车场管理员:主要由停车场信息管理,收费管理,报表管理
系统管理员:主要管理停车场和用户信息已经对停车场应用的授权管理

3.系统功能操作说明
3.1用户操作
3.1.1 登录
用户进入系统登录页面,用户输入用户名以及登录密码,选取自己的用户类型(系统默认为停车场管理员),用户正确填写信息后登录进系统。
其它功能:
1、自动登录:用户勾选自动登录则允许网页记住密码,下次登录可填写用户名直接登录。
2、立即注册:用户若无账户信息可选择立即注册功能,注册新账号。
3、忘记密码:若忘记密码可选择忘记密码功能,找回密码。
登录界面如图2-1所示。

图2-1 登录系统
选取用户类型如图2-2所示。

图2-2用户类型选取

在登录填写信息时未正确输入相关信息,会有相关提示。如图2-3所示。

图2-3 登录界面
3.1.2 注册
停车场管理员用户进入系统注册页面,用户输入用户名、手机号,登录密码、再次确认的密码、短信验证码(用户输入手机号后点击发送按钮可获取短信验证码),用户正确填写所有信息后在本系统注册新帐号。
其它功能:
1、记住密码:用户勾选记住密码则允许网页记住密码,下次登录可填写用户名直接登录。
2、直接登录:用户切换到登录界面登录帐号。
3、忘记密码:若忘记密码可选择忘记密码功能,找回密码。
注册界面如图2-4所示。

图2-4 注册界面
在注册填写信息时未正确输入相关信息,会有相关提示。如图2-5所示。

图2-5 注册界面
3.1.3 忘记密码
停车场管理员用户进入密码重置页面,用户输入手机号,新密码、再次确认的密码、短信验证码(用户输入手机号后点击发送按钮可获取短信验证码),用户正确填写所有信息后在本系统注册新帐号。
其它功能:
1、立即注册:用户若无账户信息可选择立即注册功能,注册新账号。
2、自动登录:用户勾选自动登录则允许网页记住密码,下次登录可填写用户名直接登录。
3、立即登录:用户切换到登录界面登录帐号。
密码重置页面如图2-6所示。

图2-6 密码重置界面
在重置密码填写信息时未正确输入相关信息,会有相关提示。如图2-7所示。

图2-7 密码重置界面

3.2停车场管理员
3.2.1 首页
停车场管理员进入系统首页,首页导航功能包括:
1、帐号信息显示与操作
1)帐号名称:查看账户信息
2)安全设置:设置帐号相关信息
3)退出帐号:退出当前登录
2、停车场:切换到管理停车场界面
3、设备管理:管理停车场车位
4、车辆管理:管理停车场来往车辆
5、报表管理:查看停车场相关数据报表
6、公告发布:发布相关停车场公告
7、导航条:显示当前所在页面
停车场管理员操作首页如图2-8所示。

图2-8 停车场管理员操作首页
帐号服务如图2-9所示。

图2-9 帐号服务
导航条如图2-10所示。

图2-10 导航条
3.2.2 停车场管理
3.2.2.1 新增停车场
停车场管理员选中新增停车场,即->“新增停车场”,可增加所管理的停车场。
需要输入的信息有停车场名称、所在区域、详细地址、停车场营业执照、停车位、停车场类型、停车场负责人、经营人的身份证号以及关于停车场的简单描述。如图2-11所示。

图2-11 新增停车场

用户选择停车场所在区域,如图2-12所示。

图2-12 选择所在区域

用户上传营业执照,如图2-13、图2-14所示。

图2-13 上传营业执照

图2-14 上传营业执照

正确填写相关信息后添加停车场成功。如图2-15所示。

图2-15 添加成功
3.2.2.2 查看停车场信息
停车场管理员选中停车场信息,即->“停车场信息”,可查看所管理的停车场的相关信息。
停车场管理员帐号下并未有停车场信息时,点击添加停车场可切换至添加停车场信息页面。停车场信息界面如图2-16所示。

图2-16 停车场信息

停车场管理员账号下已存有停车场信息时,可查看到所管理的停车场编号、停车场名称、所在地址、计价方式、停车位、停车场类型、停车场负责人、经营人身份证号和停车场简述。
点击编辑按钮可编辑该停车场信息,点击删除按钮可删除该条停车场信息。
停车场界面信息如图2-17所示。

图2-17 停车场信息

用户选择编辑停车场信息功能,修改已存在停车场信息。
可修改的信息包括停车场名称、停车场地址、详细地址、停车位、停车场类型、停车场负责人、经营人的身份证号以及关于停车场的简单描述。修改完成且信息无误后点击确认按钮则保存新信息,点击取消则放弃编辑停车场信息。
编辑停车场信息界面如图2-18所示。

图2-18 编辑停车场信息

用户选择删除停车场信息功能,删除已存在停车场信息。
选择删除停车场信息,系统会再次确认,若确定则继续删除,若放弃则关闭页面。如图2-19所示。

图2-19 是否删除停车场

选择确认删除停车场信息,删除停车场成功,如图2-20所示。

图2-20 成功删除停车场信息
3.2.2.3 停车场收费
停车场管理员选中收费标准,即->“收费标准”,可设置所管理的停车场的收费规则。
停车场管理员需要输入:
1、停车场编号
2、用户类型
3、收费类型(选择用户类型后出现对应的收费类型)
4、收费细则(选择收费类型后出现对应的收费细则)
5、收费折扣(选择收费类型后出现收费折扣输入框)
收费初始界面如图2-21所示。

图2-21 收费

停车场管理员需要对不同用户类型设置相应的收费规则,选择用户类型,可选择的用户类型有临时用户、期卡用户、充值卡用户。界面如图2-22所示。

图2-22 选择卡用户类型

1)临时用户
停车场管理员选择为临时用户设置规则,即->“临时用户”,可设置的规则有按阶段收费、按时收费、按天收费。如图2-23所示。

图2-23 临时卡收费类型

停车场管理员选择设置按阶段收费,即->“按阶段收费”,停车场管理员填写收费细则,填写时间段、该时间段对应的收费。点击“+”按钮后添加下一阶段,默认下一阶段起始时间为上一阶段结束的时间。如图2-24 图2-25所示。

图2-24 临时卡按阶段收费

图2-25 临时卡按阶段收费

停车场管理员选择设置按时收费,即->“按时收费”,停车场管理员填写收费细则,输入按时收费的收费价格。如图2-26所示。

图2-26 临时卡按时收费

停车场管理员选择设置按天收费,即->“按天收费”,停车场管理员填写收费细则,输入按天收费的收费价格。如图2-27所示。

图2-27 临时卡按天收费
2)期卡用户
停车场管理员选择为期卡用户设置规则,即->“期卡用户”,可设置的规则有按月收费、按季收费、按年收费。如图2-28所示。

图2-28 期卡收费类型

停车场管理员选择设置按月收费,即->“按月收费”,停车场管理员填写收费细则,输入按月收费的收费价格。如图2-29所示。

图2-29 期卡按月收费

停车场管理员选择设置按季收费,即->“按季收费”,停车场管理员填写收费细则,输入按季收费的收费价格。如图2-30所示。

图2-30 期卡按季收费

停车场管理员选择设置按年收费,即->“按年收费”,停车场管理员填写收费细则,输入按年收费的收费价格。如图2-31所示。

图2-31 期卡按年收费
3)充值卡用户
停车场管理员选择为充值卡用户设置规则,即->“充值卡用户”,填写用户收费细则。如图2-32所示。

图3-32 充值卡收费

3.2.3 设备管理
3.2.3.1 车位状态管理
停车场管理员选中停车场信息,即->“车位状态管理”,可查看所管理的停车场的相关设备信息。包括停车场的总车位数、剩余车位数、预订车位数、车位状态以及停车场内每个车位的实时情况。
车位实时情况包括车位所属片区、片区号、泊位号、泊位状态、所在车辆的车牌号(若无车辆则不现实)、预订的车牌号(若无预订则不显示)。
其它功能:
1、输入内容可检索停车场指定车位信息。
2、选择表格操作栏编辑选项对该条车位信息进行编辑。
3、选择表格操作栏移除选项对该条车位信息进行移除。
停车场信息界面如图2-33所示。

图2-33 停车场设备信息

停车场车位信息界面如图2-34所示。

图2-34 停车场车位信息界面

选择蓝色编辑按钮,可批量管理车位信息。如图2-35所示。

图2-35 批量管理
3.2.3.2 泊车流水
停车场管理员选中泊车流水,即->“泊车流水”,可查看所管理的停车场的泊车流水信息。泊车流水信息包括该流水的所属片区、片区号、泊位号、泊位状态、变化时间、是否预订、相关车牌号、进/出/预订情况。
其它功能:
1、表格底操作区域可选择每页信息条数、前往指定页面。
2、输入内容可检索停车场指定车位信息。
3、选择表格操作栏编辑选项对该条泊车流水信息进行编辑。
4、选择表格操作栏移除选项对该条泊车流水信息进行移除。
停车场泊车流水如图2-36所示。

图2-36 泊车流水

3.2.4 车辆管理
3.2.4.1 会员车辆
停车场管理员选中会员车辆,即->“会员车辆”,可查看所管理的停车场的会员车辆信息。会员车辆信息包括车辆的车牌号、车辆品牌、所属帐号、所属人姓名、所属人身份证号、添加时间、停放次数。
其它功能:
1、表格底操作区域可选择每页信息条数、前往指定页面。
2、输入内容可检索停车场指定车位信息。
3、选择表格操作栏拉黑选项拉黑该车。
4、选择表格操作栏编辑选项对该条信息进行编辑。
5、选择表格操作栏移除选项对该条信息进行移除。
会员车辆信息界面如图2-37所示。

图2-37 停车场会员车辆
3.2.4.2 黑名单
停车场管理员选中黑名单,即->“黑名单”,可查看所管理的停车场的黑名单车辆信息。黑名单车辆信息包括车辆的车牌号、欠费金额、欠费时间、欠费次数。
其它功能:
1、表格底操作区域可选择每页信息条数、前往指定页面。
2、输入内容可检索停车场指定车位信息。
3、选择表格操作栏查看选项查看具体信息。
4、选择表格操作栏编辑选项对该条信息进行编辑。
5、选择表格操作栏移除选项对该条信息进行移除。
黑名单车辆信息界面如图2-38所示。

图2-38 停车场黑名单
3.2.5 报表管理
3.2.5.1 泊车报表
停车场管理员选中泊车报表,即->“泊车报表”,查看所管理的停车场指定时间内的泊车信息报表(默认时间为一周),可查看的报表如下:
1、停车场的泊车次走势图。
2、停车场的泊车评价分析图。
3、停车场的泊车访客类型占比图。
4、停车场的累积泊车次。
5、停车场的累积评价次。
6、停车场泊车次最少的时间。
7、停车场泊车次最多的时间。
8、停车场的平均泊车次。
其它功能:选择时间按钮指定查看的时间段(一周、一月、一年)
泊车报表如图2-39 图2-40所示。

图2-39 泊车报表界面

图2-40 泊车报表界面

泊车次走势图,可查看指定时间段的泊车次数。
1、图数据:
1)纵坐标:泊车次。
2)横坐标:指定时间的构成单位。
3)红线:泊车次。停车场指定时间段的所有泊车次数总和。
2、图功能:
1)移动鼠标在指定时间查看详细信息,包括对应车次与时间
2)选择时间按钮指定查看的时间段(一周、一月、一年)
如图2-41所示。

图2-41 泊车次走势图

泊车评价分析图,可查看指定时间段的泊车评价报表。
1、图数据:
1)红色块:不满意
2)蓝黑色块:还行
3)绿色块:一般
4)橙色块:满意
5)青色块:非常满意
2、图功能:
1)移动鼠标在指定色块查看详细信息,包括对应人次与占比
2)选择时间按钮指定查看的时间段(一周、一月、一年)
如图2-42所示。

图4-42 泊车评价分析

泊车访客类型占比图,可查看指定时间段的泊车访客类型占比。
1、图数据:
1)红色块:临时用户
2)蓝黑色块:期卡用户
3)绿色块:充值卡用户
2、图功能:
1)移动鼠标在指定色块查看详细信息,包括对应人次与占比
2)选择时间按钮指定查看的时间段(一周、一月、一年)
如图2-43所示。

图4-43 访客类型占比图
3.2.5.1 收入流水
停车场管理员选中收入流水,即->“收入流水”,查看所管理的停车场指定时间内的收入流水报表(默认时间为一周),可查看的报表如下:
1、停车场的收入流水走势图。
2、停车场的收入构成单元图。
3、停车场的收入来源占比图。
4、停车场的充值卡持有人数。
5、停车场的期卡持有人数。
6、停车场临时卡停车次数。
其它功能:选择时间按钮指定查看的时间段(一周、一月、一年)
收入流水报表如图4-44 图4-45所示。

图4-44 收入流水界面

图4-45 收入流水界面

停车场收入流水走势图,可查看指定时间段的收入情况。
1、图数据:
1)纵坐标:泊车次。
2)横坐标:指定时间的构成单位。
3)红线:停车场收入。停车场指定时间段的停车场收入总和。
2、图功能:
1)移动鼠标在指定时间查看详细信息,包括对应收入与时间
2)选择时间按钮指定查看的时间段(一周、一月、一年)
如图2-46所示。

图2-46 停车场收入

停车场收入构成单元图,可查看指定时间段的收入构成单元。
1、图数据:
1)纵坐标:停车场收入,单位:元。
2)横坐标:收入总值、临时卡占值、期卡占值、充值卡占值。
2、图功能:
1)移动鼠标在指定时间查看详细信息,包括对应组成成分与收入
2)选择时间按钮指定查看的时间段(一周、一月、一年)
如图2-47所示。

图2-47 收入构成单元
停车场收入来源占比图,可查看指定时间段的收入来源占比。
1、图数据:
1)红色块:临时卡
2)蓝黑色块:期卡
3)绿色块:充值卡
2、图功能:
1)移动鼠标在指定色块查看详细信息,包括对应收入与占比
2)选择时间按钮指定查看的时间段(一周、一月、一年)
如图2-48所示。

图4-48 收入来源占比图
3.2.6 公告发布
3.2.6.1 发布公告
停车场管理员选中发布公告,即->“发布公告”,可发布停车场的公告。
需要输入的信息有公告名称、发布人、所见区域、公告类型、公告内容,还可上传相关附件。如图2-49所示。

图2-49 发布公告

编辑公告内容,停车场管理员选择添加内容,即->“添加内容”,添加公告内容。如图2-50 图2-51所示。

图2-50 编辑初始页面

图2-51 编辑公告界面
3.2.6.2 已发公告
管理员选中已发公告,即->“已发公告”,可查看停车场已经发布的公告。
停车场已发公告界面如图2-52所示。

图2-52 已发公告界面
3.3系统管理员
3.3.1 首页
系统管理员进入系统首页,首页导航功能包括:
1、帐号信息显示与操作
1)帐号名称:查看账户信息
2)安全设置:设置帐号相关信息
3)退出帐号:退出当前登录
2、停车场管理:切换到管理停车场界面
3、统计分析:管理停车场车位
4、用户数据:管理停车场来往车辆
5、系统设置:查看停车场相关数据报表
6、公告发布:发布相关停车场公告
7、导航条:显示当前所在页面
系统管理员操作首页如图2-53所示。

图2-53 系统管理员操作界面

3.3.2 停车场管理
系统管理员选中停车场数据,即->“停车场数据”,可查看系统所管理的停车场的相关信息。包括停车场序号、停车场地区号、停车场名称、停车场所在区域、停车位、创建时间。
其它功能:
1、表格底操作区域可选择每页信息条数、前往指定页面。
2、输入内容可检索指定停车场信息。
3、选择表格操作栏编辑选项对该条停车场数据信息进行编辑。
4、选择表格操作栏移除选项对该条停车场数据信息进行移除。
停车场数据信息如图2-54所示。

图2-54 停车场数据界面
3.3.3 统计分析
3.3.3.1 系统推广
系统管理员选中系统推广,即->“系统推广”,查看本系统的推广信息报表。可查看的报表如下:
1、地区推广柱状图。
2、地区推广各地图。
3、系统注册占比图。
3、系统注册最多停车场的城市及注册个数。
4、系统推广率最高的停车场的城市及推广比。
系统推广报表如图2-55 图2-56所示。

图2-55 系统推广报表

图2-56 系统推广报表

地区推广柱状图,可查看各地区已注册的和未注册的停车场。
1、图数据:
1)纵坐标:停车场个数。
2)横坐标:中国各大城市。
3)蓝色柱块:对应城市已注册的停车场个数。
4)灰色柱块:对应城市未注册的停车场个数
2、图功能:
1)移动鼠标在指定柱块查看详细信息,包括对应地区与(未)注册个数
2)鼠标拖拽图放缩柱状图
3)双击色块隐藏该色块
4)图右上方图标功能
数据视图:点击查看该图的各项数据列表
还原:还原为未拖拽前的默认图像
保存图片:将图表保存为图片储存在本地
地区推广柱状图如图2-57所示。

图2-57 地区推广柱状图

只显示未注册数据信息。如图2-58所示。

图2-58 未注册地区推广柱状图

查看柱状图数据视图,如图2-59所示。

图2-59 数据视图

地区推广各地图,可在地图上查看各地区已注册的和未注册的停车场。移动鼠标在指定柱块查看详细信息,包括对应地区与(未)注册个数。如图2-60所示。

图2-60地区推广各地图

系统注册占比图,可查看系统注册占比。
1、图数据:
1)红色块:不满意
2)绿色块:一般
2、图功能:
1)移动鼠标在指定色块查看详细信息,包括对应注册次与占比
如图2-61所示。

图2-61 系统总体注册率
3.3.3.2 资源数据分析
系统管理员选中资源数据分析,即->“资源数据分析”,查看本系统的资源数据。
1、图数据:
1)纵坐标:泊车次。
2)横坐标:指定时间的构成单位。
3)红线:泊车次。所有停车场指定时间段的所有泊车次数总和。
2、图功能:
1)移动鼠标在指定时间查看详细信息,包括对应车次与时间
2)选择时间按钮指定查看的时间段(一周、一月、一年)
系统资源数据报表如图2-62所示。

图2-62 系统总泊车次
3.3.3.3 访问数据分析
系统管理员选中访问数据分析,即->“访问数据分析”,查看本系统的访问数据分析报表。可查看的报表如下:
1、访问系统人次走势图。
2、新注册用户走势图。
3、用户评价分析图。
4、管理员评价分析图。
5、停车场类型占比图。
系统资源数据报表如图2-63图2-64所示。

图6-23

图2-64

访问系统人次走势图,可查看指定时间段的访问系统人次。
1、图数据:
1)纵坐标:访问系统人次。
2)横坐标:指定时间的构成单位。
3)折线:指定时间段的访问系统人次。
2、图功能:
1)移动鼠标在指定时间查看详细信息,包括对应访问人次与时间
2)选择时间按钮指定查看的时间段(一周、一月、一年)
如图2-65所示。

图2-65 访问系统人次图

新注册用户走势图,可查看指定时间段的新注册用户人次。
1、图数据:
1)纵坐标:新注册用户人次。
2)横坐标:指定时间的构成单位。
3)折线:指定时间段的新注册用户人次。
2、图功能:
1)移动鼠标在指定时间查看详细信息,包括对应新注册用户人次与时间
2)选择时间按钮指定查看的时间段(一周、一月、一年)
如图2-66所示。

图2-66 新用户注册人次图

用户评价分析图,可查看指定时间段的用户评价报表。
1、图数据:
1)红色块:不满意
2)蓝黑色块:还行
3)绿色块:一般
4)橙色块:满意
5)青色块:非常满意
2、图功能:
1)移动鼠标在指定色块查看详细信息,包括对应人次与占比
2)选择时间按钮指定查看的时间段(一周、一月、一年)
如图2-67所示。

图2-67用户评价分析图

管理员评价分析图,可查看指定时间段的管理员评价报表。
1、图数据:
1)红色块:不满意
2)蓝黑色块:还行
3)绿色块:一般
4)橙色块:满意
5)青色块:非常满意
2、图功能:
1)移动鼠标在指定色块查看详细信息,包括对应人次与占比
2)选择时间按钮指定查看的时间段(一周、一月、一年)
如图2-68所示。

图2-68管理员评价分析图

停车场类型占比图,可查看指定时间段的停车场类型占比。
1、图数据:
1)红色块:公共停车场
2)蓝黑色块:私有停车场
3)绿色块:专用停车场
2、图功能:
1)移动鼠标在指定色块查看详细信息,包括对应停车场个数与占比
如图2-69所示。

图2-69停车场类型占比图
3.3.4 用户数据
3.3.4.1 停车场管理员
系统管理员选中停车场管理员,即->“停车场管理员”,可查看所管理的停车场管理员信息。停车场管理员信息包括姓名、所属停车场、密码、联系电话、身份证号、性别、年龄。
其它功能:
1、表格底操作区域可选择每页信息条数、前往指定页面。
2、输入内容可检索管理员指定管理员信息。
3、选择表格操作栏查看选项查看该条管理员详细信息。
4、选择表格操作栏编辑选项对该条信息进行编辑。
5、选择表格操作栏移除选项对该条信息进行移除。
停车场管理员信息界面如图2-70所示。

图2-70 停车场管理员信息
3.3.4.2 注册用户
系统管理员选中注册用员,即->“注册用员”,可查看所管理的注册用员信息。注册用员信息包括账户、电话、创建时间、费用、积分、身份证号、信誉度。
其它功能:
1、表格底操作区域可选择每页信息条数、前往指定页面。
2、输入内容可检索管理员指定注册用员信息。
3、选择表格操作栏查看选项查看该条注册用户详细信息。
4、选择表格操作栏编辑选项对该条信息进行编辑。
5、选择表格操作栏移除选项对该条信息进行移除。
停车场管理员信息界面如图2-71所示

图2-71 注册系统用户信息

4.源代码
4.1服务端
Controller层
socket
Instructions
package com.cloud.station.controller.socket;

import com.alibaba.fastjson.JSONArray;
import com.cloud.station.pojo.DepotInfo;
import com.cloud.station.pojo.DepotStationState;
import com.cloud.station.pojo.dto.CarDTO;
import com.cloud.station.service.*;
import com.cloud.station.service.cache.SocketManager;
import com.cloud.station.service.redis.StationStateRedis;
import com.cloud.station.utils.BeanTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;

import java.io.PrintStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**

  • 指令处理
    */
    public class Instructions{
    public Map<String,String> devicesMap = new HashMap<>();//链接设备状态 appId-key
    //相关指令
    public final static String SYS_CHBT = “SYS+CHBT”;//获取心跳时间(单位秒)
    public final static String DAT_LOCKED_0=“DAT+LOCKED=0”;//锁住指定车位
    public final static String DAT_LOCKED_1=“DAT+LOCKED=1”;//解锁车位
    public final static String DAT_UPSUM=“DAT+UPSNUM”;//更新数据(车位总数量)
    public final static String DATA_LEFT=“DAT+LEFT”;//剩余数量
    public final static String SYS_REST=“SYS+REST”;//重置模块设置信息

    public final static String DAT_TIME_INTERVAL = “DAT+TTL”;//每多少毫秒同步一次数据

    public final static String SYS_CLOSED=“SYS+CLOSED”;//断开连接

    private static ApplicationContext applicationContext = null;
    @Autowired
    SocketManager socketManager;

    @Autowired
    StationOrderService stationOrderService;
    @Autowired
    DepotInfoService depotStationService;

    PrintStream out = null;
    Socket socket = null;

    public Instructions() {

    }
    public Instructions(Socket socket,PrintStream out) {
    this.out = out;
    this.socket = socket;
    }
    //保存连接
    private void saveConnection(Socket socket){
    //如果是新的socket
    Socket socket_ = this.socketManager.get(socket.getInetAddress().toString());
    if(socket_!=null) socketManager.add(socket);
    }

    public void parse(String cmd){
    //1.进行认证
    // out.println(“recived:”+cmd);

     StationStateRedis stationStateRedis = (StationStateRedis) BeanTools.getBean(StationStateRedis.class);
     stationOrderService = (StationOrderService)BeanTools.getBean(StationOrderService.class);
     PayService payService = (PayService) BeanTools.getBean(PayService.class);
     depotStationService = (DepotInfoService) BeanTools.getBean(DepotInfoService.class);
    
     if(cmd.contains("number")){//收到的是车牌信息
          CarDTO carDTO = JSONArray.parseObject(cmd,CarDTO.class);
           if(carDTO.getEndTime()!=null && carDTO.getEndTime()>0){//计算
                float cusumMoney = payService.pay(carDTO.getStationId(),carDTO.getNumber());
                out.println(cusumMoney);//总消费金额
           }else{//添加
                 //TODO 余额不足未处理
              Integer rst = stationOrderService.addByCarNum(carDTO.getStationId(),carDTO.getNumber());
              if(rst==1)out.println("OK");
              else {
                  //TODO 查询黑名单 如果存在过则不能进入
                  out.println("ERROR");
              }
           }
     }else if(cmd.contains("stationId")){
           DepotStationState depotStationState = JSONArray.parseObject(cmd,DepotStationState.class);
           stationStateRedis.save(depotStationState);
      }else if("ST+NUM".equals(getKeyFromCmd(cmd))){//获取停车场的数量(ST+NUM)
         String stationId_ = getValueFromCmd("ST+NUM",cmd);
         try{
             DepotInfo depotInfo = (DepotInfo) depotStationService.findByPrimaryKey(Long.valueOf(stationId_));
             out.println(depotInfo.getStationNum());
         }catch (Exception e){
             out.println("ERROR");
         }
     }else if("ST+LEFT".equals(getKeyFromCmd(cmd))){//获取当前停车场剩余数
         String stationId_ = getValueFromCmd("ST+LEFT",cmd);
         try{
             DepotStationState depotStationState = stationStateRedis.getByKey(Long.valueOf(stationId_));
             if(depotStationState!=null){
                 out.println(depotStationState.getLeft());
             }else{
                 DepotInfo depotInfo = (DepotInfo) depotStationService.findByPrimaryKey(Long.valueOf(stationId_));
                 out.println(depotInfo.getStationNum());
             }
    
         }catch (Exception e){
             out.println("ERROR");
         }
     }
    

    }

    /**

    • 从指令中提取值

    • 格式 key:value

    • @param key 指令key

    • @param str 字符串

    • @return
      */
      public String getValueFromCmd(String key,String str){
      String cmd = null;//指令值
      String str_ = str.trim();//去除前后空格
      if(!str_.startsWith(key)) return null;

      if(!str_.contains("?) return null;

      cmd = str_.substring(str.indexOf(":")+1);
      return cmd.trim();
      }

    /**

    • 从指令中得到KEY
    • @param cmd
    • @return
      */
      public String getKeyFromCmd(String cmd){
      String cmd_ = cmd.trim();
      if(cmd_.contains("?){
      return cmd_.substring(0,cmd_.lastIndexOf("?).trim();
      }else{
      return cmd.trim();
      }
      }

}

SocketOperate
package com.cloud.station.controller.socket;

import org.springframework.beans.factory.annotation.Autowired;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Date;

/**

  • 多线程处理socket接收的数据
    */
    public class SocketOperate extends Thread{
    private Socket socket;
    @Autowired

    public SocketOperate(Socket socket) {
    this.socket=socket;
    }
    @SuppressWarnings(“unused”)
    public void run()
    {
    PrintStream out = null;
    BufferedReader buf =null;
    Instructions instructions = null;
    boolean flag =true;
    try{
    while(flag){
    //获取Socket的输出流,用来向客户端发送数据
    out = new PrintStream(socket.getOutputStream());
    //获取Socket的输入流,用来接收从客户端发送过来的数据
    buf = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    instructions = new Instructions(socket,out);
    //接收从客户端发送过来的数据
    String str = buf.readLine();

             if(str == null || "".equals(str)){
                 flag = false;
             }else{
                 instructions.parse(str);
             }
         }
         out.close();
         socket.close();
    

// socket.setSoTimeout(30000);//设置读操作超时时间30 s
}catch(Exception ex){
out.println(“Connection closed;”);
flag = false;
ex.printStackTrace();
}
}
}

SocketServiceLoader
package com.cloud.station.controller.socket;

import com.cloud.station.service.cache.SocketManager;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

/**

  • 将socket service随tomcat启动
  • @author zhangzhongwen

*/
@WebListener
public class SocketServiceLoader implements ServletContextListener{
//socket server 线程
private SocketThread socketThread;

@Override
public void contextDestroyed(ServletContextEvent arg0) {
    System.out.println("liting: contextDestroyed");
    if(null!=socketThread && !socketThread.isInterrupted())
    {
        socketThread.closeSocketServer();
        socketThread.interrupt();
    }
}

@Override
public void contextInitialized(ServletContextEvent arg0) {
    System.out.println("liting: contextInitialized");

    if(null==socketThread)
    {
        //新建线程类
        socketThread=new SocketThread(null);
        //启动线程
        socketThread.start();
    }
}

}

SocketThread
package com.cloud.station.controller.socket;

import com.cloud.station.conf.ConfigurationManager;
import com.cloud.station.constant.ConstantsKey;
import com.cloud.station.service.cache.SocketManager;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**

  • socket 线程类
  • @author zhangzhongwen

*/
public class SocketThread extends Thread{
private ServerSocket serverSocket = null;

public SocketThread(ServerSocket serverScoket){
    try {
        if(null == serverSocket){
            this.serverSocket = new ServerSocket(8899);//TODO 这里要使用配置文件进行配置
            System.out.println("socket start");
        }
    } catch (Exception e) {
        System.out.println("SocketThread创建socket服务出错");
        e.printStackTrace();
    }

}

public void run(){

    while(!this.isInterrupted()){
        try {
            Socket socket = null;
            socket = serverSocket.accept();
            if(null != socket){
                //处理接受的数据
                new SocketOperate(socket).start();
            }

// socket.setSoTimeout(300000);

        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}


public void closeSocketServer(){
    try {
        if(null!=serverSocket && !serverSocket.isClosed())
        {
            serverSocket.close();
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

websocket
StationSateWebSocket
package com.cloud.station.controller.websocket;

import com.alibaba.fastjson.JSONArray;
import com.cloud.station.pojo.dto.AddressDTO;
import com.cloud.station.pojo.dto.MapAddressDTO;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

/**

  • 停车场状态信息WebSocket
    */
    @ServerEndpoint("/station/websoket")
    @Component
    public class StationSateWebSocket {

    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    //处理线程
    private StationStateThread stationStateThread;
    /**

    • 连接建立成功调用的方法
    • @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
      */
      @OnOpen
      public void onOpen(Session session){
      this.session = session;
      addOnlineCount(); //在线数加1

    }

    /**

    • 连接关闭调用的方法
      */
      @OnClose
      public void onClose(){
      subOnlineCount(); //在线数减1
      try {
      session.close();
      } catch (IOException e) {
      e.printStackTrace();
      }
      stationStateThread.shut();
      }

    /**

    • 收到客户端消息后调用的方法
    • @param address 客户端发送过来的消息
    • @param session 可选的参数
      */
      @OnMessage
      public void onMessage(String address, Session session,@PathParam(“client-id”) String clientId) {
      AddressDTO addressDTO = JSONArray.parseObject(address,AddressDTO.class);
      try{
      if(stationStateThread==null)stationStateThread = new StationStateThread(session,addressDTO);
      if(session.isOpen() && stationStateThread!=null)stationStateThread.start();
      }catch (Exception e){
      try {
      session.close();
      } catch (IOException e1) {
      e1.printStackTrace();
      }
      }

    }

    /**

    • 发生错误时调用
    • @param session
    • @param error
      */
      @OnError
      public void onError(Session session, Throwable error){
      try {
      session.close();
      } catch (IOException e) {
      e.printStackTrace();
      }
      stationStateThread.shut();
      error.printStackTrace();
      }

    public static synchronized int getOnlineCount() {
    return onlineCount;

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
      掌握基于腾讯人工智能(AI)的车牌识别技术,使用车牌识别技术实现一个完整的停车管理系统项目包括网页调用摄像头拍照,车牌拍照识别,上传车牌图片识别,用户管理,车辆管理(临时车与包月车),车辆出场,入场管理,停车费收费管理,按照临时车或包月车自动计算停车费,系统参数设置,修改用户密码及安全退出等功能,该系统采用Jsp技术,使用SSM框架,Mysql数据库,ajax技术及人工智能等相关技术实现。重要通知:本课程根据腾讯AI车牌识别新接口,更新了新接口源代码,发布程序,购买了课程的同学可以下载新程序,包括(运行程序及源代码),更新时间:2021-2-17项目开发技术:java,jsp,mysql,MyBatis,SpringMVC,jquery,ajax,json项目运行环境:jdk1.7及以上版本,tomcat6.0及以上版本,mysql5.5及以上版本项目开发工具: 本项目开发工具是Eclipse,也支持myEclipse,Intellij Idea等其他版本开发工具相关课程学习顺序本校课程是培养JAVA软件工程师及JSP WEB网络应用程序开发,android工程师的全套课程,课程学习顺序如下:JAVA初级工程师:    1、计算机基础    2、HTML语言基础    3、C语言从入门到精通+贪吃蛇游戏    4、贪吃蛇游戏    5、SQL SERVER数据库基础    6、JAVA从入门到精通+推箱子游戏+QQ即时通讯软件    7、推箱子游戏;    8、仿QQ即时通讯软件;JAVA中级工程师:    9、SQLSERVER数据库高级    10、SQLSERVER从入门到精通(基础+高级)              11、JavaScript从入门到精通,    12、JSP从入门到精通+点餐系统,    13、JSP从入门到精通+在线视频学习教育平台,    14、JSP从入门到精通+大型电商平台;    15、XML从入门到精通,    16、数据结构(JAVA版),JAVA高级工程师:    17、Oracle数据库从入门到精通,    18、ajax+jquery从入门到精通,    19、EasyUI从入门到精通,SSH框架:    20、Struts2从入门到精通课程,    21、Hibernate从入门到精通课程,    22、Spring从入门到精通课程;    23、Echarts从入门到精通,    24、Excel基于POI的导入导出工作流框架:    25、Activiti流程框架从入门到精通    26、JBPM流程框架从入门到精通SSM框架:    27、MyBatis从入门到精通    28、Spring MVC从入门到精通面试题:    29、职业生涯规划及面试题集锦商业项目:    30、微信公众号在线支付系统    31、微信生活缴费在线支付系统    32、支付宝生活缴费在线支付系统    33、在线考试系统    34、手机订餐管理系统,    35、CRM客户关系管理系统    36、大型房地产CRM销售管理系统    37、CMPP2,CMPP3移动网关系统人工智能:    38、人脸识别在线考试系统    39、人脸识别系统项目实战    40、车牌识别系统项目实战    41、身份证识别系统项目实战    42、营业执照识别系统项目实战          43、名片识别管理系统
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值