数据库课程设计——滴滴打车系统

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_39683463/article/details/87970951

1 引言

1.1需求分析

滴滴打车系统的主要应用需求来自乘客、司机两个身份的用户需求。对于乘客,他可以登入系统,查看自己的信息,修改自己的密码,进行打车下单的操作和给管理员留言的操作;对于司机,他可以登入系统,查看自己的信息,修改自己的密码,进行接单操作和给管理员留言的操作。

管理员是一个特殊的存在,我设计其用户名为root,密码为123,可以查看各项信息,比如所有乘客信息、所有司机信息、所有订单信息和留言信息。

1.2系统目标

  1. 实现针对不同用户的身份登入
  2. 实现乘客下单和司机接单操作
  3. 实现乘客和司机的自己密码更改
  4. 实现乘客和司机的注册操作
  5. 实现乘客和司机的给管理员留言操作
  6. 实现管理员的监控页面

1.2系统应该包含的信息

  1. 乘客和司机的用户名和密码
  2. 每个乘客的信息:

       用户名,密码,身份证号码,联系电话

  1. 每个用户的信息

       用户名,密码,身份证号码,联系电话,车子型号,车子载客量

  1. 留言信息

      留言者信息,留言的内容

1.3与系统的交互

  1. 认证:进行数据库查询,首先查询是否存在此用户,其次比对密码是否正确,再更具不同身份进行页面跳转。
  2. 如果为乘客可进行以下交互: 查看自己信息,进行密码修改,进行打车下单操作。
  3. 如果为司机可进行以下交互:  查看自己信息,进行密码修改,进行打车下单操作。
  4. 管理员查看所有表信息

1.3数据流字典和数据字典

client表结构:

                                                   图 1

driver表结构:

图2

                                                           

order表结构:

                                                           图 3

message表结构:

图4

 

2 概要设计

2.1 系统ER图

图5

 

2.2 系统功能结构图

图6

 

 

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;

 

  1. 司机表(用户名,密码,手机号,身份证号码,车子型号,车子载客量)
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;

 

  1. 订单表(订单编号,起始地,目的地,起始时间,结束时间,备注,花费,客户名司机名
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;

 

  1. 留言表(留言编号,留言者名,留言内容)
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进行交互,比如:

图7

 

当用户登入时,我的HTML代码入图7,想显示“你好啊!”+“用户名”的标签,在go程序中:

图8

 

利用GetCookie()函数获得浏览器cookie信息,再利用Data[“keyName”]=value的键值储存形式,最后将{{.keyName}}运行时渲染为value的信息,结果如图9:

图9

3.3 程序框图

登入程序:

图10

 

打车程序:

图11

4 系统实现

  1. 程序总体概述

滴滴打车模拟系统有3种角色设置:乘客、司机和管理员。他们首先都有登入界面进行身份验证,再跳转到不同的主页上。

对于乘客来说,实现了注册、登入、下单、查询、改密码和留言等功能,功能的实现主要靠表单的填写,载与数据库进行交互。对于司机来说,实现了注册、登入、接单、查询、改密码和留言等功能,与乘客有所不同的在于司机的接单操作是更新数据库的订单表,而乘客的接单是插入一个订单。管理员页面是为了方便快速查询数据库信息,可以看到各类表的信息。

  1. 详细设计与运行界面
    1. 登入认证界面:

用户的登入需要输入用户名和密码,在接收到信息之后,我们会对其身份进行验证,在跳转到不同的页面。

在程序中:

//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

 

  1. 乘客与司机注册界面

图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()函数处理就行,数据合法性可以交给数据库处理,最后有错报错,没错跳转回到登入界面就行。

运行结果:

图13

 

 

 

  1. 跳转提示界面

出于方便友善的提示信息,跳转界面会在出现页面跳转时出现,比如登入成功,表单提交成功或失败。

在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"

}

运行结果:

图14

 

 

 

  1. 乘客界面

乘客页面主要就是显示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>

运行结果:

图15

 

再以下单表提交为例子,主要就是填写起点、终点和备注,具体处理细节和逻辑和注册表差不多,就不再缀诉,运行结果:

图16

 

最后总体界面图:

图17

 

 

 

  1. 司机界面

司机的界面与乘客界面的实现基本相同,改下单功能为接单功能,运行如下:

图18

 

需要填写的表单信息为要接单的订单号和交易的费用,刷新按键还可以进行查看有没有新订单,可以实现并发的抢单。

实现接单的逻辑本质就是更新一个不完整的订单,程序如下:

//获取司机信息

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)

 

 

  1. 管理员界面

管理员界面设计出来是为了方便更好地查看数据信息。假设我将项目布置到云端服务器上,通过管理员页面,我也能够查看数据库中的信息。

运行结果:

图19

 

  1. 日志的查看

在beego中,可以调用beego.Info()和beego.Error()方法来显示程序的运行信息,帮助我们更好地掌控程序动态,相关的信息会打印在控制台上,运行结果如下:

图20

 

5 软件使用说明

5.1 软件开发和运行环境

编译器:LiteIDE X32.1

开发语言:go语言,版本 go 1.11

操作系统:window、Linux等主流系统皆可

服务程序:mysql 5.1

浏览器:支持所有主流浏览器(建议开cookies)

 

已经上传github:数据库课程设计作品——beego框架的滴滴打车系统

展开阅读全文

没有更多推荐了,返回首页