系统目标
背景:随着城市化进程的加快和人们生活水平的提高,人们对于出行的需求也在不断增加。传统的购车模式可能并不适合所有人,因此汽车租赁服务成为了一种便捷的选择。由此产生了对汽车租赁系统的需求,以提高租车服务的效率和便利性。
汽车租赁系统是一种用于管理和运营汽车租赁服务的软件系统。随着人们对灵活出行需求的增加,汽车租赁服务变得越来越受欢迎。汽车租赁系统可以帮助租车公司管理车辆库存、预订信息、客户数据、计费和结算等方面的业务。
通过汽车租赁系统,租车公司可以更有效地管理车辆资源,提高运营效率,提升客户体验。对于租车用户而言,汽车租赁系统可以提供方便快捷的租车流程,包括在线预订、车辆选择、取还车等服务,提升了租车体验。
系统的主要功能:车辆预订和租赁、用户管理、订单管理、价格和费用管理等。
支撑的课程目标:
提高我们学习的能力,通过各种方式学习到编写web应用所需要的知识。
帮助我们理解和掌握web应用程序开发的框架(springboot和vue)。
帮助我们掌握web应用中前端和服务器的通信方式(前后端互相接收、发送数据)。
提高团队沟通和合作能力、自主学习能力和独立解决问题的能力。
培养开发web应用所需的工程能力以及模块化开发能力。
功能总体描述
用户管理:注册,登录,个人信息管理
车辆管理:车辆信息录入(包括车型、品牌、状态、价格等)、车辆状态更新(可租、已租、维修中等)。
预约与租赁:用户可以查看可用车辆、选择租赁时间和地点、提交租赁请求。同时,如果该车已被租赁,用户可以使用预约功能来预约车辆。
订单管理:确认订单、生成租车合同、支付租金、查看租赁历史记录。
支付和结算:支持多种支付方式,生成账单和收据。
评价和反馈:用户可以对租赁过程和车辆进行评价,提供反馈。
系统的总体结构图如图1.1所示:
图1.1 系统总体结构图
该系统总体功能如下:
- 用户模块
- 用户的登录
- 用户的注册
- 用户修改自己的信息
- 用户上传自己的头像
- 用户修改密码
- 用户查询余额
- 用户给自己的账户充钱
- 汽车信息模块
- 汽车的分页展示
- 汽车的详细信息
- 搜索汽车
- 汽车的租赁
- 汽车的预约
- 订单模块
- 订单的创建
- 历史订单的查询
- 支付模块
- 扣除用户的金额
- 评价模块
- 评价这次租赁
用户模块设计
登录功能:如果用户记得账号密码,可以直接输入账号密码,点击确定后,会向后端服务器发送axios请求,请求的方式是GET,参数是userName和password,放在URL中,同时还使用了withCredentials配置项,把cookie (存放加密后的用户Id)也给后端。
后端会查找数据库,如果匹配成功,则允许登录;否则,提示用户名或密码错误。
如果登录成功,前端还会把用户的部分信息存到session中,方便其他组件的读取。(部分数据是加密的,比如密码和用户id)。
值得一提的是,在javaSpirit中,如果想把一个对象存储在session中,仅仅使用window.sessionStorage.setItem('userInfo',object)是不行的。因为sessionStorage只能存储字符串数据,不能直接存一个对象!如果想要把一个对象存到session中,需要用JSON.stringify()方法,来把这个对象转换成字符串,之后再存入session。
图3.2 登录功能流程图
图3.3 登录页面的情况
注册功能:如果用户没有账号密码,需要用户输入一个账号,输入两个相同的密码,再使用axios发送POST请求,参数是一个对象(对象封装了userName和password,放在请求体内)。交由后端服务器进行验证,如果验证通过(允许创建这样的账号),则注册成功(默认注册成功就直接登录);否则,提示注册失败。
同时,如果用户两次输入的密码不一致,弹框提示用户“两次输入的密码不一致,请检查”,并且不会向后端服务器发送请求。
图3.3 注册功能流程图
图3.4 注册功能示例
用户页面:
如果想要进入用户页面,需要先登录。如果在未登录的情况下访问用户页面,会直接跳转到登录页面。
图3.5 进入用户页面的前提条件
图3.6 用户中心页面示例
用户成功进入用户页面后,可以有以下操作:
- 个人信息查看。这个功能是一进入用户页面就能实现的,系统会展示用户的一些个人信息(昵称,用户名,性别,邮箱,电话等),但不会展示密码和余额。此时,可以通过点击“修改密码”和“查询余额”文字链接来执行对应操作。
图3.7 个人信息查看流程图
- 个人信息修改。用户点击按钮“修改个人信息”后,原先展示个人信息的地方会变成输入框,允许用户进行修改。还会出现两个新按钮“保存”和“取消”。点击“保存”,前端浏览器就会把用户输入的内容封装成一个对象,使用axios的PUT方式把请求发送给服务器,并同步修改前端页面的显示。当用户点击“取消”就无事发生,用户在输入框中的内容也不会保留。原理是:设置了一个user2来当做用户的修改信息,user代表后端数据库中存储的信息。确定就把user=user2;取消就把user2=user。当然,这里不能直接使用‘=’,要做一个深拷贝。由于对象中不再包含对象(也就是没有嵌套对象),可以使用JSON 将一个对象序列号再反序列化,即可。
图3.8 个人信息修改流程图
图3.9 修改个人信息示例
- 上传头像。用户可以从自己的电脑中,选取图片并上传(图片格式只能为.jpg)。它的实现是使用了饿了么-ui的upload。
- 余额充值。用户点击“余额查询”后,弹出框内有一个“充值”的文字连接,点击后会跳出一个输入框与对应提示:输入充值金额。即可完成充值。
图3.10 余额充值流程图
图3.11 余额查询示例
图3.12 余额充值示例
汽车信息模块设计
该模块的功能有:汽车查询,汽车查询结果分页展示,汽车详细信息,汽车租赁与汽车预约。
- 汽车查询与分页展示。汽车的查询是使用axios发送GET请求,带上两个参数(查询参数和页数)。我也考虑过不带页数的查询(就是只传一个查询参数),好处是:只需要发送一个请求就能够获得所有数据,减少了发送请求的次数,优化了性能。坏处是:要考虑传回来的数据大小,传回来的数据如果太大,前端不方便存储数据,会导致很多问题比如内存泄漏。因此,我最终还是选择传两个参数,发送多个请求。
对于汽车的分页展示,我使用的是Vue的v-for和饿了么ui的Pagination, v-for用于把数据逐条渲染,Pagination 用于设置每一页的数据量,总数据,总页数等。其中,翻页的功能的实现是这样的:每当当前页变化(即用户点击了其他页),会被Vue的v-on检测到,然后调用一个方法。在这个方法中,我想后端服务器请求了数据,并将前端页面的数据更新,这样前端页面就会重新渲染,结果就是展示对应页面的数据。
图3.13 汽车搜索与分页展示流程图
图3.14 汽车的分页展示
图3.15 查询结果的分页
- 汽车详细信息。当鼠标悬浮在某一辆车的图片上是,会触发:hover伪类,这个li的边框会变红,这使得用户能够知道现在选中的车具体是哪一辆。然后,如果用户点击这辆车,就会跳转到汽车详细信息页面。
在汽车详细信息页面,首先会展示这辆车的具体信息,比如车型,车名,车的座位数,颜色,图片,车牌号等。此时,如果该车处于未租赁状态,用户可以选择租赁或预约。如果该车处于已被租赁状态,用户可以选择预约;如果该车处于已预约状态,用户就不能够再租赁或预约。具体实现是:如果车处于已租赁状态,对应的按钮“立即租赁”(还有对应的选择租赁时间段的日期选择器)就会变成不可点击状态;如果车已处于已预约状态,“立即租赁”和“我要预约”都会变成不可点击状态。
图3.16 汽车租赁状态例子
- 汽车租赁和预约功能。
如果车处于可预约/租赁状态,用户就可以通过按钮下方的日期选择器来选择要租赁/预约的时间段,然后即可进行对应操作。
值得一提的是,对于日期选择器的选择功能,我设置了一些限制,比如说:现在假设这辆车已经被租赁了,租赁的时间是7.10 - 7.12。那么,点开预约的日期选择器,会发现7.12日之前的日期都不可选择。它的实现方式是:日期选择器中的每一个日期,都对应着一个参数“formDate”,我们就可以拿到这个参数,然后进行一些判断。比如获取到租赁订单的租赁结束时间,然后如果“formDate”在这个结束时间之前,就让这个formDate对应的日期变为不可选择状态。如下图的7.4日之前就是不可选择的状态。
图3.17 日期选择器展示
图3.18 租赁/预约功能的流程图
订单模块设计
该模块实现的主要功能有:订单查询,订单分页展示和创建订单。
- 创建订单。在租赁/预约功能下,如果成功租赁/预约,则会使用axios向服务器发送POST请求,请求体内传一个对象,包含:订单的起止时间,租赁/预约状态,地点,价格和Id。发送之后后端就会创建对应订单。
- 订单分页展示。进入订单分页展示页面的前提是登录,如果没登录就进入此页面,会跳转到登录页面。
该页面会展示每条订单的状态(租赁成功/失败等),和一些简略的订单信息比如车的图片,车的品牌。点击“查看订单”,就会跳转到订单查询页面。
用户登录后进入此页面,页面就会分页展示用户的订单(由新到旧展示),分页的实现是:使用的是Vue的v-for和饿了么ui的Pagination, v-for用于把数据逐条渲染,Pagination 用于设置每一页的数据量,总数据,总页数等。其中,翻页的功能的实现是这样的:每当当前页变化(即用户点击了其他页),会被Vue的v-on检测到,然后调用一个方法。在这个方法中,我想后端服务器请求了数据,并将前端页面的数据更新,这样前端页面就会重新渲染,结果就是展示对应页面的数据。
图3.19 订单分页展示部分的示例
- 订单查询。
在订单分页展示页面中,点击“查询订单”就可以进入订单详细页面,里面会展示该订单的详细信息比如 车的座位数、颜色等。
其中,有一个“在来一单”按钮。点击后可以立即跳转到汽车详细信息页面,方便用户再次租赁/预约。
-
-
- 支付模块设计
-
该模块的主要功能就是支付订单。当用户点击“租赁/预约”后,会判断用户的余额是否充足,是否支持支付该订单。如果余额不足,则无法支付改订单。就会出现“租赁/预约失败”的订单;如果余额充足,就会直接扣除余额并创建成功订单。
图3.20 支付失败效果示例
图3.21 是否支付的选择
其他模块设计(header,jump,config,vuex,router等)
该模块是很重要但在上面没有提及的模块,有以下内容:
- 头部跳转组件。
头部跳转组件是很重要的,一方面它辅助了汽车搜索功能的实现,另一方面它也实现了很多跳转,方便用户去到其他页面。该组件有以下几个功能:
图3.22 头部导航示例
- 辅助汽车搜索功能的实现。汽车搜索的功能中,要搜索的内容就是这个框里的内容,如果框里没有内容,就默认是搜索全部汽车。
- 对应的跳转。可以便捷地跳转到对应页面,比如订单管理是跳转到订单分页展示页面,网站首页是跳转到汽车分页展示页面,用户中心是跳转到用户信息查看页面。此外,点击用户头像,也可以去到用户中心。
- 动态变换位置。在“汽车分页展示”的页面下,搜索栏会有两种状态:顶部固定与中间。如下图。为了实现这种状态的转换,我的做法是:监视网页的滚动条,当滚动条的高度到了一定位置的时候,改变搜索框的class(这里用了vue的动态绑定class的功能),实现两种状态的转换。同时,还对route进行了监视,一但跳转到了其他页面,搜索框就直接固定在顶部。
图3.23 搜索框处于中间示例
图3.24 搜索框处于上面示例
- 迷你头像显示
使用了el-avatar组件,把一个头像放在span中,再放到整个头部的右侧位置。当用户未登录(和未上传头像)时,看到的是默认头像。用户登录并已上传过头像后,就会显示用户对应的上传头像。
图3.25 迷你头像显示
- 便利的登录注册与注销
如果未登录,可以去到登录/注册页面;如果已经登录,可以使用注销、用户中心功能。
难点和亮点
后端:
使用redission分布式锁,来保障同一时间用户下单得到需求
有一些异步更新的操作,比如上传头像等。
还有jwt进行用户密码的加密,以及在cookie中传输的用户id的加密。
前端:
有一些缓存和懒加载。
下载地址