1、专业专业课程设计I报告民航票务管理与售票系统专业课程设计I报告( 2011 / 2012 学年 第 二 学期)题目:民航票务管理与售票系统 专 业 软件工程 学 生 姓 名 仓业亮 班 级 学 号 B09040811 指 导 教 师 李玲娟 指 导 单 位 计算机学院软件工程系 日 期 2012年4月26日 指导教师成绩评定表学生姓名班级学号专业评分内容评分标准优秀良好中等差平时成绩认真对待课程设计,遵守实验室规定,上机不迟到早退,不做和设计无关的事设计成果设计的科学、合理性功能丰富、符合题目要求 界面友好、外观漂亮、大方程序功能执行的正确性程序算法执行的效能设计报告设计报告正确合理、反映系统
2、设计流程文档内容详实程度文档格式规范、排版美观验收答辩简练、准确阐述设计内容,能准确有条理回答各种问题,系统演示顺利。评分等级指导教师简短评语指导教师签名日期备注评分等级有五种:优秀、良好、中等、及格、不及格 民航票务管理与售票系统一、 课题内容和要求1.1课程简介:本次课程设计的基本要求主要是按照软件工程思想,以SQL Server 2000为后台数据库,以Delphi为前端开发工具,设计并实现一个民航票务管理与售票系统。其中,系统实现的功能主要有(1)可以进行航班信息、票务信息的添加、修改和删除。 (2)允许普通用户和各类人员查询有关民航航班的时刻表,包括航班号、起点、终点、日期、起飞时刻
3、、到达时刻、剩余座位数、票价、航班所属航空公司等方面的准确信息。也可以按照终点和日期进行查询。1.2. 需求描述 1.2.1 我把本系统的用户统一分为普通用户和具有信息管理职责的管理员特殊用户,其中,管理员是系统指定的用户,不用注册,且本身也不必具备修改用户信息的功能。而普通用户初次登陆时是需要注册的,注册完了之后,如果数据成功添加在了数据库的passenger表中,则显示成功注册,然后重新登陆。1.2.2可以进行航班信息、票务信息的添加、修改和删除。 该功能只能有管理员实现,其中票务信息我是不允许修改的,只有删除的选项,之所以这么做,第一是票务信息(p_ticket)关联的关联的两张表pas
4、senger乘客信息表和flight航班信息表都是可以修改的,所以票务信息的修改本质上意义不大;第二就是我的三张表都是有外键约束的,所以当票务信息被修改的时候,必然影响到其他主键表,所以技术上也添了麻烦。1.2.3用户可以对航班信息表进行一定限度的查询,包括按航班号查询,按起点和终点查询和按日期查询。三种条件选一种 1.2.4 售票信息实时更新:具体要做到的是当某个航班被售票的时候,其剩余座位数也要跟着减少一个,相应的退票的时候,座位数也要跟着加一。需要注意的是用户不具有退票的功能,必须由管理员操作。1.2.5非功能需求 (1) 可读性:程序的源代码要书写规整,要求容易理解,以便于日后程序调试
5、时容易测试和修改。 (2) 界面的设计:应本着简洁、漂亮、通俗易懂,操作简便,并具有一定的灵活性;尽可能采用开发工具构造界面,使需求定义和设计、编码相衔接;参考、比较已经成熟的软件的界面的风格,提取有用的设计方法。 (3) 可测试性:这是建立在可读性的基础之上的,如果程序不易于理解则测试起来相当麻烦,并且有可能造成灾难性后果。1.3开发运行环境系统开发平台:Delphi 7数据库管理系统软件:SQL Server 2000运行平台:Windows XP分辨率:最佳效果1024768硬盘要求:CPU:300MHz以上的处理器内存:64MB,推荐128M以上硬盘:100M以上磁盘空间二、设计思路分
6、析完成此课题的思路和基本步骤第一步:理解该系统的功能需求,进行逻辑设计,指定具体的实现计划。第二步:数据库设计,具体包括表的划分和建立,表中的属性值的定义等。第三步:测试连接,主要是测试开发环境delphi7与数据库sql2000的 连接特性。第四步:系统的模块划分,确定各个模块所要实现的功能。第五步:确定测试用例和测试方法,方便程序以后的测试。第六步:主要功能模块的设计和实现,并且辅助以测试实现。第七步:测试所完成的应用程序,排查和纠正错误。三、概要设计 3.1数据库逻辑设计如下: 3.1.1本数据库的设计中,具体涉及到了三张表的创建于修改。 Passenger用户信息表 Flight航班信
7、息表 P_ticket票务信息表 3.1.2数据库的完整性约束规则的说明(主键、外键等)如下图所示:其中选定了级联更新和删除相关的字段和记录可以在我修改flight表和passenger表的主键信息时间接的达到修改票务信息表的目的。四、详细设计 (1).系统的登陆界面如下图所示:说明:本窗体需要和数据库里的passenger表相关联,通过ADOconnection1和ADOquery1及datasource1三个控件配合,登陆按钮被点击是触发函数如下:with adoquery1 do/对用户输入的邮箱地址和密码在passenger表中查询begin close; sql.clear; sql
8、.text:=(select * from passenger where 邮箱地址=:a and 密码=:b ); parameters.parambyname(a).value:=trim(edit1.text); parameters.parambyname(b).value:=trim(edit2.text); open; if recordCount=1 then /如果存在符合输入的记录则跳转到查询主页 begin form1.Visible:=false ; form3.show; user_id:=edit1.Text; manager:=90231; /系统中自己设定的管理员
9、账号 if user_id=manager then /如果用户用的是管理员的账号 begin form3.bitbtn2.Visible:=false ;/管理员不能修改用户信息 form3.BitBtn8.Visible:=true; /管理员对信息管理的按钮可见 form3.label3.caption:=管理员 end else begin form3.BitBtn2.Visible:=true; /允许普通用户修改用户信息 form3.BitBtn8.Visible:=false; /不具有信息管理的权限 form3.Label3.Caption:=普通用户; end; end el
10、se showmessage(用户名或密码输入错误!);/密码验证错误,输出提示end;(2).新用户的注册界面如下图所示:说明:在输入用户邮箱的时候,光标进入到edit控件之内我写了一个触发函数:checkbox1.Checked:=false;checkbox1.Caption:=帮你验证邮箱;/显示界面友好而当光标移开edit控件后也有一个触发函数: if (pos(,edit1.text) =0) or (length(edit1.Text)5) then/没有字符或者 begin showmessage(邮箱地址格式不正确,请重新输入!) ;/字符长度小于5为非法 edit1.Tex
11、t:=; end else begin checkbox1.Checked:=false; /初始化checkbox标签属性 with adoquery1 do /在用户表中对此地址进行查询begin close; sql.clear; sql.text:=(select * from passenger where 邮箱地址=:a ); parameters.parambyname(a).value:=trim(edit1.text); open; if recordCount=1 then /存在则输出提示 begin checkbox1.Checked:=false ; checkbox
12、1.Caption:=邮箱已被注册!请重新输入; edit1.Text:= ; end else.end;另外,我还通过重复输入密码的验证,联系电话输入长度的限制等,使用户注册信息更加合理,也更加人性化。(3).普通用户通过登录界面之后的查询界面如下:具体的顺序图如下:说明:用户可以通过三种条件进行查询,但是不允许多条件查询。具体设定是比如我选择按照航班号进行查询时,则其后面的航班号dblookupcombobox就可用而其他的查询条件框是不可用的。源程序中dblookupcombobox的设定有必要说明一下。首先将该控件与一个adoquery控件连接好,adoquery控件的设定略去,然后设
13、定listsource、listfield和keyfield的值,第一次我keyfield的值没有设定是,是显示不出字段的值的。确定查询的点击事件触发的函数如下:with adoquery4 do /在航班信息表中进行查询begin close; sql.clear; if (dblookupcombobox1.Enabled=true) /如果选择按起降地查询and(dblookupcombobox1.Text)and(dblookupcombobox2.Text) then begin sql.text:=(select * from flight where 起点=:a and 终点=:
14、b); parameters.parambyname(a).value:=trim(dblookupcombobox1.Text); parameters.parambyname(b).value:=trim(dblookupcombobox2.Text); end else if (dblookupcombobox3.Enabled=true) and(dblookupcombobox3.Text) then /如果选择航班号查询 begin 。 /代码略去 end else if (edit1.Enabled=true) and(edit1.Text)and(edit2.Text) the
15、n begin adoquery4.SQL.Add(select * from flight where 日期 between :cong and :dao);adoquery4.Parameters.ParamByName(cong).Value:=trim(edit1.Text);adoquery4.Parameters.ParamByName(dao).Value:=trim(edit2.Text); end; end; open; if recordCount0 then begin end else showmessage(不存在符合输入的记录!);/没有检查到信息是提示 end;(
16、3).用户查询完航班信息之后可以进行订票,具体界面情况如下:说明:因为航班信息表的主键设置为了航班号和日期,所以用户在订票时必须选择航班号和日期两个选项之后才能完成航班信息的选择。为方便用户,我在选择完了航班号之后,下一个日期选项自动定位到字段值为所选航班号的所有日期,缩小了选择范围,避免了一些不必要的选项。具体代码如下:with form6.ADOQuery3 do /日期复选框用到的组件 begin close; sql.clear; sql.text:=(select * from flight where 航班号=:a); /查询符合的值 parameters.parambyname(
17、a).value:=trim(dblookupcombobox1.Text); open; end;底下的用户信息是随着用户的登陆信息自动更新的无需用户进行输入,具体实现代码如下: with form6.ADOQuery5 do /定位用户信息 begin close; sql.clear; sql.text:=(select * from p_ticket where 邮箱地址=:a ); parameters.parambyname(a).value:=trim(user_id); /用户登陆时自动赋 open; /值的变量 end;确定订票时需要对其所对应的航班信息的剩余座位数进行验证,
18、如果为零,则不允许订票,另外还要对是否进行了重复订票进行检查,具体代码如下:if (dblookupcombobox1.Text=) or (dblookupcombobox2.Text=) or (adoquery4.FieldByName(剩余座位数).Value=0) then Begin /剩余座位数为零,则不能完成订票 showmessage(没有座位了,订票失败!); end else with form6.ADOQuery5 do /检查票务信息是否重复 begin close; sql.clear; sql.text:=(select * from p_ticket where
19、 航班号=:a and 日期=:b and 邮箱地址=:c); parameters.parambyname(a).value:=trim(dblookupcombobox1.Text); parameters.parambyname(b).value:=trim(dblookupcombobox2.Text); parameters.parambyname(c).value:=trim(dbedit1.Text); open; if recordCount=1 then /在票务信息已有记录时 begin showmessage(票务信息重复,添加失败!); end;另外需要完成的一项重要的
20、功能是实现剩余座位数的动态更新,具体完成的代码如下所示:with ADOQuery4 do /更新座位数 begin i:=fieldbyname(剩余座位数).Value-1; /i是上文定义的整型变量 str(i,s); /将i转换成s字符串型的变量 Close; SQL.Clear; SQL.Text:=Update flight SET 剩余座位数=:剩余座位数 where 航班号=:a and 日期=:b ; parameters.parambyname(a).value:=trim(dblookupcombobox1.Text); parameters.parambyname(b)
21、.value:=trim(dblookupcombobox2.Text); Parameters.ParamByName(剩余座位数).Value:=s; /更新座位数的值 ExecSQL; close; SQL.Add(select * from flight ); sql.clear; /更新座位信息 sql.text:=(select * from flight where 航班号=:a and 日期=:b); parameters.parambyname(a).value:=trim(dblookupcombobox1.Text); parameters.parambyname(b).
22、value:=trim(dblookupcombobox2.Text); open;end;至此普通用户的功能都已经实现了,下文将讨论管理员的功能实现:系统中对管理员的账号信息固定为90231,所以管理员的用户信息是不允许修改的,实际中也没有多大的意义。以管理员身份登录之后系统的航班信息查询界面会增加一个信息管理选项,同时用户信息修改的按钮被隐藏,同时提醒用户是管理员身份登录,具体界面如下所示:点击信息管理则进入到下一个界面如图所示:在本界面中一个dbgrid主要显示了三张表的信息,通过上方的按钮进行控制,具体的代码如下:bitbtn6.Enabled:=true; bitbtn7.Enabl
23、ed:=true; bitbtn8.Enabled:=true; /使下方的查询、修改、删除按钮有效flight_in:=true; user_in:=false; ticket_in:=false;/上文定义的三个变量with adoquery1 do /选择航班信息表进行信息显示begin close; sql.clear; sql.text:=(select * from flight); open;end; /如果没有记录则不支持修改和删除 if dbgrid1.DataSource.DataSet.RecordCount=0 then begin bitbtn7.Enabled:=f
24、alse; bitbtn8.Enabled:=false; end;当要修改数据时,首先选中记录:然后点击修改按钮,出现如下界面:关键代码如下:if flight_in=true then /如果选中了航班信息进行修改 begin form5.Enabled:=false; form7.show; form7.dbedit1.enabled:=false; form7.dbedit2.enabled:=false; /主键不允许修改 s:=adoquery1.fieldbyname(航班号).AsString; s1:=adoquery1.fieldbyname(日期).AsString; 读
25、取光标的那一行的值 with form7.ADOQuery1 do /从航班信息表中进行定位 begin close; sql.clear; sql.text:=(select * from flight where 航班号=:a and 日期=:b ); parameters.parambyname(a).value:=s; parameters.parambyname(b).value:=s1; open; end;end;因为航班信息的显示用的都是dbedit控件,所以确定修改的代码非常简单: form7.ADOQuery1.UpdateBatch;保存修改form7.Visible:=
26、false;form5.show; 返回原来得界面form5.enabled:=true;而对于其他两个票务信息表和航班信息表我是不允许修改的,具体原因我上文已经说过了。当选中了票务信息表的时候,在点击添加按钮,即出现如下界面:说明:首先要选择航班号和日期,其次选择邮箱地址,最后确认添加,即可完成管理员售票功能,添加之前的验证代码如下:if (dblookupcombobox1.Text=) or (dblookupcombobox2.Text=) or(dblookupcombobox3.Text=) or(form10.DBEdit3.Text=)or(adoquery4.FieldByN
27、ame(剩余座位数).Value=0) thenbegin showmessage(信息不完整或者没有剩余座位了,无法完成订票!);end else begin with form10.ADOQuery7 do /对票务信息表进行查询 begin close; sql.clear;sql.text:=(select * from p_ticket where 航班号=:a and 日期=:b and 邮箱地址=:c); parameters.parambyname(a).value:=trim(dblookupcombobox1.Text); parameters.parambyname(b)
28、.value:=trim(dblookupcombobox2.Text); parameters.parambyname(c).value:=trim(dblookupcombobox3.Text); open; if recordCount=1 then /如果已经存在了相同的记录 begin showmessage(票务信息重复,添加失败!); form10.Show; end;删除票务信息之前,要先选中:选择删除按钮即可出现如下界面:确认删除时,剩余座位数会自动加一,至此管理员的票务信息的添加以及删除就完成了。(源程序代码用Times New Roman 5号字体,单倍行距)五、测试数据
29、及其结果分析(格式:宋体,4号,加粗,两端对齐)(1).用户登录测试,假设数据库中有如下一条记录:当我密码输入错误时有如下错误:用户名及密码正确验证以后即进入了主界面,用户的登录功能实现了。(2).普通用户可对航班信息进行查询,假设flight航班信息表中有如下数据:按起降地查询时有:点击确认查询有如下结果:则用户按起降地查询功能实现成功。类似的按航班号查询有如下结果:按日期查询如下:都已经实现了预期的功能:(3).用户进行订票时,下方的用户信息会自动更新:选中订票按钮之后,信息自动增加:经检查,剩余座位数也自动减一了。(4).再用管理员的身份登录时进入到信息管理界面,先增加一条航班信息如图所
30、示:点击添加点击添加出现如下界面:点击确认添加点击确认添加之后数据库显示了更新信息,如下图所示:成功添加功能顺利实现。添加票务信息时,出现如下界面:点击添加注意剩余座位数结果见下图:成功添加在数据库里查询剩余座位数是否更新:更新成功!使用类似的方法在管理员删除订票信息的时候,对应的剩余座位数也重新回到了原先的值,见下图:还原成功!至此,管理员的大部分功能已经展示完毕。六、调试过程中的问题设计和调试时存在问题的思考(问题是哪些?问题如何解决?)(1)数据库主键约束问题。原先在应用程序还没有开始写之前,就在数据库中定义了一些表格,但是在具体操作时发现,对于每一行的记录,主属性是不能被修改的,除非删
31、除,当然这也不违背我之前学的一些浅薄的数据库知识。但是在应用程序开发过程中,当向数据库中插入数据时,比如管理员用到的航班信息的插入,普通用户信息注册也要用到信息的插入,这时,如果插入了主键重复的记录之后,应用程序会返回数据库错误的提示信息,导致程序意外终止,通常遇到这种情况十分让人讨厌,因为常常会使我的电脑短暂的死机,而且在每次重新启动工程的时候,因为插入了背景图片,所以速度非常的慢,具体原因我自己也搞不清,但是问题是可以避免的。为此我也花了一些很可观的时间来实现数据插入前的主键约束检查。(2)另外一个比较类似的问题是处理外键约束。数据库中的常识,外键时引用了其他表格的主键的值,但非本表的主键
32、,在用户删除引用的外键的信息时,可以对此情况加以限制,我是选择了强制删除和更新的选项的。这就是说在我修改或删除主键的值的时候,外键的值也会跟着修改和删除。类似上面的问题也出现了,就是我在修改票务信息的时候,应用程序也会返回数据库的错误信息提示。为此我就把管理员修改票务信息的这一项功能去掉了,但是这个功能是可以间接实现的,因为用户信息和航班信息都是可以修改的。(3)delphi中的adoquery控件是一个神奇的控件,至少对我这个初学者来说的确如此,限于篇幅这里先列举我写程序过程中遇到的一小部分问题吧。第一个问题是如何实现我把修改的信息重新保存到数据库里面:我在网上搜了很久之后才知道有一个dbe
33、dit组件可以实现我的要求,(百度是一个神奇的东西,哈),之后我也尝试并掌握了dblookupcombobox的用法,实现了动态列举数据库某个列属性值的列举效果,效果很好,都是要配合adoquery这个组件来实现的。另一个问题是adoquery的post属性和open属性。具体情况大概是当我重复使用post语句是,系统就会报错,英文意思是数据库没有处于编辑或插入状态,这是adoqery的active属性没有设置成true引起的,具体还有其他的错误提示,记不清了。另一个open属性,是我在执行了这一条语句时,如果fieldbyname中的字段值如果没有取成功的话,就会报错,提示大概是参数不足,无
34、法打开之类,其他的诸如字段名不一致之类的都是小问题了。处理这类问题,关键是确定adoquery所连接的表名是否搞混了,再者就是字段名是否输入真确,最最重要的就是不能重复post;不过updatebatch是可以重复使用的。七、专业课程设计总结总结可以包括:课程设计过程的收获。本次课程设计中确实学到了不少的东西,虽然道路有些艰辛,相对于非课程设计时还是努力很多了,但终归还是圆满完成了任务,感觉挺好。课程实践中用到的delphi软件开发工具,基本掌握了delphi和sql数据库连接的技术知识。刚开始的时候,因为对该软件的基础为零,所以对本次课程设计的实现有一种茫然的感觉,但是经过两三天的学习之后,了解了它与数据库的数据交换技术之后,关键是数据插入,删除,修改的源代码,感觉它还是能够上手的。在后来的一步一步的窗体创建和编辑过程中,整个的系统框架就慢慢细化,最终完成设计,有一点成就感。最后要提到的是课程设计中我掌握了delphi的基本开发程序的方法,对程序开发方面的知识有了更加深刻的领悟。同时,在完善程序的过程中也与周边同学的相互学习当中也学到的不少的知识,同学之间的相互合作也促进了友谊。31