数据库课程设计
1 引言
1.1需求分析
滴滴打车系统的主要应用需求来自乘客、司机两个身份的用户需求。对于乘客,他可以登入系统,查看自己的信息,修改自己的密码,进行打车下单的操作和给管理员留言的操作;对于司机,他可以登入系统,查看自己的信息,修改自己的密码,进行接单操作和给管理员留言的操作。
管理员是一个特殊的存在,我设计其用户名为root,密码为123,可以查看各项信息,比如所有乘客信息、所有司机信息、所有订单信息和留言信息。
1.2系统目标
- 实现针对不同用户的身份登入
- 实现乘客下单和司机接单操作
- 实现乘客和司机的自己密码更改
- 实现乘客和司机的注册操作
- 实现乘客和司机的给管理员留言操作
- 实现管理员的监控页面
1.2系统应该包含的信息
- 乘客和司机的用户名和密码
- 每个乘客的信息:
用户名,密码,身份证号码,联系电话
- 每个用户的信息
用户名,密码,身份证号码,联系电话,车子型号,车子载客量
- 留言信息
留言者信息,留言的内容
1.3与系统的交互
- 认证:进行数据库查询,首先查询是否存在此用户,其次比对密码是否正确,再更具不同身份进行页面跳转。
- 如果为乘客可进行以下交互: 查看自己信息,进行密码修改,进行打车下单操作。
- 如果为司机可进行以下交互: 查看自己信息,进行密码修改,进行打车下单操作。
- 管理员查看所有表信息
1.3数据流字典和数据字典
client表结构:
图 1
driver表结构:
order表结构:
图 3
message表结构:
2 概要设计
2.1 系统ER图
2.2 系统功能结构图
3 程序系统设计
3.1 数据库系统设计
1.乘客表(用户名,密码,手机号,身份证号码)
create table `client`
-- --------------------------------------------------
-- Table structure for `myBeegoWeb/models.Client`
-- --------------------------------------------------
CREATE TABLE IF NOT exists `client` (
`cl_name` varchar(20) NOT NULL PRIMARY KEY,
`cl_password` varchar(20) NOT NULL DEFAULT '' ,
`cl_phone` varchar(11) NOT NULL DEFAULT '' unique,
`cl_identification_card` varchar(18) NOT NULL DEFAULT '' UNIQUE
) ENGINE=InnoDB;
- 司机表(用户名,密码,手机号,身份证号码,车子型号,车子载客量)
create table `driver`
-- --------------------------------------------------
-- Table Structure for `myBeegoWeb/models.Driver`
-- --------------------------------------------------
CREATE TABLE IF NOT EXISTS `driver` (
`dr_name` varchar(20) NOT NULL PRIMARY KEY,
`dr_password` varchar(20) NOT NULL DEFAULT '' ,
`dr_phone` varchar(11) NOT NULL DEFAULT '' UNIQUE,
`dr_identification_card` varchar(18) NOT NULL DEFAULT '' UNIQUE,
`car_brand` varchar(20) NOT NULL DEFAULT '' ,
`car_load` integer NOT NULL DEFAULT 0
) ENGINE=InnoDB;
- 订单表(订单编号,起始地,目的地,起始时间,结束时间,备注,花费,客户名,司机名)
create table `order`
-- --------------------------------------------------
-- Table Structure for `myBeegoWeb/models.Order`
-- --------------------------------------------------
CREATE TABLE IF NOT EXISTS `order` (
`or_id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY,
`orgin` varchar(30) NOT NULL DEFAULT '' ,
`destination` varchar(30) NOT NULL DEFAULT '' ,
`begin_time` datetime NOT NULL,
`endtime` datetime,
`node` varchar(255),
`cost` double precision,
`client_id` varchar(20) NOT NULL,
`driver_id` varchar(20)
) ENGINE=InnoDB;
- 留言表(留言编号,留言者名,留言内容)
create table `message`
-- --------------------------------------------------
-- Table Structure for `myBeegoWeb/models.Message`
-- --------------------------------------------------
CREATE TABLE IF NOT EXISTS `message` (
`message_id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY,
`write_by` varchar(20) NOT NULL DEFAULT '' ,
`node` varchar(255)
) ENGINE=InnoDB;
3.2 数据库连接
在go语言中,可以利用{{.keyName}}形式与HTML进行交互,比如:
当用户登入时,我的HTML代码入图7,想显示“你好啊!”+“用户名”的标签,在go程序中:
利用GetCookie()函数获得浏览器cookie信息,再利用Data[“keyName”]=value的键值储存形式,最后将{{.keyName}}运行时渲染为value的信息,结果如图9:
3.3 程序框图
登入程序:
打车程序:
4 系统实现
- 程序总体概述
滴滴打车模拟系统有3种角色设置:乘客、司机和管理员。他们首先都有登入界面进行身份验证,再跳转到不同的主页上。
对于乘客来说,实现了注册、登入、下单、查询、改密码和留言等功能,功能的实现主要靠表单的填写,载与数据库进行交互。对于司机来说,实现了注册、登入、接单、查询、改密码和留言等功能,与乘客有所不同的在于司机的接单操作是更新数据库的订单表,而乘客的接单是插入一个订单。管理员页面是为了方便快速查询数据库信息,可以看到各类表的信息。
- 详细设计与运行界面
- 登入认证界面:
用户的登入需要输入用户名和密码,在接收到信息之后,我们会对其身份进行验证,在跳转到不同的页面。
在程序中:
//Get login页面获取
func (c *Mycontroller) Get() {
c.TplName = "login.html"
}
其中c.TplName 就是起到指定显示相关的HTML模板界面。
//Post login页面的表单处理
func (c *MyController) Post() {
//GetString(name) 可获得表单内相应name的框内信息
userName := c.GetString("user_name")
password := c.GetString("password")
首先获取信息,之后进行查询,验证,比如验证是否为司机如下:
//user是一个暂存信息的结构体
user := models.Client{}
user.ClName = userName
//o为Orm对象,用于数据库操作
o := orm.NewOrm()
//进行查找,默认为靠主键查找
err1 := o.Read(&user)
if err1 != nil {
//不为乘客再看是否为司机
driver := models.Driver{}
driver.DrName = userName
err2 := o.Read(&driver)
if err2 != nil {
beego.ERROR("不存在此用户!")
c.Setsession("/skipMessage", "不存在此用户")
c.Ctx.SetCookie("skipHtml", "/login")
c.Redirect("/skip", 302)
return
}
if driver.DrPassword != password {
beego.Error("密码错误!")
c.SetSession("/skipMessage", "密码错误")
c.Ctx.SetCookie("skipHtml", "/login")
c.Redirect("/skip", 302)
return
}
c.Ctx.SetCookie("dr_name", userName)
c.SetSession("/skipMessage", "成功登入")
c.Ctx.SetCookie("skipHtml", "/driver")
c.Redirect("/skip", 302)
return
}
就先判断是否为乘客,不是在判断是否为司机,用结构体储存数据库读出的数据,再比对密码是否真确。
运行结果:
- 乘客与司机注册界面
图12中,登入键左下角有乘客注册和用户注册两个按键,是分别跳转到不同的用户注册界面的,这两个注册程序大同小异,我以乘客注册为例介绍程序:
//Get 乘客注册页面获取
func (c *ClRegistController) Get() {
c.TplName = "cl_regist.html"
}
//Post 乘客注册表单处理
func (c *ClRegistController) Post() {
cl_name := c.GetString("Cl_Name")
cl_password := c.GetString("Cl_password")
if cl_password != c.GetString("Cl_password2") {
beego.Error("两次密码输入不相同!")
c.SetSession("/skipMessage", "两次密码输入不相同!")
c.Ctx.SetCookie("skipHtml", "/cl_regist")
c.Redirect("/skip", 302)
return
}
cl_phone := c.GetString("Cl_Phone")
cl_id := c.GetString("User_id")
//3.插入数据库
o := orm.NewOrm()
client := models.Client{}
client.ClName = cl_name
client.ClPassword = cl_password
client.ClPhone = cl_phone
client.ClIdentificationCard = cl_id
_, err := o.Insert(&client)
if err != nil {
c.Ctx.WriteString("")
beego.Error("注册失败!数据库操作错误")
c.SetSession("/skipMessage", "注册失败!输入不合法")
c.Ctx.SetCookie("skipHtml", "/cl_regist")
c.Redirect("/skip", 302)
return
}
beego.Info(cl_name, " 注册成功")
c.SetSession("/skipMessage", "注册成功")
c.Ctx.SetCookie("skipHtml", "/login")
c.Redirect("/skip", 302)
}
在注册时,只要获取信息,并填写完成角色相应的结构体就行。具体相应的插入就直接调用insert()函数处理就行,数据合法性可以交给数据库处理,最后有错报错,没错跳转回到登入界面就行。
运行结果:
- 跳转提示界面
出于方便友善的提示信息,跳转界面会在出现页面跳转时出现,比如登入成功,表单提交成功或失败。
在HTML中,实现跳转的语法还是很简单的,如倒数3秒跳转login页面:
<meta http-equiv="refresh" content="3;url=/login" />
具体获取到跳转那个页面我进行了数据的缓冲,动态地获取要跳转页面信息和提示信息:
<h2>{{.skipMessage}}</h2>
<p><span>页面自动<a id="href" href="{{.skipHtml}}">跳转到{{.skipHtml}}界面</a></span><br />
在程序中:
//SkipGet 信息提醒跳转页面
func (c *SkipController) SkipGet() {
skipMessage := c.GetSession("/skipMessage")
skipHtml := c.Ctx.GetCookie("skipHtml")
c.Data["skipMessage"] = skipMessage
c.Data["skipHtml"] = skipHtml
c.TplName = "skip.html"
}
运行结果:
- 乘客界面
乘客页面主要就是显示2个表单和提交3个表——下单表,改密码表、留言表。
以显示消费记录为例子,主要就是查询order表中的乘客名为Cl_1的信息,在这里,不同乘客的信息我是利用cookis储存在浏览器里,存在浏览器关闭cookis导致查询失败的可能。程序如:
var username string
username = c.Ctx.GetCookie("cl_name")
c.Data["cl_name"] = username
client := models.Client{}
client.ClName = username
o := orm.NewOrm()
//获取用户信息
err := o.Read(&client)
if err != nil {
beego.Error("用户信息获取失败", err)
return
}
//获取已完成订单信息
var order []models.Order
_, err = o.Raw("select * from `order` where client_id = ? and cost != 0", username).QueryRows(&order)
if err != nil {
beego.Error("查询所有完成单信息出错")
return
}
c.Data["Order2"] = order
c.Data["ClName"] = client.ClName
c.Data["ClPassword"] = client.ClPassword
c.Data["ClPhone"] = client.ClPhone
c.Data["ClIdentificationCard"] = client.ClIdentificationCard
beego.Info(username, "登入成功")
c.TplName = "client.html"
在对于结构体对象的遍历中(如order),HTML与golang有很好的交互手段,在HTML中,可以进行go语法的遍历结构体,如:
<table width="900" height="100" style="margin:auto;margin-top:50px;border:1px solid #FFF" border="1" cellpadding="0" cellspacing="0" >
<tr>
<th width="12%">订单编号</th>
<th width="12%">客户姓名</th>
<th width="12">司机姓名</th>
<th width="12%">起始地</th>
<th width="12%">目的地</th>
<th width="12%">订单时间</th>
<th width="12%">交易费用</th>
<th width="16%">备注</th>
</tr>
{{range .Order2}}
<tr>
<td>{{.OrId}}</td>
<td> {{.Client.ClName}}</td>
<td> {{.Driver.DrName}}</td>
<td>{{.Orgin}}</td>
<td>{{.Destination}}</td>
<td>{{.BeginTime.Format "2006-01-02"}}</td>
<td>{{.Cost}}</td>
<td>{{.Node}}</td>
</tr>
{{end}}
</table>
运行结果:
再以下单表提交为例子,主要就是填写起点、终点和备注,具体处理细节和逻辑和注册表差不多,就不再缀诉,运行结果:
最后总体界面图:
- 司机界面
司机的界面与乘客界面的实现基本相同,改下单功能为接单功能,运行如下:
需要填写的表单信息为要接单的订单号和交易的费用,刷新按键还可以进行查看有没有新订单,可以实现并发的抢单。
实现接单的逻辑本质就是更新一个不完整的订单,程序如下:
//获取司机信息
dr_name := c.Ctx.GetCookie("dr_name")
if dr_name == "" {
beego.Error("司机信息获取失败!")
c.SetSession("/skipMessage", "司机信息获取失败!")
c.Ctx.SetCookie("skipHtml", "/driver")
c.Redirect("/skip", 302)
return
}
cost, err := c.GetFloat("cost", 10.01)
if err != nil {
beego.Error("获取价格出错!", err)
c.SetSession("/skipMessage", "获取价格出错!")
c.Ctx.SetCookie("skipHtml", "/driver")
c.Redirect("/skip", 302)
return
}
driver := models.Driver{}
driver.DrName = dr_name
o := orm.NewOrm()
err = o.Read(&driver)
if err != nil {
beego.Error("从数据库获取司机信息出错!", err)
c.SetSession("/skipMessage", "从数据库获取司机信息出错!")
c.Ctx.SetCookie("skipHtml", "/driver")
c.Redirect("/skip", 302)
return
}
//获取订单信息
orderId := c.GetString("OrId")
if orderId == "" {
beego.Error("订单信息获取失败!")
c.SetSession("/skipMessage", "订单信息获取失败!")
c.Ctx.SetCookie("skipHtml", "/driver")
c.Redirect("/skip", 302)
return
}
order := models.Order{}
order.OrId, _ = strconv.ParseInt(orderId, 10, 64)
err = o.Read(&order)
if err != nil {
beego.Error("从数据库获取订单失败!")
c.SetSession("/skipMessage", "从数据库获取订单失败!")
c.SetSession("skipHtml", "/driver")
c.Redirect("/skip", 302)
return
}
order.Driver = &driver
order.Cost = cost
//更新订单,状态为已完成
_, err = o.Update(&order)
if err != nil {
beego.Error("更新数据失败!")
c.SetSession("/skipMessage", "更新数据失败!")
c.SetSession("skipHtml", "/driver")
c.Redirect("/skip", 302)
return
}
beego.Info("接单成功!")
c.SetSession("/skipMessage", "接单成功!")
c.SetSession("skipHtml", "/driver")
c.Redirect("/skip", 302)
- 管理员界面
管理员界面设计出来是为了方便更好地查看数据信息。假设我将项目布置到云端服务器上,通过管理员页面,我也能够查看数据库中的信息。
运行结果:
- 日志的查看
在beego中,可以调用beego.Info()和beego.Error()方法来显示程序的运行信息,帮助我们更好地掌控程序动态,相关的信息会打印在控制台上,运行结果如下:
5 软件使用说明
5.1 软件开发和运行环境
编译器:LiteIDE X32.1
开发语言:go语言,版本 go 1.11
浏览器:支持所有主流浏览器(建议开cookies)
已经上传github:数据库课程设计作品——beego框架的滴滴打车系统
相关阅读
平台:MSM8937 + Android 7.1.2 一、修改开机画面 手机屏的初始化会有两部分,一部份是lk,一部分是kernel,当lk部分初始化化完成就会显
MySQL数据库中tinyint类型字段读取数据为true和false
数据库一个表中有一个tinyint类型的字段,值为0或者1,如果取出来的话,0会变成false,1会变成true。MySQL保存boolean值时用1代表TRUE,0代
之前的一个项目用到了这个系统,就在这里回顾下吧。这种比较老的系统,网上已经有很详细的教程文档和视频了,我就不长篇累牍了。就分享
文章对库存管理系统做了简单的概括和总结,希望能够给你带来一些启发和思考。库存系统作为电商后台系统中不可或缺的一部分,虽然公司
iPad mini在使用时间一长,各种软件安装卸载难免会留下一些垃圾文件在系统内。由于苹果无法直接打开系统文件夹,也没有一个好的清理