分类

课内:
不限
类型:
不限 毕业设计 课程设计 小学期 大作业
汇编语言 C语言 C++ JAVA C# JSP PYTHON PHP
数据结构与算法 操作系统 编译原理 数据库 计算机网络 软件工程 VC++程序设计
游戏 PC程序 APP 网站 其他
评分:
不限 10 9 8 7 6 5 4 3 2 1
年份:
不限 2018 2019 2020 2021

资源列表

  • 基于JAVA和SQL SERVER数据库实现的个人财务管理系统

    一、需求分析个人财务管理系统是智能化简单化个人管理的重要的组成部分。并且随着计算机技术的飞速发展,计算机在管理方面应用的旁及,利用计算机来实现个人财务管理势在必行。本文首先介绍了个人财务管理系统的开发目的,其次对个人财务管理系统的需求分析做了详细的描述。接着,又对系统数据库设计和功能结构的划分做了详细论述。然后又对个人财务管理系统的实现做了详尽的说明。在报告的最后给出了项目的测试结果以及结果分析。
    本系统是对个人的收支情况做一个简单的管理,其中宝库哦个人信息管理以及收支信息管理。 其中,个人信息管理包括用户对自己的信息进行增删查改的一些操作,同样,收支信息管理包括用户对收支情况的信息进行增删查改的管理。
    1.1 系统业务需求该系统具体需求应该有用户登录模块,用户修改信息模块,用户修改信息模块,收支查询模块,收支删除模块,收支添加模块,收支修改模块。
    1.2 系统技术目标该系统的目标主要是能对个人信息以及收支信息进行较快的增删查改,同时也能对收支信息进行各种方式的查询。
    1.3 系统的具体需求根据以上对系统的任务和目标的分析,系统的具体需求如下:

    个人信息:用户名(唯一),密码,姓名,性别,出生日期,工作,身份证号,电话号码
    收支信息:收支编号(唯一),收支日期,收支方式,收支项目,收入金额,支出金额,,总金额

    二、软件功能结构分析由需求分析可知,软件的功能应包括:个人信息管理,收支信息管理。其中,个人信息应包括,个人信息的增删查该,登录时候验证功能。收支信息管理应包括对对收支信息的各种方式查询,以及对收支信息的增加,修改以及删除功能。当然,每个用户应对应其各自的收支信息。
    2.1 个人信息功能在登录界面用户输入用户名以及密码,如果用户与密码都输入正确则可以登录进系统,如果其中任何一项与数据库中的数据不匹配则要求重新输入。当用户没有账户时候,可以点击登录界面的注册按钮注册。成功进入系统后,可以进行个人信息的查询以及修改。
    具体流程图如下:

    2.2 收支管理功能用户登录成功后进入主界面后可以选择查询方式,全部查询:查询用户所有收入支出的信息;收入查询:查询用户收入信息;支出查询:查询用户支出信息;按日期查询:查询用户当天的收入支出信息。用户也可以对收入支出信息进行修改和删除以及添加。
    具体流程图如下:

    三、数据库设计经过以上的需求的分析以及系统功能的分析,需要建立出该系统数据库的各种模型,为建立一个好的,完善的数据库做准备。
    3.1 概念模型由于该系统涉及的较少,只涉及到用户以及财务管理,所以设计比较简单。一个用户可以有多条收支记录,所以用户表与收支表是一对多的关系。通过PowerDesigner工具设计出的概念数据模型如下:

    其对应的E-R模型如下图:

    3.2 逻辑模型联系转换
    一个用户可以有多条记录,而一条记录只能对应一个用户,所以用户与记录之间是一对多的关系。
    其逻辑结构设计如下

    个人信息(用户名,密码,姓名,性别,出生日期,工作,身份证号,电话号码)
    收支信息(收支编号,收支日期,收支方式,收支项目,收入金额,支出金额,总金额)

    关系模式

    个人信息(用户名,密码,姓名,性别,出生日期,工作,身份证号,电话号码)
    收支信息(收支编号,收支日期,收支方式,收支项目,收入金额,支出金额,总金额)

    3.3 物理模型通过PowerDesigner中的概念模型生成物理模型如下:

    3.4 表结构设计用户表

    收支信息表

    四、软件代码设计本系统是对个人财政的管理,下面给出具体的功能模块以及代码实现。
    4.1 功能模块登录界面模块

    说明:

    该界面为登录界面,如果没有账户,则可以点击注册按钮注册
    当用户输入的用户名或者密码输入错误时,会提示用户名或者密码输入错误
    当点击登录时,如果用户名以及密码都正确则会提示登录成功,并跳转到主界面

    用户注册模块

    说明:

    该界面为用户注册模块
    用户填入信息,其中用户名唯一,当用户名重复时会提示“用户名已存在,请重新输入”

    主界面模块

    说明:
    该界面为用户主信息界面

    用户可以有多种查询方式:全部查询(查询全部收支信息)、收入查询(只查询收入信息)、支出管理(只查询支出信息)、日期查询(查询当天收支信息)
    显示用户所有的收入总计、支出总计以及收入支出总计

    个人信息显示模块

    说明:

    该界面为用户显示模块
    用户如果不想使用该系统可以注销掉自己的账户

    个人信息修改模块
    说明:

    修改界面与个人信息查询界面在同一模块
    用户名不能修改

    收支信息插入模块
    说明:

    该界面为添加收支信息界面
    当点击主界面的插入按钮时候,会跳转到该界面
    收支编号不能重复


    收支信息修改界面

    说明:

    该界面为收支信息修改界面
    当点击主界面中的修改按钮时(必须选中一行),跳转到该界面
    收支编号不能修改

    收支信息删除界面
    说明:

    该功能与在主界面上
    选中一行,然后点击删除,即可提示删除成功

    4.2 代码实现登录界面主要功能实现(Login.java)
    jb1.addActionListener(new ActionListener() {//登陆按钮 public void actionPerformed(ActionEvent e) { jLabel5.setVisible(false); String ad = jf1.getText(); String pass = jf2.getText(); int i=0; String sc = "select userName,passWord from admin where userName='"+ad+"'"; try { ResultSet rs = st.executeQuery(sc); while (rs.next()) { i++; String userName = rs.getString("userName"); System.out.println(userName+"sdgdfgdf"); String password = rs.getString("passWord"); if (!ad.equals(userName)||userName.equals("")) { jLabel5.setVisible(true); } else if (!pass.equals(password)) { jLabel6.setVisible(true); } else { JOptionPane.showMessageDialog(null, "登陆成功!"); Show show = new Show(); show.s=jf1.getText(); show.setVisible(true); setVisible(false); } } System.out.println(i+"sdfd"); } catch (SQLException ex) { Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex); } if(i==0){ jLabel5.setVisible(true); } } });
    说明:该代码实现了登录界面的登录、判断用户名与密码输入是否正确。当用户名或者密码输入错误的时候会提示用户名或者密码错误。同时还添加了一个注册按钮让没有账户的用户注册账户。
    用户注册功能实现(UserInsert.java)
    jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { String s1 = jf1.getText();//y用户名 String s2 = jf2.getText();//姓名 String s12 = jf7.getText();//密码 String s3 = (String) jcb.getSelectedItem();//性别 String s5 = jf4.getText();//职业 String s6 = jf5.getText();//身份证号码 String s7 = jf6.getText();//电话号码 String s8 = (String) jcb1.getSelectedItem(); String s9 = (String) jcb2.getSelectedItem(); String s10 = (String) jcb3.getSelectedItem(); String s11 = s8 + "-" + s9 + "-" + s10;//出生日期 ResultSet rs; String str ="select userName from admin where userName='"+s1+"'"; rs = st.executeQuery(str); int i=0; while (rs.next()) { i++; } if (i == 0) { if (s6.length() != 18 || s7.length() != 11) { if (s6.length() != 18) { jLabel5.setVisible(true); } if (s7.length() != 11) { jLabel14.setVisible(true); } } else { String sql = "insert into admin Values ('" + s1 + "','" + s12 + "','" + s2 + "','" + s3 + "','" + s11 + "','" + s7 + "','" + s5 + "','" + s6 + "')"; st.executeUpdate(sql); JOptionPane.showMessageDialog(null, "注册成功"); setVisible(false); } } else{ jLabel15.setVisible(true); } } catch (SQLException ex) { Logger.getLogger(UserInsert.class.getName()).log(Level.SEVERE, null, ex); } } });
    说明:该代码实现了个人信息的注册,其中用户名唯一,重复会给出提示“用户名已存在”,并且判断身份证与电话号码填写的格式是否正确。*
    全部查询实现函数(Show.java)
    jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    收入查询实现函数(Show.java)
    jb2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    支出查询实现函数(Show.java)
    jb3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    日期查询实现函数(Show.java)
    jb4.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    个人信息查询功能模块(Show.java)
    jb9.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    个人信息修改功能模块(User.java)
    jb2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    个人信息删除功能模块(User.java)
    Jb3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    收支信息插入功能模块(UserInsert.java)
    jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    收支信息添加功能模块(Insert.java)
    jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    收支信息删除功能模块(show.java)
    Jb7.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    五、总结通过该课程设计,我认识到软件设计是基于需求分析和可行性分析的基础上的,软件设计阶段需要合理的分析需求分析中的细节部分的实现,既要考虑到关键处代码的可实现性,又要考虑到开发过程中遇到的问题。刚开始觉得该 项目建立的数据库比较简单,没有认真进行需求分析,所有导致后面举步维艰。后来重新进行需求分析,一步一步来,最终完成了该课程设计。软件设计是把需求分析中的问题抽象化,又要把抽象化了的需求形象的从预期的实现中体现出来。 本小组的个人财务管理系统系统的设计实现了预期的功能,对个人消费进行记录,个人的收入进行统计,对个人收支进行汇总并给出相应的理财提示信息。在这次的个人财务管理系统设计中将理论知识应用到实际中使得对理论知识的理解有了更进一步的理解,如果仅仅只是运用理论知识,是远远不够的。必须理论联系实际,才能很好的将各门课程学好,并用于实际案例中。
    这次设计使我的编程水平提高了一大步。由于这次设计涉及到数据库,我的学到了不少编程工具与数据库连接的知识,对数据库的操作有了进一步的了解。这次设计对我的综合能力是一次很好的锻炼,自己的能力和知识还很有限。所以今后我的学习道路还是很漫长的。
    16 评论 478 下载 2018-10-25 21:36:27 下载需要15点积分
  • 基于JSP的学生会信息管理系统

    摘 要随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了学生会管理信息系统的开发全过程。通过分析学生会信息管理的不足,创建了一个计算机管理学生会信息的方案。文章介绍了学生会管理信息系统的系统分析部分,包括可行性分析等,系统设计部分主要介绍了系统功能设计和数据库设计。
    本学生会管理信息系统实现的功能主要包含活动信息,活动查询,人员信息,用户中心,还包括个人后台和管理员后台等功能。因而具有一定的实用性。本站是一个B/S模式系统,采用JSP技术,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得学生会信息管理工作系统化、规范化。
    本系统的使用使管理人员从繁重的工作中解脱出来,实现无纸化办公,能够有效的提高学生会信息管理效率。
    关键词:学生会信息;JSP技术;MYSQL数据库
    AbstractWith the deepening and extensive application of information technology in management, the implementation of management information systems has gradually matured in technology. This paper introduces the whole process of the development of the Student Union Management Information System. By analyzing the insufficiency of student union information management, a program for computer management of student union information was created. The article introduces the system analysis part of the student union management information system, including feasibility analysis, etc. The system design part mainly introduces the system function design and database design.
    The functions implemented by the Student Union Management Information System mainly include activity information, activity query, personnel information, user center, and functions such as personal background and administrator background. Therefore, it has certain practicability. This site is a B/S mode system, using JSP technology, MYSQL database design and development, fully guarantee the stability of the system. The system has the characteristics of clear interface, simple operation and complete functions, which makes the student information management system systematic and standardized.
    The use of this system frees managers from heavy work and realizes paperless office, which can effectively improve the efficiency of student information management.
    Key words:Student Union Information; JSP Technology; MYSQL Database
    一、绪论1.1、选题的背景随着信息时代的来临,计算机技术在现代社会中的运用也是越来越广泛。以计算机技术为基础的各项运用也逐渐走入学校管理的各个层面。利用计算机技术设计出来的信息管理系统也是这个信息时代的一大课题和必不可少的一项内容。目前,随着我国的现代信息技术的高速发展,学校的各方面都已经进入了现代信息化管理的一个阶段,相关的计算机管理系统的引入使得学校各部门的工作效率日益提高,但却很少有专门针对学校团委学生会的管理系统[1]。基于调查,现阶段很多学院的团总支学生会没有专门的管理系统,基本都是出于人工管理的阶段,在学生会管理上仍然存在着许多不足,不能很好的处理[2]。其中有材料、资源、经验等信息无法得到完全存档,没有科学的安排和规划,使得每届学生会干部都需要从上一届学生干部那收集工作信息,导致工作无法创新发展,学生社团文化没有得到很好的传承。各部门之间的工作较独立,无法真正了解各部门的工作状况和信息交流,不能很好地团结学生会的内部成员。而随着我国素质化教育的不断推进,团委学生会也在学校的管理工作中扮演这越来越重要的角色,所以需要设计一套专门服务于学校的老师和同学且具有现代信息特色的团委学生会信息管理系统是一件急需解决的问题[3]。鉴于以上存在的不足,我认为开发一套安全可靠、科学实用、功能完备的学生会信息管理系统是具有非常重要的意义和很高的价值,从而进一步完善学生会的管理。
    本设计的学生会信息管理系统就是为了解决学生会各个部门间的信息交流而设计的,设计的初衷是在于建立一个能够初步实现学生会信息管理系统的智能化管理,提高学生会部门管理效率,学生会干事的各种工作状态能够得到及时的反馈,各部门的活动信息能够及时的展现。而且,学生会信息管理系统所需的管理人员少,效率高,成本低,在人力、物力、金钱、时间上相比现在的人工记录信息要强很多[4]。
    1.2、课题的目的对于学生会来说,利用计算机支持学生会高效率完成学生会各个部门的日常事务,是适应现代学校学生会的要求、推动学生会管理走向科学化、规范化的必要条件[5]。而且学生会的管理是一项繁琐、复杂的工作,日常检查、活动安排、各部门之间的协调工作、办公室用品的借还情况等,一般不允许出差,而且有很强的时间性,如果实行手工操作,每天的检查工作会使用大量的表格,另外交到各个部门工作起来不是很方便,这就会耗费工作人员大量的时间和精力,计算机进行学生会工作的统一管理时,不仅能够保证各项检查工作的准确无误、快速输出,而且还可以利用计算机对有关检查的各项信息进行统计,存储,服务于各个部门的学生工作处,可以方便老师第一时间看到自己学院的学生会信息状态[6]。同时计算机具有手工管理所无法比拟的优点。例如:查找方便、可靠性高、存储量大、保密性好、成本低等。这些优点能够极大地提高学生会信息管理的效率。
    不同的学校具有不同的学生会管理制度,这就决定了不同的学校需要不同的学生会信息管理系统,上海立信会计金融学院信息管理学院现在的学生会工作都是用手工保存在各个部门的部长处,工作起来较费劲,而且效率不是很高,面对目前的实际状况,迫切需要开发一个新的系统来适应这些工作。
    1.3、系统设计思想一个成功的网站应明确建设网站的目的,确定网站的功能,确定网站规模、投入费用,进行必要的市场分析等。只有详细的策划,才能避免在网站建设中出现的很多问题,使网站建设能顺利进行。同时,一个大型的计算机网站系统,必须有一个正确的设计指导思想,通过合理选择数据结构、网络结构、操作系统以及开发环境,构成一个完善的网络体系结构,才能充分发挥计算机信息管理的优势。根据现实生活中网民的实际需求,本系统的设计按照下述原则进行。

    有效性:实际上这里的有效性包括两个方面的意思:有用性和可用性。有用性是指站点潜在的能满足用户需求的功能,而可用性是指能够通过站点的操作实现特定的目标。可以看出一个站点如果不能恰当运行或设计得非常槽糕就不是一个好站点。可用站点的效益应该非常高,并易于学习,在实现用户目标时令人满意而不出错。
    高可靠性:一个实用的网站同时必须是可靠的,本设计通过合理而先进的网络设计以及软、硬件的优化选型,可保证网站的可靠性与容错性。
    高安全性:在设计中,将充分利用网络软、硬件提供的各种安全措施,既可以保证用户共享资源,充分考虑系统及数据资源的容灾、备份、恢复的要求。为系统提供强大的数据库备份工具。可以保证关键数据的安全性。操作权限级,设置不同的角色确保每一步的操作权限,可以由管理员进行设置。
    先进性:采用目前国际上最先进的开发技术,使用JSP开发技术,MYSQL作为网站后台数据库。采用这些技术降低了以后的系统运营成本,提高了系统的稳定性和易维护性。
    采用标准技术:本网站的所有设计遵循国际上现行的标准进行,以提高系统的开放性。
    外观和技术平衡:系统采用Web风格的界面设计,界面友好、美观,使用方便,易学易用。网站设计的关键问题是外观和技术的平衡。外现不好的网站令人厌烦,站点可以运行很好,但却不能带动用户积极性,相反,如果外观非常有表现力,但技术有限,用户则会感到非常失望。在外观与技术之间需要确定一个清晰而连续的关系,即外观与站点的意图相关,对不同类型的网站处理方法不同。

    二、相关技术综述2.1、研究的方法及手段学生会信息管理系统基于MyEclipse平台,选择JSP,HTML,Java,JavaScript语言,采用B/S结构完成系统的设计,数据库选用Microsoft SQL Server。本学生会信息管理系统基于MyEclipse平台,主要采用JSP技术和数据库技术实现[7]。Windows7操作系统下,利用J2EE框架,并使用Java等编译语言Jbulider为开发工具。Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点[8]。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等[9]。MyEclipse是一种很好用的Java开发工具,它的功能非常强大,支持也特别广泛,尤其是对各种开源产品都有支持。目前支持Java Servlet,AJAX,JSP,JSF,Struts,Hibernate,JDBC数据库链接工具等多项功能[10]。
    2.2、MyEclipse平台MyEclipse企业级工作平台(MyEclipse Enterprise Workbench,简称MyEclipse)是对EclipseIDE的扩展,利用它我们可以在数据库和JavaEE的开发、发布以及应用程序服务器的整合方面极大的提高工作效率。它是功能丰富的JavaEE集成开发环境,包括了完备的编码、调试、测试和发布功能,完整支持HTML、Struts、JSP、CSS、Javascript、Spring、SQL。MyEclipse 是一个十分优秀的用于开发Java, J2EE的 Eclipse 插件集合,MyEclipse的功能非常强大,支持也十分广泛,尤其是对各种开源产品的支持十分不错[11]。而且它的功能是非常强大的,它支持的技术范围也是特别地广泛的,尤其是对各种各样的开源产品都是有支持的。可以说MyEclipse是几乎囊括了目前所有主流开源产品的专属eclipse开发工具[12]。
    本系统实在Windows7的环境下开发的,本机既安装了tomcat服务器,又安装了浏览器,这样计算机同时扮演服务器端与客户端的角色,仿真成网络环境,方便系统开发,还运用了Microsoft Visual Studio.NET2003来设计网页的美观性。本系统采用的是Microsoft SQL Server数据库,主要运用SQL语句访问它。JSP通过Java语言的JDBC技术与数据库相连,只要数据库有JDBC的驱动程序就可与之相连[13]。
    2.3、JSP技术JSP(JavaServer Pages)是由Sun Microsystems公司倡导、许多公司参与一起建立的一种动态网页技术标准。在传统的网页HTML文件(.htm,.html)中加入Java程序片段(Scriptlet)和JSP标签,就构成了JSP网页Java程序片段可以操纵数据库、重新定向网页以及发送E-mail等,实现建立动态网站所需要的功能。所有程序操作都在服务器端执行,网络上次送给客户端的仅是得到的结果,这样大大降低了对客户浏览器的要求,即使客户浏览器端不支持Java,也可以访问JSP网页[14]。
    JSP技术使用Java编程语言编写类XML的tags 和 scriptlets,来封装产生动态网页的处理逻辑,网页还能通过tags和scriptlets 访问存在于服务器的资源的应用逻辑,JSP将网页逻辑与网页设计的显示分离,支持可重用的基于组件的设计,使基于Web的应用程序的开发变得迅速和容易[15]。JSP是一种动态页面技术,它主要目的是将表示逻辑从Servlet中分离出来。
    2.4、B/S结构B/S体系结构,即Browser/Server(浏览器/服务器)结构,是随着Internet技术的兴起,对C/S体系结构的一种变化或者改进的结构。在B/S体系结构下,用户界面完全通过WWW浏览器实现,一部分事务逻辑在前端实现,但是主要事务逻辑在服务器端实现[16]。B/S体系结构主要是利用不断成熟的WWW浏览器技术,结合浏览器的多种脚本语言,用通用浏览器就实现了原来需要复杂的专用软件才能实现的强大功能,并节约了开发成本,是一种全新的软件体系结构。基于B/S体系结构的软件,系统安装、修改和维护全在服务器端解决。用户在使用系统时,仅仅需要一个浏览器就可运行全部的模块,真正达到了“零客户端”的功能,很容易在运行时自动升级[17]。
    2.5、Microsoft SQL ServerMicrosoft SQL Server是一个全面的数据库平台,使用集成的商业智能 (BI) 工具提供了企业级的数据管理。它的数据库引擎为关系型数据和结构化数据提供了更安全可靠的存储功能,此外SQL Server结合了分析、报表、集成和通知功能。这是您的企业可以构建和部署经济有效的BI解决方案,帮助您的团队通过记分卡、Dashboard、Web services和移动设备将数据应用推向业务的各个领域[18]。
    三、系统分析3.1 可行性分析通过对本学生会管理信息系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。
    3.1.1 技术可行性本学生会管理信息系统采用JSP技术,JAVA作为开发语言,是基于WEB平台的B/S架构系统。

    Java提供了稳定的性能、优秀的升级性、更快速的开发、更简便的管理、全新的语言以及服务。整个系统帮用户做了大部分不重要的琐碎的工作
    基于B/S模式的系统的开发已发展日趋成熟
    众所周知,Java是面向对象的开发语言。程序开发员可以在MyEclipse平台上面方便的使用一些已知的解决方案

    因此,学生会管理信息系统在开发技术上具有很高可行性,且开发人员掌握了一定的开发技术,所以此系统的开发技术具有可行性。
    3.1.2 经济可行性本学生会管理信息系统采用的软件都是开源的,这样能够削减很多的精力和资源,降低开发成本。同时对计算机的配置要求也极低,即使是学生会淘汰下来的计算机也能够满足需要,因此,本系统在经济上是完全具有可行性的,所以在经济上是十分可行的。
    3.1.3 操作可行性本学生会管理信息系统的界面简单易操作,用户只要平时有在用过电脑,都能进行访问和操作。本系统具有易操作、易管理、交互性好的特点,在操作上是非常简单的,因此在操作上具有很高的可行性。
    综上所述,此系统开发目标已明确,在技术、经济和操作方面都具有很高的可行性,并且投入少、功能完善、管理方便,因此系统的开发是完全可行的。
    3.2 系统性能分析3.2.1 系统安全性此学生会管理信息系统要严格控制管理权限,具体要求如下:

    要想对学生会管理信息系统进行管理,首先要依靠用户名和密码在系统中登陆,无权限的用户不可以通过任何方式登录系统和对系统的任何信息和数据进行查看,这样可以保证系统的安全可靠性和准确性
    在具体实现中对不同的权限进行设定,不同权限的用户在系统中登陆后,不可以越级操作

    3.2.2 数据完整性
    所有记录信息要保持全面,信息记录内容不可以是空。
    各种数据间相互联系要保持正确。
    相同数据在不同记录中要保持一致。

    3.3 系统界面分析目前,界面设计已经成为对软件质量进行评价的一条关键指标,一个好的用户界面可以使用户使用系统的信心和兴趣增加,从而使工作效率提高,JSP技术是将JAVA语言作为脚本语言的,JSP网页给整个服务器端的JAVA库单元提供了一个接口用来服务HTTP的应用程序。创建动态页面比较方便。客户界面是指软件系统与用户交互的接口,往往涵盖输出、输入、人机对话的界面格式等。
    3.3.1 输出设计输出是由电脑对输入的基本信息进行解决,生成高质量的有效信息,并使之具有一定的格式,提供给管理者使用,这是输出设计的主要责任和目标。
    系统开发的过程与实施过程相反,并不是从输入设计到输出设计,而是从输出设计到输入设计。这是由于输出表格与使用者直接相联系,设计的目的应当是确保使用者可以很方便的使用输出表格,并且可以将各部门的有用信息及时的反映出来。输出设计的准绳是既要整体琢磨不同管理层的所有需要,又要简洁,不要提供给用户不需要的信息。
    3.3.2 输入设计输入数据的收集和录入是比较麻烦的,需要非常多的人力和一定设备,而且经常出错。一旦输入系统的数据不正确,那么处理后的输出就会扩大这些错误,因此输入的数据的准确性对整个系统的性能起着决定性意义。
    输入设计有以下几点原则:

    输入量应尽量保持在能够满足处理要求的最低限度。输入量越少,错误率就会越少,数据的准备时间也越少
    应尽可能的使输入的准备以及输入的过程进行时比较方便,这样使错误的发生率降低
    应尽量早检查输入数据(尽量接近原数据发生点),以便使错误更正比较及时
    输入数据尽早地记录成其处理所需的形式,以防止数据由一种介质转移到另一种介质时需要转录而可能发生的错误

    3.4 系统流程和逻辑登录流程图

    修改密码流程图

    四、系统概要设计4.1 概述本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示:

    4.2 系统结构本系统是基于B/S架构的网站系统,设计的功能结构图如下图所示:

    4.3 数据库设计4.3.1 数据库实体概念设计的目标是设计出反映某个组织部门信息需求的数据库系统概念模式,数据库系统的概念模式独立于数据库系统的逻辑结构、独立于数据库管理系统(DBMS)、独立于计算机系统。
    概念模式的设计方法是在需求分析的基础上,用概念数据模型(例如E-R模型)表示数据及数据之间的相互联系,设计出反映用户信息需求和处理需求的数据库系统概念模式。概念设计的目标是准确描述应用领域的信息模式,支持用户的各种应用,这样既容易转换为数据库系统逻辑模式,又容易为用户理解。数据库系统概念模式是面向现实世界的数据模型,不能直接用于数据库系统的实现。在此阶段,用户可以参与和评价数据库系统的设计,从而有利于保证数据库系统的设计与用户的需求相吻合。在概念模式的设计中,E-R模型法是最常见的设计方法。本系统的E-R图如下图所示:

    4.3.2 数据库设计表学生会管理信息系统需要后台数据库,下面介绍数据库中的各个表的详细信息:
    数据库名:xsh
    表名:admin



    序号
    列名
    数据类型
    长度
    小数位
    标识
    主键
    外键
    允许空
    默认值
    说明




    1
    id
    int
    4






    auto_increment


    2
    username
    varchar
    50









    3
    password
    varchar
    50









    4
    realname
    varchar
    50









    5
    sex
    varchar
    50









    6
    age
    varchar
    50









    7
    tel
    varchar
    50









    8
    address
    varchar
    50









    9
    addtime
    varchar
    50









    10
    sf
    varchar
    50





    管理用户



    表名:hd



    序号
    列名
    数据类型
    长度
    小数位
    标识
    主键
    外键
    允许空
    默认值
    说明




    1
    id
    int
    4






    auto_increment


    2
    mc
    varchar
    500









    3
    cd
    varchar
    500









    4
    ys
    varchar
    500









    5
    sj
    varchar
    500









    6
    nr
    text










    7
    member
    varchar
    500









    8
    fbsj
    varchar
    500









    9
    sh
    varchar
    500





    暂无



    10
    yj
    varchar
    500





    暂无



    11
    hf
    varchar
    500





    暂无



    表名:member



    序号
    列名
    数据类型
    长度
    小数位
    标识
    主键
    外键
    允许空
    默认值
    说明




    1
    id
    int
    4






    auto_increment


    2
    username
    varchar
    50









    3
    password
    varchar
    50









    4
    realname
    varchar
    50









    5
    sex
    varchar
    50









    6
    age
    varchar
    50









    7
    address
    varchar
    50









    8
    email
    varchar
    50









    9
    zy
    varchar
    50









    10
    bm
    varchar
    50





    在用



    11
    sl
    int
    4





    0



    表名:xw



    序号
    列名
    数据类型
    长度
    小数位
    标识
    主键
    外键
    允许空
    默认值
    说明




    1
    id
    int
    4






    auto_increment


    2
    bt
    varchar
    500









    3
    nr
    text










    4
    sj
    varchar
    500









    五、系统详细实现5.1 系统登陆模块调试成功后会自动跳转到首页界面,在这个界面里可以看到用户中心,用户中心可以实现用户的登陆,没有登陆只能进行各种信息的浏览,不能操作,登陆的进修可以看到需要输入账号和密码,没有账号和密码的可以进行注册。

    5.2 系统首页实现系统的首页是给人的第一印象,本系统采用了上下两部分的展示效果,上面是各个功能的展示,下面是功能的相对应信息内容,可以看到主要的功能有活动信息,人员信息,信息查询,活动查询,用户中心等。

    5.3 密码管理模块的实现用户可以对自己的登陆密码进行修改,可以防止密码的泄露,修改的时候需要注意的是旧密码的输入,具体的效果如下图所示:

    5.4 用户信息管理模块这个功能是对用户的个人信息进行修改,可以看到用户的详细信息,包括名字和登陆账号的信息,具体效果如下图5-4所示:

    5.5 活动信息管理模块实现活动信息管理功能是本系统的主要功能,可以实现对活动信息的添加和删除修改,并且可以对活动信息进行查询,实际的设计效果界面如图5-5所示:

    5.6公共信息管理功能实现可以对公共信息进行添加和管理,并且可以进行公共信息进行查询,具体的实现界面如图5-6所示:

    5.7 个人后台功能设计个人后台包括活动信息的添加和查询管理,并且可以修改自己的信息和对密码进行修改,界面如图5-7所示:

    5.8 关键代码5.8.1 登录注册代码<table width="100%" border="0" align="center" cellpadding="4" cellspacing="0" class="rtable"> <tbody> <tr class="tr1"> <td class="rldatee daslist"></td> <td class="rltitle daslist">    注册用户登录</td> </tr> <tr class="tr1"> <td class="rldatee daslist">登录帐号:</td><input type=hidden name=method value="mlogin"/><input type=hidden name=sf value="注册用户"/> <td class="rltitle dotlist"><input type="text" size="30" name="username" required /></td> </tr> <tr class="tr1"> <td class="rldatee daslist">登录密码:</td> <td class="rltitle dotlist"><input type="password" size="30" name="password" required /></td> </tr> <tr class="tr1"> <td class="rldatee daslist"></td> <td class="rltitle daslist"><input type="submit" value="用户登录" style="width:80px;" /> <input type="button" value="用户注册" style="width:80px;" onclick="reg()"/> <input type="button" value="找回密码" style="width:80px;" onclick="lost()"/></td> </tr> <tr class="tr1"> <td class="rldatee daslist"></td> <td class="rltitle daslist"> </td> </tr>
    5.8.2 活动信息代码<div class="cmain"> <div class="rmain"> <div class="rdetail"><div class="rdtitle"><span><%=list.get(1).toString() %></span></div><div class="rdmark"> 场地:<%=list.get(2).toString() %> 预算:<%=list.get(3).toString() %> 时间:<%=list.get(4).toString() %> 发布用户:<%=list.get(6).toString() %> 发布时间:<%=list.get(7).toString() %> </div><div class="rcontent"><%=list.get(5).toString() %></div><div class="rdmark"></div>
    5.8.3 活动信息查询代码<table width="100%" border="0" align="center" cellpadding="4" cellspacing="0" class="rtable"> <tbody> <tr class="tr1"> <td class="rldatee daslist"></td> <td class="rltitle daslist"> </td> </tr> <tr class="tr1"> <td class="rldatee daslist">活动名称:</td> <td class="rltitle dotlist"><input type="text" size="30" name="word" required /></td> </tr> <tr class="tr1"> <td class="rldatee daslist"></td> <td class="rltitle daslist"><input type="submit" value="查询" style="width:80px;" /></td> </tr> <tr class="tr1"> <td class="rldatee daslist"></td> <td class="rltitle daslist"> </td> </tr> </tbody>
    5.8.4 活动信息发布代码<div class="main"> <div class="narea"><div> <img height="150" src="<%=basePath%>images/zgm.jpg" width="1020"> </div></div><div class="cmain"> <div class="rmain"> <div class="rdetail"><div class="rdtitle"><span><%=list.get(1).toString() %></span></div><div class="rdmark"> 发布时间:<%=list.get(3).toString() %> </div><div class="rcontent"><%=list.get(2).toString() %></div><div class="rdmark"></div>5.8.5用户密码找回代码<table width="100%" border="0" align="center" cellpadding="4" cellspacing="0" class="rtable"> <tbody> <tr class="tr1"> <td class="rldatee daslist"></td> <td class="rltitle daslist">    找回密码</td> </tr> <tr class="tr1"> <td class="rldatee daslist">登录帐号:</td> <td class="rltitle dotlist"><input type="text" size="30" name="username" required /></td> </tr> <tr class="tr1"> <td class="rldatee daslist">密保邮箱:</td> <td class="rltitle dotlist"><input type="email" size="30" name="email" required /></td> </tr> <tr class="tr1"> <td class="rldatee daslist"></td> <td class="rltitle daslist"><input type="submit" value="确定提交" style="width:80px;"/> <input type="button" value="返回登录" style="width:80px;" onclick="login()"/></td> </tr> </tbody></table>
    六、系统测试6.1 概念和意义测试的定义:程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为:

    目的:发现程序的错误;
    任务:通过在计算机上执行程序,暴露程序中潜在的错误。

    另一个预测是相关的术语叫纠错(Debugging)。它的目的与任务可以规定为:

    目的:定位和纠正错误;
    任务:消除软件故障,保证程序的可靠运行。测试与纠错的关系,可以用图6-1的数据流图来说明。图中表明,每一次测试都要准备好若干必要的测试数据,与被测试程序一道送入计算机执行。通常把一次程序执行需要的测试数据,称为一个“测试用例(Test Case)。每一个测试用例产生一个相应的“测试结果”。如果它与“期望结果”不想符合,便说明程序中存在错误,需要用纠错来改正。


    6.2 特性挑剔性
    测试是为了证明程序有错,而不是证明程序无错。因此,对于被测程序就是要“纯毛求疵”,就是要“鸡蛋里挑骨头”。
    复杂性
    测试仪程序则比较容易,这其实是一个误区。设计测试用力是一项需要细致和高度技巧的高能工作,稍有不慎就会顾此失彼,发生不应用得数楼。
    不彻底性
    实际测试都是不彻底的,当然不能够保证测试后的程序不存在遗漏的错误。
    经济性
    通场这种测试称为“选择测试(Selective Testing)”。为了降低测试成本,选择测试用力是应注意遵守“经济性”的原则。
    6.3 重要性软件测试在软件生命周期中占据重要的地位,在传统的瀑布模型中,软件测试学仅处于运行维护阶段之前,是软件产品交付用户使用之前保证软件质量的重要手段。近来,软件工程界趋向于一种新的观点,即认为软件生命周期每一阶段中都应包含测试,从而检验本阶段的成果是否接近预期的目标,尽可能早的发现错误并加以修正,如果不在早期阶段进行测试,错误的延时扩散常常会导致最后成品测试的巨大困难。
    6.4 测试方法首先我们来说界面测试,界面测试是为了使程序在不同的的操作平台上能够运行界面,并且能够保持原来的风格。我把完整程序拷贝到Windows 7环境下,似的程序运行正常,运行界面上的字体图片等设置都能够保持得非常好。不出现字体变形等情况!
    其次进行功能测试。该系统测试采用的是单元测试,集成测试,完善性测试等多种方式进行测试。
    经过测试,所有功能都能得以实现,没有任何变形。至此,在功能的测试上也已经比较圆满的完成了。
    由于经验不足,写代码时出现了一些考虑不周的系统缺陷,写代码的时候会出现与设想不一致,比如说代码不规范导致接口与接口之间出现问题,功能与客户的要求不符合,这样导致产品不能过关,无法交付。所以产品在上线前必须反复测试,经过反复测试,修改,再测试,再修改,产品才能够不断完善。在整个系统测试中,根据需求文档和设计文档,逐一对功能进行检测并写好测试用例,有效避免残片缺陷,因为产品出现缺陷不仅影响功能,而且可以导致数据的不准确,导致产品质量的降低,经过测试,才能使得产品的稳定性和成熟度得到极大的提升,产品质量也才有保证。
    6.5 功能测试功能测试主要包括五项内容:适用性、准确性、可操作性、依从性、安全性。
    本系统功能测试如表6.1所示:



    测试内容
    测试结果




    适用性



    准确性



    可操作性



    依从性



    安全性




    6.6 可用性测试可用性测试用于检测系统的可操作性、可理解性、可学习性等方面内容。具体测试方面如表6.2所示。



    测试项
    测试人员的评价




    窗口移动、大小改变、关闭等操作是否正常



    操作模块是否友好



    模块、提示内容等文字描述是否正确



    模块布局是否协调、合理



    模块的状态是否正确(对选中项能否发生对应切换)



    鼠标、键盘操作是否支持



    所需数据项是否正确显示



    操作流程是否合理



    是否提供帮助信息




    6.7 性能测试性能测试主要通过模拟系统运行环境,测试系统性能是否符合客户需求。性能测试的重要技术指标就是:系统运行速度、网络响应时间和支持并发节点数。

    系统运行速度:通过在不同计算机上试运行本系统,没有发现有任何迟滞、停顿现象
    网络响应时间:网络响应时间主要包括网络最小响应时间、平均响应时间、最大响应时间三个参数。经过测试,在网络运营良好状态下,NBA局域网内响应时间三参数为:1/2/6s,NBA外网响应时间三参数为3/7/12s,符合客户需求,属于用户心理可承受范围
    支持并发节点数:经过模拟环境测试,本系统在并发节点达46个时,网络运营速度会发生较大波动,延迟时间10秒左右,符合客户需求

    6.8 测试分析本网站设计时借鉴了国内外优秀网站的优点,从界面到系统设计都保证了用户能够方便操作。系统的主要特点和优点归纳如下:

    本系统用的移置性和针对性都比较高,因为针对性高可以提供更好的服务而移置性可以在多个系统上运行,更给客户带来了极大的方便
    该完整内容全面,管理方便可以及时的全面的处理各种错误,异常,这样避免了很多因用户的马虎操作而出现的失误,其操作方便,用户界面友好,能够上网的人都可以很好的进行操作

    6.9 测试结果分析经过对上述测试结果分析,本系统符合用户需求。所有基本功能点实现,操作简单,操作流程简单合理,产品运行性能良好,是一款值得推广的学生会管理信息系统。
    七、结论在这次课程设计中遇到的最困难的方面就是在数据库方面的知识,在刚开始进行课程设计的时候感觉十分困难,根本不知道该从何处下手,但不断的坚持,设计最终被完成。无论多么的困难,只要能够坚持下来,善于去找到好的材料来研究,在研究中充分利用资源,没有困难是不会被成功解决的。
    在开发系统的过程中,本人运用到了JSP技术和平时学习中所了解的一些技术,通过实现这些技术,大大提高了整个系统的性能。在论文中这些技术都做了比较详细的介绍。本系统还存在很多缺点和不完善的地方,例如有些细节上做的还不够完善,有些功能模块还需要加强。在今后的日子里,能够对这些不足进行改善。
    通过这次最终的课程设计,平时所学到的知识不仅融合了,而且获得了许多计算机知识。在整个设计过程中明白了许多东西,也培养独立工作能力,树立信心,对自己能力的工作能力,我相信以后会学习和工作生活中有至关重要的作用。同时也大大提高了手的能力,使其难以充分体会探索的乐趣和成功的创作过程,设计过程中汲取的东西,是一笔宝贵的财富。
    回顾过去做课程设计的整个过程,充满了付出和收获,但是当你看到成果的时候的感觉,是一种难以用言语表达的喜悦之感这些在课程设计过程中学习到的东西将会使我终身受益!
    最后,感谢指导老师的关心和指导,在我课程设计的整个过程中,他给与了我很多的帮助和讲解,在导师的帮助下我的课程设计才能如此顺利的完成。
    九、参考文献[1] 张红. 中职学校学生会管理系统的设计与实现[D]. 厦门大学, 2014.
    [2]王文婷.高校学生事务管理理论与实践探究.中国纺织出版社.2018.10(7):95~95.
    [3] 穆盼盼. 试析学生会的组织结构特征:松散联结基础上的牢固联结性[J]. 内蒙古财经大学学报, 2012, 10(3):74-77.
    [4] 杨燕, 李艳会. 高职院校学生会的管理及对策研究[J]. 湖南邮电职业技术学院学报, 2018(1)
    [5] 曾伟仁. 网络化背景下学生会管理系统的构建[J]. 网友世界, 2014(19):143-143.
    [6] 田娟. 基于Grails的学生会工作管理系统研究[J]. 湖南城市学院学报(自然科学版), 2016, 25(4):117-118.
    [7] 田娟. 基于Grails的学生会工作管理系统研究[J]. 湖南城市学院学报(自然科学版), 2016, 25(4):117-118.
    [8] 明日科技.Java从入门到精通.清华大学出版社,2016.09
    [9] 金百东,刘德山.Java设计模式及应用案例(第二版).人民邮电出版社,2017.11
    [10] 张建军,吴启武.Java课程设计案例精编(第三版).清华大学出版社,2016.5
    [11] 林菡, 陈书林, 翁玲敏,等. 学生会管理系统的设计与实现[J]. 软件, 2014, 37(4):90-93.
    [12] Joshua Bloch , Effective Java[M]United States of America :Prentice Hall PTR,2012.
    [13] 刘中兵.开发突击者:Java web 主流框架开发[M]北京:电子工业出版社,2011:80~95.
    [14] 贾志城.王云.JSP程序设计[M].北京:人民邮电出版社,2016:100~120.
    [15] 刘晓华,张健,周慧贞.JSP应用开发详解(第三版)[M]北京:电子工业出版社,2007:205~220.
    [16] (美)锡德霍姆.基于标准的网页设计技巧与实战(第二版),2010,09(8):100~101.
    [17] 焦辰菲, 于林静, 霍玉慧. 学生工作日常管理系统的开发[J]. 成功(教育), 2011(2):180-180.
    [18] 王俊伟,史创明。SQL Server 数据库管理与应用[J].北京:清华大学出版社,2008:304~315.
    8 评论 123 下载 2019-05-09 21:02:32 下载需要13点积分
  • 基于QT的网络五子棋游戏程序的设计与实现

    摘 要在现在如此发达并且得到广泛应用的现代网络技术下,集趣味性,娱乐性,益智性,并且包含网络功能的休闲类游戏以及成为了人们选择网络休闲游戏的要求。
    系统采用当今广为流行的五子棋游戏为模版,利用C++的第三方GUI设计工具Qt为程序设计界面,并结合软件工程的思想开发一款基于网络的五子棋游戏对弈软件。本软件采用P2P的模式,利用一个服务端来辅助各个客户端之间的查找和链接,服务端用于记录当前各个客户端的游戏状态,并将实时更新的各个客户端的状态发送到其他客户端,方便客户端加入其他客户端建立的游戏主机,并建立P2P链接,进行游戏。客户端是玩家用于建立游戏主机或者加入游戏进行五子棋对弈的主程序,具有当今五子棋游戏常见的聊天功能、悔棋功能、认输功能、计分功能、玩家断网处理等。
    玩家只需运行客户端,连接到指定的服务端,就可以加入其他的游戏主机进行游戏,或者建立游戏主机,等待其他客户端的加入进行游戏对弈。
    关键字: 多线程,Qt,socket
    ABSTRACTWith the development and widely usage of computernetwork, it has been a requirement for a casual online game to be interesting,entertaining and intelligence-improving.
    This paper implements a online Gobang game based onthe popular Gobang, used third-party C++ GUI library Qt and combined softwareengineering model. The software uses P2P model, which uses a sever end to helpclients find and connect with each other and help record the status of everyclient and send it to other clients in order to make it convenient to join thehost and establish the P2P connection between clients to start the game. Clientis the main program for user to create or join the Gobang game and have thefunctionalities of chatting, regretting, yielding, scoring and connectionproblems handling.
    All user needs to do is run a client, connect to thespecific server, then he can join a host or create a host himself and wait forother clients to join and have a game.
    Key words:multithreading, Qt, socket
    1 绪论1.1 课题研究意义五子棋[1]是起源于中国古代的传统黑白棋种之一。现代五子棋日文称之为“连珠”,英文称之为“Renju”、“Gobang”或“FIR”(Five in a Row 的缩写),亦有“ 连五子”、“五子连”、“串珠” 、“五目”、“五目碰”、“五格”等多种称谓。
    五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为广大人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。它是中西文化的交流点,是古今哲理的结晶。
    五子棋起源于古代中国,发展于日本,风靡于欧洲。对于它与围棋的关系有两种说法,一说早于围棋,早在“尧造围棋”之前,民间就已有五子棋游戏;一说源于围棋,是围棋发展的一个分支。在中国的文化里,倍受人们的青睐。古代的五子棋的棋具与围棋相同。五子棋大约随围棋一起在我国南北朝时先后传入朝鲜、日本等地。从此,五子棋经过了不断的改良,例如棋盘由原来的纵横各十七道改为现行的纵横各十五道的五子棋专用棋盘等等。二十世纪初,五子棋传入欧洲并迅速风靡了全欧洲。通过一系列的变化,使五子棋这一简单的游戏系统化、规范化,最终成为今天的职业连珠五子棋,同时也成为一种国际比赛棋。
    在网络发达的今天,对于二人对弈的五子棋,开发一款带有网络功能的五子棋游戏,能够更加方便身在异地的玩家进行游戏。
    1.2 课题研究目的五子棋在我国的历史可谓是源远流长,喜爱它的玩家也是大有人在。但目前的五子棋软件一般都是单机版的,游戏无法在异地的玩家之间进行,因此为了方便异地的玩家在一起进行五子棋游戏,设计出一款基于网络版的五子棋游戏,玩家可以通过网络挑选自己喜爱的对手并同其进行比赛,比赛过程中可以进行聊天,达到相互交流经验的作用,同时能让身处各地的玩家连接到服务器进行五子棋对弈。
    1.3 研究现状分析目前常见的单机类五子棋游戏可分为“人机模式”与“双人模式”。“人机模式”指人与按照事先编写好的五子棋落子算法程序来进行游戏的计算机进行对弈,“双人模式”指两个人通过使用同一台计算机,交替落子来进行游戏。这两种方式,都需要玩家双方在同一台计算机面前进行完成,因此局限性很大,玩家不能再异地的不同的计算机上来进行游戏。
    随着现代计算机网络的迅速发展,网络上的计算机之间的通信已经变得十分便捷。这也为身在异地间的用户利用网络来进行游戏提供了途径。
    网络版的五子棋软件利用网络连接协议TCP/IP,在不同地方的玩家之间建立一个TCP连接,并用这个连接来交换数据,进行通信。因此,网络版的五子棋软件在游戏之前必须确定对网络参数设置的正确性,设置正确之后,才能进行玩家双方的TCP成功连接。连接成功后,双方轮流下棋,同时将每一步落子的信息通过网络连接传送给对方,使双方棋盘上的状态保持一致。
    与单机版的五子棋软件相比,网络版的五子棋软件也提供了所有单机版的五子棋软件所具有的功能,例如:倒计时器、“认输”、“和棋”和“悔棋”等。但对于网络版的五子棋来说,这些功能的同步都是通过网络信息交互来实现的,因此,网络版的五子棋游戏实现过程较单机版要复杂一些。
    在胜负判断方面,单机版的五子棋软件与网络版的五子棋软件可以采用完全相同的算法(如果不考虑先手禁手等)。一方玩家下完一步棋后,系统会自动判断当前落子之后,玩家是否胜利,如果没有胜利,再将落子的信息传送给对方,如果判断结果为胜利,则直接发送胜利消息给对方。每次落子之后,都要进行这样一次胜负判断定的过程。另外,由于网络版的五子棋的游戏双方可能不在同一个地点,因此,提供聊天功能很有必要。
    目前常见的网络五子棋的游戏形式又可分为两种,一种是以QQ五子棋(如图1.1)为代表的桌面应用程序的游戏形式,一种是网页flash(如图1.2)的游戏形式。

    系统结构方面,QQ五子棋游戏采用了C/S结构,而网页flash的五子棋采用的是B/S结构。
    功能方面,二者均提供了常见的悔棋、计分、计时、聊天、认输等功能。均未设计五子棋中“先手禁手”等规则。不同之处在于,常见的网页五子棋对于一方断网的情况不能及时发现,发现后也只是做出提醒另外一方的操作。而QQ五子棋能够对一方断网的情况及时发现,并且采用电脑托管或者直接结束比赛并计算相应分数的操作。
    游戏流畅度方面,网页flash的游戏形式受限于浏览器解析网页代码的速度限制,游戏载入时间明显过长。而QQ五子棋只需要基本的Windows操作系统即可,运行环境要求较低,运行流畅。
    1.4 各章内容简介本文第一章介绍了课题的研究背景,第二章简单介绍了实现程序所用到的技术介绍,第三章对程序需求进行了分析,第四章为系统的设计思想以及详细设计,第五章介绍了系统的实现过程,第六章展示了系统的效果,最后第七章总结了系统已完成的工作和下一步待完成的工作。
    2 实现技术2.1 P2P模式2.1.1 P2P模式介绍P2P[2](peer-to-peer, 简称P2P)又称对等互联网络技术,是一种网络新技术,依赖网络中参与者的计算能力和带宽,而不是把依赖都聚集在较少的几台服务器上。请注意与point-to-point之间的区别,peer-to-peer一般译为端对端或者群对群,指对等网中的节点;point-to-point一般译为点对点,对应于普通网络节点。P2P网络通常用于通过Ad Hoc连接来连接节点。这类网络可以用于多种用途,各种文件共享软件已经得到了广泛的使用。P2P技术也被使用在类似VoIP等实时媒体业务的数据通信中。
    纯点对点网络没有客户端或服务器的概念,只有平等的同级节点,同时对网络上的其它节点充当客户端和服务器。这种网络设计模型不同于客户端-服务器模型,在客户端-服务器模型中通信通常来往于一个中央服务器。
    2.1.2 P2P模式的优势P2P网络的一个重要的目标就是让所有的客户端都能提供资源,包括带宽,存储空间和计算能力。因此,当有节点加入且对系统请求增多,整个系统的容量也增大。这是具有一组固定服务器的Client-Server结构不能实现的,因为在上述这种结构中,客户端的增加意味着所有用户更慢的数据传输。
    P2P网络的分布特性通过在多节点上复制数据,也增加了防故障的健壮性,并且在纯P2P网络中,节点不需要依靠一个中心索引服务器来发现数据。在后一种情况下,系统也不会出现单点崩溃。
    当用P2P来描述Napster 网络时,对等协议被认为是重要的,但是,实际中,Napster 网络取得的成就是对等节点(就像网络的末枝)联合一个中心索引来实现。这可以使它能快速并且高效的定位可用的内容。对等协议只是一种通用的方法来实现这一点。
    2.1.3 P2P模式的应用点对点技术有许多应用。共享包含各种格式音频,视频,数据等的文件是非常普遍的,实时数据(如IP电话通信)也可以使用P2P技术来传送。
    有些网络和通信渠道,像Napster,OpenNAP,和IRC@find,一方面使用了主从式架构结构来处理一些任务(如搜索功能),另一方面又同时使用P2P结构来处理其他任务。而有些网络,如Gnutella和Freenet,使用P2P结构来处理所有的任务,有时被认为是真正的P2P网络。尽管Gnutella也使用了目录服务器来方便节点得到其它节点的网络地址。
    2.2 Qt2.2.1 Qt介绍
    UI(User Interface)也可以称之为用户接口或使用者接口,是系统和用户之间进行交互和信息交换的媒介,它实现信息的内部形式与人类可以接受形式之间的转换。
    Qt[3]是由挪威TrollTech公司于1995年底出品,之后被诺基亚公司收购并维护的一个跨平台的C++图形用户界面应用程序框架。广泛用于开发GUI程序,这种情况下又被称为部件工具箱。也可用于开发非GUI程序,比如控制台工具和服务器。自从1996年早些时候,Qt进入商业领域,它已经成为全世界范围类数千种成功的应用程序的基础,被GoogleEarth、KDE、西门子公司等使用。它是诺基亚(Nokia)的Qt Development Frameworks部门的产品。
    经过多年发展,Qt不但拥有了完善的C++图形库,而且近年来的版本逐渐集成了数据库、OpenGL库、多媒体库、网络、脚本库、XML库、WebKit库等等,其核心库也加入了进程间通信、多线程等模块,极大的丰富了Qt开发大规模复杂跨平台应用程序的能力,真正意义上实现了其研发宗旨“Code Less; Create More; Deploy Anywhere.”。
    2.2.2 Qt模块模块化 QtC++ 类库提供一套丰富的应用程序生成块 (block),包含了构建高级跨平台应用程序所需的全部功能。Qt模块结构图如图2.1:

    其中本系统设计到更多的Qt的消息响应机制和多线程如下:
    1.Qt的消息响应机制:信号与槽:
    Qt利用信号与槽(signals/slots)机制取代传统的callback来进行对象之间的沟通。当操作事件发生的时候,对象会发提交一个信号(signal);而槽(slot)则是一个函数接受特定信号并且运行槽本身设置的动作。信号与槽之间,则通过QObject的静态方法connect来连结。
    信号在任何运行点上皆可发射,甚至可以在槽里再发射另一个信号,信号与槽的连结不限定为一对一的连结,一个信号可以连结到多个槽或多个信号连结到同一个槽,甚至信号也可连接到信号。
    以往的callback缺乏类型安全,在调用处理函数时,无法确定是传递正确型态的参数。但信号和其接受的槽之间传递的数据型态必须要相符合,否则编译器会提出警告。信号和槽可接受任何数量、任何型态的参数,所以信号与槽机制是完全类型安全。
    信号与槽机制也确保了低耦合性,发送信号的类并不知道是哪个槽会接受,也就是说一个信号可以调用所有可用的槽。此机制会确保当在”连接”信号和槽时,槽会接受信号的参数并且正确运行。
    2.多线程
    Qt的运行绪支持是独立于平台的运行绪类,采用信号与槽机制,实现类型安全的运行绪间通讯。这使得它易于开发具可移植性的多线程Qt应用程序。并能充分利用多核架构,获得最佳运行性能,还能根据可用的处理器内核数自动调整使用的运行绪数。多线程程序设计也是一个执行耗时操作而不会冻结用户界面的有效典范。
    2.2.3 Qt的优势1.面向对象
    Qt的良好封装机制使得Qt的模块化程度非常高,可重用性较好,对于用户开发来说是非常方便的。Qt提供了一种称为signals/slots的安全类型来替代callback,这使得各个元件之间的协同工作变得十分简单。
    2.丰富的API
    Qt包括多达250个以上的C++类,还提供基于模板的collections,serialization,file,I/Odevice,directorymanagement,date/time类。甚至还包括正则表达式的处理功能。
    3.优秀的跨平台能力
    使用Qt开发的软件,相同的代码可以在任何支持的平台上编译与运行,而不需要修改源代码。会自动依平台的不同,表现平台特有的图形界面风格。

    Linux/X11:用于X Window System(如Solaris、AIX、HP-UX、Linux、BSD)。支持KDevelop和EclipseIDE集成Mac:用于Apple Mac OS X。基于Cocoa框架。支持Universal Binary。支持以Xcode编辑、编译和测试。Windows:用于Microsoft Windows。支持Visual Studio集成Embedded Linux:用于嵌入式Linux。可以通过编译移除不常使用的组件与功能。通过自己的视窗系统QWS,不需依赖X Window System,直接写入Linux帧缓冲。可以减少存储器消耗。并提供虚拟帧缓冲QVFb,方便在桌面系统上进行嵌入式测试。Windows CE / Mobile :用于Windows CESymbian:用于Symbian platformMaemo:用于Maemo
    4.大量的开发文档
    对于Qt的各个模块,都有对应的帮助文档和编写好的例子供开发人员参考。
    3 系统需求分析服务端程序运行流程图如图3.1:

    打开服务端后,用户首先设置服务参数,然后等待客户端连接。
    当收到客户端的连接时,将目前已经连接到服务端的所有客户端的状态(正在游戏中,建立了主机并等待玩家加入)发送到刚刚连接进来的客户端。
    如果收到客户端请求:请求建立游戏主机、请求加入别人的游戏主机进行游戏,则服务端更新此客户端的状态,然后将最新的状态发送给各个客户端。
    客户端程序运行流程图如图3.2:

    打开客户端后,用户首先设置服务器参数,然后连接服务端。连接成功后,客户端会收到来自服务端的其他客户端的当前状态,用户可以选择是建立游戏主机,还是加入别人的游戏主机进行游戏。
    1.功能需求
    程序主要核心功能如图3.3:


    服务器开始、退出
    服务端程序能够开启、关闭五子棋游戏的服务。关闭服务时,能够给当前已连接的客户端发送关闭服务消息。
    玩家开始、退出
    玩家进入游戏主机之后,需要点击准备才能开始游戏,若玩家在游戏时退出游戏,需要向对手发送退出游戏的信息。
    聊天功能
    玩家在对弈过程中可以发送信息进行交流。
    悔棋
    玩家在对弈过程中,能够进行悔棋请求,如果对方答应悔棋请求,则系统撤销双方玩家最近一次的落子;若对方不答应悔棋请求,则游戏继续。
    认输
    玩家在对弈过程中,可以直接选择认输,不需要经过对方同意。
    计分
    程序能保存当前两个玩家从开始第一句对弈,到其中一方离开游戏这期间的战绩情况。
    断网处理
    当其中一方玩家意外断网时,程序能通过超时相应判断出对方丢失了网络连接并作出处理。

    2.环境需求

    装有windows或者linux的操作系统的计算机两台计算机的CPU不低于P4,内存不小于64M10/10Mbps自适应网卡每台计算机各一块每台计算机都应配置有TCP/IP协议
    3.用户界面需求

    界面友好、美观界面简洁操作界面方便、易懂
    4.异常处理需求

    处理端口号冲突时的异常当出现错误落子位置时,此次操作无效如果网络非正常断开,则终止此局游戏
    4 系统设计4.1系统设计思想本系统的能够实现一个在网络上供玩家进行对战的网络版的五子棋游戏,玩家只要登陆到服务器上,然后选择其它已创建好的游戏主机,进行五子棋对战游戏。或者自己建立一个游戏主机,等待对方的加入。
    在C/S 模式游戏中,服务端一般提供所有用户的全局信息,并能提供客户之间的信息转发,客户之间的通讯必须通过服务端进行。因为在多个客户能够连接到同一台服务端上,所以服务端必须用线程负责每个用户的通讯和消息处理。
    但是考虑到如果采用这种思路,当客户端达到一定的数量之后,会增加服务端的负荷,而且当两个玩家开始游戏之后,服务端只需知道玩家双方是否退出游戏以及双方的游戏结果即可,而玩家之间的对弈信息、聊天等信息大可不必经过服务端。
    基于以上考虑的原因,决定采用P2P的网络模式:服务端程序开启服务后,通过一个线程监听客户端的连接,一旦有客户端连接,服务端便为该客户端建立连接并启动一个特定的线程,利用该连接不断获取客户端操作请求,从而更新游戏大厅信息,让其他玩家及时了解到哪些客户端建立了游戏主机,哪些客户端之间正在进行游戏对弈。而当客户端加入了另外一个客户端建立的游戏主机时,二者便建立起P2P连接,用于传送二者之间的对弈信息,操作请求(悔棋,认输等),聊天信息等。设计思想的结构拓扑图如图4.1:

    4.2 系统总体设计系统使用Socket技术与Qt多线程机制结合,使用C/S模式与P2P模式结合,在进行客户与服务端以及各个客户端之间进行信息的交互。
    其中,对客户端进行的各个操作请求产生的数据包发送的对象如表4.1:



    客户端操作类型
    数据包发送对象




    用户登录请求
    服务器


    用户建立主机请求
    服务器


    用户加入游戏请求
    服务器


    网络丢失确认
    服务器


    对方网络丢失信息通知
    服务器


    发送认输通知
    客户端


    发送落子信息
    客户端


    发送聊天内容
    客户端


    发送悔棋请求
    客户端



    用户程序之间进行交互的协议如图4.2:

    其中,“数据类型”字段如表4.2:



    消息类型
    说明




    COMM_SERVER_CONN_FAILED
    连接服务器失败


    COMM_SERVER_CONN_SUCCESSFUL
    连接服务器成功


    COMM_SERVER_CLOSE
    服务器关闭


    COMM_SERVER_GAMEINFO
    服务器发送大厅信息


    COMM_CLIENT_QUITGAME
    客户端退出游戏


    COMM_CLIENT_DISCONN
    客户端请求断开服务器


    COMM_CLIENT_CONN
    客户端请求连接服务器


    COMM_CLIENT_CREATE
    客户端请求创建主机


    COMM_CLIENT_JOIN
    客户端请求加入游戏


    COMM_CLIENT_GAMESTART
    双方准备完毕,游戏开始


    COMM_CLIENT_GAMEOVER
    某方玩家胜利,游戏结束


    COMM_CLIENT_GAMEOP
    玩家游戏操作:落子


    COMM_CLIENT_CHAT
    玩家游戏操作:发送聊天信息


    COMM_CLIENT_UNDO
    玩家游戏操作:悔棋


    COMM_CLIENT_UNDO_YES
    玩家游戏操作:悔棋回复yes


    COMM_CLIENT_UNDO_NO
    玩家游戏操作:悔棋回复no


    COMM_CLIENT_LOSE
    玩家游戏操作:认输


    COMM_CLIENT_LOSTCONN
    玩家发送消息:对手超时,判定为掉线



    请求方需要发出请求时,便把消息类型设置为如上对应的消息类型(例如:服务器连接请求),并设置请求相关的数据(例如:需要连接的服务器的IP以及端口),最后发送此数据包。
    数据字段根据第一个字段的不同设置不同的数据,有可能为包含五子棋落子位置的信息;有可能为空数据(例如:连接服务器成功则数据字段为空,连接服务器失败则数据字段为连接服务器失败的原因)。
    接收方在接受到此数据包之后,首先判断出数据包的类型什么,然后利用接受到的数据(例如:服务器的IP以及端口)以及数据包类型(例如:服务器连接请求)来处理数据(例如:是否接受此客户端的连接),处理完毕之后,设置响应数据包类型为具体的响应类型(例如:连接成功),并且设置响应相关的数据(例如:连接成功则没有数据,连接失败则数据为连接失败的原因),最后发送此数据包。
    例如某个客户端在连接服务器时,详细流程如图4.2:

    客户端想服务端发送连接请求,数据包设置如图中“数据包(1)”,服务端收到连接请求之后,判断出此时已达服务端最大的连接数,然后将数据包设置如图中“数据包(2)”,然后将此数据包发送给刚刚的客户端,通知客户端此次连接因为服务器已经达到了最大连接数,拒绝客户端的连接。
    4.3 系统工作流程4.3.1 服务端工作流程基于以上设计,服务端只负责本地游戏服务的开启,以及各个客户端的连接,建立主机,加入游戏等请求,因此服务端的工作流程如图4.3:

    服务端首先设置服务参数,然后开启本地服务,等待客户端的连接。
    当接受到客户端的连接之后,建立一个新线程,用于接受客户端的操作请求,父线程则继续等待客户端的连接。
    当子线程收到客户端发来的操作请求时,则根据对应的请求类型做相应的处理。
    4.3.2 客户端工作流程基于以上设计,客户在与服务端交互时采用C/S模式,与其他玩家对弈时,采用P2P模式,因此客户端的工作流程如图4.4:

    客户端连接到服务端之后,首先获取到服务端发送来的各个客户端的状态,然后选择是自己建立游戏主机,还是加入别人的游戏。
    游戏中,客户端与客户端之间会建立P2P连接,传递各种游戏操作信息。
    4.4 五子连珠算法设计五子棋游戏中,如果一方胜利,则胜利时的五子连珠必定与玩家最后落下的那颗棋子相关。因此每当用户落下一颗棋子时,程序便判断包括这颗棋子在内的纵向、横向、斜向的五颗棋子有没有五子相连的情况,若有,则此方胜利,反之,继续比赛。
    五子棋程序中,采用一个二维数组保存棋盘的每个位置的当前状况(白色棋子,黑色棋子,没有落子)。当其中一方胜利时,在棋盘记录中,五子相连的方向的当前状态应同为白子或同为黑子。
    以斜向为例,胜利时的可能情况如图4.5所示:(所有圆均表示同一个玩家落下的棋子,填充色的圆表示最后落下的子):

















    每次落下一颗棋子时,程序判断斜向这5种情况以及其他几个方向类似情况是否为同色,若是,则胜利,反之,继续比赛。
    程序伪代码:
    curPosX,curPosY : 当前落子的横纵坐标count : 棋盘格数(19)winColor : 当前落子玩家所持有的棋子的颜色chessboardRecord[count][count] : 记录棋盘各个位置的落子的颜色的二维数组for I from 4 to 1 step 1 if curPosX<0 or curPosY<0 then continue; end if for J from 0 to 5 step 1 if curPosX>count-1 or curPosY>count-1 then break end if if chessboardRecord[curPosX][curPosY]<>winColor break end if else if j=4 return true end if end forend for
    5 系统实现5.1 主要的数据结构// 用于记录某个棋子是主机落下的还是对手落下的enum playerRole enum playerRole{ HOST, GUEST};
    // 记录当前游戏状态是playingGame(正在游戏)还是readyToPlayingGame(等待对方按下准备按钮,然后开始游戏)enum playerStatus enum playerStatus{ playingGame, readyToPlayingGame};
    // 用户程序之间交互协议enum comm_request_typeenum comm_request_type{ //连接服务器失败 COMM_SERVER_CONN_FAILED, //连接服务器成功 COMM_SERVER_CONN_SUCCESSFUL, //服务器关闭 COMM_SERVER_CLOSE, //服务器发送大厅信息 COMM_SERVER_GAMEINFO, //退出游戏 COMM_CLIENT_QUITGAME, //请求断开服务器 COMM_CLIENT_DISCONN, //客户端请求连接服务器 COMM_CLIENT_CONN, //客户端请求创建主机 COMM_CLIENT_CREATE, //客户端请求加入游戏 COMM_CLIENT_JOIN, //双方准备完毕,游戏开始 COMM_CLIENT_GAMESTART, //某方玩家胜利,游戏结束 COMM_CLIENT_GAMEOVER, //玩家游戏操作:落子 COMM_CLIENT_GAMEOP, //玩家游戏操作:发送聊天信息 COMM_CLIENT_CHAT, //玩家游戏操作:悔棋 COMM_CLIENT_UNDO, //玩家游戏操作:悔棋回复yes COMM_CLIENT_UNDO_YES, //玩家游戏操作:悔棋回复no COMM_CLIENT_UNDO_NO, //玩家游戏操作:认输 COMM_CLIENT_LOSE, //玩家发来消息,对方掉线 COMM_CLIENT_LOSTCONN};
    // 用户程序之间交互数据包的格式struct msg_request_structstruct msg_request_struct{ //请求类型 qint8 request; //数据 QString data;};
    5.2 服务端的实现5.2.1 界面实现服务端能够开启本地服务,以及实时查看游戏大厅信息:哪些玩家正在对弈,哪些玩家在等待其他玩家加入等。因此服务端应具有两个界面,分别用来配置本地服务以及显示游戏大厅信息。如图5.1和图5.2:

    5.2.2 主要的成员变量// 用户程序之间交互的数据结构msg_request_struct* msg_req_struct;
    // 记录对弈双方的IP信息,若主机在等待其他玩家加入,则其对手IP地址置为“-”QList<QPair<QString, QString> >playerFightInfo;
    // 保存服务端本地开启的服务套接字QTcpServer *tcpServer_player;
    5.2.3 功能实现1.客户端连接限制功能
    考虑到服务端运行环境不同,所能承受的负荷也不同,因此加入“客户端连接限制”功能,防止过多的客户端连接导致服务端的负荷过大。
    在服务端的服务配置界面,可以设定服务端允许的最大连接数,当客户端的连接数达到了服务端设置的最大连接数的时候,服务端便不允许其他客户端连接。
    核心代码:
    QTcpSocket *tcpSocket_player = tcpServer_player->nextPendingConnection();DataClass::curConnCount++; if(DataClass::curConnCount > DataClass::maxConnectionLimit){ DataClass::curConnCount--; tcpSocket_player->close(); tcpSocket_player = NULL; return ;}
    2.广播游戏大厅信息(建立主机,加入游戏,退出游戏等)
    服务端与客户端之间的信息交互采用C/S模式,因此当有客户端更新并向服务端发送信息(例如建立主机,加入游戏,退出游戏等)之后,服务端应及时将更新之后的信息广播出去,使得其他客户端及时更新大厅信息。
    核心代码:
    QString qsNull = "-";playerFightInfo.push_back(qMakePair(clientAddr, qsNull));updateGameInfo();QList<QTcpSocket* > allTcpSocket = tcpServer_player->findChildren<QTcpSocket *>(); QString data; for(int i=0; i<playerFightInfo.size(); i++)data += playerFightInfo[i].first + " " + playerFightInfo[i].second + "_";for(int i=0; i<allTcpSocket.size(); i++){DataClass::sendMsg(COMM_SERVER_GAMEINFO, data, tcpSocket);}
    客户端收到服务端发送过来的data之后,用正则表达式分析出对弈双方的信息,然后更新本地显示。
    5.3 客户端的实现5.3.1 界面实现客户端具有一个配置连接服务器的界面,用于输入连接服务器信息,如图5.3:

    登陆服务器成功之后,会显示从服务器接受到得玩家对弈信息,用户这时可以选择建立游戏主机等待别人加入,或者是加入别人的主机进行对弈,如图5.4:

    玩家选择了建立游戏主机或者加入游戏后,会弹出游戏界面等待开始游戏,如图5.5:

    5.3.2 主要的成员变量// 记录超时时间的定时器QTimer timer;
    // 记录当前棋盘的落子信息int chessboardRecord[19][19];
    // 用户程序之间交互的数据结构msg_request_struct* msg_req_struct;
    // 当前玩家的身份(参考5.1的playerRole数据结构)playerRole plyRole;
    // 当前游戏状态(参考5.1的playerStatus数据结构)playerStatus plyStatus;
    // 下一步该谁落子(参考5.1的playerRole数据结构)playerRole whosTurn;
    // 记录对战成绩int win, lose;
    // 记录当前已经落下的棋子的信息:落子的位置,谁落的这颗子QList<QPair<QPoint, enum playerRole> > pieceRecord;
    5.3.3 功能实现1.玩家开始、退出
    开始时输入玩家的姓名,同时下方会显示出相应的IP地址。在输入相关的信息后就会弹出游戏界面,而游戏设置的对话框随即会自动隐藏,释放。这时就开始等待对方的加入,等有人加入后就可以开始游戏了。或者直接加入别人建立的主机。如果不想玩了就可以按退出按钮,一方退出游戏后,另一方就会显示尚未连线,然后等待下一个玩家的进入。功能详细流程如图5.6:

    核心代码:
    // 建立游戏主机DataClass::sendMsg(COMM_CLIENT_CREATE, "", tcpSocket_server); GameStatus gameStatus;gameStatus.setPara(tcpSocket_server);connect(tcpSocket_server, SIGNAL(readyRead()), &gameStatus, SLOT(getNewDataFromServer()));gameStatus.setPlayerRole(HOST);gameStatus.exec();
    // 加入游戏int row = ui.clientStatus_client_TBW->currentRow();if(ui.clientStatus_client_TBW->item(row,1)->text() != "-"){ QMessageBox::information(this,"错误","此主机正在对战中..."); return ;}DataClass::sendMsg(COMM_CLIENT_JOIN,ui.clientStatus_client_TBW->item(row, 0)->text(), tcpSocket_server); GameStatus gameStatus;gameStatus.setPara(tcpSocket_server);connect(tcpSocket_server, SIGNAL(readyRead()), &gameStatus, SLOT(getNewDataFromServer()));gameStatus.setPlayerInfo(ui.clientStatus_client_TBW->item(row,0)->text());gameStatus.setPlayerRole(GUEST);gameStatus.exec();
    // 退出游戏if(plyRole == HOST){ plyStatus = readyToPlayingGame; ui.chatLog_client_TE->clear(); ui.record_me_client_LE->setText("胜利:" + QString::number(win) + "场,失败:" + QString::number(lose) + "场!"); ui.record_rivar_client_LE->setText(""); ui.addr_rivar_client_LE->setText(""); QMessageBox::information(NULL,"提示","对方退出游戏!");}else if(plyRole == GUEST){ ui.gameReady_client_BTN->setDisabled(false); closeByServer = true; this->close();}
    2.用户之间聊天
    在下棋的同时可以通过聊天窗口和对方进行聊天会话,写完信息之后点击发送,就可以在公共的显示栏中看到自己发出的信息和对方回应的信息。进而开始用户之间的交流,同时所用的组合框的下拉菜单中会有一些简便的备用的语句,可以点击随即发送,这样就能省去部分打字的时间。
    核心代码:
    if(ui.sendwords_client_LE->text() == ""){ QMessageBox::information(NULL,"错误","请先输入文字!"); return ;}ui.chatLog_client_TE->append("自己: " + ui.sendwords_client_LE->text());DataClass::sendMsg(COMM_CLIENT_CHAT,ui.sendwords_client_LE->text(),tcpSocket_player);ui.sendwords_client_LE->setText("");
    3.悔棋、认输
    在游戏中,玩家可以发出悔棋请求,如果对方同意悔棋,则程序自动回退一步;若对方不同意悔棋,则请求无效。玩家也可以发出认输请求,程序自动结束本轮游戏并计分,认输请求不需要对方同意。悔棋功能详细流程如图5.7:

    核心代码:
    // 悔棋 if(whosTurn != plyRole) { QMessageBox::information(NULL,"错误","轮到你下棋的时候你才能发出悔棋请求!"); return ; } if(!(DataClass::checkDialog("确认","确认悔棋?"))) return ; whosTurn = (plyRole == HOST ? GUEST : HOST); DataClass::sendMsg(COMM_CLIENT_UNDO,"",tcpSocket_player);
    // 收到悔棋响应(同意悔棋)QMessageBox::information(NULL,"提示","对方同意悔棋!");whosTurn = plyRole;if(pieceRecord.size() > 0){ chessboardRecord[pieceRecord[pieceRecord.size() - 1].first.x()-1][pieceRecord[pieceRecord.size() - 1].first.y()-1] = 0; pieceRecord.removeAt(pieceRecord.size() - 1);}if(pieceRecord.size() > 0){ chessboardRecord[pieceRecord[pieceRecord.size() - 1].first.x()-1][pieceRecord[pieceRecord.size() - 1].first.y()-1] = 0; pieceRecord.removeAt(pieceRecord.size() - 1);}update();
    // 收到悔棋响应(不同意悔棋)whosTurn = plyRole;QMessageBox::information(NULL,"错误","对方不同意悔棋请求!");
    // 认输if(!(DataClass::checkDialog("确认","确认认输?"))) return ;DataClass::sendMsg(COMM_CLIENT_LOSE,"",tcpSocket_player); if(plyRole == GUEST) ui.gameReady_client_BTN->setDisabled(false);ui.undo_client_BTN->setDisabled(true);ui.lose_client_BTN->setDisabled(true);plyStatus = readyToPlayingGame;lose += 1;ui.record_me_client_LE->setText("胜利:" + QString::number(win) + "场,失败:" + QString::number(lose) + "场!");ui.record_rivar_client_LE->setText("胜利:" + QString::number(lose) + "场,失败:" + QString::number(win) + "场!");
    4.计分
    游戏开始的时候双方的战绩均为零,当一轮过后战绩就会被刷新一次,各自几胜几败很清晰的出现在界面上,由于最先下棋的玩家胜利的几率会很大,所以根据各自的胜负情况会交替双方先手的顺序,达到公平的目的。
    5.断网处理
    当客户端在等待对方操作时超时,则测试是否能连接服务器。若能连接,则向服务器发送对方以断网的相关信息并结束比赛计算分数;若不能连接,则提示用户已丢失与服务器和对方的连接。断网处理的详细流程如图5.8:

    核心代码:
    QTimer timer;connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));timer.start(30000); if(tcpSocket_player->isValid()) return ;QMessageBox::information(NULL,"提示","对方超时!");dataInit();ui.undo_client_BTN->setDisabled(true);ui.lose_client_BTN->setDisabled(true);ui.send_client_BTN->setDisabled(true); if(plyRole == GUEST){ DataClass::sendMsg(COMM_CLIENT_LOSTCONN,"HOST " +ui.addr_rivar_client_LE->text(),tcpSocket_server); if(tcpSocket_player) { tcpSocket_player->close(); tcpSocket_player = NULL; } this->close();}else if(plyRole == HOST){ DataClass::sendMsg(COMM_CLIENT_LOSTCONN,"GUEST " + ui.addr_rivar_client_LE->text(),tcpSocket_server); plyStatus = readyToPlayingGame; ui.chatLog_client_TE->clear(); ui.record_me_client_LE->setText("胜利:" + QString::number(win) + "场,失败:" + QString::number(lose) + "场!"); ui.record_rivar_client_LE->setText(""); ui.addr_rivar_client_LE->setText(""); if(tcpSocket_player) { tcpSocket_player->close(); tcpSocket_player = NULL; } if(tcpServer_player) { tcpServer_player->close(); tcpServer_player = NULL; }}
    5.3.4 五子连珠算法核心代码(4个方向中,以斜向为例):
    checkWinLURD(int last_x, int last_y, int winColor)函数:for(int j=4; j>-1; j--){ if(last_x - j <0 || last_y - j < 0) continue; for(int z=0; z<5; z++) { if(last_x - j + z > 18 || last_y - j + z > 18) break; if(chessboardRecord[last_x - j + z][last_y - j + z] != winColor) break; else if(z == 4) return true; }}return false;
    6 系统效果展示6.1 服务端效果展示服务端配置页面(默认为监听端口为45454端口,默认连接上限为50),如图6.1:

    开启服务有,当有客户端连接时,左下角会实时更新当前连接数。当客户端建立游戏主机之,服务端也会及时显示,如图6.2:

    当有玩家加入游戏时,服务端也能及时更新,如图6.3:

    6.2 客户端效果展示
    客户端连接服务器配置页面,如图6.4:

    客户端登陆后,会实时显示当前连接到服务端的游戏主机信息,如图6.5:

    玩家此时可以选择加入别人的游戏主机(双击主机列表),游戏界面如图6.6:

    点击“准备”按钮之后,即可开始游戏,如图6.7:

    游戏过程中,玩家可以聊天,如图6.8:

    游戏过程中,玩家可以点击“悔棋”、“认输”、“退出”按钮达到相应功能。
    7 结论7.1 已完成的工作目前本软件已完成的工作如下:

    了解五子棋游戏的落子规则,并设计相应的判断胜利算法。
    通过查阅相关资料,对于本软件设计了一个比较简单且快速有效的五子连珠算法。
    学习网络编程技术,掌握C/S模式网络程序的基本编程方法。
    经分析,本软件最终采用了P2P的网络模式,相比于C/S模式,P2P模式使得本软件效率更高。
    学习GUI程序设计,设计五子棋游戏的程序界面。
    本软件已实现一个操作方便,界面美观的五子棋游戏程序。
    设计并实现网络五子棋的服务器和客户端程序。
    本软件已实现服务器和客户端程序,服务端用于收集客户端的游戏状态信息,客户端用于玩家之间的对弈。
    设计并实现悔棋、认输、计分、聊天等游戏辅助功能。
    本软件已实现常见的游戏功能:悔棋,认输,计分,聊天等功能。

    另外,程序还实现了断网处理:当对方玩家1分钟之内没用做任何操作,则系统认为此玩家已丢失网络连接,结束此局比赛,并且让丢失连接的玩家退出此游戏主机。
    7.2 下一步待完成的工作本系统和其它的网络五子棋软件相比,功能上还存在着一定的差距,例如:本系统必须要知道主机的IP地址以及端口号才能建立连接、第三方观看的玩家不能加入棋局等等。
    要想设计出更完善的网络五子棋软件,仍然需要做大量的工作:
    1.服务器的设置
    在网络中将其中一台计算机设置成为固定的服务器,其IP地址和端口号是固定不变的,客户端可以直接连接到此服务器上,然后通过服务器上的信息选择对手或者创建游戏主机,这样就省去了玩家必须知道游戏主机的IP地址和端口号的麻烦了。
    2.界面需要进一步美化
    界面可以适当进行美化,提高游戏的娱乐性。
    3.提高通信的可靠性
    在采用同TCP连接的一般情况下,网络五子棋软件都可以正常稳定的工作,但是仍不能保证其任何情况下都能正常稳定,一旦由于某种原因使得网络传输过程中的数据丢失,将使双方的游戏数据不一致,游戏便无法继续进行。因此,可以考虑一方断网之后,计算机智能代替下棋的功能。
    4.扩充功能。
    增加记录当前棋谱的功能,以供五子棋残局爱好者能在日后研究。
    致谢从论文选题到搜集资料,从程序的设计到反复调试,从论文的成型到反复修改,期间经历了太多的喜悦、痛苦和彷徨。如今,伴随着这篇毕业论文的最终成稿,自己甚至还有一点成就感。
    我要感谢我的导师。他为人随和热情,治学严谨细心。在闲聊中她总是能像知心朋友一样鼓励你,在论文的写作和措辞等方面她也总会以“专业标准”严格要求你,从选题、定题开始,一直到最后论文的反复修改、润色,老师始终认真负责地给予我深刻而细致地指导,帮助我开拓研究思路,精心点拨、热忱鼓励。正是老师的无私帮助与热忱鼓励,我的毕业论文才能够得以顺利完成,谢谢老师。
    我要感谢班里的同学们,在百忙之中抽出时间帮助我搜集文献资料,帮助我理清论文写作思路,对我的论文提出了诸多宝贵的意见和建议。
    参考文献[1] Wikipedia.五子棋[EB/OL].[2011-04-07]. http://zh.wikipedia.org/zh/五子棋
    [2] Wikipedia.点对点技术[EB/OL].[2011-04-02].http://zh.wikipedia.org/wiki/点对点技术
    [3] Wikipedia.Qt[EB/OL].[2011-04-03].http://zh.wikipedia.org/wiki/Qt
    [4] Bruce Eckel.Thinking in Java[M].北京:机械工业出版社, 2007.
    [5] Thomas H.Cormen,Charles E.Leiserson,Ronald L.Rivest,CliffordStein.Introduction to Algorithms[M].北京:机械工业出版社, 2006.
    [6] Jasmin Blanchette,Mark Summerfield.C++ GUI Qt 4[M].北京:机械工业出版社, 2009.
    [7] 蔡志明.精通Qt4编程(第二版)[M].北京:机械工业出版社, 2011.
    [8] 严蔚敏,吴伟民.数据结构(C语言版)[M].北京:清华大学出版社, 2007.
    [9] 张银犬. 基于P2P技术的信息资源共享模式研究[EB/OL].[2005-11-25]. http://epub.cnki.net/grid2008/detail.aspx?filename=TSGJ200505012&dbname=CJFD2005
    [10] 顾军,王恒莉,徐丽. P2P网络模型的分析与探讨[EB/OL].[2005-10-01]. http://epub.cnki.net/grid2008/detail.aspx?filename=JISJ200510015&dbname=CJFD2005
    [11] 马睿. 基于Qt的TCP网络编程研究与应用[EB/OL].[2011-01-12]. http://epub.cnki.net/grid2008/detail.aspx?filename=FJDN201011067&dbname=CJFD2010
    8 评论 283 下载 2018-09-27 23:33:59 下载需要15点积分
  • 基于qt实现的简易画板及图灵机可视化功能

    总设计思路本项目中,我们自己设计了一个画板,我们可以在画板上画图,并从图中读取信息,整个画板主要由两个部分组成,左边大半部分时用于画图,右边部分由两个文本框和一个button按钮组成,用于显示信息和程序控制。
    画图部分总体画图布局
    画图的主要在paintevent中实现,我们将点的信息存储在QList<QPoint>中,边的信息存储在QList<QLine>中,将点和边的信息以QList<QString>的形式存储,每次鼠标点击一次屏幕触发一次mousepressevent事件,mousepressevent中调用一次paintevent绘制图像,以此为基础实现画图功能
    画点
    画点部分,我们用一个半径为20的圆表示点,点信息用一个QList保存。画图时,先点击工具栏结点按钮,然后鼠标点击画板,画板就会绘制一个以鼠标点击处为圆心画圆。
    划线
    画线部分,我们需要先点击工具栏上直线按钮,然后选择两个点,在两个点中绘制一条有向线,并将信息存储在QList中。此处两次点击都通过对点集的遍历判断选定顶点,并且可以实现绘制指向自己的边的功能,具体方法是判断两个顶点一致之后,绘制三条直线呈现三角形,重新指回顶点。
    撤销结点
    撤销结点部分,我们需要点击工具栏撤销节点按钮,然后点击需要撤销的结点,画板上就会删除结点及与结点相关联的边。点击撤销按钮后,用户会点击一次画板选择点,代码中,我们会获取到鼠标点击位置,遍历所有的QList<QPoint>,找到与鼠标点击位置最近的结点,将其从QList中删除,然后遍历QList<QLine>将与该点相关联的边也全部删除。这里由于使用的是QList里面的removeat函数,所以在遍历的过程中需要在找到一条边删除之后i—;确保遍历了每一条边。
    撤销边
    撤销边与撤销结点思路类似,我们点击撤销边按钮后,点击画板上两点,我们获取两点坐标然后遍历整个QList<QLine>,找出与其最近的边然后删除。
    选中
    选中顶点和选择边和撤销功能的类似,我们首先需要点击按钮,然后在屏幕上选择一点(两点),然后遍历整个QList<QPoint>(QList<QLine>),找出与之相邻最近的点(边),将其存储在selectpoint(selectline)中,将其传入paintevent事件中,当其绘制第selectpoint(selectline)个点(边)时,通过函数setColor,改变画笔颜色为red。显示在画板上效果为选中的点(边)颜色变为红色。同时,选中之后会弹出一个弹窗,用于输入选中的结点(边)的信息。
    程序运行进行图灵机程序模拟时,需要先点击工具栏运行按钮,然后系统会跳出可输入对话框,需要我们输入起点终点和初始字符串,然后会在主界面右下角显示初始状态,每点击一次nextstep的button按钮,就会进入到下一个状态,并将其显示在文本框下一行。如果图灵机可以成功到达终点,则会在文本框中显示success,否则显示fail
    图灵机实现代码通过循环判断下一步所处的节点,实现图灵机功能,首先确定起始点,之后遍历边集,找到边的起始点和图灵机起始点一致的边,之后对边上的信息进行spilt处理和遍历,确定输入的字符串和边的信息中的输入字符串一样,确定边之后,在改变show字符串中的点的位置和字符,在textedit中进行输出,并对于字符串状态进行判断,如果已经到达终点就可以输出SUCCESS END并且之后不在进行操作。
    注:详细代码在附件中给出
    0 评论 1 下载 2021-08-04 21:41:32 下载需要10点积分
  • 基于JSP和MySQL的网上零食销售系统的设计与实现

    摘 要本文介绍了网上零食销售系统的整个开发过程,采用国内认准的B2C商城建站系统模式,并按照现有的购物系统的现状而设计开发的网络买卖平台。
    本文主要阐述的了整个系统的完成过程,模拟了一个具备卖家,买家和管理员的网络交易系统。而本平台对不同的用户进行了细致的分划。对各个模块进行了功能上的丰富和优化。利用这些模块之间的交互完成整个物品的交易过程,为消费者和商家提供方便快捷的商务体验。说明书中已经简单的引述了电子商务的历史和现状,同样也介绍了该系统需要完成的功能,对整个项目的完成流程和进行时间进行了详细的规划。最后,对网上零食销售系统的前台应用软件进行了一些简要介绍。
    网上零食销售系统以JSP为主要的网页开发技术。利用B/S三层架构作为开发的基础框架,出于对系统的维护性,耦合性和安全性的考量,利用JavaBean对项目中关键部分进行封装的处理。数据库采用了后期维护十分便捷的MYSQL5.0数据库,其拥有的用可视化工具可以对字段进行快速准确的修改。
    关键字:JSP;B/S三层架构;JavaBean;MYSQL5.0
    AbstractThis article describes the online snack sales system throughout the development process, the use of domestic B2C mall to build the system model, and in accordance with the existing shopping system, the current design and development of network trading platform.
    This paper focuses on the completion of the whole system, simulates a network transaction system with sellers, buyers and administrators. But this platform carries on the detailed division to the different user. The modules are enriched and optimized in function. Use the interaction between these modules to complete the transaction process of the whole article, providing consumers and businesses with convenient and quick business experience. The manual has briefly quoted the history and current situation of e-commerce, and also introduced the functions that the system needs to complete. It also gives a detailed plan for the completion process and the time of the whole project. Finally, the online snack sales system of the front application software are briefly introduced.
    Online snack sales system to JSP as the main web development technology. The B/S three tier architecture is used as the basic framework of the development, and the encapsulation of the key parts of the system is processed by using JavaBean for consideration of system maintainability, coupling and security. The database adopts the MYSQL5.0 database which is convenient for later maintenance, Its own visual tools allow for rapid and accurate changes to the field.
    Key Words: JSP; B/S structure; JavaBean; MYSQL5.0
    1 绪论目前,我国的网民数量已经达到7.31亿人,随着互联网购物和互联网支付的普及,使得人类的经济活动进入了一个崭新的时代。淘宝,京东等网络消费平台功能的日益完善,使得人们足不出户就可以得到自己想要的东西。如今的互联网已经成为了我们生活中无法替代的部分,越来愈多的人感受到了互联网所带来的方便和快乐,也有越来愈多的人喜欢通过互联网购物来丰富自己的生活。如今的购物已不是当年去实体店挑选商品那种单一的存在,而是在一个虚拟的交易平台中,只需简单几步就可以实现整个购物的过程。
    JSP是一种动态的以网页为平台的开发技术,它具备很好的兼容性,可以引用JSP中自带的标签将Java代码导入到HTML网页中。相对于CGI程序JSP在性能方面更加快捷,而服务器端有着强大的兼容性等优势。随着互联网技术的日益完善,JSP技术在网络编程中也显得更加举足轻重。因此我采用了JSP作为我毕设的首要开发工具,建设了一个能实现简易的互联网交易的购物网站——网上零食销售系统。这个系统能够满足游客的注册和用户的登陆功能;可以满足用户对产品类别的查询,产品的下单,订单信息的查看等功能。基本上已经可以完成一个简单的交易过程,并且通过对数据库的编写和对代码的编写及完善,对于一个交易系统所需的技术都基本体现出来了,总的来说,目前的大型交易网站基本就是在我这个系统的基础上完善和扩充的。
    这次毕业设计中,我通过对相关电商网站运作原理的调查,初步绝定了整个项目的需求,并了解了当前最流行的动态网页技术JSP,对其有关知识和技术进行了深入的学习,实际的操作更是使得原本只存在与概念中的雏形得以实现。后期对于bug的修复和页面的美化更是锻炼了自己刻苦和谨慎的态度,这对于将来以后的工作和学习将是一笔不小的财富。
    1.1 开发背景在时代发展的今天,VR技术的出现使得人们可以在虚拟空间内进行活动,而AR则使得现实中可以模拟出你想要看到的东西。如果将这些与电子商务相联系的话,一个新的时代将会到来,若想足不出户就想得到这些虚拟的东西,购物网站成为了时下最为流行的选择,完善的购物系统,多样的支付方式,在体验虚拟的物品的同时打开购物网站,将其变为现实,短时间内天南海北的东西将会送到我们的手中,而这些都得益与物流的快速发展。正是在这一大趋势下我将“网上零食销售系统”作为了我的毕业设计。
    1.2 国内外现状
    网络交易(Electronic Commerce):从概念上讲是指产生在信息网络企业之间、电商和消费者之间还有个人与个人之间通过英特网的方式而进行的交易行为。国外因为网络发展起步早,因此国外的网络环境的都比较完善,功能齐全。
    进入21世纪以后,通过互联网技术,计算机技术和远距离交互技术,使得原本复杂的交易过程完全电子化和人性化。主流信息系统是基于B\S架构来设计并实现的管理系统[1]。而经济全球化的今天,国内外的消费者仅仅只需要在电脑或者手机前简单的对商品进行选择和付款便可足不出户获得远在大江南北的东西。网络所带来的便利已经开始影响到日常的生活,原本纸质的交易方式,已经实现到“互联网+”这种新兴的交易方式。
    由此可见,不管是在国内还是国外,如果要建立一个完善的电子商务系统,需要对大批的信息进行分析和处理,建设过程中还必须掌握数据库系统的理论和实际操作能力。对于如今已经成为不可或缺的网络交易平台,对于该系统的实现显得更加重要了。
    1.3 系统说明网上零食销售系统是在JSP的基础上进行开发和完善的。可以为卖家和买家两种用户提供在线交互平台,经过反复优化已符合我国目前流行的购物交互方式。卖家可以在平台中实现注册,上架新商品,商品打折,商店信息更新等功能;买家可以在平台中实现简单的注册,商品关键字的查询,将商品添加到购物车,订单付款等功能;网站维护人员可通过对商城各模块信息进行完善和删改,会员的信息的完善和删改等功能对商城进行改进和维护。
    2 开发环境介绍  2.1 JSP简介JSP动态网页技术的出现,得益于在Sun Microsystems公司的努力下,将行业内大小公司汇总起来,共同确定了现在所使用的动态网页技术规则。JSP=HTML+JAVA即在HTML中利用JSP自带的标签将原本存在于java文件中的代码导入进去,得到了我们现在所使用的.jsp文件。
    用JSP开发的Web应用拥有很好的兼容性,不光在传统操作系统Windows下可以运行,而在其他操作系统中也能完成其拥有的功能并且运行良好。
    JSP与Java Servlet两者有许多共通之处,例如都是在服务器端开始运作的,这时候客户端那边会得到一个HTML的文件,这时你只要拥有一个浏览器就可以很轻松的进行浏览了。
    在JSP已经飞快成长的今天,各大企业因其方便管理和较低的耦合性已经成为主流的网站建设方式。接下来我会讲述几个对于JSP关键性的几个问题,并对其进行简单的分析。
    2.1.1 Java Server Pages的工作原理JSP即HTML与Java的联合体。接下来将介绍怎样利用JSP来建立网页的:

    首先打开浏览器,利用浏览器对服务端发送一个HTML的申请
    服务端接受到申请后,会判断这是一个JSP网页的需求,接下来把这个需求发送给JSP引擎。利用URL或是.jsp文件来完成
    JSP引擎得到JSP文件后将其转换为servlet。其实就是将所有模块中的文本替换成了println()语句,而JSP元素则经过处理变成了java代码
    得到了servlet的JSP引擎将其进行编译,最终得到了可执行类,同时将最初的需求传递给了servlet引擎
    服务端的部分组件会对servlet引擎进行调用的同时加载并且运行servlet类。该部分运行时,servlet会生成HTML格式的输出,这个输出将会内嵌于HTTP response中发送给服务端
    服务端将静态的HTML页面的方式将HTTP response投射到我们的浏览器上
    服务端将HTTP response中处理得到的动态的HTML网页,其处理方式与静态页面相通

    以下是上述步骤的工作原理图,如图2.1所示:

    2.1.2 Java Server Pages的生命周期JSP的生命周期类似Servlet,而其关键在于基层的功能。
    以下是JSP生命周期中所经历的几个阶段:

    编译阶段:servlet容器编译成servlet源文件,产生servlet类
    初始化阶段:加载与JSP相对的servlet类,建立它的实例,同时调用它的初始化方法
    执行阶段:调用与JSP相对的servlet实例地服务方法
    销毁阶段:调用与JSP相对的servlet实例地销毁方法,紧接着销毁servlet实例

    以下为JSP生命周期的图示,如图2.2所示:

    2.2 Servlet技术简介Servlet其应用最重要的语言就是Java,其技术是作为JSP的发起者SUN建立地。作为现今主流的动态网页开发技术,程序员只需实现其已经拥有的接口和相应的继承类就可以轻松的将java文件变成动态网页。简单的说Servlet可以看作是在服务器端上运行的java程序。
    Servlet工作流程分为以下几步:

    客户端向服务端发送所需得到的消息
    服务端获得消息后需要将其传递到Servlet进行必要的处理
    Servlet对获得的消息进行处理,其产生的响应内容会被导入到Servlet
    服务端向客户端做出反馈

    以下为Servlet工作流程图,如图2.3所示:

    Servlet架构为我们提供了简化的开发过程,而这些过程可以细分为更加简单的类,这些类在开发过程中将使得原本复杂的代码变得更加条理。
    以下是我总结的Servlet提供给我们的类:

    控制程序流程的类
    实现和执行程序事务逻辑的类
    自定义的标记库使得创建和验证HTML表单更加容易

    Servlet体系结构:
    在项目的开发过程中,MVC设计模式被分为:模型,视窗和控制器。
    而Servlet在MVC模式的情况下,模型被分为:

    系统的内部状态
    可以改变状态的操作(事务逻辑)

    以下为Servlet的实现MVC框架的流程图,如图2.4:

    框架中所使用的组件:

    ActionServlet:控制器
    ActionClass:包含事务逻辑
    ActionForm:显示模块数据
    ActionMapping:帮助控制器将请求映射到操作
    ActionForward:用来指示操作转移的对象
    ActionError:用来存储和回收错误
    Servlet标记库:可以减轻开发显示层次的工作

    2.3 系统数据的介绍2.3.1 数据库的概念数据库好比是一个存放大量信息的仓库,以计算机为媒介将大量的数据长时间存放其中的一个集合体。数据库拥有集成、数量多、可分享和耐久强地特点。而数据简单地说就是对某些东西的所记录的符号,也就是说可以是简单的数字或是字母,还可以是图片或是声音都可以经过机器语言化后以数据的形式存入计算机中。
    数据库有以下特点:

    数据集成化:数据库将数据集合在一起,通过文件内部的约束机制,将本来混杂在一起的数据变得有条有理,防止了数据出现重复或着数据错乱等情况。方便了今后对于数据库的维护
    数据数量庞大性:作为众多数据的载体,其会被要求存在大量的数据,在同一时间内如果同时调用将会对存储器造成不小的负荷,要想解决这些问题必须利用移动硬盘,固态硬盘等数据存储设备来进行分担
    数据分享性强:其冗余度非常低,维护和增添新的数据将会变得非常便捷,同一个库可以对多个用户进行分享,同一时间可以处理不通的操作
    数据耐久性强:简言之就是长时间存储库中的数据

    而我们平时进行的商城中的交易,数据库的作用显得尤为重要,商城开发商将页面与后台数据库进行交互,将页面数据进行处理,完成存储等关键的行为。而数据库将这些收到的信息利用其集成化的特性将数据分门别类。而实现这些功能JSP技术就成为了这个项目的关键,其作为应用编程的接口,将页面与数据库进行连接。作为商城当访问数量过于庞大时,如果不能进行有效的处理将会出现系统瘫痪等不可预料的后果。这时,程序员利用JSP占用计算机资源少的特点对其功能进行拓展,使其在执行能力高的情况下还能提高资源的利用率。
    2.3.2 MySQL数据库简介MySQL源于瑞典的MySQL AB公司创造的,经过几次转手最终MySQL成为了Oracle公司的一员。虽然MySQL相对于大型数据库而言有许多无法与之媲美的能力,但是这并不能让其退出历史舞台,而其以功能的实用性,成本低和开源性成功占领了个人和中小企业的市场。其简单易学,维护方便,执行效率高,可兼容诸如Linux,windows这些主流平台更是使其成为了程序员不得不去学习和了解的主流数据库。
    MySQL能够有如今的成就还得益于其使用不需要支付任何费用,免费的经营手段让其用户获得了最大的收益。
    2.4 系统运行环境配置
    操作系统:Windows7、Windows10等主流系统
    CPU:最低要求能够运行Windows系统即可,如果想提高执行效率建议使用最新的CPU
    内存:建议使用500M以上的内存
    硬盘大小:建议预留100M的空间来对相关软件进行安装

    3 总体设计3.1 功能分析经过对时下大型电商网站的调查,对该系统的功能进行的大体的划分,网上零食销售系统将划分为两大管理模块。前台模块涵盖物品类别的查询,物品信息的查看,物品的订购,购物车,个人信息的修改等功能。后台模块涵盖平台中新闻的删改,商城中物品的维护,交易单的维护和注册人员的维护等模块。
    前台的具体描述如下:

    浏览商品

    商品详细资料商品编号
    订购商品
    购物车
    用户信息维护

    用户注册用户登陆用户资料修改

    后台管理具体描述如下:

    新闻管理

    添加新闻修改新闻删除新闻
    商品管理

    添加商品类别修改商品类别删除商品类别添加商品信息修改商品信息删除商品信息查看商品信息
    订单管理

    处理订单办理发货办理结帐删除订单
    友情连接

    增加友情连接删除友情连接修改友情连接
    会员管理功能

    注册用户修改用户信息删除用户信息
    系统用户管理功能

    添加系统用户修改系统用户信息删除系统用户信息

    由此可见本系统需求将获得6个完善的功能。
    以下为两个管理模块之间的关系图,如图3.1所示:

    经过反复设计之后,我需要一个系统开启前就拥有一个最初的管理员,因此我在数据库中添加了一个名为“Admin”的初始管理员方便今后的维护,他可以对网站已注册会员进行修改和调整,还可添加新的系统维护人员。
    以下为用户管理功能模块的示意图,如图3.2所示:

    3.2 系统流程分析本系统分以下两个流程:
    以下为用户交易流程图,如图3.3所示。

    以下为后台交易单管理流程图,如图3.4所示:

    3.3 数据流图以下为注册时数据流图,如图3.5所示:

    3.4 系统结构分析3.4.1 逻辑结构本系统是利用B/S三层架构作为开发的基础框架,将其以一个网页的形式展示在网络平台中,访问者可以通过网页实现商品的实时查看,实时购买,实时查看交易单等功能。而该系统可以作为各大电子商务网站的基础,拥有非常大的拓展性,能够经过程序员二次加工增加更多所需要的功能。
    以下为网站工作情况示意图,如图3.6所示:

    以下为网站物理结构示意图,如图3.7所示:

    4 数据库设计4.1 数据表的介绍该系统地数据库采用MYSQL5.0数据库,其作用是将网站中得到的数据进行存储,我将系统数据库地名字设为FOODEMARKET,其中包括9张表。以下为数据库中的数据表:
    4.1.1 messages(留言表)


    字段名
    数据类型
    是否主键
    描述




    id
    int

    id


    saver
    varchar(255)

    发布人


    savetime
    varchar(255)

    发布时间


    [content]
    varchar(255)

    发布内容


    recontent
    varchar(255)

    回复内容



    4.1.2 news(站内新闻表)


    字段名
    数据类型
    是否主键
    描述




    id
    int

    id


    title
    varchar(255)

    标题


    [content]
    text

    内容


    savetime
    varchar(255)

    保存时间


    infotype
    varchar(255)

    信息类别


    filename
    varchar(255)

    相关图片



    4.1.3 pinlun(商品评论表)


    字段名
    数据类型
    是否主键
    描述




    id
    int

    id


    saver
    varchar(255)

    发布人


    savetime
    varchar(255)

    发布时间


    [content]
    varchar(255)

    内容


    pid
    varchar(255)

    商品ID


    infotype
    varchar(255)

    信息类别



    4.1.4 pros(商品表)


    字段名
    数据类型
    是否主键
    描述




    id
    int

    id


    proshop
    varchar(255)

    卖家


    proname
    varchar(255)

    商品名称


    price
    varchar(255)

    价格


    discount
    varchar(255)

    折扣


    filename
    varchar(255)

    相关图片


    bei
    varchar(5000)

    商品说明


    extbei
    varchar(255)

    说明


    status
    varchar(255)

    状态


    savetime
    varchar(255)

    保存时间


    cjnum
    varchar(255)

    成交量



    4.1.5 proscar(购物车表)


    字段名
    数据类型
    是否主键
    描述




    id
    int

    id


    uname
    varchar(255)

    用户


    pid
    varchar(255)

    商品ID


    num
    varchar(255)

    数量



    4.1.6 prosorder(订单表)


    字段名
    数据类型
    是否主键
    描述




    id
    int

    id


    uname
    varchar(255)

    发送人


    savetime
    varchar(255)

    发送时间


    prosinfo
    varchar(1000)

    订单信息


    toshop
    varchar(255)

    卖家


    status
    varchar(255)

    订单状态


    fkstatus
    varchar(255)

    付款状态



    4.1.7 sysuser(用户表)


    字段名
    数据类型
    是否主键
    描述




    id
    int

    id


    uname
    varchar(255)

    用户名


    upass
    varchar(255)

    登录密码


    utype
    varchar(255)

    用户类别


    tname
    varchar(255)

    姓名


    sex
    varchar(255)

    性别


    age
    varchar(255)

    年龄


    tel
    varchar(255)

    联系电话


    addrs
    varchar(255)

    地址


    filename
    varchar(255)

    头像


    qq
    varchar(255)

    QQ


    bei
    varchar(255)

    说明


    savetime
    varchar(255)

    注册时间



    4.1.8 splb(商品类别表)


    字段名
    数据类型
    是否主键
    描述




    id
    int

    id


    pid
    varchar(255)

    上级类别


    lbname
    varchar(255)

    类别名称



    4.1.9 yqlj(友情链接表)


    字段名
    数据类型
    是否主键
    描述




    id
    int

    id


    ljname
    varchar(255)

    链接名称


    ljurl
    varchar(255)

    路径


    filename
    varchar(255)

    图片



    4.2 用户模块设计概述4.2.1 系统原理本系统是利用B/S三层架构作为开发的基础框架,以下为其原理图,如图4.1所示:

    网上零食销售系统的主要体系结构包括:

    数据服务器
    WEB服务器
    后台管理平台
    客户端

    影响应用系统设计的因素包括:

    业务处理方式
    数据处理量,存储量
    应用功能设计
    服务器设计
    存储设计
    安全设计

    4.2.2 用户模块的程序流程图用户模块的设计,其主要功能的程序流程图设计如图4.2所示:

    5 详细设计5.1 前台伴随着我国人民消费水平的日益提高以及网络消费的飞快普及,在购物网站上买东西已经成为时下最为流行的一种消费手段。不光如此在购物网站的发展进程中还催生了新的节日,例如双十一购物节,双十二购物节,这些节日的产生低于得益于电子商务等的蓬勃发展,商家在赚取更多资金的情况下还优惠了消费者,这种双赢的经销手段使得交易双方变的更加紧密。
    以下为网上零食销售系统的前台首页,如图5.1所示:

    首页功能涵盖游客的注册、用户的登陆、最新活动的展示、物品关键字的查询、最新物品的展示等模块。
    5.1.1 会员登录游客只有进行用户登陆后才可以正常在购物平台内进行购买物品。

    登录:登陆是建立在原本游客已经注册会员的情况下进行的,用户只需点击登陆在文本框内按照提示将自己的“用户ID”和“ID的密码”输入进去,点击提交便可完成登陆
    注册:注册是针对未在本网站进行信息填写的游客,只有对信息进行填写才可以享受到平台内作为购物者完整的消费权限。游客只需点击界面右上角“注册”,就会跳转到注册页面。游客只需在相应的文本框内按照提示将信息完善后点击“提交”,如收到“注册成功”的提示即完成注册

    代码如下:
    <form name="form" method="post" action="memberAction.do?action=1" onSubmit="return land()"><table width="80%" height="90" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td width="39%" height="20"><div align="right">用户名:</div></td> <td width="61%"><input name="name" type="text" size="13"></td> </tr> <tr> <td height="20"><div align="right">密  码:</div></td> <td><input name="password" type="password" size="13"></td> </tr> <tr align="center"> <td height="27"> </td> <td><input type="submit" name="Submit3" value="登录"></td> </tr> <tr align="center"> <td height="23"> <div align="right"> <table width="82%" height="77%" border="0" cellpadding="0" cellspacing="0"> <tr> <td bgcolor="#FFFFFF" class="linkBlack"><div align="center"><a href="member/memberRegister.jsp">注   册</a></div> </td> </tr> </table> </div></td> </tr></table></form>5.1.2 会员资料修改用户登陆后如果想对注册时的信息进行二次修改,只需点击“个人信息”,这时会跳转到用户信息修改页面。在这里你可以修改除了用户ID以外的信息,通过文本框内提示的信息即可完成,最后点击“提交”即修改成功。
    5.1.3 购买商品登陆用户需要购买商品,可以选择在首页中展示的最新上架的商品,或者用户可以在“商品一览”,“打折专区”和“销售排行”中点击自己喜欢的商品名称,在右上角选择“加入购物车”,然后进入用户中心对加入的商品进行简单的购买和付款操作,然后等待卖家发货即可。
    代码如下:
    <form method="post" action="cart_modify.jsp" name="form"> <table width="96%" border="1" align="center" cellpadding="0" cellspacing="0" bordercolor="#FFFFFF" bordercolordark="#819BBC" bordercolorlight="#FFFFFF"> <tr> <td width="16%" height="28"><div align="center">序号</div></td> <td width="23%"><div align="center">商品的名称</div></td> <td width="22%"><div align="center">商品价格</div></td> <td width="22%"><div align="center">商品数量</div></td> <td width="17%"><div align="center">总金额</div></td> </tr> <% float sum=0; Vector cart=(Vector)session.getAttribute("cart"); for(int i=0;i<cart.size();i++){ SellGoodsForm form=(SellGoodsForm)cart.elementAt(i); sum=sum+form.number*form.price; %> <tr> <td height="28"><div align="center"><%=i+1%></div></td> <td><div align="center"><%=dao.selectOneGoods(new Integer(form.ID)).getName()%></div></td> <td><div align="center"><%=form.price%>元</div></td> <td><div align="center"><input name="num<%=i%>" size="7" type="text" value="<%=form.number%>" onBlur="check(this.form)"></div></td> <td><div align="center"><%=form.number*form.price%>元</div></td> </tr> <script language="javascript"><!-- function check(myform){ if(isNaN(myform.num<%=i%>.value) || myform.num<%=i%>.value.indexOf('.',0)!=-1){ alert("请不要输入非法字符");myform.num<%=i%>.focus();return;} if(myform.num<%=i%>.value==""){ alert("请输入修改的数量");myform.num<%=i%>.focus();return;} myform.submit(); }--> </script> <%}%> </table> </form>
    作为一个合格的购物系统,用户在购买时可能需要买多个同样的商品,这时我们可以在购买时对数量进行修改或是在购物车中进行修改。
    5.1.4 查看订单用户只需进入会员页面,点击“查看订单”便可跟踪所有的交易单信息。
    5.1.5 交易记录在首页中点击“成交记录”便可查看。
    5.1.6 商城资讯在首页中点击“商城资讯”便可查看。
    5.2 后台通过 http://localhost:8080/foodemarket/login.jsp ,进入如下图5.2 所示的后台登录界面:

    在“用户名”和“密码”的文本框中输入用户名:admin,密码:123,点击“提交信息”,即可跳转到后台维护界面。在商城管理界面拥交易信息、网站信息、基础信息、系统管理和个人信息五大板块。
    以下为后台管理页面,如图5.3所示:

    5.2.1 交易信息点击“进行中的订单”,界面中将会出现实时的交易情况,在这里你可以完成对商品的监控。
    5.2.2 网站信息点击“商城介绍”、“商城资讯”、“广告图片”、“联系我们”、“商城公告”、“留言板”和“友情链接”可以对首页中这些模块信息进行修改。
    5.2.3 基础信息这里可以对买家,买家用户进行信息的管理,点击“商品管理”还可以对商城内所有正在销售的物品进行和卖家一样的操作,这里还有对商品评价和属性的管理。
    5.2.4 系统管理这里可以对管理员信息和成员的维护,点击“添加管理员”即可在出现的界面中填写信息加入新的管理员。而点击“管理员维护”则可看到现在商城内已存在的管理员信息。
    5.2.5 个人信息这里可以点击“基本资料管理”对当前的账号进行除了ID以外信息的修改,而点击“修改登陆密码”则可以更改当前账号的密码。
    5.2.6 退出后台点击右上角的“退出系统”,将会跳转到网上零食销售系统的首页。
    经过多次的测试和优化,本系统将所有模块的内容全部完成与数据库的交互,小到一个数字,大到一个图片内容完成了整个系统的整合。如果说现在的淘宝,京东等大型电子商场是一个已经羽翼丰满的老鹰,那我这个系统就是一个刚破壳而出的雏鹰,只要肯花时间去完善对其进行内容和功能上的扩展,便可缩短与它们之间的差距,成为更为可靠的购物平台。
    参考文献[1] 魏松.基于UML的学生信息管理系统的设计与实现[D].南京:南京理工大学,2010.
    [2] 云舟工作室编著.精通ASP3.0网络编程.人民邮电出版社.2001
    [3] 曹建主编.Dreamweaver与ASP实战演练.电子工业出版社.2001
    [4] Time创作室编著.office2000系列丛书Access2000.人民邮电出版社.1999
    [5] 武晓军、陈海滨编著.Javascript/VBScript网页编程实例解析.清华大学出版社.2001
    [6] [美]Greg Buczek著,王小娟、陈代川译.Access2002数据库开发即时应用.人民邮电出版社.2002
    [7] 林金霖.ASP实务经典.中国铁道出版社.2000
    [8] 使用MD5加密数据库中的用户密码 .http://www.ccw.com.cn
    [9] 刘禾,蔡锋. 精通ASP架站技巧[M]. 北京:中国青年出版社,2002.
    [10] 张海藩. 软件工程[M]. 北京:人民邮电出版社,2002.
    [11] Alberto Manuel Ricart.Active server pages 3 exploitation enchiridion[M]. 北京:电子工业出版社,2003.
    [12] Eric A.Smith Active server pages[M]. 北京:电子工业出版社,2003.
    [13] Dave Mercer.ASP 3.0 programme[M]. 北京:人民邮电出版社,2003.
    [14] 张建章. 浅谈ASP开发WEB数据库应用技术. 计算机应用系统[J],1998,9.
    [15] 龚玉清.网页设计的色彩运用. 现代教育技术[J],2003,5.
    [16] 段永红,李春海. 基于JSP的网站建设. 电脑开发与应用[J],2000,8.
    [17] 裴树军,张仁伟. 基于JSP的动态WEB技术设计. 哈尔滨理工大学学报
    [18] 杨青. JSP的主要技术特点分析. 电脑与信息技术[J],1999,4.
    [19] 曹淑琴. JSP技术的网站建设.华北科技学院学报[J],2003,1.
    [20] 吴玉新. JSP后台解决方案[M]. 北京:人民邮电出版社,2003.
    [21] 黄明,粱旭. JSP信息系统设计与开发实例[M]. 北京:机械工业出版社,2003.
    5 评论 142 下载 2020-08-03 19:00:52 下载需要13点积分
  • 基于C#实现的电影院售票管理系统

    一、引言1.1选题背景随着互联网和电子商务的快速发展,网上购物已经成了现代人生活中很重要的一种方式,如:数码产品、生活用品、化妆品护肤品等,只要是人们需要到的东西,基本都可以在网上购买。除了购买各种物品,现代人的生活也不再向过去一样单调,除了学习和工作之余,人们的娱乐生活也逐渐丰富,最普遍的娱乐休闲方式之一就是到电影院看电影,那么传统的电影订票窗口显然已经不能满足人们的需要了,所以开发一个电影院网上订票系统是非常必要和可行的。以前传统的电影票订票方法是去电影院的购票窗口查看电影的上映时间、场次、可选座位等信息再进行购票,人们往往需要排队才能买到电影票,这样不仅浪费了人们宝贵的时间,而且电影院工作人员的工作量也很大,对于这种低效率、浪费时间的事情,完全可以以网上购票的方式来改变。
    为了提高劳动的效率、节约成本、提高服务质量,我们小组开发了此款系统,用以方便影院的售票和客户的购买,通过这个系统,可以很快的实现会员注册、登录、购票,后台管理员可以新增影片、排片等基本操作。
    二、需求分析2.1 用户需求需要在网上购买电影票的用户可使用本系统,进行会员的注册登陆之后可以进行网上查询电影、购买电影票等操作,省去了去电影院实体窗口排队买票的繁 琐程序。
    2.2 系统功能分析
    新用户的注册、登录,用户数据能存在后台数据库中
    电影的录入、删除、查询、修改
    电影的排片
    管理员查询会员级别等信息
    会员查询影片信息
    会员购买电影票

    2.3 条件与限制系统可以实现一些基本的购票功能,但系统较简单,尚存在很多缺陷,不能实现完善和全面的功能。
    缺陷:

    首先要使用admin进行登录才能开始注册会员
    购票后无法查看购票信息
    不可以支持选座
    购票时不能通过搜索影片名字等来查找影片

    三、模块设计3.1 系统流程图系统流程图如图一所示:

    系统功能图如图二所示:

    3.2 系统使用指南对于用户
    首先,系统使用者先通过admin登录,进入到新用户注册页面,以管理员的身份为用户注册一个新的会员账号,已注册好的账号密码自动保存在后台数据库中,用户下次可以直接使用已注册的会员账号登录本系统进行电影的查询、购票等操作。
    对于管理员
    首先,管理员可以为新用户注册不同级别的会员账号、查看会员的信息。其次,管理员可在系统后台做电影的录入、删除、查询、修改等基本操作,除此之外,添加好影片后可以对电影进行的排片。
    四、数据库设计及实现4.1 系统E-R图E-R图如图三所示:

    4.2 逻辑结构设计(关系数据库设计)
    顾客(Cus、CusCard、CusType、CusTel(key))
    登陆(UserName、UsePwd、UserType)
    电影(Mname(key)、MBZ、MLanguage、MTYPE、MDirector、MACT、MTime)
    排片(MName(key)、MPrice、MRoom、Mcount、MTime、MBRQ、MERQ)
    上映(ID(key)、MName、MPrice、MRoom、MCount、MTime、MRQ)
    购票(PID(key)、Cname、GPCount、GPJE、MName、SYRQ、FYT、GPRQ、CZY)

    4.3 数据库主要代码及触发器会员信息
    CREATE TABLE [dbo].[Cus]( [CusTel] VARCHAR(50) NOT NULL PRIMARY KEY, [CusName] VARCHAR(50) NOT NULL, [CusCard] VARCHAR(50) NULL, [CusType] VARCHAR(50) NULL)
    触发器
    SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER TRIGGER [dbo].[InsertULogin] on [dbo].[Cus]after insertasdeclare @username varchar(50)declare @userpwd varchar(50)select @username=CusTel from inserted select @userpwd= right(CusCard,6) from inserted insert into ULogin values(@username,@userpwd,'C')
    购票信息
    CREATE TABLE [dbo].[GP]( [PID] VARCHAR(50) NOT NULL PRIMARY KEY, [CName] VARCHAR(50) NOT NULL, [GPCount] INT NULL, [GPJE] FLOAT NULL, [MName] VARCHAR(50) NULL, [SYRQ] VARCHAR(50) NULL, [GPRQ] VARCHAR(50) NULL, [CZY] VARCHAR(50) NULL, [FYT] VARCHAR(50) NULL)
    触发器
    SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER TRIGGER [dbo].[UpdatePP] on [dbo].[GP]after insertasdeclare @MName varchar(50)declare @SYRQ varchar(50)declare @count intselect @MName= MName,@SYRQ=SYRQ,@count=GPCount from inserted update MovieSY set mcount=mcount-@count where MName=@MName and MRQ=@SYRQ
    电影信息
    CREATE TABLE [dbo].[Movie]( [MName] VARCHAR(50) NOT NULL PRIMARY KEY, [MLanguage] VARCHAR(50) NOT NULL, [MDirector] VARCHAR(50) NULL, [MAct] VARCHAR(50) NULL, [MName] INT NULL, [MBZ] VARCHAR(255) NULL, [MType] VARCHAR(50) NULL)
    上映信息
    CREATE TABLE [dbo].[MovieSY]( [ID] INT NOT NULL PRIMARY KEY, [MName] VARCHAR(50) NOT NULL, [MRoom] INT NULL, [MCount] varchar(50) NULL, [MName] INT NULL, [MTime] VARCHAR(50) NULL, [MRQ] VARCHAR(50) NULL)
    排片信息
    CREATE TABLE [dbo].[PP]( [MName] VARCHAR(50) NOT NULL PRIMARY KEY, [MPrice] INT NOT NULL, [MRoom] VARCHAR(50) NULL, [MCount] INT NULL, [MTime] VARCHAR(50) NULL, [MBRQ] VARCHAR(50) NULL, [MERQ] VARCHAR(50) NULL)
    触发器
    SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER TRIGGER [dbo].[InsertPP] on [dbo].[PP]after insertasdeclare @MName varchar(50)declare @BRQ varchar(50)declare @ERQ varchar(50)declare @MTime varchar(50)declare @MRoom varchar(50)declare @MPrice intdeclare @MCount intdeclare @MBRQ datetimedeclare @MERQ datetimedeclare @RQ varchar(50)select @MName= MName,@BRQ=MBRQ,@ERQ=MERQ,@MTime=MTime,@MRoom=MRoom,@MPrice=MPrice, @MCount=MCount from inserted set @MBRQ=CONVERT (datetime,@BRQ)set @MERQ=CONVERT (datetime,@ERQ)while @MBRQ<=@MERQbegin set @rq=CONVERT(varchar(50), @MBRQ, 112)insert into MovieSY values(@MName,@MPrice,@MRoom,@MCount,@MTime,@RQ) set @MBRQ=DATEADD(DAY,1,@MBRQ)endCREATE TABLE [dbo].[MovieSY]( [UserName] VARCHAR(50) NOT NULL PRIMARY KEY, [UserPwd] VARCHAR(50) NOT NULL, [UserType] VARCHAR(50) NULL)
    五、系统设计与实现5.1系统开发环境
    硬件环境

    Intel Pentium 166MHz或以上;内存:需要至少512MHZ;
    软件环境

    运行于Windows2010版的操作系统之上;SQL Server2008数据库;Visual Studio2013;

    5.2 功能模块
    输入功能模块
    查询显示功能模块
    查询、售票功能模块
    登录、注册功能模块

    5.3 系统主要页面展示登录、注册页面

    登陆后的页面

    会员注册页面

    会员信息查询页面

    添加影片页面

    查询修改影片页面

    排片页面

    “排片”页面通过连接数据库,可以搜索影片的名字、导演、主演来选择影片,再输入票价,放映大厅,座位数,放映时间等信息,最后确认排片。
    购票页面

    购票页面通过对获得的已经被排片的电影进行选择而进行购票这一操作。在购票前需填入购票数量、联系电话,系统会自动计算合计金额。之后点击购票按钮则能进行购票操作。但一旦购票成功则不能进行退票操作,也不能查看所购买的电影票。
    数据库页面

    六、主要特色6.1 系统实用性系统首先可以进行新用户的注册,用户数据能存在后台数据库中。管理员可以进行电影的录入、删除、查询、修改,添加好影片后进行电影的排片。退出登录后再使用之前注册的会员登录,可以购买电影票。
    6.2 突出优势和特色(创新点)
    购票时可以看到影片的导演、主演等信息
    用户分为钻石用户,白金用户和普通用户,对用户进行了分类

    7 小结数据库技术课程设计是一次对课堂所学知识的灵活应用,是理论知识与实践的相结合。经过了一周的课程设计,本系统基本达到了当初的设计要求,设计上也基本合理。我们不仅对数据库系统的认识更加深入,同时也掌握了面向实体的系统分析的基本方法,对VS也有了新的认识,也知道了要有坚持不懈,不惧困难的精神,才能取得成功。一个简单的系统,每一个细节都需要在实践中去挖掘并进行进一步的修改完善。本次课设让我们受益匪浅,在分析问题以及解决问题等方面的能力有所提高,也是一次很好的同学之间交流合作的机会。数据库技术的用途很广,还有很多值得我们学习,希望今后能有更多这样的机会。
    34 评论 400 下载 2019-01-01 21:08:08 下载需要15点积分
  • 基于linux C语言实现的扫雷游戏

    数据定义雷区大小为 10x10,雷的数量是 10
    #define MINEAREA_WIDTH 10 //纵向#define MINEAREA_LENGTH 10 //横向#define MINE_NUMBER 10
    将每个方块的状态分类:

    初始状态判定为雷(也就是通常的插旗)排除(若周边有 n 个雷则显示为 n,0 则显示为空,用 -1 来表示雷)
    #define SQUARE_INIT 0#define SQUARE_FLAG 1#define SQUARE_CLEAN 2#define SQUARE_ZERO 0#define SQUARE_MINE -1
    显示图形
    #define GRAPH_INIT '.'#define GRAPH_MINE '@'#define GRAPH_NULL ' '#define GRAPH_FLAG 'F'
    初始化雷区信息int init_mine(struct square_t square[MINEAREA_WIDTH][MINEAREA_LENGTH])
    将每个格子的类型和地雷数初始化为 0
    for (n = 0; n < MINEAREA_WIDTH; ++n) { for (m = 0; m < MINEAREA_LENGTH; ++m) { square[n][m].type = 0; square[n][m].mine = 0; }}
    对周围的格子显示的其周围地雷数加 1
    for (i = 0; i < MINE_NUMBER; ++i) { x = random() % MINEAREA_LENGTH; y = random() % MINEAREA_WIDTH; if (square[y][x].mine == SQUARE_MINE) { --i; } else { square[y][x].mine = SQUARE_MINE; //把周围的mine加1 if (check_yx(y-1, x ) == 0 && square[y-1][x ].mine != SQUARE_MINE) ++square[y-1][x ].mine; if (check_yx(y+1, x ) == 0 && square[y+1][x ].mine != SQUARE_MINE) ++square[y+1][x ].mine;
    界面初始化操作清屏,关闭特殊字符,关闭回显,启用 keypad 模式,光标不可见等:
    int win_init(int width, int length, int mine_num){ //初始化为curses 模式,用来清除屏幕上所有的字符 initscr(); //关闭特殊字符处理 raw(); //关闭回显模式 noecho(); //启用keypad模式。此时读键盘操作能够返回 用户在按下逻辑键时对应的KEY_定义 keypad(stdscr, TRUE); //光标不可见 curs_set(0); //刷新物理屏幕 refresh();
    用for循环,对没一行进行规则输出图标,两个空格大小为一格:
    for (j = 0; j < frame_width - 2; ++j) { addch('|'); for (i = 0; i < length * 2 + 1 - 2; ++i) { if (j % 2 == 0) { if (i % 2 == 0) { addch(GRAPH_INIT);addch(' '); } else { addch('|'); } } else { if (i % 2 == 0) { addch('-');addch('-'); } else { addch('+'); } } } addch('|');NEWLINE;}printw(line);NEWLINE;SET_CURSOR(g_cur_y, g_cur_x);refresh();
    主循环int game_loop(struct square_t square[MINEAREA_WIDTH][MINEAREA_LENGTH])
    switch…case对键盘的输入进行判定,方向键进行移动和‘z’翻开格子,’x’标记格子,‘q’退出while循环:
    switch (input = getch()) { case KEY_UP: win_mv_cursor(-1, 0, MINEAREA_WIDTH, MINEAREA_LENGTH); break;
    在对格子的操作中进行游戏的其它判定

    初始状态的格子被插旗
    已经插旗了的旗子又被插旗操作

    case 'x': if (square[g_cur_y][g_cur_x].type == SQUARE_INIT) { square[g_cur_y][g_cur_x].type = SQUARE_FLAG; --remain_mines; if (square[g_cur_y][g_cur_x].mine == SQUARE_MINE) ++sweeped_mines; } else if (square[g_cur_y][g_cur_x].type == SQUARE_FLAG) { square[g_cur_y][g_cur_x].type = SQUARE_INIT; ++remain_mines; if (square[g_cur_y][g_cur_x].mine == SQUARE_MINE) --sweeped_mines; } else break; if (sweeped_mines == MINE_NUMBER) { win_win(); goto GAME_OVER; } win_refresh(square, MINEAREA_WIDTH, MINEAREA_LENGTH, remain_mines); break;
    空白格子周围相同的清零操作
    int clean_zero_squares(struct square_t square[MINEAREA_WIDTH][MINEAREA_LENGTH], int cur_y, int cur_x){ if (check_yx(cur_y - 1, cur_x) == 0 && square[cur_y - 1][cur_x].mine == SQUARE_ZERO && square[cur_y - 1][cur_x].type != SQUARE_CLEAN) { square[cur_y - 1][cur_x].type = SQUARE_CLEAN; clean_zero_squares(square, cur_y - 1, cur_x); } if (check_yx(cur_y + 1, cur_x) == 0 && square[cur_y + 1][cur_x].mine == SQUARE_ZERO && square[cur_y + 1][cur_x].type != SQUARE_CLEAN) { square[cur_y + 1][cur_x].type = SQUARE_CLEAN; clean_zero_squares(square, cur_y + 1, cur_x); }
    刷新界面
    将对应的格子地雷数量所对应的状态转换成对应的图形:
    int win_refresh(struct square_t square[MINEAREA_WIDTH][MINEAREA_LENGTH], int width, int length, int mines){ if (square == NULL) return -1; win_refresh_remine_mines(mines); int j, i; for (j = 0; j < width; ++j) { for (i = 0; i < length; ++i) { switch (square[j][i].type) { case SQUARE_INIT: WPRINT_CHAR(_W(j), _L(i), GRAPH_INIT); break; case SQUARE_FLAG: WPRINT_CHAR(_W(j), _L(i), GRAPH_FLAG); break;
    编译和执行
    效果展示游戏开始界面

    游戏进行时

    踩到雷了

    游戏胜利
    1 评论 1 下载 2021-08-04 10:55:41 下载需要10点积分
  • 基于Python实现的简单生命游戏

    一、引言1.1 开发背景康威生命游戏,又称康威生命棋,是英国数学家约翰•何顿•康威在1970年发明的细胞自动机。 它最初于1970年10月在《科学美国人》杂志上马丁•葛登能的“数学游戏”专栏出现。在游戏的进行中,杂乱无序的细胞会逐渐演化出各种精致、有形的结构;这些结构往往有很好的对称性,而且每一代都在变化形状。一些形状已经锁定,不会逐代变化。有时,一些已经成形的结构会因为一些无序细胞的“入侵”而被破坏。但是形状和秩序经常能从杂乱中产生出来。对于生成的形状和秩序我们称作 pattern。或者在这里,我们也把它称作 creature。“生命游戏”并不是通常意义上的游戏,它没有游戏玩家之间的竞争,也谈不上输赢,甚至可以说游戏的一开始就注定了结果。
    1.2 开发目的和意义本游戏是小组共同开发的课程设计项目,实现了基础的康威生命游戏规则,能够模拟生命繁殖演化的基本过程,实现了必要的图形界面。
    开发生命游戏,让“仿真生物”生存于计算机上,在计算机上生存、死亡,从而模拟生命的演化,通过计算机的模拟,了解生命在一定规则下,开始条件对最终结果的影响,突发事件对最终结果的影响。
    二、需求分析2.1 设计内容和要求制作用户图形界面,使得游戏在运行时,用户能在图形界面上进行操作和直观的看到演化过程与结果。
    按钮,开始、暂停、重置,用来控制繁衍进程。
    用户界面的要求:一个N*N的二维格子界面和对应开始、暂停、重置的按钮,每一个格子代表一个生命,亮为生、暗为死,每一次格子的生与死都显示在屏幕上。
    一个细胞在下一个时刻生死取决于相邻八个方格中活着的或死了的细胞的数量。用代码实现生命游戏中的规则,通过算法控制,计算格子在每一刻的生死状态。
    使用鼠标添加或删去细胞。
    添加游戏说明,方便用户使用。
    2.2 技术上的可行性分析2.2.1 游戏功能在一个二维矩形世界中,每个方格里居住着一个活着的或死了的细胞,每个细胞有两种状态-存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动。
    一个细胞在下一个时刻生死取决于相邻八个方格中活着的或死了的细胞的数量,模拟生命繁衍。
    可以通过按钮控制繁衍进程,使用鼠标添加或删去细胞。
    2.2.2 游戏规则
    人口过少:当周围低于2个(不包含2个)存活细胞时, 本单元活细胞死亡
    稳定:当周围有2个或3个存活细胞时, 本单元细胞保持原样
    人口过剩:当周围有3个以上的存活细胞时,本单元活细胞死亡
    繁殖:当周围有3个存活细胞时,本单元细胞存活/活化

    2.2.3 游戏界面
    背景世界地图为黑色,画有灰白的网格线,作为各细胞间的分界
    单个活细胞为矩形,红色,死亡细胞为黑色,构成背景
    地图右侧放置按钮,开始、暂停、重置,用来控制繁衍进程
    添加游戏说明,方便用户使用

    经查阅资料并进行分析,利用python及其标准化的库,可以实现我们的设计要求
    2.3 开发环境与工具使用
    操作系统:Windows
    开发工具:PyCharm Community Editon 2016.1.3、Java Pydev
    开发语言:Python
    编码方式:UTF-8
    团队管理工具:leangoo
    版本控制工具:Git
    自动单元测试框架:pyunit
    性能分析:profile
    代码检查:pylint

    三、总体设计3.1 总体结构
    3.2 各功能模块描述
    Button :定义按钮的图像以及具体的位置
    Cell:定义细胞类,包括细胞的大小和颜色,获取细胞位置在画布上绘制细胞
    Data:画布,以及程序相关的具体的数据
    Draw:将画布擦除后,画上按钮,格子以及具体的网格线,然后遍历网格数组中的细胞状态
    next_generation:定义细胞更新的规则:当一个细胞周围有两个或三个细胞时细胞状态为存活,当周围细胞过多或者过少时定义为细胞死亡
    States:将整个游戏世界设定为二维数组,每个网格的状态值分为0,1两种,定义按钮功能,含开始运行、暂停、重置三个方法

    开始运行:获取当前鼠标的状态和位置随时更新画布,并且根据细胞规则随时更新细胞暂停:根据鼠标状态随时更新画布重置:初始化整个画布,数组用0填充
    main:程序的开始入口,设置界面的大小,定义状态机的三种状态:运行状态,暂停状态,以及重置,然后进入游戏的主循环

    3.3 主要模块设计状态机三种状态的设置:开始,暂停,以及重置,主要在States模块中实现:

    States:将整个游戏世界设定为二维数组,每个网格的状态值分为0,1两种,定义按钮功能,含开始运行、暂停、重置三个方法

    开始运行:获取当前鼠标的状态和位置随时更新画布,并且根据细胞规则随时更新细胞
    暂停:根据鼠标状态随时更新画布
    重置:初始化整个画布,数组用0填充


    3.4 核心代码设计next_generation:细胞规则的制定是核心代码的一部分,具体设计。遍历二维数组,更新接下来各个细胞的状态:
    def next_generation(): nbrs_count = sum(np.roll(np.roll(pygame.world, i, 0), j, 1) for i in (-1, 0, 1) for j in (-1, 0, 1) if (i != 0 or j != 0)) pygame.world = (nbrs_count == 3) | ((pygame.world == 1) & (nbrs_count == 2)).astype('int')
    四、测试分析4.1 游戏开始测试测试点击开始按钮游戏界面立即作出响应,并且可以按照细胞规则进行正确的更新。
    4.2 游戏重置测试点击重置按钮,程序立即作出响应,并且画布被擦除。
    4.3 使用工具进行分析测试
    自动单元测试框架:pyunit
    性能分析:profile
    代码检查:pylint

    分析测试细节详情请见对应的工具使用文档。
    五、具体的使用说明
    打开程序,出现游戏界面
    在界面上选择点击相应格子,左键添加细胞,右键擦除细胞
    点击开始,程序自动运行,最终在界面上显示结果,或为一有各个格子组成的特殊图形,或一直杂乱的进行演化
    也可在任意时刻点击暂停按钮,查看到这一时刻生命游戏在一定规则下生成的结果
    玩家可以随时在画布上添加或者擦除细胞
    点击重置按钮可以清空画布,重新来过

    运行截图演示:




    2 评论 91 下载 2018-11-06 09:56:14 下载需要9点积分
  • 基于QT与mplayer的视频播放器

    一、课题的介绍和课题的任务1.1 课题的介绍本次课程设计我选的题目是视频播放器。目前市场上各种应用商店上有各种播放器,而且功能都很强大。一直对里面的具体实现有兴趣,所以这次就尝试着写了个视频播放器。并且加进去了一些很实用的功能,比如截屏和录屏。
    1.2 课题的任务包括视频的播放暂停、音量的加减、播放速度的设置、以及视频文件的添加删除、屏幕的截屏以及录屏。画面不卡顿。播放时进度条能刷新。
    二、设计的要求
    能进行视频的播放
    能暂停正在播放的视频
    能播放正在暂停的视频
    能调节视频播放的视频
    能进行视频播放进度的调节
    能停止正在播放的视频
    能添加新的视频文件到播放列表
    能删除播放列表中选中的视频
    能改变视频播放的速度
    能对正在播放的视频进行截屏
    能录制正在播放的视频

    三、系统的分析和系统中类的设计
    窗口类QMainWidndow
    按钮类QPushButton
    标签类QLabel
    列表类QList
    滑动条类QSilider
    显示类QWidge

    四、系统的实现及调试系统模块框架图

    程序具体实现
    4.1 添加文件进视频播放列表
    代码实现:
    void mplayer_video::on_open_clicked(){ QStringList filenames =QFileDialog::getOpenFileNames(this,tr("选择文件"),"/",tr("视频文件(*mp3 *mp4 *wma *3gp *wav *avi *flv *rmvb *mkv *ts *wmv)")); // *号和前面的要隔开至少一个空格,不能连起来。 if(filenames.count()!=0) ui->list->addItems(filenames);}
    4.2 双击列表选项进行播放
    代码实现:
    void mplayer_video::on_list_itemDoubleClicked(QListWidgetItem *item){ speed=1; ui->lupin_lable->setVisible(false); play(item->text());}void mplayer_video::play(QString fileName){ QStringList arg1; process->kill(); process=new QProcess(this); arg1 << fileName; arg1 << "-slave";//默认情况下,mplayer接受键盘的命令,而"-slave"使其不再接受键盘事件,而是作为后台程序运行, //接受以“\n”结束的命令控制,这样我们可以在进程中给他发送命令,而不需要操作键盘了. arg1 << "-quiet"; //尽可能的不打印播放信息 arg1 << "-zoom"; //视频居中,四周黑条,全屏播放 arg1 << "-wid" << QString::number((unsigned int)(ui->widget->winId())); // "-wid <窗口标识>" 是指让MPlayer依附于那个窗口, //ui->widget->winId() 这个指令就是用来获取widget的标识码 , //这样视频播放的时候,就在这个部件里播放,相当于给他固定起来。 connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataRecieve())); process->start(arg,arg1); //开始播放进程 ui->zanting->setText("暂停");}void mplayer_video::dataRecieve(){ process->write("get_time_length\n"); process->write("get_time_pos\n"); process->write("get_percent_pos\n"); while(process->canReadLine()) { QByteArray b=process->readLine(); if(b.startsWith("ANS_TIME_POSITION")) { b.replace(QByteArray("\n"),QByteArray("")); QString s(b); currentStr=s.mid(18); ui->horizontalSlider->setValue(s.mid(18).toFloat()); //更新进度条 } else if((b.startsWith("ANS_LENGTH"))) { b.replace(QByteArray("\n"),QByteArray("")); QString s(b); totalTime=s.mid(11); ui->label_time->setText(currentStr+"秒/"+totalTime+"秒 "); //显示时间进度 ui->horizontalSlider->setRange(0,s.mid(11).toFloat()); } else if((b.startsWith("ANS_PERCENT_POSITION"))) { b.replace(QByteArray("\n"),QByteArray("")); QString s(b); currentPercent=s.mid(21); ui->percentLabel->setText(currentPercent+"%"); } }}
    4.3 播放与暂停的实现
    代码实现:
    void mplayer_video::on_zanting_clicked(){ ui->lupin_lable->setVisible(false); process->write("pause\n"); //ui->list->currentRow()!=-1 判断是否有选中某条数据 //play(ui->list->item(ui->list->currentRow())->text()); 播放选中的某条数据 if(ui->zanting->text()=="播放") { if(ui->list->count()==0) QMessageBox::warning(this,"提示","播放列表为空",QMessageBox::Yes); else { connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataRecieve())); process->write("get_time_length\n"); process->write("get_time_pos\n"); process->write("get_percent_pos\n"); ui->zanting->setText("暂停"); } } else { disconnect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataRecieve())); ui->zanting->setText("播放"); }}
    4.4 快进与回退代码实现:
    void mplayer_video::on_back_clicked(){ process->write("seek -10\n");}void mplayer_video::on_quick_clicked(){ process->write("seek +10\n");}
    4.5 加速与减速代码实现:
    void mplayer_video::on_back_clicked(){ process->write("seek -10\n");}void mplayer_video::on_quick_clicked(){ process->write("seek +10\n");}
    4.6 停止播放代码实现:
    void mplayer_video::on_stop_clicked(){ process->write("quit\n"); ui->horizontalSlider->setSliderPosition(0); ui->label_time->clear(); ui->percentLabel->clear(); ui->zanting->setText("播放");}
    4.7 从播放列表中删除中选中的视频
    代码实现:
    void mplayer_video::on_del_clicked(){ if(ui->list->currentRow()==-1) QMessageBox::warning(this,"提示","未选中项目或列表为空",QMessageBox::Yes); else { ui->list->takeItem(ui->list->currentRow()); process->close(); ui->horizontalSlider->setSliderPosition(0); //更新进度条 ui->label_time->clear(); ui->percentLabel->clear(); }}
    4.8 加速播放与减速播放
    代码实现:
    定义一个全局静态浮点型变量 speed并初始化为1,每次点击加速,speed的值乘以二,每次点击减速,speed的值除以2
    void mplayer_video::on_jiansu_clicked(){ speed=speed/2; process->write(QString("speed_set "+QString::number(speed)+" 2\n").toUtf8());}void mplayer_video::on_jiasu_clicked(){ speed=speed*2; process->write(QString("speed_set "+QString::number(speed)+" 2\n").toUtf8());}
    4.9 视频播放进度条的刷新这是本程序里最复杂的部分之一。
    主要实现是用connect函数链接进程与DataRecieve函数
    代码实现:
    void mplayer_video::dataRecieve(){ process->write("get_time_length\n"); process->write("get_time_pos\n"); process->write("get_percent_pos\n"); while(process->canReadLine()) { QByteArray b=process->readLine(); if(b.startsWith("ANS_TIME_POSITION")) { b.replace(QByteArray("\n"),QByteArray("")); QString s(b); currentStr=s.mid(18); ui->horizontalSlider->setValue(s.mid(18).toFloat()); //更新进度条 } else if((b.startsWith("ANS_LENGTH"))) { b.replace(QByteArray("\n"),QByteArray("")); QString s(b); totalTime=s.mid(11); ui->label_time->setText(currentStr+"秒/"+totalTime+"秒 "); //显示时间进度 ui->horizontalSlider->setRange(0,s.mid(11).toFloat()); } else if((b.startsWith("ANS_PERCENT_POSITION"))) { b.replace(QByteArray("\n"),QByteArray("")); QString s(b); currentPercent=s.mid(21); ui->percentLabel->setText(currentPercent+"%"); } }}
    4.10 声音滑动条对声音的调节
    代码实现:
    void mplayer_video::on_voice_slider_sliderMoved(int v){ if(ui->zanting->text()=="播放") { process->write(QString("volume "+QString::number(v)+" 2\n").toUtf8()); process->write("pause\n"); } else{ process->write(QString("volume "+QString::number(v)+" 2\n").toUtf8()); }}
    4.11 设置图片按钮
    代码实现:
    QPixmap pixmap; pixmap.load("G:/mplayer_video/voice.jpg"); ui->voice->setFixedSize(pixmap.width(),pixmap.height()); ui->voice->setIcon(pixmap); ui->voice->setIconSize(QSize(pixmap.width(),pixmap.height())); ui->voice->setToolTip("音量"); ui->voice->show();
    4.12 屏幕截图
    代码实现:
    void mplayer_video::on_jietu_clicked(){ cout<<"ok"<<endl; process->write("pause\n"); if(ui->zanting->text()=="播放") { cout<<"1"<<endl; QPixmap snapImage = QPixmap::grabWindow(QApplication::desktop()->winId()); QString filename; QString slcStr; filename = QFileDialog::getSaveFileName(this,tr("保存图片"),"./未命名",tr("PNG(*.png);;JPG(*.jpg);;BMP(*.bmp)"),&slcStr);//弹出保存图片的文件窗口 if(slcStr.left(3)=="JPG") { if(filename.right(3)!="jpg") { filename+=".jpg"; } } if(slcStr.left(3)=="PNG") { if(filename.right(3)!="png") { filename+=".png"; } } if(slcStr.left(3)=="BMP") { if(filename.right(3)!="bmp") { filename+=".bmp"; } } if(filename!=NULL) { snapImage.save(filename); } } else { cout<<"2"<<endl; disconnect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataRecieve())); ui->zanting->setText("播放"); QPixmap snapImage = QPixmap::grabWindow(QApplication::desktop()->winId()); QString filename; QString slcStr; filename = QFileDialog::getSaveFileName(this,tr("保存图片"),"./未命名",tr("PNG(*.png);;JPG(*.jpg);;BMP(*.bmp)"),&slcStr);//弹出保存图片的文件窗口 if(slcStr.left(3)=="JPG") { if(filename.right(3)!="jpg") { filename+=".jpg"; } } if(slcStr.left(3)=="PNG") { if(filename.right(3)!="png") { filename+=".png"; } } if(slcStr.left(3)=="BMP") { if(filename.right(3)!="bmp") { filename+=".bmp"; } } if(filename!=NULL) { snapImage.save(filename); } connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataRecieve())); process->write("get_time_length\n"); process->write("get_time_pos\n"); process->write("get_percent_pos\n"); ui->zanting->setText("暂停"); }}
    4.13 屏幕录制代码实现:
    void mplayer_video::on_lupin_clicked(){ if(ui->lupin->text()=="录屏") { photoStart(); timer->start(50); ui->lupin->setText("停止"); } else { timer->stop(); ui->lupin->setText("录屏"); }}void mplayer_video::photoStart(){ QDir *d = new QDir(); QString dirName("D:\\video"); if(!d->exists(dirName)) { d->mkdir(dirName); }}void mplayer_video::timerUpdate(){ QPixmap p; QString dirNamee("D:\\video\\"); dirNamee=dirNamee+QString::number(number)+".jpg"; p = QPixmap::grabWindow(QApplication::desktop()->winId()); p.save(dirNamee); number+=1;}
    4.14 屏幕录屏播放代码实现:
    void mplayer_video::on_lupinstart_clicked(){ process->write("quit\n"); QString dirName("D:\\video"); qdir = new QDir(dirName); qdir->setSorting(QDir::Reversed|QDir::Time); list = qdir->entryInfoList(); number2=0; timer2->start(100);}void mplayer_video::on_stop_bofang_clicked(){ timer2->stop(); ui->lupin_lable->setVisible(false);}
    五、系统的使用说明打开程序,点击添加文件进行视频播放列表视频的添加。双击列表中某条记录进行视频的播放,播放按钮自动转换成暂停按钮。点击播放将会播放视频,点击暂停视频会暂停。除了一些视频播放器的基本功能外,本程序还加入了屏幕截图与屏幕录制的功能。具体操作用按钮可以实现。
    11 评论 271 下载 2018-11-15 11:09:18 下载需要10点积分
  • 基于Java实现的飞机大战小游戏

    1.实作项目简介本项目是一款简单的飞机大战小游戏,程序使用Eclipse开发。
    2.项目设计2.1 总体架构设计
    2.2 类设计com.controller包

    com.element包

    com.manager包

    com.show包

    2.3 基本功能
    玩家飞机有四种不同外型的飞机可选择
    通过键盘上下左右键控制飞机的移动
    游戏中敌机在界面上方随机出现,自动发射子弹,并且从上到下垂直方向移动,到达边界自动消失
    Boss飞机在界面上方水平方向随机移动,并且发射子弹的速度大于普通敌机发射子弹的速度
    爆炸效果,敌机与Boss机被玩家击中,玩家被敌机子弹击中,玩家与敌机碰撞均有爆炸效果
    游戏中的道具有血包和护盾两类,血包可为玩家提供一滴血,护盾可为玩家抵挡3颗子弹,并且只持续5秒钟
    玩家的血量上限是10

    3.系统实现3.1 界面GameHomePanel类
    public class GameHomePanel extends JPanel{ private JButton startGameButton = null; private JButton setPalyerButton = null; private ImageIcon backImg = null; public GameHomePanel() { init(); } public void init() { GameLoad.loadImg(); this.startGameButton = new JButton(); this.backImg = GameLoad.imgMap.get("homeimg"); Image img = this.backImg.getImage().getScaledInstance(GameJFrame.GameX, GameJFrame.GameY, Image.SCALE_SMOOTH); this.backImg = new ImageIcon(img); this.startGameButton.setIcon(new ImageIcon("image/startgame.png")); this.startGameButton.setBounds(GameJFrame.GameX / 10 * 3, GameJFrame.GameY / 7 * 5, GameJFrame.GameX / 10 * 4, 80); this.startGameButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO 自动生成的方法存根 GameStart.changePage("game"); } }); this.startGameButton.setBorderPainted(false); this.startGameButton.setBackground(new Color(92, 152, 183)); this.startGameButton.setFocusPainted(false);// this.startGameButton.setContentAreaFilled(false); this.add(this.startGameButton); this.setPalyerButton = new JButton("设置"); this.setPalyerButton.setFont(new Font("Courier", Font.BOLD, 26)); this.setPalyerButton.setForeground(new Color(253, 255, 205)); this.setPalyerButton.setBounds(GameJFrame.GameX / 10 * 3 + 50, GameJFrame.GameY / 7 * 5 + 100, GameJFrame.GameX / 10 * 2, 50); this.setPalyerButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO 自动生成的方法存根 new GameDialog(GameStart.gj, "Set"); } }); this.setPalyerButton.setBorderPainted(false); this.setPalyerButton.setBackground(new Color(92, 152, 183)); this.setPalyerButton.setFocusPainted(false); this.add(this.setPalyerButton); this.setLayout(null); this.setVisible(true);// System.out.println("home"); } @Override public void paint(Graphics g) { // TODO 自动生成的方法存根 super.paint(g); g.drawImage(this.backImg.getImage(), 0, 0, null); g.drawImage(new ImageIcon("image/planemenu.png").getImage(), 90, 0, null); }}
    GameJFrame类
    public class GameJFrame extends JFrame{ public final static int GameX = 600; public final static int GameY = 900; private JPanel jPanel = null; //正在显示的面板 private KeyListener keyListener = null; //键盘监听 private Thread thead = null; //游戏主线程 private JMenuBar menuBar = null; //菜单栏 public GameJFrame() { init(); } public void init() { this.setSize(GameX, GameY); //设置窗体大小 this.setTitle("飞机大战"); this.initJMenuBar(); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLocationRelativeTo(null); //屏幕居中显示 } protected void initJMenuBar() { this.menuBar = new JMenuBar(); this.setJMenuBar(this.menuBar); JMenu menu1 = new JMenu("菜单"); this.menuBar.add(menu1); JMenuItem item1 = new JMenuItem("开始游戏"); menu1.add(item1); menu1.addSeparator(); JMenuItem item2 = new JMenuItem("重新开始"); menu1.add(item2); menu1.addSeparator(); JMenuItem item3 = new JMenuItem("游戏玩法"); menu1.add(item3); item2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(GameJFrame.this.jPanel instanceof GameMainJPanel) reStartGame(); } }); item3.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO 自动生成的方法存根 new GameDialog(GameJFrame.this, "HowToPlay"); } }); } public void changePanel(JPanel jpt) { if(this.jPanel != null) this.remove(this.jPanel); this.jPanel = jpt; } /** * @显示启动界面 */ public void showHomePage() { if(this.jPanel != null) this.add(this.jPanel); if(this.jPanel instanceof Runnable) { new Thread((Runnable) this.jPanel).start(); } this.setVisible(true); } /** * 启动方法 */ public void startGame() { GameThread.reSetAllTime(); if(this.jPanel != null) this.add(this.jPanel); if(this.thead == null) this.thead = new GameThread(); this.thead.start(); //启动游戏主线程 if(this.keyListener == null) this.keyListener = new GameListener(); this.addKeyListener(this.keyListener);// this.setVisible(true); if(this.jPanel instanceof Runnable) { new Thread((Runnable)this.jPanel).start(); } System.out.println("startGame: " + Thread.activeCount()); } public void reStartGame() { System.out.println("reStartGame: " + Thread.activeCount()); this.EndGame(); this.jPanel = new GameMainJPanel();// System.out.println("reStart");// System.out.println(((GameThread)this.thead).isInterrupted()); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } this.startGame(); this.reFalsh(); } public void EndGame() { //结束run方法,停止相关线程 ((GameMainJPanel)this.jPanel).panelIsRunning = false; ((GameThread)this.thead).stopGameThread = true; ((GameThread)this.thead).isRunning = false; this.remove(this.jPanel); this.removeKeyListener(this.keyListener); this.jPanel = null; this.keyListener = null; this.thead = null; } public void reFalsh() { this.setVisible(false); this.setVisible(true); } public void addListener() { if(this.keyListener != null) this.addKeyListener(this.keyListener); } public void removeListener() { this.removeKeyListener(this.keyListener); } public void setjPanel(JPanel jPanel) { this.jPanel = jPanel; } public void setKeyListener(KeyListener keyListener) { this.keyListener = keyListener; } public void setThead(Thread thead) { this.thead = thead; }}
    GameMainJPanel类
    /** * @说明 游戏的主要面板 * @功能说明 主要进行元素的显示,同时进行界面的刷新(多线程) * * @多线程刷新 1.本类实现线程接口 */public class GameMainJPanel extends JPanel implements Runnable{// 联动管理器 private ElementManager em; public boolean panelIsRunning = true; public GameMainJPanel() { init(); } public void init() { em = ElementManager.getManager();//得到元素管理器对象 } @Override public void paint(Graphics g) { super.paint(g); Map<GameElement, List<ElementObj>> all = em.getGameElements(); for(GameElement ge : GameElement.values()) { List<ElementObj> list = all.get(ge); for(int i=0; i<list.size(); i++) { ElementObj obj = list.get(i); obj.showElement(g); } } g.setFont(new Font("Times New Roman", Font.BOLD, 24)); int allTime = GameThread.getAllTime()/1000; int munite = allTime / 60; int second = allTime % 60; String m; String s; if(munite < 10) m = "0" + Integer.toString(munite); else m = Integer.toString(munite); if(second<10) s = "0" + Integer.toString(second); else s = Integer.toString(second); g.drawString("Time: "+ m + ":" + s, 0, 50); } @Override public void run() { while(this.panelIsRunning) {// System.out.println("多线程运动"); this.repaint(); try { Thread.sleep(10); //休眠10毫秒 1秒刷新20次 } catch (InterruptedException e) { e.printStackTrace(); } } } }
    3.2 控制GameListener类
    /** * @说明 监听类,用于监听用户的操作 KeyListener */public class GameListener implements KeyListener{ private ElementManager em = ElementManager.getManager(); private Set<Integer> set = new HashSet<Integer>(); @Override public void keyTyped(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); List<ElementObj> play = em.getElementsByKey(GameElement.PLAY); for(ElementObj obj : play) { obj.keyClick(true, e.getKeyCode()); } } @Override public void keyReleased(KeyEvent e) { List<ElementObj> play = em.getElementsByKey(GameElement.PLAY); for(ElementObj obj : play) { obj.keyClick(false, e.getKeyCode()); } }}
    GameThread类
    /** * @说明 游戏的主线程,用于控制游戏加载,游戏关卡,游戏运行时自动化 * 游戏判定;游戏地图切换 资源释放和重新读取。 */public class GameThread extends Thread{ private ElementManager em; public boolean stopGameThread = false; public boolean isRunning = true; private static int allTime = 2* 60 * 1000; //2分钟 private static int sleepTime = 10; private int winNumbers = 70; //赢得游戏需击杀的敌人数 public GameThread() { em = ElementManager.getManager(); } @Override public void run() {//游戏的run方法 ,主线程 while(!this.stopGameThread) {// 加载游戏资源(场景资源) gameLoad();// 游戏进行时游戏过程中 gameRun();// 游戏场景结束游戏资源回收(场景资源) gameOver(); try { sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } }// System.out.println("游戏主线程中断"); } /** * 游戏的加载 */ private void gameLoad() { System.out.println("加载中。。。。。");// GameLoad.loadImg(); //加载图片 GameLoad.loadMap(1); //可以变为变量,每一关重新加载 加载地图// 加载主角 GameLoad.loadPlay(GameDialog.getPlayN());//也可以带参数,单机还是2人// 加载敌人NPC等 GameLoad.loadEnemy(3);// 全部加载完成,游戏启动 } /** * @说明 游戏进行时 * @任务说明 游戏过程中需要做的事情:1.自动化玩家的移动,碰撞,死亡 * 2.新元素的增加(NPC死亡后出现道具)等 * */ private void gameRun() { long gameTime = 0L; // System.out.println(this.getName()); System.out.println("加载成功,进入游戏"); while(this.isRunning) { Map<GameElement, List<ElementObj>> all = em.getGameElements(); List<ElementObj> enemys = em.getElementsByKey(GameElement.ENEMY); List<ElementObj> files = em.getElementsByKey(GameElement.PLAYFILE); List<ElementObj> maps = em.getElementsByKey(GameElement.MAPS); List<ElementObj> props = em.getElementsByKey(GameElement.PROP); List<ElementObj> player = em.getElementsByKey(GameElement.PLAY); List<ElementObj> enemyFiles = em.getElementsByKey(GameElement.ENEMYFILE); List<ElementObj> boss = em.getElementsByKey(GameElement.BOSS); List<ElementObj> shield = em.getElementsByKey(GameElement.SHIELD); moveAndUpdate(all,gameTime); //游戏元素自动化方法 ElementPK(files, enemys, 0); ElementPK(player, props, 1); ElementPK(player, enemys, 0); ElementPK(files, boss, 0); ElementPK(player, enemyFiles, 0); ElementPK(files, enemyFiles, 0); ElementPK(shield, enemyFiles, 0); ElementPK(enemyFiles, shield, 0); gameTime++; //唯一的时间控制 if(gameTime % 300 == 0) GameLoad.loadEnemy(3); //设置敌人数量 if(gameTime % 2000 == 0) { //间隔20秒出现boss GameLoad.loadBoss(new Random().nextInt(2) + 1, gameTime); //设置boss数量 }// System.out.println("isRunning"); this.MedJudge(); allTime -= sleepTime; try { sleep(10);//默认理解为 1秒刷新100次 } catch (InterruptedException e) { e.printStackTrace(); } } } private void MedJudge() { if(em.getElementsByKey(GameElement.PLAY).size() <= 0) { GameStart.gj.EndGame(); new GameDialog(GameStart.gj, "LoseGame"); return; } if(allTime <= 0) { int n = ((PaoPao)em.getElementsByKey(GameElement.PLAY).get(0)).getKillEnemy(); if(n < winNumbers) {// System.out.println("失败"); GameStart.gj.EndGame(); new GameDialog(GameStart.gj, "LoseGame"); }else { GameStart.gj.EndGame(); new GameDialog(GameStart.gj, "WinGame"); } } } /** * @说明 碰撞处理 * @param listA 如果是单方面损失碰撞,则这个变量不受损失 * @param listB * @param type 碰撞类型,0表示互损碰撞,1表示单方面损失碰撞 */ public void ElementPK(List<ElementObj> listA, List<ElementObj>listB, int type) { for(int i=0; i<listA.size(); i++) { ElementObj lista = listA.get(i); for(int j=0; j<listB.size(); j++) { ElementObj listb = listB.get(j); if(lista.pk(listb)) { if(type == 0) { lista.setLive(false); listb.setLive(false); if(lista instanceof Enemy || lista instanceof Boss) { if(!lista.isLive() && em.getElementsByKey(GameElement.PLAY).size() > 0) //如果想做双玩家模式,要区别是哪个击杀的 ((PaoPao)em.getElementsByKey(GameElement.PLAY).get(0)).addKillEnemy(1); } if(listb instanceof Enemy || listb instanceof Boss) { if(!listb.isLive() && em.getElementsByKey(GameElement.PLAY).size() > 0) ((PaoPao)em.getElementsByKey(GameElement.PLAY).get(0)).addKillEnemy(1); } } else if(type == 1) { lista.setLive(true); listb.setLive(false); } break; } } } }// 游戏元素自动化方法 public void moveAndUpdate(Map<GameElement, List<ElementObj>> all,long gameTime) { for(GameElement ge:GameElement.values()) { List<ElementObj> list = all.get(ge); for(int i=list.size()-1; i>=0 ;i--){ ElementObj obj=list.get(i); if(!obj.isLive()) { //如果死亡 obj.die(); list.remove(i); continue; } obj.model(gameTime); } } } /**游戏结束*/ private void gameOver() { for(GameElement ge : GameElement.values()) { if(this.em.getElementsByKey(ge).size() > 0) this.em.getElementsByKey(ge).clear(); } System.out.println("gameOver"); } public static void reSetAllTime() { allTime = 2 * 60 * 1000; } public static int getAllTime() { return allTime; }}
    3.3 资源管理ElementManager类
    /** * @说明 本类是元素管理器,专门存储所有的元素,同时,提供方法 * 给予视图和控制获取数据 */public class ElementManager { private Map<GameElement,List<ElementObj>> gameElements; public Map<GameElement, List<ElementObj>> getGameElements() { return gameElements; }// 添加元素(多半由加载器调用) public void addElement(ElementObj obj,GameElement ge) { gameElements.get(ge).add(obj); //添加对象到集合中,按key值就行存储 } public List<ElementObj> getElementsByKey(GameElement ge){ return gameElements.get(ge); } private static ElementManager EM = null; //引用// synchronized线程锁->保证本方法执行中只有一个线程 public static synchronized ElementManager getManager() { if(EM == null) { //控制判定 EM = new ElementManager(); } return EM; } private ElementManager() { //私有化构造方法 init(); //实例化方法 } /** * 本方法是为 将来可能出现的功能扩展,重写init方法准备的。 */ public void init() { //实例化在这里完成 gameElements = new HashMap<GameElement,List<ElementObj>>();// 将每种元素集合都放入到 map中 for(GameElement ge : GameElement.values()) { //通过循环读取枚举类型的方式添加集合 gameElements.put(ge, new ArrayList<ElementObj>()); } }}
    GameLoad类
    /** * 说明 加载器(工具:用户读取配置文件的工具)工具类,大多提供的是 static方法 * @author * */public class GameLoad { private static ElementManager em = ElementManager.getManager(); public static Map<String,ImageIcon> imgMap = new HashMap<>();// 用户读取文件的类 private static Properties pro =new Properties(); /** * @说明 传入地图id有加载方法依据文件规则自动产生地图文件名称,加载文件 * ,如果有地图可调用这个方法 * @param mapId 文件编号,文件id */ public static void MapLoad(int mapId) { String mapName = "com/text/" + mapId + ".map"; ClassLoader classLoader = GameLoad.class.getClassLoader(); InputStream maps = classLoader.getResourceAsStream(mapName); if(maps == null) { System.out.println("配置文件读取异常,请重新安装"); return; } try { pro.clear(); pro.load(maps); Enumeration<?> names = pro.propertyNames(); while(names.hasMoreElements()) { //获取是无序的 String key = names.nextElement().toString(); System.out.println(pro.getProperty(key)); String [] arrs = pro.getProperty(key).split(";"); for(int i=0; i<arrs.length; i++) { ElementObj obj = getObj("map"); ElementObj element = obj.createElement(key+","+arrs[i]); System.out.println(element); em.addElement(element, GameElement.MAPS); } } } catch (IOException e) { e.printStackTrace(); } } /** *@说明 加载图片代码 * */ public static void loadImg() { //可以带参数,因为不同的关也可能需要不一样的图片资源 String texturl = "com/text/GameData.pro"; //文件的命名可以更加有规律 ClassLoader classLoader = GameLoad.class.getClassLoader(); InputStream texts = classLoader.getResourceAsStream(texturl); pro.clear(); try {// System.out.println(texts); pro.load(texts); Set<Object> set = pro.keySet(); for(Object o:set) { String url=pro.getProperty(o.toString());// System.out.println(o.toString() + url); imgMap.put(o.toString(), new ImageIcon(url)); } } catch (IOException e) { e.printStackTrace(); } } /** * 加载玩家 */ public static void loadPlay(int playN) { loadObj(); String playStr = "250,800,player" + String.valueOf(playN); ElementObj obj = getObj("paopao"); ElementObj play = obj.createElement(playStr); em.addElement(play, GameElement.PLAY); } public static void loadEnemy(int enemyNumber) { loadObj();// ElementObj obj = getObj("enemy"); for(int i=0; i<enemyNumber; i++) { ElementObj obj = getObj("enemy"); ElementObj enemy = obj.createElement(null); em.addElement(enemy, GameElement.ENEMY); } } public static void loadBoss(int bossNumber, long gameTime) { loadObj(); for(int i=0; i<bossNumber; i++) { ElementObj obj = getObj("boss"); ElementObj boss = obj.createElement(null); em.addElement(boss, GameElement.BOSS); } } public static void loadMap(int mapsNumber) { loadObj(); for(int i=0; i<mapsNumber; i++) { ElementObj obj = getObj("maps"); ElementObj maps = obj.createElement(null); em.addElement(maps, GameElement.MAPS); } } public static ElementObj getObj(String str) { try { Class<?> class1 = objMap.get(str); Object newInstance = class1.newInstance(); if(newInstance instanceof ElementObj) { return (ElementObj)newInstance; //这个对象就和new Play()等价 } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } /** * 扩展: 使用配置文件,来实例化对象 通过固定的key(字符串来实例化) * @param args */ private static Map<String,Class<?>> objMap=new HashMap<>(); public static void loadObj() { String texturl = "com/text/obj.pro"; //文件的命名可以更加有规律 ClassLoader classLoader = GameLoad.class.getClassLoader(); InputStream texts = classLoader.getResourceAsStream(texturl); pro.clear(); try { pro.load(texts); Set<Object> set = pro.keySet(); for(Object o:set) { String classUrl=pro.getProperty(o.toString());// 使用反射的方式直接将类进行获取 Class<?> forName = Class.forName(classUrl); objMap.put(o.toString(), forName); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }// 用于测试// public static void main(String[] args) {// MapLoad(5);// // }}
    4.游戏界面展示游戏界面1

    游戏界面2

    游戏界面3

    5.不足
    只有一个游戏关卡
    游戏平衡欠缺
    无背景音乐
    0 评论 1 下载 2021-07-29 10:54:32 下载需要11点积分
  • 基于Jsp和MySQL实现的教务信息管理系统

    基于Jsp和MySQL实现的教务信息管理系统# 一、引言
    随着信息技术的革命与发展,计算机已经成为我们学习和工作的得力助手,逐渐改变着信息的管理方式提高了信息管理的安全性和效率,节省了大量的人力和财力。同时 Internet 的普及也促进各个行业的发展,从邮寄信件到 E-mail,从电话会议到网络会议,从传统物流到电子商务,从面对面授课到运程教学等等一系列的变化,人们无不感到 Internet 的强大。信息管理技术的迅速发展正得力于 Internet 的普及和发展。
    目前社会上信息管理系统发展飞快,各个企事业单位都引入了信息管理软件 来管理自己日益增长的各种信息。鉴于目前学校教学规模的日益扩大,教务信息 呈爆炸性增长的前提下,教务信息管理的自动化与准确化的要求日益强烈的背景 下构思出来的,该项目开发的软件就是为学校教务信息管理系统软件,系统完全 独立开发,力求使系统功能简洁明了,但功能齐全且易于操作。该项目设计完成 后可用于一些教育单位(包括学校,学院等等)的教务信息的管理
    二、目的《Asp.Net 应用开发项目设计》课程是软件工程专业学生的一项必修实践性教学环节。通过课程设计,使学生提高理论联系实际解决实际问题的能力;也使学生对基于面向对象的理论进行系统设计过程中的诸多具体问题有感性的认识和深入的理解;进而提高学生的学习兴趣为其将来顺利进入毕业环节作必要的准备。
    三、概述与需求分析学生教务管理系统针对的学校学生情况对学生各科课程有效的管理。能够快 速的查询出学生的各科课程情况,以及所在班级等各种用途。相应的需求如下:

    能够存储一定数量的学生信息,并方便有效地进行相应的数据操作和管理,这主要包括学生信息的录人、删除及修改
    能够对一定数量的读者进行相应的信息存储与管理,这其中包括查询学生信息的登记、删除及修改,学生资料的统计与查询
    能够提供一定的安全机制,提供数据信息授权访问,防止随意删改,同时提供信息备份服务
    使网站更加容易管理和维护,不需对过多人员培训,提高工作效率

    四、系统分析4.1 可行性分析4.1.1 管理可行性信息化的教师教务管理在如今的信息时代是大势所趋,而且随着现代管理理念、方法和途径的提高。教务信息化管理手段日趋成熟,所以从长远利益出发,主管领导对该项目的开发与实施会大力支持。
    4.1.2 技术可行性本系统采用 Windows 作为操作平台。数据库选用 MYSQL,该数据库管理系统在 Windows 环境下可以连接 Java 运行,其体积小、速度快、总体拥有成本低,提高数据的可用性。本系统的应用软件开发平台选用 My Eclipse,java 版本为 JDK1.8,服务器为 tomcat8.5.
    4.1.3 经济可行性采用教师教务管理系统可取代原系统的单据手工传递工作,减少人工开支,节省资金、并且可大大提高信息量的获取,缩短信息处理周期,改进教学质量,能及时反馈学生的平时表现和成绩,反馈教学信息的利用率,使教学质量更上一个台阶。
    4.1.4 社会可行性本系统操作简单,易于理解,只需通过简单熟悉,上手较快,教师学生都可以进行操作,营运环境要求低。
    4.2 业务功能分析教务信息管理系统主要面对 3 个对象(管理员、教师、学生)。下面将详细介绍每个模块的业务功能以及流程图。

    学生模块:根据学生信息,获取其学生基本信息和已经选择的课程

    学生列表显示个人的基本信息选课列表显示所有已经选好的课程,包括上课时间和上课地点,授课老师学生可以在自己的选课管理中精确查询自己所选课程修改个人基本信息级密码
    教师模块:教师登录后,可以获取自己的课程列表,并可以对自己所教课程进行管理,设置上课时间及地点的安排

    学生列表显示所有选择自己课程的学生姓名、班级等基本信息班级列表显示班级的名称及班级的介绍教师列表显示教师本人的基本信息,并且可以进行修改课程列表显示课程安排,各科所选人数和设置上限人数修改密码可以进行修改个人密码
    管理员模块:可对教师信息、学生信息、课程信息进行各种操作。主要功能有

    学生列表显示所有学生姓名、班级等基本信息班级列表显示班级的名称及班级的介绍教师列表显示所有教师姓名、班级、工号等基本信息课程管理列表显示所有课程及对应的任课老师选课列表显示所有显示选择的科目

    4.3 总体功能模块图
    4.4 数据流程图
    五、系统详细设计与实现该系统涉及到的功能比较多,因此在这里只选取部分功能的实现来展开介绍。
    5.1 登录模块教务信息管理系统,如果每一个人进入计算机的人都能够对系统进行操作,就可能有意或无意的破坏数据,对用户产生不良影响,甚至造成无法估量的损失。
    因此,在进入系统之前要设置密码输入功能用户登录关键是判断它的密码和账号是否与数据库中存在的用户信息吻合,若存在则登录成功,若登录不成功,重新输入或者相管理员申请,由管理员分配教师账号,学生账号密码由教师分配。
    <script type="text/javascript"> $(function() { //点击图片切换验证码 $("#vcodeImg").click(function() { this.src = "CpachaServlet?method=loginCapcha&t=" + new Date().getTime(); }); //登录 $("#submitBtn").click(function() { var data = $("#form").serialize(); $.ajax({ type: "post",url: "LoginServlet?method=Login",data: data,dataType: "text", //返回数据类型 success: function(msg) { if ("vcodeError" == msg) { $.messager.alert("消息提醒","验证码错误!","warning"); $("#vcodeImg").click(); //切换验证码 $("input[name='vcode']").val(""); //清空验证码输入框 } else if ("loginError" == msg) { $.messager.alert("消息提醒","用户名或密码错误!","warning"); $("#vcodeImg").click(); //切换验证码 $("input[name='vcode']").val(""); //清空验证码输入框 } else if ("loginSuccess" == msg) { window.location.href = "SystemServlet?method=toAdminView"; } else { alert(msg); } } }); }); //设置复选框 $(".skin-minimal input").iCheck({ radioClass: 'iradio-blue',increaseArea: '25%' }); })</script><title> 登录|教务信息管理系统</title><meta name="keywords" content="教务信息管理系统"></head><body> <div class="header" style="padding: 0;"> <h2 style="color: white; width: 400px; height: 60px; line-height: 60px; margin: 0 0 0 30px; padding: 0;"> 教务信息管理系统 </h2> </div> <div class="loginWraper"> <div id="loginform" class="loginBox"> <form id="form" class="form form-horizontal" method="post"> <div class="row cl"> <label class="form-label col-3"> <i class="Hui-iconfont">  </i> </label> <div class="formControls col-8"> <input id="" name="account" type="text" placeholder="账户" class="input-text size-L"> </div> </div> <div class="row cl"> <label class="form-label col-3"> <i class="Hui-iconfont">  </i> </label> <div class="formControls col-8"> <input id="" name="password" type="password" placeholder="密码" class="input-text size-L"> </div> </div> <div class="row cl"> <div class="formControls col-8 col-offset-3"> <input class="input-text size-L" name="vcode" type="text" placeholder="请输入验证码" style="width: 200px;"> <img title="点击图片切换验证码" id="vcodeImg" src="CpachaServlet?method=loginCapcha"> </div> </div> <div class="mt-20 skin-minimal" style="text-align: center;"> <div class="radio-box"> <input type="radio" id="radio-2" name="type" checked value="2" /> <label for="radio-1"> 学生 </label> </div> <div class="radio-box"> <input type="radio" id="radio-3" name="type" value="3" /> <label for="radio-2"> 老师 </label> </div> <div class="radio-box"> <input type="radio" id="radio-1" name="type" value="1" /> <label for="radio-3"> 管理员 </label> </div> </div> <div class="row"> <div style="text-align: center;" class="formControls col-8 col-offset-3"> <input id="submitBtn" type="button" class="btn btn-success radius size-L" value=" 登    录 "> </div> </div> </form> </div> </div> <div class="footer">   </div></body></html>
    5.2 教师信息管理代码实现教师和管理员可以对信息进行修改:
    <html> <head> <meta charset="UTF-8"> <title> 教师列表 </title> <link rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css"> <link rel="stylesheet" type="text/css" href="easyui/themes/icon.css"> <link rel="stylesheet" type="text/css" href="easyui/css/demo.css"> <script type="text/javascript" src="easyui/jquery.min.js"> </script> <script type="text/javascript" src="easyui/jquery.easyui.min.js"> </script> <script type="text/javascript" src="easyui/js/validateExtends.js"> </script> <script type="text/javascript"> $(function() { var table; //datagrid初始化 $('#dataList').datagrid({ title: '教师列表',iconCls: 'icon-more', //图标 border: true,collapsible: false, //是否可折叠的 fit: true, //自动大小 method: "post",url: "TeacherServlet?method=TeacherList&t=" + new Date().getTime(),idField: 'id',singleSelect: false, //是否单选 pagination: true, //分页控件 rownumbers: true, //行号 sortName: 'id',sortOrder: 'DESC',remoteSort: false,columns: [[{ field: 'chk',checkbox: true,width: 50 }, { field: 'id',title: 'ID',width: 50,sortable: true }, { field: 'sn',title: '工号',width: 150,sortable: true }, { field: 'name',title: '姓名',width: 150 }, { field: 'sex',title: '性别',width: 100 }, { field: 'mobile',title: '电话',width: 150 }, { field: 'qq',title: 'QQ',width: 150 }, { field: 'clazz_id',title: '班级',width: 150,formatter: function(value,row,index) { if (row.clazzId) { var clazzList = $("#clazzList").combobox("getData"); for (var i = 0; i < clazzList.length; i++) { //console.log(clazzList[i]); if (row.clazzId == clazzList[i].id) return clazzList[i].name; } return row.clazzId; } else { return 'not found'; } } }]],toolbar: "#toolbar",onBeforeLoad: function() { try { $("#clazzList").combobox("getData") } catch(err) { preLoadClazz(); } } }); //设置分页控件 var p = $('#dataList').datagrid('getPager'); $(p).pagination({ pageSize: 10, //每页显示的记录条数,默认为10 pageList: [10,20,30,50,100], //可以设置每页记录条数的列表 beforePageText: '第', //页数文本框前显示的汉字 afterPageText: '页 共 {pages} 页',displayMsg: '当前显示 {from} - {to} 条记录 共 {total} 条记录', }); //设置工具类按钮 $("#add").click(function() { table = $("#addTable"); $("#addDialog").dialog("open"); }); //修改 $("#edit").click(function() { table = $("#editTable"); var selectRows = $("#dataList").datagrid("getSelections"); if (selectRows.length != 1) { $.messager.alert("消息提醒","请选择一条数据进行操作!","warning"); } else { $("#editDialog").dialog("open"); } }); //删除 $("#delete").click(function() { var selectRows = $("#dataList").datagrid("getSelections"); var selectLength = selectRows.length; if (selectLength == 0) { $.messager.alert("消息提醒","请选择数据进行删除!","warning"); } else { var ids = []; $(selectRows).each(function(i,row) { ids[i] = row.id; }); $.messager.confirm("消息提醒","将删除与教师相关的所有数据,确认继续?", function(r) { if (r) { $.ajax({ type: "post",url: "TeacherServlet?method=DeleteTeacher",data: { ids: ids },success: function(msg) { if (msg == "success") { $.messager.alert("消息提醒","删除成功!","info"); //刷新表格 $("#dataList").datagrid("reload"); $("#dataList").datagrid("uncheckAll"); } else { $.messager.alert("消息提醒","删除失败!","warning"); return; } } }); } }); } }); function preLoadClazz() { $("#clazzList").combobox({ width: "150",height: "25",valueField: "id",textField: "name",multiple: false, //可多选 editable: false, //不可编辑 method: "post",url: "ClazzServlet?method=getClazzList&t=" + new Date().getTime() + "&from=combox",onChange: function(newValue,oldValue) { //加载班级下的学生 //$('#dataList').datagrid("options").queryParams = {clazzid: newValue}; //$('#dataList').datagrid("reload"); } }); } //设置添加窗口 $("#addDialog").dialog({ title: "添加教师",width: 850,height: 550,iconCls: "icon-add",modal: true,collapsible: false,minimizable: false,maximizable: false,draggable: true,closed: true,buttons: [{ text: '添加',plain: true,iconCls: 'icon-user_add',handler: function() { var validate = $("#addForm").form("validate"); if (!validate) { $.messager.alert("消息提醒","请检查你输入的数据!","warning"); return; } else { var clazzid = $("#add_clazzList").combobox("getValue"); var name = $("#add_name").textbox("getText"); var sex = $("#add_sex").textbox("getText"); var phone = $("#add_phone").textbox("getText"); var qq = $("#add_qq").textbox("getText"); var password = $("#add_password").textbox("getText"); var data = { clazzid: clazzid,name: name,sex: sex,mobile: phone,qq: qq,password: password }; $.ajax({ type: "post",url: "TeacherServlet?method=AddTeacher",data: data,success: function(msg) { if (msg == "success") { $.messager.alert("消息提醒","添加成功!","info"); //关闭窗口 $("#addDialog").dialog("close"); //清空原表格数据 $("#add_number").textbox('setValue',""); $("#add_name").textbox('setValue',""); $("#add_sex").textbox('setValue',"男"); $("#add_phone").textbox('setValue',""); $("#add_qq").textbox('setValue',""); $(table).find(".chooseTr").remove(); //重新刷新页面数据 $('#dataList').datagrid("reload"); } else { $.messager.alert("消息提醒","添加失败!","warning"); return; } } }); } } }, { text: '重置',plain: true,iconCls: 'icon-reload',handler: function() { $("#add_number").textbox('setValue',""); $("#add_name").textbox('setValue',""); $("#add_phone").textbox('setValue',""); $("#add_qq").textbox('setValue',""); $(table).find(".chooseTr").remove(); } },],onClose: function() { $("#add_number").textbox('setValue',""); $("#add_name").textbox('setValue',""); $("#add_phone").textbox('setValue',""); $("#add_qq").textbox('setValue',""); $(table).find(".chooseTr").remove(); } }); //下拉框通用属性 $("#edit_clazzList, #add_clazzList").combobox({ width: "200",height: "30",valueField: "id",textField: "name",multiple: false, //不可多选 editable: false, //不可编辑 method: "post", }); $("#add_clazzList").combobox({ url: "ClazzServlet?method=getClazzList&t=" + new Date().getTime() + "&from=combox",onLoadSuccess: function() { //默认选择第一条数据 var data = $(this).combobox("getData"); $(this).combobox("setValue",data[0].id); } }); //编辑教师信息班级下拉框 $("#edit_clazzList").combobox({ url: "ClazzServlet?method=getClazzList&t=" + new Date().getTime() + "&from=combox",onLoadSuccess: function() { //默认选择第一条数据 var data = $(this).combobox("getData"); $(this).combobox("setValue",data[0].id); } }); //编辑教师信息 $("#editDialog").dialog({ title: "修改教师信息",width: 850,height: 550,iconCls: "icon-edit",modal: true,collapsible: false,minimizable: false,maximizable: false,draggable: true,closed: true,buttons: [{ text: '提交',plain: true,iconCls: 'icon-user_add',handler: function() { var validate = $("#editForm").form("validate"); if (!validate) { $.messager.alert("消息提醒","请检查你输入的数据!","warning"); return; } else { var clazzid = $("#edit_clazzList").combobox("getValue"); var id = $("#dataList").datagrid("getSelected").id; var name = $("#edit_name").textbox("getText"); var sex = $("#edit_sex").textbox("getText"); var phone = $("#edit_phone").textbox("getText"); var qq = $("#edit_qq").textbox("getText"); var data = { id: id,clazzid: clazzid,name: name,sex: sex,mobile: phone,qq: qq }; $.ajax({ type: "post",url: "TeacherServlet?method=EditTeacher",data: data,success: function(msg) { if (msg == "success") { $.messager.alert("消息提醒","修改成功!","info"); //关闭窗口 $("#editDialog").dialog("close"); //清空原表格数据 $("#edit_name").textbox('setValue',""); $("#edit_sex").textbox('setValue',"男"); $("#edit_phone").textbox('setValue',""); $("#edit_qq").textbox('setValue',""); //重新刷新页面数据 $('#dataList').datagrid("reload"); $('#dataList').datagrid("uncheckAll"); } else { $.messager.alert("消息提醒","修改失败!","warning"); return; } } }); } } }, { text: '重置',plain: true,iconCls: 'icon-reload',handler: function() { $("#edit_name").textbox('setValue',""); $("#edit_phone").textbox('setValue',""); $("#edit_qq").textbox('setValue',""); $(table).find(".chooseTr").remove(); } },],onBeforeOpen: function() { var selectRow = $("#dataList").datagrid("getSelected"); //设置值 $("#edit_name").textbox('setValue',selectRow.name); $("#edit_sex").textbox('setValue',selectRow.sex); $("#edit_phone").textbox('setValue',selectRow.mobile); $("#edit_qq").textbox('setValue',selectRow.qq); $("#edit_photo").attr("src","PhotoServlet?method=getPhoto&type=2&tid=" + selectRow.id); $("#set-photo-id").val(selectRow.id); var clazzid = selectRow.clazzId; setTimeout(function() { $("#edit_clazzList").combobox('setValue',clazzid); },100); },onClose: function() { $("#edit_name").textbox('setValue',""); $("#edit_phone").textbox('setValue',""); $("#edit_qq").textbox('setValue',""); } }); //搜索按钮监听事件 $("#search-btn").click(function() { $('#dataList').datagrid('load', { teacherName: $('#search_student_name').val(),clazzid: $("#clazzList").combobox('getValue') == '' ? 0 : $("#clazzList").combobox('getValue') }); }); }); //上传图片按钮事件 $("#upload-photo-btn").click(function() {}); function uploadPhoto() { var action = $("#uploadForm").attr('action'); var pos = action.indexOf('tid'); if (pos != -1) { action = action.substring(0,pos - 1); } $("#uploadForm").attr('action',action + '&tid=' + $("#set-photo-id").val()); $("#uploadForm").submit(); setTimeout(function() { var message = $(window.frames["photo_target"].document).find("#message").text(); $.messager.alert("消息提醒",message,"info"); $("#edit_photo").attr("src","PhotoServlet?method=getPhoto&tid=" + $("#set-photo-id").val()); },1500) } </script> </head> <body> <!-- 数据列表 --> <table id="dataList" cellspacing="0" cellpadding="0"> </table> <!-- 工具栏 --> <div id="toolbar"> <c:if test="${userType == 1}"> <div style="float: left;"> <a id="add" href="javascript:;" class="easyui-linkbutton" data-options="iconCls:'icon-add',plain:true"> 添加 </a> </div> <div style="float: left;" class="datagrid-btn-separator"> </div> </c:if> <div style="float: left;"> <a id="edit" href="javascript:;" class="easyui-linkbutton" data-options="iconCls:'icon-edit',plain:true"> 修改 </a> </div> <div style="float: left;" class="datagrid-btn-separator"> </div> <c:if test="${userType == 1}"> <div style="float: left;"> <a id="delete" href="javascript:;" class="easyui-linkbutton" data-options="iconCls:'icon-some-delete',plain:true"> 删除 </a> </div> </c:if> <div style="float: left;margin-top:4px;" class="datagrid-btn-separator">     姓名: <input id="search_student_name" class="easyui-textbox" name="search_student_name" /> </div> <div style="margin-left: 10px;margin-top:4px;"> 班级: <input id="clazzList" class="easyui-textbox" name="clazz" /> <a id="search-btn" href="javascript:;" class="easyui-linkbutton" data-options="iconCls:'icon-search',plain:true"> 搜索 </a> </div> </div> <!-- 添加窗口 --> <div id="addDialog" style="padding: 10px;"> <div style=" position: absolute; margin-left: 560px; width: 200px; border: 1px solid #EEF4FF" id="photo"> <img alt="照片" style="max-width: 200px; max-height: 400px;" title="照片" src="PhotoServlet?method=getPhoto" /> </div> <form id="addForm" method="post"> <table id="addTable" border=0 style="width:800px; table-layout:fixed;" cellpadding="6"> <tr> <td style="width:40px"> 班级: </td> <td colspan="3"> <input id="add_clazzList" style="width: 200px; height: 30px;" class="easyui-textbox" name="clazzid" /> </td> <td style="width:80px"> </td> </tr> <tr> <td> 姓名: </td> <td colspan="4"> <input id="add_name" style="width: 200px; height: 30px;" class="easyui-textbox" type="text" name="name" data-options="required:true, missingMessage:'请填写姓名'" /> </td> </tr> <tr> <td> 密码: </td> <td colspan="4"> <input id="add_password" style="width: 200px; height: 30px;" class="easyui-textbox" type="password" name="password" data-options="required:true, missingMessage:'请填写密码'" /> </td> </tr> <tr> <td> 性别: </td> <td colspan="4"> <select id="add_sex" class="easyui-combobox" data-options="editable: false, panelHeight: 50, width: 60, height: 30" name="sex"> <option value="男"> 男 </option> <option value="女"> 女 </option> </select> </td> </tr> <tr> <td> 电话: </td> <td colspan="4"> <input id="add_phone" style="width: 200px; height: 30px;" class="easyui-textbox" type="text" name="phone" validType="mobile" /> </td> </tr> <tr> <td> QQ: </td> <td colspan="4"> <input id="add_qq" style="width: 200px; height: 30px;" class="easyui-textbox" type="text" name="qq" validType="number" /> </td> </tr> </table> </form> </div> <!-- 修改窗口 --> <div id="editDialog" style="padding: 10px"> <div style=" position: absolute; margin-left: 560px; width: 200px; border: 1px solid #EEF4FF"> <img id="edit_photo" alt="照片" style="max-width: 200px; max-height: 400px;" title="照片" src="" /> <form id="uploadForm" method="post" enctype="multipart/form-data" action="PhotoServlet?method=SetPhoto" target="photo_target"> <!-- StudentServlet?method=SetPhoto --> <input type="hidden" name="tid" id="set-photo-id"> <input class="easyui-filebox" name="photo" data-options="prompt:'选择照片'" style="width:200px;"> <input id="upload-photo-btn" onClick="uploadPhoto()" class="easyui-linkbutton" style="width: 50px; height: 24px;" type="button" value="上传" /> </form> </div> <form id="editForm" method="post"> <table id="editTable" border=0 style="width:800px; table-layout:fixed;" cellpadding="6"> <tr> <td style="width:40px"> 班级: </td> <td colspan="3"> <input id="edit_clazzList" style="width: 200px; height: 30px;" class="easyui-textbox" name="clazzid" /> </td> <td style="width:80px"> </td> </tr> <tr> <td> 姓名: </td> <td> <input id="edit_name" style="width: 200px; height: 30px;" class="easyui-textbox" type="text" name="name" data-options="required:true, missingMessage:'请填写姓名'" /> </td> </tr> <tr> <td> 性别: </td> <td> <select id="edit_sex" class="easyui-combobox" data-options="editable: false, panelHeight: 50, width: 60, height: 30" name="sex"> <option value="男"> 男 </option> <option value="女"> 女 </option> </select> </td> </tr> <tr> <td> 电话: </td> <td> <input id="edit_phone" style="width: 200px; height: 30px;" class="easyui-textbox" type="text" name="phone" validType="mobile" /> </td> </tr> <tr> <td> QQ: </td> <td colspan="4"> <input id="edit_qq" style="width: 200px; height: 30px;" class="easyui-textbox" type="text" name="qq" validType="number" /> </td> </tr> </table> </form> </div> <iframe id="photo_target" name="photo_target"> </iframe> </body></html>
    5.3 后台管理代码实现系统管理员可以对后台所有数据进行管理,部分代码如下:
    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> 教务信息管理系统 管理员后台 </title> <link rel="shortcut icon" href="favicon.ico" /> <link rel="bookmark" href="favicon.ico" /> <link rel="stylesheet" type="text/css" href="easyui/css/default.css" /> <link rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css" /> <link rel="stylesheet" type="text/css" href="easyui/themes/icon.css" /> <script type="text/javascript" src="easyui/jquery.min.js"> </script> <script type="text/javascript" src="easyui/jquery.easyui.min.js"> </script> <script type="text/javascript" src='easyui/js/outlook2.js'> </script> <script type="text/javascript"> var _menus = { "menus": [ { "menuid": "2","icon": "","menuname": "学生信息管理","menus": [{ "menuid": "21","menuname": "学生列表","icon": "icon-user-student","url": "StudentServlet?method=toStudentListView" },] }, < c: if test = "${userType == 1 || userType == 3}" > { "menuid": "4","icon": "","menuname": "班级信息管理","menus": [{ "menuid": "42","menuname": "班级列表","icon": "icon-house","url": "ClazzServlet?method=toClazzListView" }] }, < /c:if><c:if test="${userType == 1 || userType == 3}">{ "menuid":"3","icon":"","menuname":"教师信息管理","menus":[ {"menuid":"31","menuname":"教师列表","icon":"icon-user-teacher","url":"TeacherServlet?method=toTeacherListView"}, ] },</c: if > <c: if test = "${userType == 1 || userType == 3}" > { "menuid": "6","icon": "","menuname": "课程信息管理","menus": [{ "menuid": "61","menuname": "课程列表","icon": "icon-book-open","url": "CourseServlet?method=toCourseListView" },] }, < /c:if>{ "menuid":"7","icon":"","menuname":"选课信息管理","menus":[ {"menuid":"71","menuname":"选课列表","icon":"icon-book-open","url":"SelectedCourseServlet?method=toSelectedCourseListView"}, ]},{ "menuid":"5","icon":"","menuname":"系统管理","menus":[ {"menuid":"51","menuname":"修改密码","icon":"icon-set","url":"SystemServlet?method=toPersonalView"}, ]} ] };/ </script> </head> <body class="easyui-layout" style="overflow-y: hidden" scroll="no"> <noscript> <div style=" position:absolute; z-index:100000; height:2046px;top:0px;left:0px; width:100%; background:white; text-align:center;"> <img src="images/noscript.gif" alt='抱歉,请开启脚本支持!' /> </div> </noscript> <div region="north" split="true" border="false" style="overflow: hidden; height: 30px; background: url(images/layout-browser-hd-bg.gif) #7f99be repeat-x center 50%; line-height: 20px; color: #fff; font-family: Verdana, 微软雅黑,黑体"> <span style="float:right; padding-right:20px;" class="head"> <span style="color:red; font-weight:bold;"> $ {user.name}  </span> 您好      <a href="LoginServlet?method=logout" id="loginOut"> 安全退出 </a> </span> <span style="padding-left:10px; font-size: 16px; "> 教务信息管理系统 </span> </div> <div region="south" split="true" style="height: 30px; background: #D2E0F2; "> <div class="footer"> © </div> </div> <div region="west" hide="true" split="true" title="导航菜单" style="width:180px;" id="west"> <div id="nav" class="easyui-accordion" fit="true" border="false"> <!-- 导航内容 --> </div> </div> <div id="mainPanle" region="center" style="background: #eee; overflow-y:hidden"> <div id="tabs" class="easyui-tabs" fit="true" border="false"> <jsp:include page="welcome.jsp" /> </div> </div> <iframe width=0 height=0 src="refresh.jsp"> </iframe> </body></html>
    六、功能测试6.1 登录功能测试
    6.2 学生成功登录功能测试学生成功登录图

    学生修改密码测试图

    6.3 教师成功登录功能测试教师成功登录测试图

    教师查看学生消息测试图

    教师管理课程测试图

    6.4 管理员功能测试管理员成功登录图

    管理员管理所有教师测试图

    管理员对所有课程管理图

    总结在该系统的开发过程中,我参阅了很多相关的书籍,许多网站的帮助解决了我许多难题。系统中所有的页面,我都争取使页面上代码简捷、易懂、易改。
    经过多天的设计与开发,系统终于基本开发完成,各项预期功能都已得到实现。当然,该系统还具有进一步的扩展空间,将会伴随着日后的使用逐步完成,使得界面更加优美,操作更加顺畅。设计和开发过程中遇到的问题也都得到解决,学到了很多的开发经验,受益无穷。
    1 评论 3 下载 2021-07-23 12:23:19 下载需要12点积分
  • 基于JSP和MYSQL数据库实现的在线考试系统

    1 系统概述1.1 功能模块教学部需要考试系统,该考试系统需要完成如下功能:

    考试系统只针对于Java课程,题目全部为单项选择,共10题
    学生注册、登录
    后台管理员功能:题库管理、录入试卷、修改试卷
    试卷生成
    考试
    试卷评分
    分数查看


    1.2 软件环境
    操作系统:WindowsXP、Windows2000 Server,windows server 2003,Linux
    数据库系统:MYSQL5.1及以上版本
    CASE工具: Rational Rose、Visio
    开发工具: Eclipse
    编程语言:Java
    支撑软件:JDK1.5及以上版本、Tomcat,JBoss或其他应用服务器

    1.3 基本设计概念和处理流程
    1.4 系统总体结构
    2 系统功能
    2.1 详细功能2.1.1 注册用户信息



    字段名
    字段类型
    说明




    用户名
    字符串
    用户名,用于登陆,用户唯一标识


    密码
    字符串
    密码要求加密存放


    姓名
    字符串
    用户真实姓名


    性别
    字符串



    电话
    字符串
    可以写多个联系方式


    邮件地址
    字符串



    备注
    字符串



    用户进入首页,如果没有注册,点击注册可以进入注册页面,注册完后,进入登陆页面,并要求自己将注册用户名填入登陆界面的用户名框内。如果已存在用户名,则返回注册界面,提示用户名已存在。

    2.1.2 用户登陆用户进入登陆页面,输入用户密码,点击登陆。登陆成功进入用户首页,登陆失败,返回登陆页面。
    2.1.3 用户密码修改用户在自己界面菜单上点击密码修改,进入密码修改界面,输入原密码,输入新密码和新确认密码,检验成功后进行修改。

    2.1.4. 用户管理
    2.1.4.1 用户查询查询条件:用户名,姓名
    查询结果:显示用户名称、用户名、性别,电话、邮件、备注
    2.1.4.2 用户删除勾选用户后,弹出确认对话框,用户确定后删除,可以进行多条删除,删除用户将删除用户所有考试信息。删除失败将进入失败页面并提示信息。
    2.1.5 题库管理题库全是选择题,选择项数至少两项,至多五项。题库题目名称不能重复。
    题目



    字段名
    字段类型
    说明




    题目名称
    字符串



    答案
    字符
    A,B,C,D,E这样的单字母编号



    选项



    字段名
    字段类型
    说明




    选项编号
    字符
    A,B,C,D这样的编号


    选项名称
    字符串
    选项名


    所属题目ID
    数字
    题目的ID号,在建表时设计



    2.1.5.1 题目添加管理员添加题目到题库。从查询界面点击添加按钮,进入编辑界面,填写题目名称,动态添加选项,至少两项,至多五项,点击添加完成。
    2.1.5.2 题目删除在查询界面中,勾选查询结果,进行删除,删除失败将进入失败界面。不能删除已被试卷引用的题库
    2.1.5.3 题目修改在查询界面,点击要修改的记录,进入编辑界面,修改改相关信息,进行保存。
    2.1.5.4 题目查询查询条件:题目名称
    查询结果:题目列表及选项(展现方式自定)
    2.1.6 试卷管理试卷



    字段名
    字段数据类型
    说明




    试卷名称
    字符型



    考试开始时间
    日期型



    考试结束时间
    日期型



    试卷题目



    字段名
    字段类型
    说明




    题目名称
    字符串



    答案
    字符
    A,B,C,D,E这样的单字母编号


    所属试卷ID
    数字
    试卷的ID号



    试卷选项



    字段名
    字段类型
    说明




    选项编号
    字符
    A,B,C,D这样的编号


    选项名称
    字符串
    选项名


    所属试卷题目ID
    数字
    题目的ID号,在建表时设计



    2.1.6.1 试卷录入从查询界面,点击添加按钮进入添加试卷界面,填写题目信息,从题库的题目列表中选择题目。(此处具体方式可以灵活设计),点击添加完成。
    校验:要求考试结束时间必须大于考试开始时间,考试开始时间必须大于当前(服务器)系统时间30分钟以上。
    2.1.6.2 删除试卷试卷删除时,已考过或正在考的试卷不能删除。(已考过即是在考试结果中能查到该试卷,正在考检查系统服务器时间是否在考试区间内)
    在查询界面,勾选查询结果,点击删除,用户确认删除后,删除所选试卷。删除失败将进入失败界面并提示信息.
    2.1.6.3 修改试卷从查询界面,点击某条记录进入编辑界面。修改相关信息。已考过或正在考的试卷不能再修改。
    2.1.6.4 试卷查询查询条件:试卷名称
    查询结果:试卷名称,考试开始时间,考试结束时间
    2.1.7 考试结果查询


    字段名
    字段类型
    说明




    考试试卷
    字符串



    考生姓名
    字符串



    考试分数
    字符串



    管理员选择考试试卷,点击查询,显示该考试的结果,按分数自动排名,默认查询最近一次已结束的考试排名。
    显示结果:姓名、用户名、分数、排名
    2.1.8 管理员登陆参考用户登陆
    2.1.9 管理员密码修改参考用户密码修改
    2.1.10 考试用户登陆后,在考试列表中,能够查询到当前时间可以考试的试卷。选择试卷进入考试。在时间(取系统服务器时间)未到前,用户如果做完题目可以点击提交按钮提交。在考试时间到之后,系统将自动提交用户试卷。已考过的试卷不会出现在试卷查询列表。考试结束系统计算分数,自动跳转到分数查看界面。

    2.1.11 分数查看在菜单上点击分数查看,显示用户考试科目,日期及分数。
    查询结果:考试科目,日期,分数。
    6 评论 392 下载 2018-11-05 21:01:47 下载需要13点积分
  • 基于JSP和MySQL的网上订餐管理系统的设计与实现

    摘 要随着科学技术与经济的快速发展,网络信息技术也有了显著的提升与进步,当今的社会是一个集数字化,网络化,信息化的,并且是以网络为核心的现代化社会。伴随信息互联网的高速成长,使得互联网应用也走进家家户户的日常生活。网上订餐作为一种新的生活方式,更加新颖。
    毕业设计中,界面的设计主要使用了在jsp插入HTML语言以及JavaScript对系统的页面进行相关的加工处理完善以使得页面实现的效果尽可能的满足美观的要求。而对于后台的设计主要是使用了javaSE基础编程,及javaEE中的Jsp页面的动态编程,servlet处理交互逻辑,并且使用jdbc连接数据库,数据库则选用了更为高效的MySql数据库。
    本论文就此次毕业设计的系统内容,从餐品的管理,餐品的分类以及查询,到订餐车实现,客户对订单的处理,再到系统对订餐和餐品的管理。系统从业务流程的角度上分析,完成了订餐系统的基本功能,可是使得用户通过互联网进行点餐以及交易。相比于以往的订餐方式,网上订餐更加便捷,高效,对于餐厅更加节省人力,有利于管理,对于顾客更加省时省力。
    关键字:网上订餐系统;JSP;系统管理
    AbstractWith the rapid development of science and technology and economy, network information technology has also been improved and significant progress, the society is a set of digital, network, information, and network as the core of the modern society. With the rapid growth of information and Internet, Internet applications have entered daily life in every family. Online ordering as a new way of life, more innovative.
    The graduation design, the interface design of the main use of the HTML language and JavaScript system to insert page processing related to the perfect page to achieve the effect of as much as possible to meet the aesthetic requirements in jsp. For the background of the design is mainly used javaSE based programming, dynamic programming and javaEE Jsp page, servlet interactive logic, and use JDBC to connect to the database, the database is more efficient in MySql database.
    This paper on the graduation design of the system content, from the management of the meal, the classification of food and query, to the order cart, customer order processing, and then to the system of ordering and food management. From the point of view of the business process, the system has completed the basic functions of the ordering system, but it allows users to order and trade via the internet. Compared to the previous way of ordering, online ordering more convenient and efficient, for restaurants to save more manpower, is conducive to management, for customers more time and effort.
    Keywords: online ordering system; JSP; system management
    绪 论随着我国在本世纪科学技术与经济的快速提高,网络信息技术也有了显著的提升与进步。在我们平日生活中有很多生活方式以及习惯随着周围信息化的快速提高也有和以往相比变化越发的翻天覆地。本次毕业设计“基于jsp的网上订餐系统的设计与实现”,相比与之前传统的电话订餐,门店订餐这种靠无线电话,人工传递的方式的信息途径,这些方式解决问题的效率很低,店家(餐厅)不能及时将餐厅对菜品的调整通知顾客,顾客对于用餐需求也不能进行调整,线下的交流并不能形成方便快捷的交互。很多时候对于,餐厅以及顾客都是一种损失。由于上述缺陷,为了适应当前时代信息快速发展,数据大爆炸的趋势,采用先进的发展的网上订餐管理系统使上述的种种缺陷得以得到缓解和解决,精简了餐厅的工作流程,顾客的订餐更加便捷,从而提高了餐厅的营业额。由于网络的的快速发展,所以订餐系统随着网络也要有一定的发展与变化。因此毕业设计“基于jsp的网上订餐系统的设计与实现”是非常有必要的。网上订餐系统对订餐所涉及的两个主要用户:客户与店家(餐厅),在实现网上订餐之前,双方进行订餐工作,双方都需要花费大量不必要的时间精力。而快速发展的网络技术,使得订餐系统中所要使用的管理流程在很大程度上做到了极大的简化了,使得餐厅的管理系统更加快速高效,更加便捷。提高餐厅工作人员的整体工作效率,更加给使用订餐系统的顾客更加便捷的使用享受和良好的用户体验。
    从始至终人们都寻求便捷,舒适的生活方式。网络作为提高生活水平的重要工具,在出现后,人们逐渐对其产生了依赖,在依赖的同时也希望网络能给自己带来更方便的帮助,从而大量的销售网站,娱乐网站等等也就慢慢诞生了,这个网上订餐系统是一种基于B/S架构的一种系统模式,订餐系统网站的上手非常的方便,即使第一次登陆,通过网站的指引也会让您订餐非常顺利便捷,如同多次订餐的老顾客一般。
    此次毕业设计的系统,网上订餐系统的开发与设计,在系统可靠性,以及项目的扩展性上占有极大优势。此外对一些java相关技术进行了部分研究,设计并且实现系统,同时为以后自己的可能还要做的其他项目打下了有效以及坚实的基础。
    1 系统概述与技术介绍网上订餐系统作为一个销售管理系统,首先在页面的结构上一定要相对有自己的独特之处,凸显餐厅的风格,餐品的质量。只有如此才能从一开始吸引顾客的目光,通过美观的页面满足顾客对此类订餐系统的好感依赖以及业务功能的需求。与此同时,系统也要有先对强的实用性,系统的实用性不强,这样的系统会是的顾客产生厌恶心理,不利于一个餐厅的未来发展。当然,作为一个销售管理系统,要对顾客的点餐做数据统计,这样才能方便餐厅对该顾客的用餐习惯分析,更好的对顾客实施更加人性化的服务。
    1.1 课题背景上世纪90年代,互联网逐渐走进人们的视野,在不知不觉中改变着社会的商品交易方式。国内各大企业从认识到互联网的重要性之后,一直坚持不断的探索网上交易的可能。但是由于网络生活具有很大的虚拟性,商家的信誉很难得到保证、有关网上交易的法规未出台、物流的滞后以及其他的一些问题,都成为了网络交易发展的绊脚石。但是,社会的进步是具有持续性的,21世纪以来,各个瓶颈问题包括网上支付、物流速递等一一被攻破,网上交易的黄金时代也随之来临。
    调查显示,由于科技的进步极大地繁荣了物质生产生活,人们对于生活的便利性要求进一步提高,网上交易特别是以食品外卖为代表与大众日常生活休戚相关的网络交易量将在未来几年达到高峰。
    网上交易这一方式给人们的消费模式注入了一股新的活力,极大地冲击了原有的传统购物消费习惯。网上订餐这一方式,在90后人群中拥有大量的支持者,促使他们做出选择的,不仅仅是这一形式的便利性,还包括相关网站对于消费者的引导。
    1.2 B/S结构的介绍此次系统的设计过程主要运用到了我们在学校以及公司经常提及使用的B/S结构。所谓的B/S系统就是浏览器、服务器的系统结构。网上订餐系统使用B/S结构,主要就是需要服务端的计算机安装数据库以及服务器。而在客户端,一个浏览器就足够。服务器在服务端运行,浏览器在客户端运行,
    B/S结构作为目前最先进的软件构造技术,在用户使用的浏览器向服务器提交了一些请求之后,服务器端如果接收到了用户在浏览器端发送的请求之后,服务器端对从浏览器接收而来的请求对其进行相应的业务逻辑处理,随后将其完成处理后的结果返回给浏览器所在的客户端。
    B/S结构也是有很多种的,例如:针对OA系统的开发,这些系统主要包括应用程序的研发(基于C/S结构的开发),以及使用传统的C/S结构的跟网络技术结合的混合应用,以及到目前为止是我们常常用到的网站制作的技术。但是不可否认的是,每中结构以及技术都有自己的优点以及缺点:在此前的C/S结构中,更多的它是一种比较传统的使用较为广泛的软件开发的模式,主要是通过客户端以及数据库两层结构完成系统的实现,在两层之间还可以加入其他层次与结构,C/S作为先前传统的软件开发标准以及开发设计结构,在伴随网络和软件的开发技术快速进步,在各种新兴技术不断出现下,被取代或弥补了其结构的很多缺陷,于是也被其衍生出来的新兴结构技术在系统开发的过程中渐渐的将其取代。
    1.3 JSP技术的介绍此次网上订餐系统中页面主要使用到的技术是java的JSP技术,JSP技术之所以被广泛被使用到各种项目中去,主要也是因为其自身拥有的很多功能,这使得在项目中可以实现满足开发人员,程序员对项目所需要的效果。
    作为JSP技术的基础,servlet技术在此前的开发中一直被开发人员所应用。JSP技术的优点:

    进过一次的开发和编写,可以在多种平台运行:因为JSP/Servlet都是基于Java变成语言的,因此具有其编程语言的一个主要优点——平台无关性,这个就是著名的的“一次编写,随处运行(WORA – Write Once, Run Anywhere)”
    系统的多平台支持性:在目前已知的所有平台JSP技术可以进行任意的环境开发,并且在平台中将项目部署在任意的环境里,相比于其他技术,可以根据自己项目的需求任意的环境中拓展。这些优势相比ASP/PHP的局限性是显而易见的
    强大的可伸缩性:JSP可以运行小到从有一个jar文件,大到多台服务器进行集群和负载均衡,多到多台Application进行transaction,还有消息处理,从一台服务器到无数台服务器,Java程序编程语言显示了其巨大的能量
    功能得多态多样以及获得大多数开发工具的技术支持:这个优势和ASP有点类似,java拥有众多的的开发工具并且极为优秀好用。并且都是免费下载使用的,而且可以成功稳定得在多个平台上顺利运行
    JSP标签可扩充性:JSP对Web网页的动态构建主要是利用脚本技术和标签,JSP技术站在开发者的角度考虑允许开发者拓展JSP标签,定制专属的标签库,xml标签拥有很好的兼容性以及强大的功能,网页制作者可以充分利用,减少对脚本语言的大量依赖,利用自己定制的标签,使网页制作程序员降低了制作网页的难度以及复杂度

    1.4 JavaScript语言介绍此次毕业设计,在其中的前台jsp页面中大量的使用了前端脚本语言JavaScript。 JavaScript编程语言以其独有特性,使得他在目前的大多数项目的前台页面设计以及编程都占有重要的一席之地。由于js设计来的产品会主要运行在用户的浏览器客户端,使得只要用户点击页面的一些按钮或者特殊位置,就可以触发特定的事件进行操作,在页面的JavaScript脚本就会将事件传给客户端(浏览器),在客户端被设计好的事件就会执行进行相应的事件处理完成一系列的操作。
    网上订餐管理系统在前台页面的编写设计中就多次使用到了JavaScript这种流行的前端编程语言,众多的优势,使得很多项目的前台都是它和它发展衍生的众多类库编写的,例如我们熟知的:jQuery,easyUI,Extjs等在众多的丰富的前端js类库。
    网上订餐管理系统在很多地方都用到了JavaScript脚本语言,例如:顾客以及管理员登录页面时候的,检出数据是否有效,包括重复为空等场景。
    1.5 MySQL数据库介绍首先要说的是MySQL是一个开源免费的数据库。这也是为什么作为一个小型关系型数据库管理系统,却获得了大量的使用,当然这并不是它的最大优点。MySQL数据库拥有很多优点,比如说:MySql的适应性很好,运行和反应速度快,使用的可靠性高。与此同时,结构化查询语句是MySql数据库系统主要使用的数据库管理方式,结构化查询语言也是目前在数据库管理语言中最受人们欢迎的,也是最为常用的。因此在很多的项目系统开发中都会被开发人员关注,经常使用。由于数据库开发者的允许,MySql作为开源的软件,在官方网站和很多其他网站都可下载到各种版本的MySql数据库。并且根据个人或者开发团队的项目需要对下载的代码做出合理的修改。由此我们可以看出,作为一个小型的关系型数据库,在一些项目的管理上是一个很好的选择,当然这也是在此项目没有超出MySql的数据处理能力的范围之外。
    1.6 MyEclipse介绍此次毕业设计主要是面向顾客用户在前台页面订餐,后台管理人员对前台页面出来的数据请求进行数据处理,并对客户端页面进行及时调整,完善的管理系统。
    MyEclipse开发软件对系统项目的开发更加方便快捷,开发项目的管理更具有条理性。相比于被广泛使用的Eclipse开发软件,MyEclipse在Eclipse开发软件的基础上进行了详细的优化和功能的完善,并且对Eclipse的开发环境进行了优化,最大的限度进行了拓展。使用Eclipse中很多时候我们自己要寻找安装插件,但是MyEclipse基本会帮开发人员在使用之前就集成好了,这对于开发人员的开发是十分便利的,因此目前正在广泛使用于企业级集成开发中去。而且,MyEclipse开发软件在应用程序的整合方面也显得十分成功,如果开发人员能十分熟悉Eclipse,那么对MyEclipse的使用也一定不会陌生,因为MyEclipse的快捷键与Eclipse基本保持一致。
    1.7 MVC模式介绍此次毕业设计为了能够在设计实现上达到最初的想法及要求。并且使完成的系统可以具有一个优秀系统所拥有的一些优点:安全性高,可移植性好,跨品台性高,拓展性优秀,还能具有分布式结构。因此在项目中用到了前文所介绍的B/S结构体系,我所设计实现的订餐系统正式基于Java编程语言的B/S设计模式的。为了更加完善系统,结合在大学时期学过的计算机软件知识,我还用到了另一个结构模式,MVC三层结构,MVC三层结构主要是指基于模型model,视图view以及控制controller的结构模型,而MVC正是这三者英文的首字母缩写。
    控制器,视图,模型三层软件设计模式是MVC软件设计模式的根本。这三层模式对应到了实际项目系统中的web服务器。目前,在网上订餐管理系统中主要使用的MVC模式,如下图。

    由以上的结构图可以得知,在此次的项目系统中,前台界面页面的主要任务就是使用系统的用户可以正常的使用系统逻辑正确完成所要实现的业务。当我们使用网上订餐管理系统的时候,仅仅需要在用户的本地计算机,移动通讯设备安装一个浏览器,在这里使用的浏览器不会限制其版本,开发团队以及类型。用户就可以通过这个浏览器作为客户端与我们的网上订餐管理系统建立网络连接,用户在使用的浏览器中发送需求信息,交由在系统当中的业务逻辑进行准确的数据处理,这些过程主要是由MVC结构中的对应层次进行处理的。业务逻辑得到准确的执行处理后,将处理好的数据进行数据库的数据交互。在模型层中,数据访问层必不可少,他主要实现了当前的系统(网上订餐管理系统)对数据的增、删、改、查等数据处理操作。
    由上述的阐述,我们可以得出MVC设计模式具有众多的优势,其中主要是有:

    低耦合性,高内聚性
    有利于开发者使用,极高的重用性
    可以简单方便的使用,快速的部署
    具有比较好的可维护性,易于未来的维护
    具有生命周期本身成本较低的优势
    软件过程化的管理方法更有利于开发的进行

    2 系统需求分析2.1 开发环境此次毕业设计“基于JSP的网上订餐管理系统”的开发计算机环境主要是:

    学校配发的戴尔品牌笔记本电脑,型号是惠普242G1
    处理器为英特尔酷睿i5 3代系列
    内存容量为 4GB
    显示屏 14英寸
    显卡芯片品牌NVIDIA
    型号NVIDIA GeForce GT 730M+Intel GMA HD 4000
    硬盘品牌希捷,容量500GB
    使用的系统是Windows7旗舰版 SP1

    在我开发完成的订餐项目系统中,主要使用的数据库是当前非常受欢迎的开源免费的数据库MySQL。进行项目系统开发,发布管理的软件也是MyEclipse工具。使用到的技术,主要是JSP技术,以及前端流行的脚本语言JavaScript,还有JAVA编程语言,HTML标签 等。此次完成的系统项目,订餐管理系统是不需要使用户安装客户端程序就可以使用,用户只需要使用浏览器就可以正常的,完整的使用订餐管理系统的全部所有功能。
    2.2 需求分析参照软件开发的标准规范,参考很多成功的软件开发案例,软件开发很重要的一环就是软件需求分析。软件需求分析当中很重要的一点就是通过这次分析,真正准确了解到用户的真实需求,完整准确地项目设计以及编码开发,这样才能在项目完成之后,交给用户一个满意的系统。不仅如此,同时还能在软件开发之初,对软件项目进行风险评估。最后完成一次完整的软件开发设计。
    软件项目的需求分析这个在软件开发过程中至关重要的一环,无论在什么时候都占有着不可忽视的地位,不能被省略或者敷衍而过。这正是因为它在整个的项目开发当中有着举足轻重的作用。因为软件项目的需求分析,才能在项目的设计开发之前,充分理解用户需要,准确的明确开发的方向。在开发的过程中知道。什么功能是必须实现的,什么工作是必须完成的。对系统进行全面的定义,准确,具体的需求,才能更好的实现在项目开发当中具有极其重要的功能。
    一个完善优秀的项目系统在开发之初,开发的初期就要准备充足的资料,进行项目的需求分析。只有在这个阶段完成一个明细,详尽的需求分析,我们才能在后期的设计,编码中更好的实现系统功能,完成一个用户满意的系统。
    2.3 可行性研究分析在开发的前期,对一个项目系统进行可行性分析,这是软件开发过程中不可或缺的工作。从多个角度,维度进行可行性分析,可以将项目分析的更加透彻具体,从项目的方方面面来深入理解项目系统。
    2.3.1 技术可行性分析在目前大多数的公司使用到的软件开发工具是MyEclipse ,例如我目前实习的公司就是用的是MyEclipse2016,因此我在我此次的项目系统,网上订餐管理系统就是用到了MyEclipse 软件开发工具。ava作为一当下最受欢迎关注的编程语言,历久弥新,而且方便灵活使用,是此次开发系统的不二之选。
    2.2.2 经济的可行性分析此次毕业设计,在整个项目系统设计编码完成之后,用户不需要在自己所在的客户端安装任何的客户端应用程序,只需要正常上网就可以完成对系统的访问和使用,除此之外,只要保证项目系统被正确的部署在服务器上,并且已经正常运行。那么,用户就可在任何连接互联网的浏览器上对系统进行访问。
    2.2.3 法律可行性分析此次毕业设计“基于JSP的网上订餐管理系统的设计与实现”,不仅可以提高餐厅对订餐的管理效率,为顾客对订餐需求上提供便利,提供更加贴心优质的服务,良好的用户使用体验。而且在整个的开发过程中都符合具体的软件开发流程及规范的。在项目的的开发过程中使用到的都是一些开源的免费的数据库以及开发人员主要使用的开发工具,参考以及使用到的一些代码,也都是在开源社区和论坛分享的主要开源代码。因此,此次的网上订餐管理系统是不存在任何问题,在法律上是可行的,满足法律可行性的所有要求。
    为了实现这些要求,我对界面页面的开发做到最大化的简单易懂,将功能实现尽可能的减少不必要的步骤,做到让顾客在最短的事件内可以快速订餐,突出餐厅餐品的特色。做到只要会使用电脑查看网页,就能成功点餐。因此,在操作可行性上也十分可靠。
    3 系统概要设计3.1 系统设计概述系统的设计阶段作为在项目开的发整个过程中,最为复杂的一环,其实也是在项目开发的整个过程中极为重要的的一环,必须经过,必不可缺少。在进行系统项目的设计之前,说明系统项目已经完成了对其自身的分析与设计阶段,这是一个具有发展性的过程,将从分析阶段得出的有些抽象的用户需求进行具体的实现,编码。在对系统项目的设计过程中需要考虑众多因素,例如在系统实现过程中所面对的内在环境和外在因素,对项目进行良好的业务和功能完善以及应该具有的敬业态度。
    作为主要的任务和目标,在系统设计阶段就是为了满足在系统分析阶段提出的用户要求.因此,要从用户的要求出发在不仅可以满足系统分析阶段得出的对系统项目逻辑功能的同时,还要充分考虑到多方因素,包括技术,成本以及时间环境等相关方面。对于不论是在正在进行中的整体的设计结构还是局部的每一个部分,都有相关的技术和针对性的应对方案。在合理的要求和基础上,对项目系统所必要的需求进行满足,并且提出该系统具体到实处的实行方案,使其可以得到完整的实现,完成最初的目标以及要求。
    系统设计的主要方向以及相关要点:

    在系统设计的阶段,主要工作涉及到了绝大多数都是技术以及专业知识
    为了满足用户的需求,在系统项目的设计过程中,可以对之前已经得出的系统项目分析结论作出一些修改,当然,这是基于非原则性上的
    使整个项目系统最终可以获得成功,不仅仅需要完善的分析,严谨的设计,更需要系统项目的设计环境。这个环境不仅仅是技术环境与管理环境,更是两者的有效结合。因此,这是急不可缺的重要一点

    有上述可知系统设计的要点,那么为了更好地设计系统项目就需要了解系统设计的原则:

    易用性原则:对项目做系统设计是为了,开发出的系统项目,可以满足用户提出的需求,达到用户的满意。这种满足需求表现在各个方面,例如:用户的业务需求,用户的逻辑需求,以及使用户处理部分业务时候更加简便,提高用户的用户体验
    开发阶段原则:开发项目系统软件,在系统技术选择阶段主要是站在系统的数据结构的角度进行设计与开发,而实现功能阶段则有不同,这是需要站到用户需求以及开发人员实现的角度考虑的
    业务完整原则:设计实现的项目系统软件,要保证在完成业务的同时保证数据的完整性,减少数据的无处,例如数据库中常常出现的脏读,误读等数据误差
    规范化的业务原则:在最初的设计阶段中,系统主要是完成用户需求要求的业务,但是在实际的操作总。对于系统项目的要求是更高的,它不仅要正确的完成用户的业务要求,也要面对完善的业务流程,以及系统安全性

    3.2 系统功能分析作为网上订餐管理系统主要是为顾客提供便捷,全面的订餐服务,重点要放在面对顾客的页面功能上,其次是管理员对餐品以及餐厅的管理,系统主要模块的设计:

    前台模块

    食品展示模块食品查询模块购物车模块收银台模块用户维护模块订单查询模块公告模块
    后台模块

    食品管理模块用户管理模块管理员维护模块订单管理模块公告管理模块留言管理模块

    如图3-1系统功能层次图所示。
    主要包括这几个方面,其中顾客订餐功能模块是主要重点模块,其次是管理员管理功能模块。当订餐系统管理员使用拥有管理权限的管理员用登录管理员页面的时候。可以看到目前订餐系统中保存的用户信息数据,菜品的数据,员工的数据以及状态,订餐的具体信息,采购原材料的具体情况,以及对顾客页面的管理,例如:留言板,以及营养小贴士等等。通过管理员对餐厅的管理,给予顾客最好的网上订餐服务。
    顾客订餐功能的相对应的模块:主要是顾客进入订餐系统网站之后,可以看到整体的订餐系统网站结构,进行系统的客户端登录,注册,以及对现登陆用户的信息修改,搜索菜品,点餐,订餐,支付,留言的相关功能,通过众多的订餐系统功能。
    管理员系统管理功能相关模块:主要是餐厅管理员从后台管理页面登录管理系统之后,对订餐系统的一些具体业务的调整,可以注册新管理员,以及对现有登录管理员信息的修改,查看分析管理目前注册的顾客的信息,查看修改调整现有菜品的具体情况,新增,删除,完善菜品;对目前餐厅原材料的采购和统计;以及对餐厅员工的管理,新增删除和调整状态;更重要的是可以对目前已知订餐的及时管理,还有就是对顾客订餐页面的一些人性化管理,查看顾客留言,修改给顾客查看的营养小贴士。
    通过这个两个主要的模块,可以完成订餐系统的综合管理,包括了顾客的主要功能,注册,登录,点餐等;以及管理员对餐厅多方面的管理,完成管理员对顾客的服务交互。

    3.3 系统用例图通过管理员用例图,可以清晰的,直观的看到管理员在网上订餐管理系统中对用户订餐以及用户本身的一些主要的操作:

    管理员可以管理餐品信息

    管理员可以添加菜品信息管理员可以删除菜品信息
    管理员可以管理订单信息
    管理员可以管理订餐系统中注册的用户信息

    管理员可以删除用户注册信息管理员可以修改用户信息
    管理员可以对留言进行管理
    管理员可以对用户进行管理

    管理员用例图图,如图3-2所示。

    通过用户(顾客)用例图,可以更加直观的理解在网上订餐管理系统中主要的客户端服务,用户主要使用的功能以及进行的操作,如下:

    游客可以注册会员信息
    游客可以浏览菜品
    游客可以查看公告
    注册会员的用户可以通过注册信息登录
    会员可以在订餐页面浏览菜品信息
    会员可以修改会员信息
    会员可以对正在进行的订餐进行修改
    会员可以对完成的订餐进行查询
    会员可以进行留言

    因此,为了可以更加准确,生动的理解上述所说的用户主要使用的订餐服务功能。绘制用例图就很方便的展示了用户使用主要使用的功能,用户(顾客)用例图,如图3-3所示。

    对于主要功能的业务处理,例如网上订餐管理系统整个业务逻辑处理中最为主要的一部分就是订单处理部分,为了更加直观的理解整个业务逻辑,最对订单的具体的操作如下:

    可以通过用户操作对订单信息,菜品信息进行添加
    可以通过用户操作对订单信息,菜品信息进行处理
    可以通过用户操作对订单信息,菜品信息进行删除

    3.4 系统流程图想对订餐管理系统进行操作,管理员需要登录订餐管理系统的后台管理系统,才能进行一系列的对应管理操作。如果登录时候出现异常,登录失败等状况,系统会要求管理员核对身份密码后重新登录。登录成功之后,就可以通过订餐管理系统的后台模块对整个订餐管理系统进行正确有效的管理。对订单的处理,对菜品的修改,添加,删除。对员工的添加,删除,管理。对原材料的采购登记。订餐管理系统目前的概况,都可以从订餐管理系统的管理员模块进行查看,分析,以及做出及时的相应调整。
    如图,是订餐管理系统的后台管理员模块操作的基本流程图,通过路程图,可以更为直观的看到管理员进行登录操作时的系统业务流程,进行登录,成功进行模块的管理,失败则重新登录等操作,如图3-4管理员流程图所示。

    4 数据库设计与实现4.1 数据库的结构设计一个项目系统软件的设计开发,数据库可以说是必不可少的,没有数据库,用户的数据无法保存,系统的使用人员无法处理数据,那么整个系统可以说是没有意义,以及没有任何使用价值的。在系统项目中,数据库就是用来给用户,管理员等各种使用系统的角色进行数据存储以及取出等交互动作的。不仅如此,根据数据的数据结构的不同,数据库还会对应有不同的存储方式。
    网上订餐管理系统,主要是使用流行的关系数据库MySQL,MySQL是一个开源的免费的关系型数据库,在开发者中极为流行,极为受欢迎。他的众多优点,例如:开源,免费使用,对服务器占用更小,速度更快,是系统更加流畅。这些都使得,系统软件开发的陈本较低,用户体验更佳。
    此次,我们毕业设计“基于JSP的网上订餐管理系统的设计与实现”中主要使用到了MySQL数据库,以下,就对主要的数据表结构进行描述与说明。
    4.1.1 概念结构设计本数据库为满足网上订餐系统的要求,保证使用者信息准确充分的同时,系统的安全性也同样重要。所以,至少要拥有以下功能:

    建立数据表保存使用者注册、登录、验证等功能所需要的数据
    建立两张表,分别保存食品分类信息和食品的详细信息所需要的数据,对食品分类信息分类管理
    使用者确认下单后出现的订单应当记录,包括订单号、地址等详细信息
    订单自动生成滞后,需要记录订单的状态
    除系统管理员外,其他人不能进行系统维护,所以要建立一张表保存管理员的信息
    使用者会对餐品提出意见,那么应该有留言表,留言表内含标题、日期和留言详情

    根据以上信息,网上订餐系统的E-R图如图4-1所示。

    4.1.2 表概要说明网上订餐管理系统主要包括了9张数据表,分别是餐品菜品信息数据表c_book,用户顾客注册数据表表member,管理员数据表admin,餐品菜品类别数据表c_booktype,用户评论数据表comment,订餐车数据表gouwuche,营养小贴士数据表news,订单数据表num,订单详情信息数据表orderbook。其中最为重要的5张数据表,将会在详细描述其表结构。
    4.1.3 数据表的结构餐品菜品信息表c_book
    餐品菜品信息数据表主要是用来保存菜品的基本信息,价格,菜名,描述等,该表的结构如表4-1所示。



    字段名
    数据类型
    长度
    主键否
    描述




    id
    int
    4

    ID


    name
    varchar
    50

    菜名


    author
    varchar
    50

    厨师


    price
    varchar
    50

    价钱


    number
    varchar
    50

    编号


    type
    varchar
    50

    类别


    Sum
    varchar
    50

    数量


    Remark
    varchar
    50

    描述


    tate
    varchar
    50

    原材料


    imgpath
    varchar
    150

    菜品图片



    管理员信息数据表admin
    管理员信息数据表,主要是适用于保存管理员的基本信息。表结构如表4-2所示。



    字段名
    数据类型
    长度
    主键否
    描述




    id
    int
    4

    ID


    name
    varchar
    50

    用户名


    quanxian
    varchar
    10

    权限


    pwd
    varchar
    50

    密码



    菜品类型数据表 c_booktype
    菜品类型数据表,主要保存了当前订餐系统的菜品类型,类型可以根据餐厅的需求,管理员对其进行增加,删除,以及修改等操作管理,如表4-3所示。



    字段名
    数据类型
    长度
    主键否
    描述




    Id
    int
    4

    id


    name
    varchar
    50

    菜品类型名



    用户(顾客)注册信息数据表member
    用户注册信息数据表主要保存了,使用订餐管理系统的用户注册的信息,这张数据表极为重要,表结构如表4-4所示。



    字段名
    数据类型
    长度
    主键否
    描述




    Id
    int
    4

    id


    name
    varchar
    50

    用户名


    pwd
    varchar
    50

    密码


    sex
    varchar
    50

    性别


    realname
    varchar
    50

    真实姓名


    age
    varchar
    50

    年龄


    card
    varchar
    50

    身份证号


    address
    varchar
    150

    地址


    phone
    varchar
    50

    电话(手机)


    email
    varchar
    50

    电子邮件


    code
    varchar
    50

    邮政编码


    type
    varchar
    50

    会员



    订单详情信息数据表orderbook
    订餐详细信息数据表,主要记录了顾客订餐之后,完成的订餐,订餐中主要记录了此时用户完成的订单的详细信息。数据表的结构如表4-5所示。



    字段名
    数据类型
    长度
    主键否
    描述




    id
    int
    4

    id


    userid
    varchar
    50

    用户id编号


    bookid
    varchar
    50

    菜品id标号


    booksum
    varchar
    50

    菜品数量


    times
    varchar
    50

    订餐时间



    5 系统的实现5.1 前台模块首页作为网上订餐管理系统,展现给用户的客户端前台页面是整个项目中最为重要的一环,而首页也是使用户的留下主要印象,重要的得分点之一。一个好的首页能为系统做良好的推广效应,展现系统的主要功能,使得用户可以通过简单快捷的熟悉上手,掌握使用方法,实现自己当前的需求。前台客户端页面首页,运行效果如图5-1。

    如图5-1,我们可以看到,用户使用的首页展示了系统客户端的主要功能,包括,用户的登录,一些管理员希望用户看到的信息,以及目前餐厅主要的菜品,还有就是重要的模块功能导航栏,通过导航栏的点击,用户可以进入相应的功能模块,实现自己目前的需求,包括:详细的点餐,会员中心,订餐车,留言,找回密码等主要用户使用功能。
    首页的部分JSP页面代码:
    <table border="0" width="99%" cellspacing="0" cellpadding="0"height="100%"><tr><td><% ArrayList alNewly = (ArrayList) request.getAttribute("books"); ArrayList alType = (ArrayList) request.getAttribute("type"); int tem = 0; int x = 0; if (alNewly.size() % 3 == 0) { tem = alNewly.size() / 3; } else { tem = alNewly.size() / 3 + 1; }for (int n = 1; n <= tem; n++) { %><table cellspacing="0" cellpadding="3" width="710" border="0"><tr><% for (int i = n * 3 - 3; i < alNewly.size(); i++) { ArrayList alNewlyRow = (ArrayList) alNewly.get(i); %><td align="middle" width="710"> <table border="0" cellspacing="0" cellpadding="0"><tr><td colspan="2" align="center" bgcolor="#FFE3BB"><font color="#ff9900"><% for (int j = 0; j < alType.size(); j++) { ArrayList alTypeRow = (ArrayList) alType.get(j); if (alTypeRow.get(0).equals(alNewlyRow.get(8))) { %><a href="servlet/SearchServlet?types=<%=aTypeRow.get(0)%>"><%=alTypeRow.get(1)%></a><% break;}}%></font>
    5.2 用户注册登录管理用户在使用订餐管理系统客户端页面进行订餐。首先需要登录系统,登录之后才能享受订餐系统带来的便捷快速的订餐服务,如果当前还没有可以登录的账号,首页提供有注册用户的入口。针对已经登录的用户,若果想对自己当前所使用的用户信息进行一些调整,系统也提供了会员中心管理页面,来满足此类用户的需求。如图5-2为用户登录功能的页面:

    用户进行登录之后就可以进行点餐,搜索等相应功能的操作了。用户登录的程序流程图如图5-3所示。

    在用户进行注册成为系统的正式用户之后,就可以进行功能的使用了,但是如果出现对当前用户信息的变更操作,就可以在用户的会员中心,对当前登录的用户信息进行修改,如图5-4为用户会员中心页面效果图:

    5.3 用户订餐管理功能订餐管理系统,作为用户使用的客户端的主要功能就是给用户带来便利的网上点餐服务,此次设计实现的基于JSP的网上订餐管理系统,点餐服务主要通过两个页面来展示菜品使用户进行点餐操作,一是首页点餐,首页会展示目前主要的菜品,以及销售排行和新上菜品,根据这些推荐信息,可以给用户带来更加贴心的用户体验;二是搜索点餐,可以通过首页上方的工具栏,点击进入搜索点餐页面,通过菜品的名称或者菜品所属的类别进行针对性的搜索,然后进行点餐,如图5-5为首页点餐页面效果图。

    如图5-6为搜索点餐页面效果图。

    搜索点餐页面,通过针对性的搜索可以使用户快速的找到自己需要的菜品,进而完成自己的点餐过程。
    进行菜品搜索的servlet部分主要代码是:
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Validate vd = new Validate(); String name = vd.getUnicode(request.getParameter("name")); String types = vd.getUnicode(request.getParameter("types")); String sql = "select * from s "; String[] args = {"id","name","author","publishing","number","price","storage","brief","type","tate","sums","imgpath","price1","sums1"}; if(name != null && !name.equals("")){ sql += "where name like '%"+name+"%'";//构建对菜品名称查询的SQL语句 } if(types != null && !types.equals("")){ sql += "where type='"+types+"'";//构建对菜品类别查询的SQL语句 } SelectBean sb = new SelectBean(); ArrayList al = sb.select(sql, args); request.setAttribute("search", al); RequestDispatcher rd=request.getRequestDispatcher("/qiantai/search.jsp");//跳转到前台菜品搜索页面 rd.forward(request,response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); }
    当用户找到自己心仪的菜品之后,进行点餐操作,所选菜品点餐成功之后,将跳转到订餐车页面,订餐车页面将展示目前为止,用户所选的菜品,如图5-7为订餐车页面效果图。

    在购物车页面中,用户可以清晰的看到目前所点的菜品信息,也可以根据目前自己的需求对已经点的菜品进行操作,例如修改数量,或者删除目前选中的菜品,甚至清空,如果认为还有所需要的菜品,可以点击继续点餐,进入点餐页面,继续点餐操作。当用户认为菜品足够,可以点击收银台,进行订单的提交。
    进行提交之后,将进入收银台页面,点击在线支付,将提供支付宝链接,这样就可以支持网上在线支付,使得用户可以付款进而完成当前的订单。如图5-9为收银台页面效果图。

    5.4 用户其他功能操作页面网上订餐管理系统,不仅能让用户进行注册,登录,修改信息的操作,更重要的是让用户得到良好的订餐功能体验。因此,用户除了可以操作上述的订餐页面之外,也可由有其他更加人性化的功能,例如在此次毕业设计“基于JSP的网上订餐管理系统”中出现的营养小贴士,以及在线留言功能。
    营养小贴士可以用过管理员在后台进行编写,让点餐的用户看到,提供更加贴心的服务,而在线留言功能可以让用户对当前订餐管理系统中存在的问题,以及改进意见进行表达,达到更好的交互体验。如图5-10为用户在线留言页面效果图。

    5.5 后台管理员登录,注册功能作为一个订餐管理系统,仅仅有用户功能的页面是远远不够的,要提供更加全面的服务,为餐厅管理员提供功能管理页面就显得十分重要。通过系统的后台管理管理页面,对餐厅做出实时的管理,了解用户点餐情况以及目前员工的管理,这样才能更好运作系统,使得用户拥有更好的用户订餐体验。
    如图5-11为后台管理员登录页面效果图,5-11为注册管理员,以及修改管理员页面效果图。

    通过登录,管理员可以进入后台管理页面对订餐系统进行管理,可以对当前登录管理员进行修改以及添加新管理员。

    5.6 后台管理员菜品管理管理员通过添加新菜品,以及修改原有菜品,对订餐系统中的菜品进行调整,通过添加菜品的类别可以对菜品进行更加完善的管理。添加菜品时候,通过添加菜名,原材料,价格,图片,以及添加目前拥有的菜品类别等信息,来给用户展示一道菜的方方面面,这样使用户通过网络放心的进行订餐。如图5-13为添加菜品页面效果图。

    5.7 后台员工及会员管理管理员登录后台管理系统之后,不仅能对现有系统注册的会员进行管理,还可以对当前餐厅的员工进行管理,可以添加,删除,修改员工信息,根据目前员工的工作状态也可以在系统中进行标注。添加了员工搜索功能,这样方便了网上订餐管理系统,后台管理模块对员工的综合管理,如图5-14为员工管理页面效果图。

    5.8 后台材料采购管理作为一个订餐管理系统,要将每一天做菜使用的原材料进行统计管理,这样才是一个完善的订餐管理系统。对于原材料采购的记录管理,这样更能方便餐厅管理员,对整个餐厅进行全面的管理,做到对每一天的食材的把控,部分食材采购量的调整,对餐厅运营的成本的管理把控。如图5-15为原材料采购管理页面效果图。

    通过对原材料的统计把控,以及对一段时间的采购单种类及数量的分析,可以知道什么时候需要采购什么材料,采购的数量的参考量,采购的具体方向。对近期,原材料价格走向进行统计分析,得出对餐厅最为合适的采购方案,避免不必要的采购,或采购的数量不准确,导致的餐厅管理成本的提高,这都是需要注意以及及时避免的。
    5.9 销售订餐及统计管理作为网上订餐管理系统,对于当前订餐订单的管理是不可或缺的,因为只有对近期订单进行分析才能知道,用户喜欢的菜品,进而进行针对化的应对,挺高服务质量,对销量高的菜品背后的工作者—厨师,进行奖励管理,提高工作效率,菜品的质量保证。对近期采购单的统计,有效的看出采购方向,和采购数量,为今后采购提供了有力的数据参考保障,避免采购人员出现不必要的事物,餐厅承担不必要的损失。如图5-16为销售订单管理页面效果图。

    如图可以看到,管理页面提供了多样的搜索条件用来搜索符合条件的订餐,例如:用户id,菜品名称,订购数量,这些搜索条件可以快速定位符合条件的订单,然后反馈给管理员来进行订单的管理。
    除此之外,还有统计管理功能,如图5-17为统计管理功能页面效果图:

    如图,统计管理页面可以清晰,完整的看到当日的订餐销售量,销售信息,以及当日对原材料的采购量信息,这方便了管理员对餐厅的管理,也为用户提供快速,优质的使用体验实现了坚实的保障。
    使管理员对当前餐厅的实时状况有了深刻的认识,哪些菜品销量高,需要提前准备,原材料需要大量采购;哪些菜品销量过低,需要减少原材料的采购,甚至下架。近期的用户更喜欢,哪些类别的菜品,是否与天气季节相关,需要对员工厨师进行具体化的调整,提供了有力的数据佐证,与数据分析的资料。这都对今后餐厅的发展十分重要,也是网上订餐管理系统可以被餐厅使用的重要原因之一。
    6 系统测试在大学四年的专业知识学习中,可以得知。作为完整的规范的软件开发流程,在完成系统设计,编码开发之后,进行软件测试是非常重要的一环。是对完成开发,即将投入使用的系统的一次性能以及质量的综合鉴定。在项目正式上线使用之前,进行的必要工作。也是对项目最初的需求分析,系统的总体设计,编码开发的检验,多方面工作的综合最终审核。
    6.1 测试方法在项目进行完整的整合与交互中,对项目系统进行全面的测试,对项目的整体进行问题的查找,在这个过程中耗时相对而言较多。但是也正是因为系统测试的存在,使得系统有了综合质量的保证。
    为了确保网上订餐系统的稳定运行,本节对主要功能模块进行测试。
    6.2 测试流程写好测试的数据以及案例,并对测试数据进行设计逻辑的处理,得出期望结果。
    6.2.1 前台首页测试
    查询模块的测试:首先点击主页正中间的查询栏,在查询栏里中输入要查找的菜品关键字,如果弹出所查找菜品的信息,则说明该模块可行。对该模块进行大量数据的测试,验证其成功无错误
    菜品分类浏览模块的测试:单击页面左边的菜品分类信息,选定某一种类后,系统会弹出属于该类别的所有菜品信息。对给模块进行大量数据的测试,验证其成功无错误,该模块能够完整地实现功能

    6.2.2 购物车模块测试在本模块中首先对修改数量单元进行了测试,如果填写的数量为可行的有效数字如1、2、3,则系统提示修改成功,如果输入的制服非法,系统默认修改数量为1。通过随机数据的测试,验证其成功无错误。假如使用者订购了同一个商品,系统就会对该商品的购买数量进行累加。
    然后对购物车是否能满足使用者的购买数量进行测试,向购物车中添加大量的食品,查看购物车是否会发生崩溃现象。经过测试,购物车完全满足设计要求,达到了预期目标。
    6.2.3 菜品管理模块测试
    添加功能的测试:在菜品添加的功能下,对于已经选定的菜品名、菜品信息、菜品的图片、价格、特价、菜品种类进行添加。通过下拉的选择列表选择菜品的类别,对于菜品图片的添加,需要选择本地的菜品图片,然后上传,当所有必须的食品信息都已经填写完毕的时候,即可上传添加。完成添加以后,随机使用几组不完整的数据对本功能进行测试,均显示失败
    删除功能的测试:以上述添加的这一条记录为例,点击删除按钮,会跳出是否删除的提示信息,点击确定按钮之后,系统返回删除成功的信息。对于菜品分类信息的删除,则需要在本分类之下已经没有菜品信息,否则将不能删除

    6.2.4 会员注册模块测试在会员注册模块中涉及到了三项数据,项目分别为密码和确认密码、使用者真实姓名、住址、性别、E_mail、QQ。测试这个模块准备的数据有:

    979332、979332、王艺博、太原市万柏林区、男、123456@qq.com、123456
    岑志云、12345、1234岑志云、太原市万柏林区、男、bzhi@123.com、6434634

    点击注册按钮,输入第一组数据,单击注册按钮网站会提示表单信息不能为空,因为表单信息要全部填写,而昵称没有填写。接着测试第二组数据,两次所输入的密码并不一样,系统会弹出提示。
    6.3 系统测试结果当本次毕业设计完成完整的项目开发之后,对本次的“基于JSP的网上订餐管理系统设计与实现”,进行了相应的测试,主要的情况如下:
    在项目开发的过程中,每一个进程的每一步都需要被全面的考虑到,从而确保系统在个个时期具备可控性和稳定性。本章注重对前台首页、购物车模块、使用者注册模块和商品管理模块进行了详细的测试说明。对这些模块进行大量数据的测试,验证其成功无错误。
    参考文献[1] 康牧,JSP动态网站开发实用教程,清华大学出版社,2009.
    [2] 戴维尔,JavaScript程序员教程,电子工业出版社,2010.
    [3] 杨学瑜,高立军,软件开发过程与项目管理,电子工业出版社,2008.
    [4].唐友国 湛洪波著.JSP网站开发详解.电子工业出版社2008年10月.
    [5]卫红春等著.信息系统分析与设计[M].北京.清华大学出版社.2009.
    [6] 张文静 林琪著.JSP程序设计.人民邮电出版社.2005.
    [7] 张孝祥、徐明华, JAVA基础与案例开发详解, 清华大学出版社, 2009.
    [8] 张洁才,Java web应用开发教程,科学出版社,2005.
    [9] 戴维尔,JavaScript程序员教程,电子工业出版社,2010.
    [10] James D. McCaffrey等著.NET软件测试自动化之道[M]. 北京.电子工业出版社.2007.
    [11] 黎连业、王华、李淑春,软件测试与测试技术,清华大学出版社,2009.
    [12] 张大方 李玮等著.软件测试技术与管理[M].湖南.湖南大学出版社,2007.
    [13] (美)Elliotte Rusty Harold著.Java Network Programming.东南大学出版社 .2005.
    [14] (美)H.M.Deitel,P.Jdeitel著.Java程序设计教程(第五版). 清华大学出版社.2004.
    [15] (美)David flanagan著.Java技术手册(第五版).东南大学出版社.2006.
    [16] (美)John J.Patrick著.SQL基础(第二版).清华大学出版社.2004.
    12 评论 251 下载 2020-08-04 12:30:59 下载需要13点积分
  • 基于MFC实现的俄罗斯方块游戏

    1.需求分析需要实现的功能:

    使用键盘方向键实现方块的控制和移动
    程序能够对方块的位置进行判断,防止方块移动出界


    当满足消行条件时,能够及时消去满足条件的行数,其他保持不变
    实现加分和等级晋级,以及游戏难度增加等附加功能

    2.设计分析2.1 方块显示可以采用二维数组来对方块进行控制变化和显示。1-代表有方块,0-无方块。如:
    Now[4][4]={ 1,1,1,0 0,1,0,0 0,0,0,0 0,0,0,0};

    2.2 背景数组ArryBK[18][12]={0,0,…,0};
    屏幕绘制采用双缓冲,现在内存绘制,最后一次性送到显存;
    2.3 数据结构设计定义结构体
    struct shape { int ary[4][4]; //方块数组 CPoint pt; //起点(方块左上角),X-所在行,Y-所在列};
    定义类
    class CRussia {public: //构造函数,用来初始化数据成员 CRussia(); virtual ~CRussia(); //重新开始游戏 void GameAgain(); //判断游戏是否结束 bool IsOver(); //将当前形状数组附加到背景数组 void Attch(); //获得当前速度,用开控制游戏难度 int GetSpeed()const; //在内存dc中画出当前图形 void DrawNow(CDC *); //在内存dc中画出右边分数,等级,和下一图形 void DrawScores(CDC *); //在内存dc画出背景 void DrawRussia(CDC *); //消行 void DeleteLines(); //当用户按下方向键上时调用,用来变换矩阵 void InvertShape(); //用来产生随机矩阵图形 void RandShape(); //用来判断方向,当用户按下方向键,左(2),右(3),下(1)时调用 void Judge(int i=1);//默认判断方向为下private: bool m_bOver; //判断是否结束 int m_scores; //玩家得分 int m_speed; //时间间隔,用来设置定时器控制难度 int m_level; //玩家级数 shape Now; //当前矩阵图形 shape Will; //下一矩阵图形 int Russia[18][12]; //背景矩阵 CBitmap m_fangkuai; //方块位图};
    3.设计实现游戏数据初始化
    方块初始起点设置成第0行,第6列。
    CRussia::CRussia(){ m_level=1; m_scores=0; m_speed=600; //600ms间隔 m_bOver=false; m_fangkuai.LoadBitmap(IDB_FANGKUAI); int i,j; for(i=0;i<18;i++) for(j=0;j<12;j++) { Russia[i][j]=0; //背景数组清空 } for (i=0;i<4;i++) for(j=0;j<4;j++) { Now.ary[i][j]=0; //当前矩阵数组清空 Will.ary[i][j]=0; //下一矩阵数组清空 } //当前矩阵图形初始化 Now.ary[0][0]=1; Now.ary[0][1]=1; Now.ary[1][0]=1; Now.ary[2][0]=1; Now.pt.x=0; Now.pt.y=6; //下一矩阵图形初始化 Will.ary[0][0]=1; Will.ary[0][1]=1; Will.ary[1][0]=1; Will.ary[2][0]=1; Will.pt.x=6; Will.pt.y=0;}
    方块,背景及玩家信息屏幕绘制实现
    当前方块图形绘制,由于Now.pt.x表示所在行数,Now.pt.y表示所在列数。正好与默认坐标映射模式相反,所以在BitBlt()函数的前2个参数的X,Y坐标时,调换了行和列的坐标值。
    void CRussia::DrawNow(CDC *pDc){ // 创建内存dc CDC memDc; memDc.CreateCompatibleDC(pDc); int nDC=memDc.SaveDC(); //初始化内存dc memDc.SelectObject(m_fangkuai); for (int i=0;i<4;i++) for(int j=0;j<4;j++) { if (1==Now.ary[i][j]) { //将方块图案绘制到缓冲内存dc中 pDc->BitBlt(30*(j+Now.pt.y),30*(i+Now.pt.x),30,30,&memDc,0,0,SRCCOPY); } } memDc.RestoreDC(nDC); }
    背景数组绘制。
    void CRussia::DrawRussia(CDC *pDc){ CDC memDc; memDc.CreateCompatibleDC(pDc); int nDC=memDc.SaveDC(); memDc.SelectObject(m_fangkuai); for (int i=0;i<18;i++) for(int j=0;j<12;j++) { if (1==Russia[i][j]) { pDc->BitBlt(30*j,30*i,30,30,&memDc,0,0,SRCCOPY); } } memDc.RestoreDC(nDC);}
    游戏附加信息绘制。
    void CRussia::DrawScores(CDC *pDC){ CDC memDc; memDc.CreateCompatibleDC(pDC); int nDC=memDc.SaveDC(); memDc.SelectObject(m_fangkuai); for (int i=0;i<4;i++) for(int j=0;j<4;j++) { if (1==Will.ary[i][j]) { pDC->BitBlt(30*(j+13),30*(i+8),30,30,&memDc,0,0,SRCCOPY); } } memDc.RestoreDC(nDC); int nOldDC=pDC->SaveDC(); CFont font; font.CreatePointFont(300,"华文楷体"); pDC->SelectObject(&font); CString str; pDC->SetTextColor(RGB(20,255,0)); pDC->SetBkColor(RGB(255,255,0)); str.Format("%d",m_level); pDC->TextOut(430,120,str); str.Format("%d",m_scores); pDC->TextOut(430,2,str); pDC->RestoreDC(nOldDC);}
    键盘方向控制实现
    默认方向向下,当方块向下移动时,遍历方块数组依次判断每个值为1的方块的正下方方块是否有方块阻挡,以及判断是否碰到底界,如果遇到阻挡或碰到底,则将当前方块数组附加到背景数组,并返回结束本次移动,否则Now.pt.x++方块起点的X值加1。
    void CRussia::Judge(int i){ //1-下; 2-左 3-右 int j=0,k=0; switch(i) { case 1: for ( j=0;j<4;j++) for( k=0;k<4;k++) { if (1==Now.ary[j][k]) { //判断是否遇阻,以及是否遇到底界 if (1==Russia[Now.pt.x+j+1][Now.pt.y+k]||17==Now.pt.x+j) { if (0==Now.pt.x) { m_bOver=true; MessageBeep(1); } Attch(); return; } } } Now.pt.x++; break; case 2: for (j=0;j<4;j++) for(k=0;k<4;k++) { if (1==Now.ary[j][k]) { //判断是否遇阻,以及是否遇到左边界 if (1==Russia[Now.pt.x+j][Now.pt.y+k-1]||0==Now.pt.y) { MessageBeep(1); return; } } } Now.pt.y--; break; case 3: for (j=0;j<4;j++) for(k=0;k<4;k++) { if (1==Now.ary[j][k]) { //判断是否遇阻,以及是否遇到右边界 if (1==Russia[Now.pt.x+j][Now.pt.y+k+1]||11==Now.pt.y+k) { MessageBeep(1); return; } } } Now.pt.y++; break; default: break; }}
    Attch()函数的实现,遍历当前方块数组,值为1的坐标赋值给背景数组对应的点。并判断是否可以消行。
    void CRussia::Attch(){ for (int i=0;i<4;i++) for(int j=0;j<4;j++) { if (1==Now.ary[i][j]) { Russia[Now.pt.x+i][Now.pt.y+j]=1; } } DeleteLines(); RandShape();}
    DeleteLines()的实现,遍历背景数组,从第一行开始判断。并用nRet记录可消行的行数值。如果nRet不为0,则消行;
    void CRussia::DeleteLines(){ static int nflag=1; int nRet=0; bool bRet=true; for (int i=0;i<18;i++) { for (int j=0;j<12;j++) { if(0==Russia[i][j]) { bRet=false; break; } } //判断是否有一整行全部为1,即达到消行状态 if (bRet) { nRet++; } bRet=true; } //可消行数为1行 if (1==nRet) { m_scores+=1; } //可消行数为2行 if (2==nRet) { m_scores+=3; } //可消行数为3行 if (3==nRet) { m_scores+=5; } //可消行数为4行 if (4==nRet) { m_scores+=10; } if (m_scores>50*nflag) //加分,晋级,及难度控制 { m_level+=1; m_speed-=50; nflag++; } if (nRet!=0) { bool bFlag=true; for (int i=0;i<18;i++) { for (int j=0;j<12;j++) { if(0==Russia[i][j]) { bFlag=false; break; } } //为了记录所在行数值i,采用一行一行消去 if (bFlag) { //可消行,i值记录了可消的行所在的行数 for(int m=0;m<i;m++) for (int k=0;k<12;k++) { //第i行以上整体下移一行 Russia[i-m][k]=Russia[i-m-1][k]; } } bFlag=true; } }}
    方向上键控制,用来转换方块矩阵图形InvertShape()。
    void CRussia::InvertShape(){ int i=0,j=0,MaxV=0; for ( i=0;i<4;i++) for( j=0;j<4;j++) { Now.ary[i][j]=0; //清空 } static int k=2; switch(k) { case 0: Now.ary[0][0]=1; Now.ary[0][1]=1; Now.ary[1][0]=1; Now.ary[1][1]=1; break; case 1: Now.ary[0][0]=1; Now.ary[0][1]=1; Now.ary[1][0]=1; Now.ary[2][0]=1; break; case 2: Now.ary[0][0]=1; Now.ary[0][1]=1; Now.ary[1][1]=1; Now.ary[2][1]=1; break; case 3: Now.ary[0][0]=1; Now.ary[1][0]=1; Now.ary[1][1]=1; Now.ary[1][2]=1; break; case 4: Now.ary[0][2]=1; Now.ary[1][0]=1; Now.ary[1][1]=1; Now.ary[1][2]=1; break; case 5: Now.ary[0][0]=1; Now.ary[0][1]=1; Now.ary[0][2]=1; Now.ary[1][0]=1; break; case 6: Now.ary[0][0]=1; Now.ary[0][1]=1; Now.ary[0][2]=1; Now.ary[1][2]=1; break; case 7: Now.ary[0][1]=1; Now.ary[1][0]=1; Now.ary[1][1]=1; Now.ary[2][0]=1; break; case 8: Now.ary[0][1]=1; Now.ary[0][2]=1; Now.ary[1][0]=1; Now.ary[1][1]=1; break; case 9: Now.ary[0][1]=1; Now.ary[1][0]=1; Now.ary[1][1]=1; Now.ary[1][2]=1; break; case 10: Now.ary[0][0]=1; Now.ary[0][1]=1; Now.ary[0][2]=1; Now.ary[1][1]=1; break; case 11: Now.ary[0][0]=1; Now.ary[1][0]=1; Now.ary[2][0]=1; Now.ary[3][0]=1; break; case 12: Now.ary[0][0]=1; Now.ary[0][1]=1; Now.ary[0][2]=1; Now.ary[0][3]=1; break; } k=++k%13; //判断是否出右边界,出界则向左移动方块起点 for ( i=0;i<4;i++) for( j=0;j<4;j++) { if (1==Now.ary[i][j]) { if (12==Now.pt.y+j) Now.pt.y-=1; if (13==Now.pt.y+j) Now.pt.y-=2; if (14==Now.pt.y+j) Now.pt.y-=3; } }}
    4.游戏测试经多次测试,游戏可以按照设计文档的功能需求运行;

    5 评论 88 下载 2019-06-06 11:04:40 下载需要11点积分
  • 基于Python的PyGame实现的超级马里奥游戏

    一、选题在《实践:数据结构与算法实践》中选择了“超级马里奥第一关”为最后作业的题目。
    超级马里奥是红白机上的横版过关类游戏。
    功能特性在于在实现人物移动的同时,要使背景的地图也要进行移动,还有砖块、怪物等其他要素也要进行移动,因为只有让两者一起进行移动,才能让人物和地图和其他的要素保持相对的位置。后期又加入了音效和美化了一下界面。
    二、方案该选题难题主要分为以下几点实现。

    实现了人物的动态移动效果。主要是使用了MyLibrary.py里精灵类来实现的,该类在继承pygame自带的基础类上,加入符合本游戏需要运作的相关代码。在主文件main.py中我使用了四个精灵去实现人物的移动:向左走、向右走、向左跳、向右跳。然后通过一些变量继承来让马里奥实现了在图上只有一个存在且能完成四个动作。但也因为我这样设计导致了后面难以使用Pygame的碰撞检测函数,改用了点坐标去判断,有点累赘。
    由于马里奥掉下坑和其他一些需要根据位图来判断地方和屏幕上直接绘图的数据时不同的。所以要实现人物移动的同时,要让地图、问号砖块、砖块、旗画在当前的屏幕上,以此必须要这些要素也实现相对的移动。当马里奥运行到屏幕中间时,屏幕会向左运动,而马里奥横坐标会固定在屏幕中间,以此形成一种马里奥在移动的错觉,其他的要素(问号砖块、怪物)也是在此条件下发现地图在进行相对移动时,这些要素也会进行向左移动,以此保证一种没有动的错觉。
    关于水管和其他三角形障碍物的判定,由于马里奥精灵是使用了四个精灵来实现的,所以使用pygame自带的碰撞检测的话也不是很好用,我就直接采用了点坐标判断的方式,为了能更直观的去写代码。
    在最后阶段,加碰砖块的特效、金币闪烁的特效,蘑菇出现的特效、所有的特效。这里也使用了精灵去实现特效。
    由于时间有限,最后并没有实现马里奥吃蘑菇变大和吃花变无敌的特效,很遗憾。

    三、关键技术关键技术分为以下几点:

    马里奥动态实现。马里奥动态实现时调用了四种不同的精灵去实现,根据键盘的不同反应会调用不同的精灵,以此实现了马里奥向左走、向右走、向左跳、向右跳的动态画面。这样写的好处是我可以实现空中变向和空中控制降落地点的原作没有的功能。
    碰撞检测。由于马里奥动态实现不是单个精灵的问题,这里是采用了点坐标判断的方式,也就是meetobstacle.py实现的代码相当多,数据也是很复杂。
    马里奥撞击问号砖块的判定问题和特效问题。也是有一个碰撞检测的函数去进行了判断,然后加载动画效果,再最后在原地方画上另外一种砖块。
    怪兽的移动、死亡、杀死马里奥。首先要实现怪物和马里奥之间相对距离随地图的改变而变化的问题,是地图移动时,怪物还是以一种原来的速度去移动。然后追加怪兽被踩时死亡效果和杀死马里奥的判定。

    四、结果和效果人物移动和跳跃的效果可能有点违和,没有实现原作的吃蘑菇升级功能和吃花无敌功能,额外实现了空中变向和可以玩家在跳跃时选择落地点的功能。






    五、总结和不足前两周的时候,我本来是打算实现超级马里奥,但发现运用c语言去实现的话问题会有很多,于是后来就选择了中国象棋。在稍微接触了一点Python和pygame的一些相关知识后,就决定用python去实现了这个之前有点遗憾的游戏。从结果上也可以看出,Python由于拥有功能更加完善和多样的库,所以使用Python去实现像超级马里奥之类的动作较多、场景较多的游戏是比C语言要更完善的。Python的库真的很多、很方便,利用好这些库的话,可以轻松实现C语言很难实现的功能。
    不足之处是没有考虑到将判定的坐标进行变量化,而是直接用数据去进行了判定,如果在一开始考虑到这点的话,可以很轻松实现马里奥吃蘑菇变大的功能,但由于写到结尾才发现这个问题,所以就没有实现这个功能,是我一个很大的遗憾。
    11 评论 382 下载 2019-02-22 18:04:00 下载需要12点积分
显示 0 到 15 ,共 15 条
eject