分类

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

资源列表

  • 基于JAVA实现的记忆测试小游戏

    1 需求分析与总体设计1.1 需求分析记忆测试系统是通过回忆法测试记忆能力,测试手段分为初级、中级和高级三个级别,使用该系统以达到测试和锻炼记忆能力的目的。同时保存每个用户的不同等级的成绩。
    在记忆测试系统中,编写6个Java源文件:MemoryGame.java、MemoryTestArea.java、Block.java、ShowRecordDialog.java、Record.java、People.java。
    记忆测试系统的功能结构图如图1.1所示:

    1.2 总体设计模块1.2.1 MemoryGame.java(主类)MemoryTestArea类是主类MemoryGame窗口中的一个JPanel容器,所创见的对象称为“测试区”,这个“测试区”别添加到MemoryGame窗口的中心。MemoryTestArea类主要有6种类型的成员:ArrayList<Block>、String、Record、Timer、File和Thread对象。
    1.2.2 MemoryTestArea.javaMemoryTestArea类是主类MemoryGame窗口中的一个JPanel容器,所创见的对象称为“测试区”,这个“测试区”别添加到MemoryGame窗口的中心。MemoryTestArea类主要有6种类型的成员:ArrayList<Block>、String、Record、Timer、File和Thread对象。
    1.2.3 Block.javaBlock类是Jbubtton的子类,负责为MemoryTestArea类中的ArrayList<Block>数组表提供Block对象。
    1.2.4 Record.javaRecord类是javax.swing包中Jdialog对话框的子类,当用户成功单击出相应级别所要求的图表相同的方块后,Record创建的对象负责保存用户的名字和成绩到相应的级别文件中。
    1.2.5 ShowRecordDialog.javaShowRecordDialog类是java.swing包中JDialog对话框的子类,当用户单击“查看排行榜”时,ShowRecordDialog创建的对象显示用户的成绩。
    1.2.6 People.javaPeople对象封装用户的名字和成绩,以便ShowRecordDialog对象可以按成绩的高低排序用户。
    1.2.7 Backgroundmusic.javaBackgroundmusic类是给系统增加的背景音乐。并且循环播放。
    1.2.8 图像文件hzw0.jpg、hzw1.jpg、hzw2.jpg、hzw3.jpg、hzw4.jpg、hzw5.jpg、hzw6.jpg、hzw7.jpg、hyrz0.jpg、hyrz1.jpg、hyrz2.jpg、hyrz3.jpg、hyrz4.jpg、hyrz5.jpg、hyrz6.jpg、hyrz7.jpg。(系统所需的图像文件,存放于根目录下。)
    2 详细设计
    操作界面设计:编译运行,选择级别,图标游戏开始,如果用户不清楚相同图标的位置时,点击提示
    界面方案:窗口大小:setBounds(100,100,400,360);setVisible(true)
    字体的大小和颜色:hinMessage.setFont(new Font(“宋体”,Font.BOLD,18))
    布局控制:又上到下,先是菜单:选择级别,查看排行榜,选择图标
    提示信息:hintMessage.setText(“您需要用鼠标单击出” +col+“个同样图标的方块” )

    2.1 MemoryGame主类MemoryGame创建窗口如图2.1所示

    2.1.1 成员变量
    bar是JMenuBar类创建的菜单条,可以向bar中添加菜单
    menuGrade、menuResult、menuIcon是JMenu创建的三个菜单,这三个菜单的名称分别是“选择级别”、“查看排行榜”和“选择图标”
    oneGradeItem、twoGradeItem、threeGradeIte是JMenuItem类创建的三个菜单项,被添加到menuGrade菜单中,这三个菜单项的名称分别是“初级”,“中级”和“高级”
    oneGradeResult、twoGradeResult、threeGradeResult是JMenuItem类创建的三个菜单项,被添加到menuResult菜单中,这三个菜单项的名称分别是“初级排行榜”,“中级排行榜”和“高级排行榜”
    hzwImageIcon、hyrzImageIcon是JMenuItem类创建的两个菜单项,被添加到menuIcon菜单中,这两个菜单项的名称分别是“海贼王图标”和“火影忍者图标”
    ileOneGrade、fileTwoGrade、fileThreeGrade和gradeFile是File类创建的四个文件对象。fileOneGrade、fileTwoGrade、fileThreeGrade所引用的文件分别是“初级记忆排行榜.txt”、“中级记忆排行榜.txt”、“高级记忆排行榜.txt”,分别用来写入三个级别的成绩。gradeFile可以是fileOneGrade、fileTwoGrade、fileThreeGrade中的某一个
    imageName是String类型的组件,每个单元是一个图像文件的名字
    memoryArea是测试区对象,由MemoryArea类负责创建
    showDiolag是负责显示成绩的对话框,由ShowRecordDialog类负责创建
    m和n的int型数据,其值可以确定相应级别中测试区中方块的数量,例如,对于中级水平,m=6,n=7,测试区一个有42个方块

    2.1.2 方法
    actionPerformed(ActionEvent)方法是MemoryGame类实现ActionListener接口中的方法,负责执行菜单项发出的有关命令。用户选择菜单中的菜单项可触发ActionEvent事件,导致actionPerformed(ActionEvent)方法执行相应的操作
    MemoryGame()是构造方法,负责完成窗口的初始化
    main(String[])方法是软件运行的入口方法

    2.2 MemoryTestArea类MemoryTestArea创建的测试区如图2.2所示

    2.2.1 成员变量
    row和col的值确定测试区中方块的数量。MemoryTestArea类创建的对象memoryArea是MemoryGame中的成员,memoryArea对象通过调用initBlock(int,int,String[],file)方法将MemoryGame类中m和n的值传递给row和col
    usedTime是用户的用时,单位是秒
    success的值是用户找到的具有同样的图标的方块的个数
    gradeFile是级别文件,memoryArea对象通过调用initBlock(int,int,String[],file)方法将MemoryGame类中的gradeFile的引用传递给memoryArea对象中的 gradeFile
    数组表allBlockList单元的个数是row和col的乘积,它的每个单元存放着一个Block对象。memoryArea对象在调用initBlock(int,int,String[],file)方法时完成对allBlockList单元的初始化,即创建单元中的Block对象
    字符串数组imageFileName中的每个单元是一幅图像文件的文字。memoryArea对象通过调用setImageName(String[])方法将MemoryGame中存放图像文件名字的imageName数组的引用传递给imageFileName
    链表openIconList用来存放用户找到的图标相同的方块上的图标
    链表openBlockList用来存放用户找到的图标相同的方块
    hintThread是用Thread类创建的线程对象,用来提示测试区中的Block上的图标,提示方式是将测试区中的各个Block上图标持续显示1200毫秒
    hintButton是注册了ActionEvent事件的监听器,当单击它时,启动hintThread线程
    showUsedTime显示用户的用时,即显示usedTime的值
    hintMessage根据不同的级别显示相应的提示信息,如该级别需要用户寻找的相同图标方块的数目
    timer是计时器,负责改变usedTime的值
    record负责提供保存成绩的界面,是一个对话框,默认不可见。当用户寻找出级别所要求的相同图标方块的数目后,该对话框可见,用户可以在该对话框中输入姓名,并保存所输入的姓名和usedTime的值到gradeFile指定的级别文件中

    2.2.2 方法
    MemoryTestArea()是构造方法,创建memoryArea对象时需使用该构造方法
    initBlock(int,int,String[],file)方法。memoryArea对象调用该方法将参数的值传递给row、col、imageFileName和gradeFile,并依据这些值设置allBlockList数组表的大小,然后创建allBlockList的单元中Block对象,并设置Block对象上的图标
    setImageName(String[])方法。memoryArea对象调用该方法可以将MemoryGame中存放图像文件名字的imageName数组的引用传递给imageFileName。当用户单击MemoryGame主类窗口的cartImageIcon和animalImageIcon菜单项时,memoryArea对象将调用该方法把存放图像文件名字的imageName数组的引用传递给imageFileName
    actionPerformed(ActionEvent)方法。该方法是MemoryArea类实现的ActionListener接口中的方法。memoryArea中的每个Block对象都注册了ActionEvent事件监听器,当用户单击memoryArea中的某个Block对象时,actionPerformed(ActionEvent)方法将被调用执行,所执行的主要操作是:如果该Block对象未显示图标,并且该Block对象设置的图标和openIconList的中存放的图标相同,就将该图标添加到链表openIconList中,同时将该Block对象上图标显示出来,并将success的值增1;如果该Block对象未显示图标,并且该Block对象设置的图标和openIconLis的中存放的图标不相同,就将openIconList清空,然后再将该图标添加到链表openIconList中,同时将该Block对象上图标显示出来,并将success的值设置成1。但用户单击hintButton按钮时,actionPerformed(ActionEvent)方法将被调用执行,执行的主要操作是启动hintThread线程
    run()方法。该方法是MemoryArea类实现的Runnable接口中的方法,启动hintThread线程后,该方法将执行,其主要操作是将测试区中的未显示图标的各个Block对象上的图标持续显示1200毫秒

    2.3 Block类Block类创建的按钮如图2.3所示









    图标不可见方块
    图标可见方块



    2.3.1 成员变量
    openStateIocn是方块上的图标
    2.3.2 方法
    Block对象调用setOpenStateIcon(ImageIcon)方法可以设置它上面的图标
    Block对象调用openStateIcon()方法可以获得它上面的图标

    2.4 Record类Record类创建的保存成绩对话框,如图2.4所示

    2.4.1 成员变量
    time是用户的用时
    yourName是用户用来输入名字的文本框
    enter,cancel是按钮对象,用户单击enter按钮可保存成绩,单击cancel按钮可放弃保存成绩
    gradeFile是级别文件

    2.4.2 方法
    Record()是构造方法,负责创建record对象
    setGradeFile(File)方法。Record类创建的Record对话框是测试区MemoryTestArea中的一个成员。当用户成功单击出相应级别所要求的图标相同的方块后,测试区弹出Record对话框,Record对话框将调用setGradeFile(File)方法将测试区中的级别文件传递给Record对话框gradeFile
    setTime(int)方法。当用户成功单击出相应级别所要求的图标相同的方块后,测试区弹出Record对话框,Record对话框将调用setTime(int)方法将测试区记录的用户用时传递给Record对话框中的time
    actionPerformed(ActionEvent)是ActionListener接口中的方法,enter和cancel按钮注册了ActionEvent事件,当用户单击enter时,actionPerformed(ActionEvent)方法被调用执行,其操作是将用户在文本框yourName中输入的名字以及time的值保存到gradeFile文件中,然后关闭当前对话框;当用户单击cancel按钮时,actionPerformed(ActionEvent)方法将被调用执行,其操作是关闭当前对话框

    2.5 ShowRecordDialog类ShowRecordDialog类创建的查看排行榜对话框,如图2.5所示

    2.5.1 成员变量
    gradeFile是对话框要读取的文件,该文件存储成绩
    clear是注册了ActionEvent事件的按钮
    showArea文本区显示对话框从gradeFile文件中读出的成绩
    treeSet负责将成绩按高低排序

    2.5.2 方法
    ShowRecordDialog()是构造方法,负责创建showDialog对象
    setGradeFile(File)方法。ShowRecordDialog类创建的ShowRecordDialog对话框是主类MemoryGame窗口中的一个成员。当用户选择窗口上的“查看排行榜”菜单中的菜单项时,ShowRecordDialog对话框调用setGradeFile(File)方法将相应的级别文件传递给gradeFile
    showRecord()方法。ShowRecordDialog对话框调用showRecord()方法读取gradeFile文件中的成绩,为了将成绩按高低顺序显示在showArea文本区中,showRecord()方法根据读取的名字和该名字的对应成绩,创建一个People对象,并将该People对象存放在treeSet树集中
    actionPerformed(ActionEvent)是ActionListener接口中的方法,clear注册了ActionEvent事件,当用户单击clear按钮时,actionPerformed(ActionEvent)方法被调用执行,清除gradeFile文件中的内容

    2.6 People类People类对象中的数据使用户的姓名和成绩,被显示在ShowRecordDialog对话框中shoeArea的文本区中,如图2.6所示

    2.6.1 成员变量
    name是用户的名字
    time是用户的用时

    2.6.2 方法
    getTime()方法返回time
    getName()方法返回name
    compareTo(Object)是comparable接口中的方法,其操作是确定People对象的大小关系

    2.7 Backgroundmusic类Backgroundmusic类添加背景音乐。
    2.7.1 成员变量
    File:需要读取的文件,该文件储存音频文件
    URI:统一资源标识符,是一个用于标识资源名称的字符串
    URL:统一资源定位符,指出文件的位置

    2.7.2 方法
    AudioClip()是用于播放音频剪辑的简单抽象
    aau.loop()循环播放背景音乐
    e.printStackTrace()是深层次的输出异常调用的流程

    3 系统测试记忆测试系统主界面如图4.1所示:

    记忆测试系统选择等级如图4.2所示:

    记忆测试系统选择图标如图4.3所示:

    记忆测试系统初级难度海贼王图标背景测试成功效果图如图4.4所示:

    记忆测试系统高级难度火影忍者图标背景测试成功效果图如图4.5所示:

    记忆测试系统查看排行榜测试效果图如4.6所示

    总结这次课程设计选择做了一个有意思的小系统—记忆测试系统,也算一个小游戏吧。可用于娱乐性的检验个人记忆力。按设计要求,系统的基本功能都已实现,玩家用户进入界面可以自行选择等级测试,本系统提供了三个等级以供选择,分别为初级、中级和高级。还可以根据玩家用户的喜好选择图标类型,本人因为喜爱动漫,就增加了海贼王和火影忍者两种图标。测试完成后会记录玩家用户的用时成绩,并排好序。因为本系统的记忆测试还是有些难度的,所以做了提示功能,玩家可以牺牲游戏时间得到提示。
    此系统值得一提的新增项,就是加入了背景音乐,玩家用户一打开运行此程序,背景音乐就开始播放,并且是循环播放,给以玩家更好的体验。
    本程序还有一些地方做的不够细致,考虑的不够完善。发现了自身的一些知识储备不足,调试程序的时候遇到各种各样的错误提示,这里有同学的大力帮助,还有自己网上查询一些案例分析,慢慢的把程序调试出来了。在最后的阶段遇到的一个图片如何放入运行的窗体的问题,这是最后一步,也是最关键的一步,不知道将图片放入哪个指定的文件夹,后来经过同一组的同学们一起网上查找,自己测试,后来发现原来只要把图像文件放入根目录就行。当时就有种豁然开朗的感觉,或许这就是程序员开发、调试程序的乐趣吧。
    这个记忆测试系统还有许多改进的地方,还有更多的设想。比如:在玩家选中正确图标时、选错图标时、成功完成一次测试时播放不同类型的音效,以此提高玩家的感官体验。在用户玩家选择不同等级测试时,更换不同的背景音乐。在玩机用户完成测试后也播放不一样的音乐。还有这个系统的操作界面改进,初始界面过于单调,略显古板,本想通过更改界面颜色让系统看上去更美观一些。
    本次课程设计收获了很多,做一个系统,需要静心、有耐心、要细心。切实结合用户的使用需求和现实意义去完成设计。不管什么系统,只用运用到实际应用中,才具有现实意义。
    这是一次很不错的开发系统经验。
    1 评论 2 下载 2019-05-19 18:32:02 下载需要13点积分
  • 基于QT和MYSQL数据库实现的学生信息管理系统

    一、使用说明该学生信息管理系统使用的数据库为MySQL,在另外一台电脑上(老师的电脑)运行时运行环境必须满足以下要求:

    那台电脑必须要安装数据库MySQL;
    在那台电脑的MySQL中导入本人数据库脚本文件 studentmanager.sql (该文件已打包好)(在后面写了导入studentmanager.sql 的方法)
    在MySQL的安装目录下的lib文件夹中的libmysql.dll文件复制到Qt安装目录下的bin目录中
    最后在原代码中的globle.cpp 文件中更改连接数据库的账号和密码( 更改QString sqluser=”root” 的值为更改账号,更改QString sqlpass=”123456” 的值为更改密码,此处我的数据库账号为root,密码为123456,此处账号密码要对应自己MySQL账号密码)

    以上步骤若没完成则会编译运行不了!
    studentmanager.sql 数据库导入过程如下所示:

    将studentmanager.sql文件复制到D盘根目录中
    进入MySQL命令行界面
    输入MySQL密码进入
    输入 use studentmanager;SOURCE d:/studentmanager.sql; (source 后面跟的是sql脚本本文件的路径,此处是为什么把该sql文件复制到D盘根目录中;)

    二、studentmanager 数据库表格说明该 studentmanager.sql 有六张表,用Navicat for MySQL (数据库图形界面操作软件)。
    展现如下所示:
    admin表(管理员登录表)

    用该表的username作为账号和password作为密码可登录管理员端
    student表(学生基本信息表)

    用该表的id 作为账号, password 作为密码可登录学生端
    class表(班级信息表)

    course表(课程信息表)

    fee表(缴费信息表)

    score表(分数信息表)

    三、本程序需解决的关键技术问题该学生管理系统主要使用到Qt 的数据库编程开发,在Qt框架下进行数据库的增删查改相关功能开发。
    3.1 如何使用qt 连接数据库连接数据库要使用qt 的QSqlDatabase类,该类提供了数据库连接的相关方法,以及执行mysql的sql 命令的功能。
    3.2 从数据库获取信息乱码问题在连接完数据库时输入以下代码,可解决数据库乱码问题。
    QSqlQuery query(db);db.exec("SET NAMES 'GBK'");
    3.3 登录功能的实现
    在Qt的UI界面将登入界面设计好后实现登录功能
    连接数据库
    通过判断哪个单选框被选中,来判断是学生还是管理员
    从数据库查找相应管理员表,和学生表,通过 while(query.next())循环 一一对从行编辑器中获取的账号,密码与从数据库中获取的账号密码进行匹配,若匹配成功则跳转进入相应的学生端和管理员端界面

    3.4 如何实现间界面间传值界面传值使用全局变量实现的,创建全局变量:新建了一个C++类文件globle。声明全局变量使用关键字extern。在另一个C++类文件中只需要包含globle.h 的头文件就可以使用该全局变量,就能通过全局变量在不同的界面中传值。
    3.5 如何实现界面跳转举个例子:
    this->hide();userlogin *ti=new userlogin;ti->show();
    就先hide当前界面,在创建要新跳的界面对象指针,通过对象指针show跳转后的界面。
    3.6 对于使用qttablewidget 表格类显示所有学生信息的方法此处我用了QVariantList 这个数据结构将从数据库中或取得所有学生信息储存起来。在用嵌套的两个for循环将其展现到qttablewidget 表格中具体代码如下:
    //遍历list_all_student,将获取的学生信息展现到表格tablewidget中for(int i1=0;i1<list_all_student.size();i1++){ int row = ui->tableWidget->rowCount(); ui->tableWidget->insertRow(row); QStringList rowdata=list_all_student[i1].toStringList(); for(int i = 0 ; i <rowdata .size() ; i++) { QTableWidgetItem *item = new QTableWidgetItem; item->setText(rowdata.at(i)); ui->tableWidget->setItem(row , i , item); }}
    3.7 如何实现对数据库进行增删查改具体代码:
    QSqlQuery query(db);db.exec("SET NAMES 'GBK'");query.exec("select dormnum,id,name,sex,bednum,beizhu from student");while(query.next())...........
    只需要更改 query.exec(“select dormnum,id,name,sex,bednum,beizhu from student”);中的sql 命令即可实现增删查改
    添加数据:insert xxx(id, username) values(xx, "xxx");修改数据:update tablename set xx=xx,xxx=xx where xxx=xxx and xxx=xxx;删除数据:delete from tablename where xx=xxx and xxx = xxx or xxx = xxx;查询数据:select * from xxx;
    四、功能展现登录功能

    管理员端

    学生端

    显示所有学生信息

    班级信息查询

    学生信息管理

    增添功能

    删除功能

    更改功能

    五、总结写这个学生信息管理系统历时两个星期。一开始拿到任务书感觉这是一个不可能完成的任务 ,主要是我们还没有学数据库原理,对数据库非常的陌生。千里之行始于足下,即使困难也要努力去完成,我就去看了一下老师给我们的书籍资料,并没有完全看懂。之后又去网上找了个Qt视频教程,对Qt的信号与槽机制了解比较深了。开始写一个像计算器的小程序,更加深刻体会qt的框架。然后又去网上找了一些数据库MySQL的教程于是就安装了MySQL,和Navicat for MySQL。初步了解数据库的使用。慢慢的开始写,从一开始解决如何连接数据库,如何页面跳转,到后面的如何进行数据库增删查改,和使用qttablewidget表格,都是去查阅文档,网上查资料。当我遇到一个数据结构QVariantList 不知如何下手是也是翻阅文档找到它的使用方法。
    总的来说,这次编程经历让我深刻体会到:不要一开始就胆怯害怕,千里之行始于足下。当迈出了第一步你会发现问题并没有你想想的那么难。学习编程不懂的,要学会查文档,网上查资料。自学是很重要的能力。
    3 评论 36 下载 2018-10-31 09:26:58 下载需要5点积分
  • 基于JAVA WEB的计算机网络课程在线考试系统的设计与实现

    摘 要本系统基于B/S结构的模式开发,通过网络给广大用户提供了比较可靠、方便、快捷的在线测评平台,系统主要实现了自动抽取试题、人工出题、套题选择、自动阅卷计分、在线测试、用户信息管理、成绩存档、错题管理等功能。用户利用浏览器可以直接访问本平台,通过选择要考的套题进行测试,测试结束后系统自动为用户判卷得出测试成绩,并显示出测试中错题和相应的答案解析,使得用户非常方便完成一次计算机网络课程的在线测评。
    关键词:B/S模式;在线测试;计算机网络;
    AbstractThe system uses B/S structure of the model development, through the network to provide customers with a more reliable, convenient and fast online evaluation platform, system is mainly to achieve the automatic extraction questions, artificial out of question, sets of questions selected, automatic scoring line in mind when testing, user information management, performance archiving, error management and other functions. users can use the browser to directly access the platform, by selecting a set of questions to test, after testing the system automatically for the user graders test results obtained, and shows the test wrong questions and corresponding answers to resolve, allows users to easily complete a computer network courses online evaluation.
    Key words: B/S mode; Online Testing; Computer Network;
    1 引言1.1 研究背景计算机网络技术的飞速发展以及计算机技术的发展及计算机的日益普及,现在很多国内外的大学和社会其他部门都已经开设了远程教育,通过计算机网络实现异地教育和培训,从而为在线测评系统发展提供了坚实的基础。相对于传统的笔试,网络在线测评系统集测试、评卷、成绩统计、查看错题等为一体,突破了时间与空间的限制,使得用户在任意时刻、任意地点,只要在有网的情况,均可以完成一次测评,这不仅节省了资源,而且提高了评分的客观性、公正性和准确度,大大改善了平时考试和测试的效率。
    1.2 国内外研究现状1977年Lord经过大量的研究,提出了现代测试理论,他发现由多选题组成的计算机辅助考试,与传统的纸质考试两种不同的考试形式对测试的人来说没有特别显著的差异。而BiNET做了一个有关于自适应考试的研究,研究的内容是智力测试。到了1960年,一些学者认为如果对课间的考试采用CAT可能会更加的好。
    随着时间的发展,1996年底,国外渐渐的出现网络教学的系统和平台,像英国的OPEN COOLEGE、美国的NTU这些都是十分典型的例子。在英国的Derby大学运用网络教育的力量成功完成了以色列的本科教育;上海电视大学与澳大利亚昆士兰大学合作完成了在上海开设本科学历的教育课程。
    国内的的网上测评技术的研究与西方国家相比相对要晚一些,我国在1995年首条连通所有的计算机互联网CERNET才正式投入使用。虽然起步比较晚,但在网络远程教育方面发展的相当迅猛。北京大学、清华大学、华南理工大学、上海复旦大学、河北大学、北京医科大学、湖南大学这些高等学校都已经在自己的网站上设立了自己的测评系统。很多公司都非常热情的和高校合作开办网络教育的课程。在中国知名度最高的清华大学也在网上举办了计算机网上硕士研究生的教育,全国各地纷纷上网咨询,报名人数更是达到了上万。
    2 设计方法研究概述2.1 可行性研究2.1.1 经济可行性分析主要是对项目的经济效益进行评价,利用计算机来实现网上测试以成为适应当今教学管理的方式。开发一套能满足网上测评系统的软件是十分必要的,实现试卷管理和试卷生成自动化,在减少由于认为失误而造成损失的同时,也可以使参加测试的人快速的找出自己的薄弱知识点。本系统在经济上是可以接受的,并且本系统实施后可以显著提高测试效率,有助于提高个人的知识的学习。所以本系统在经济上是可行的。
    2.2.2 技术可行性分析软件方面:网络化测试只需要一个web浏览器即可,用户便能通过浏览器访问到测试平台,在数据库方面有Oracle,它能存储海量数据,并且对数据能够进行优化,其易用性、灵活性、安全性为数据库的开发和存储为开发创造了比较好的条件,所以在软件方面完全具有可行性。硬件方面:随着科学技术的发展,硬件发展速度突飞猛进,如今的硬件设备完全能满足系统在硬件方面的需求。
    2.2 系统开发技术系统设计基于B/S结构体系,前台采用JSP和JavaScript技术,后台运用目前主流的三层架构,数据库为ORACLE,开发工具是My Eclipse 8.5,服务器是Tomcat。
    2.2.1 B/S模式B/S(Browser/Server,浏览器/服务器)模式又称B/S结构。它是随着Internet技术的兴起,对C/S模式应用的扩展。B/S模式维护运行都比较简便,能实现从不同的地点,不同的人员,以不同的接入方式访问和操作共同的数据;但它最大的缺点是对网络的依赖性太强,这导致在没有网络的情况下是没有办法访问和操作数据。
    随着www和Internet的流行,以往的C/S模式完全无法满足全球网络互连、开放、信心共享的要求,就在此时B/S模式(浏览器/服务器)渐渐出现,它最大的特点是用户可以通过自己本机的浏览器去访问Internet上的数据、图像、动画、文本、视频点播和声音信息,这些信息都是从许多个web服务器应运而生,然而Web服务器可以通过各种各样的方式与数据服务器相连,一般数据库中都存着海量的数据。客户端除了WWW浏览器,一般无须任何用户程序,只需从Web服务器上下载程序到本地来执行,在下载过程中若遇到与数据库有关的指令,由Web服务器交给数据库服务器来解释执行,并返回给Web服务器,Web服务器又返回给用户。在这种结构中,将许许多多的网连接到一块,形成一个巨大的网,即全球网。而各个企业可以在此结构的基础上建立自己的Intranet。
    2.2.2 JSP技术JSP网页是由传统网页HTML文件中加入JSP标记和Java程序段构成。JSP(Java Server Page)是由Sun公司提出、多个互联网公司一起参与合作而建立的一种动态网页开发技术的标准。JSP规范是中间件应用服务器、Web服务器、交易系统以及软件开发工具厂商间广泛合作的成果,这种技术为创建一个动态的Web网页提供了非常方便的方法。JSP的设计目的是Web应用系统的构造变得更加方便、容易、快捷,而这些应用程序可以和各种中间件应用服务器、Web服务器、浏览器和各种开发工具协同工作。
    JSP继承了Java很多优点,用JSP开发动态网站十分方便,开发效率高。此外,JSP还具有强大的组件(Java Bean)支持此功能,可以方便地实现组件复用,进一步提高了开发效率。
    2.2.3 Oracle数据库Oracle是由美国甲骨文公司开发的一款数据库产品,它具有很多的优点,功能也非常强大,这导致Oracle受到了很多企业家的青睐,在系统开发中应用非常广泛。Oracle数据库的存储结构分为逻辑存储结构和物理存储结构,逻辑存储结构是用于描述Oracle内部组织和管理数据的方式;物理存储结构是用于描述Oracle外部即操作系统中组织和管理数据的方式。
    在启动Oracle数据库服务器时,实际上是在服务器的内存中创建一个Oracle实例(即在服务器内存中分配共享内存并创建相关的后台内存),然后由这个实例来访问和控制磁盘中的数据文件。Oracle有一个很大的内存快,成为全局区(SGA)。
    Oracle数据库始终保持一定数量的服务器进程,用户的请求首先被连接到一个称为“调度程序”的特殊服务进程,然后由调度程序为用户分配一个服务器进程为其提供服务。这意味着只需要使用很少的服务器进程,便可以为多个用户进程提供服务。
    2.2.4 自动生成试卷技术自动生成试卷的关键在于随机抽取试题,并保证抽取的试题不能重复,但是在数据库中如果不断频繁的抽取试题又显得效率比较低,所以问题的核心在于随机、不重复、高效,实现此技术主要有两种方法。
    第一种是利用java中随机函数,抽取出符合要求的试题,但为了保证抽取试题不重复,可以给每一道试题在数据库中加入一个mark字段,在抽取的过程中,如果该试题被抽取到,则将该试题的mark字段置为1,这样我们每抽取一次都会先判断这道试题的mark字段是否为1,如果为1,那么本次抽取无效进入下一次随机,否则抽取有效。这种方式需要在数据库中加入一个mark字段,并且每次随机时都需要判断mark字段的值,显得比较笨重,因此系统采用的是第二种方法。
    第二种方法更为可靠、高效、复杂,该算法主要分为三个步骤:第一步是得到随机抽取试题总数和题库中试题总数,然后生成一个1到题库试题总数的阵列,阵列模型可以由程序中数组构造;第二步是生成随机数将阵列打乱;第三步是根据要求抽取试题数,如果题库中试题总数为10题,需要抽取5题,那么最后结果为取打乱后阵列的前5个即可满足要求。
    第一步:生成1到题库总数阵列(假如题库中有十道试题)如表2-1所示。



    A1
    A2
    A3
    A4
    A5
    A6
    A7
    A8
    A9
    A10




    1
    2
    3
    4
    5
    6
    7
    8
    9
    10



    第二步:生成两个随机数,如3和6,此时交换索引为3和6中的内容,交换后阵列如表2-2所示。



    A1
    A2
    A3
    A4
    A5
    A6
    A7
    A8
    A9
    A10




    1
    2
    6
    4
    5
    3
    7
    8
    9
    10



    第三步:不断重复第二步就可以将阵列打乱,如果需要抽取的试题数为5,那么此时可以取(1,2,6,4,5),最后根据这些题号在数据库中进行相应查询即可。
    2.2.5 简答题批阅算法网络在线测试是很难实现主观题精准的批阅,因为在传统的人工阅卷过程中,不同的人批阅的结果也会不一致,用系统就更难实现了,这也是技术上的一大瓶颈。
    本系统实现了简答题批阅算法,算法的思想主要是计算两个字符串之间的Levenshtein 距离,Levenshtein 距离又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数,编辑操作包括插入、删除、替换操作,编辑距离的算法是首先由俄国科学家Levenshtein提出的,故又叫Levenshtein Distance。举个简单的例子,现在比较字符串abc和abe之间的差异,算法的实现步骤如下:
    将字符串想象成下表2-3的结构。A处 是一个标记,为了方便讲解,不是这个表的内容。




    abc
    a
    b
    c




    abe
    0
    1
    2
    3


    a
    1
    A处




    b
    2





    e
    3





    计算A处的值。它的值取决于:左边的1、上边的1、左上角的0,按照Levenshtein distance的意思:上面的值和左面的值都要求加1,这样得到都是2。A处,由于是两个a相同,左上角的值加0.这样得到0+0=0,最后算出三个值,左边计算后为2,上边计算后为2,左上角计算为0,所以A处取他们里面最小的0,可用一个公式表示A处的值:min{左边值+1,上边值+1,(0,1)}。
    计算出A处值后,变成如下表2-4。B处的值根据第二步得到。




    abc
    a
    b
    c




    abe
    0
    1
    2
    3


    a
    1
    0




    b
    2
    B处




    e
    3





    依次类推得到填写完整表如下表2-5所示。




    abc
    a
    b
    c




    abe
    0
    1
    2
    3


    a
    1
    A处0
    D处1
    G处2


    b
    2
    B处1
    E处0
    H处1


    e
    3
    C处2
    F处1
    I处1



    计算相似度。先取两个字符串长度的最大值(maxlength),操作数记为A,那么两个字符串之间的相似度可表示为:1-(A/maxLength),最后得出abc和abe之间的相似度为0.666。
    现在要解决的问题是将这种思想如何用程序实现,那么需要将二维表格在程序中表示出来,解决方案是用二维数组表示上面所示二维表,通过双层for循环和一定的算法可以计算出两个字符串的距离,这样就可以比较两个字符串之间的相似度。
    3 系统的设计与实现3.1 系统功能需求分析3.1.1 功能描述
    系统角色分为:管理员、用户
    管理员输入用户名和密码登入系统
    管理员登入系统后,可以对用户基本信息进行增删改查操作
    管理员登入系统后,可以对题库进行增删改查
    管理员登入系统后,按照一定的步骤手动生成试卷,并且可以对试卷进行增删改查
    管理员登入系统后,可以对某个试卷进行授权操作
    用户注册个人信息
    输入用户名和密码登入系统
    用户登入系统后,可以对个人信息进行修改
    用户登入系统后,可以选择某一套试题进行测试
    用户登入系统后,测试完成一套试题,可以查看此套试题成绩
    用户登入系统后,测试完成一套试题,可以查看此套试题成绩排名
    用户登入系统后,测试完成一套试题,可以查看此套试题错题

    3.1.2 参与者用例图管理员用例图如图3-1所示。

    用户用例主要包括注册、登录、修改个人信息、在线测试、查看成绩、查看错题、查看排名等。用户用例图如图3-2所示。

    3.2 系统流程图本系统拥有管理员和用户两种角色,管理员登录系统后能够进行用户信息管理、题库管理、试卷管理、考试管理;用户登录后可以进行测试信息管理、成绩管理、我的测试管理、个人信息管理。系统整体结构图如图3-3所示。

    管理员登录系统后,点击用户管理系统会查出所有的用户信息,管理员可以添加用户,也可以选中一条用户信息后,对该信息进行查看详情、删除、修改等操作。用户信息管理流程图如图3-4所示。

    管理员可以对单选题、多选题、填空题、判断题、简答题进行添加,添加之前需进行题目重复验证避免相同的题目产生。管理员添加试题流程图如图3-5所示。

    管理员手动生成试卷包括很多个步骤,首先需要填写试卷的基本信息,然后点击下一步添加各个题型的题目,题目需要管理员手动添加。管理员生成试卷流程图如图3-6所示。

    添加完一套试卷后,用户是不能直接在网上进行测评的,需要管理员选中试卷点击授权,那么此套试卷才可以在网上进行测试,点击查看详情可以查看试卷的一些基本信息。管理员试卷授权流程图如图3-7所示。

    用户登录系统后,可以选中某一试卷进行测试,测试完成后点击提交,系统会根据用户答题情况来给定分数,系统实现了简答题批阅算法,所以用户测试完一套试卷后是全自动化批阅试卷的过程。用户在线测试流程图如图3-8所示。

    当用户测试完一套试题后,点击最新成绩查询,界面上会显示出用户最近一次测试的成绩,点击历史成绩查询会将用户以前参加的所有试题都罗列出来,用户也可以选择某套试卷点击查看错题,系统会显示出这套试卷的错题信息给用户参考。用户查看成绩以及错题流程图如图3-9所示。

    3.3 系统数据分析3.3.1 数据实体图用户实体包括用户Id、用户名、密码信息。用户登陆实体如图3-10所示。

    单选题实体包括单选题主键、单选题编号、单选题题目、A选项、B选项、C选项、D选项、答案、答案解析。单选题实体如图3-11所示。

    多选题试题包括多选题主键、多选题编号、多选题题目、A选项、B选项、C选项、D选项、E选项、答案、答案解析。多选题实体图如图3-12所示。

    判断题实体包括判断题主键、判断题编号、判断题题目、判断题答案、答案解析。判断题实体图如图3-13所示。

    填空题实体包括填空题主键、填空题题目、填空题编号、填空题答案、填空题答案解析。填空题实体图如图3-14所示。

    简答题实体包括主键、简答题题目、简答题编号、简答题答案、简答题答案解析。简答题实体图如图3-15所示。

    试卷实体包括试卷主键、试卷编号、试卷题目、单择题编号集、多选题编号集、填空题编号集、判断题编号集、简答题编号集。试卷实体图如图3-16所示。

    3.3.2 数据表数据库表设计在整个软件开发过程中起着至关重要的作用,一个优秀的数据库设计可以大大简化开发,提高开发效率。本系统数据库设计共13张表,下面用二维表格一一进行描述。
    用户表t_user



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [username]
    用户名
    Varchar2(30)
    N
    唯一


    [password]
    密码
    Varchar2(30)
    N



    用户信息表t_student



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [stu_id]
    用户登录名
    Varchar2(30)
    N
    外键


    [stu_name]
    用户姓名
    Varchar2(50)
    Y



    [stu_sex]
    用户性别
    Varchar2(20)
    Y



    [stu_qq]
    用户QQ
    Varchar2(20)
    Y



    单选题表t_choice



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [choice_num]
    单选题编号
    Number
    N
    唯一


    [choice_ques]
    单选题题目
    Varchar2(50)
    N



    [a]
    A选项
    Varchar2(50)
    N



    [b]
    B选项
    Varchar2(50)
    N



    [c]
    C选项
    Varchar2(50)
    N



    [d]
    D选项
    Varchar2(50)
    N



    [choice_ans]
    单选题答案
    Varchar2(5)
    N



    [answer_anlysis]
    答案解析
    Varchar2(50)
    N



    多选题表t_multi_choice



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [mc_num]
    多选题编号
    Number
    N
    唯一


    [mc_ques]
    多选题题目
    Varchar2(50)
    N



    [a]
    A选项
    Varchar2(50)
    N



    [b]
    B选项
    Varchar2(50)
    N



    [c]
    C选项
    Varchar2(50)
    N



    [d]
    D选项
    Varchar2(50)
    N



    [e]
    E选项
    Varchar2(50)
    N



    [mc_ans]
    多选题答案
    Varchar2(5)
    N



    [answer_anlysis]
    答案解析
    Varchar2(50)
    N



    判断题表t_tfng



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [tfng_num]
    判断题编号
    Number
    N
    唯一


    [tfng_ques]
    判断题题目
    Varchar2(50)
    N



    [tfng_ans]
    判断题答案
    Varchar2(50)
    N



    [answer_anlysis]
    判断题答案解析
    Varchar2(50)
    N



    填空题表t_completion



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [completion_num]
    填空题编号
    Number
    N
    唯一


    [completion _ques]
    填空题题目
    Varchar2(50)
    N



    [completion _ans]
    填空题答案
    Varchar2(50)
    N



    [answer_anlysis]
    填空题答案解析
    Varchar2(50)
    N



    简答题表t_short_answer



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [sa_num]
    简答题编号
    Number
    N
    唯一


    [sa _ques]
    简答题题目
    Varchar2(50)
    N



    [sa _ans]
    简答题答案
    Varchar2(50)
    N



    [answer_anlysis]
    简答题答案解析
    Varchar2(50)
    N



    试卷表t_paper



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [paper_num]
    试卷编号
    Number
    N
    唯一


    [paper_name]
    试卷名称
    Varchar2(50)
    N



    [dx_num]
    单选题集
    Varchar2(50)
    N



    [mul_num]
    多选题集
    Varchar2(50)
    N



    [pd_num]
    判断题集
    Varchar2(50)
    N



    [tk_num]
    填空题集
    Varchar2(50)
    N



    [sa_num]
    简答题集
    Varchar2(50)
    N



    试卷信息表t_paper_info



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [paper_num]
    试卷编号
    Number
    N
    外键


    [dx_num]
    单选题个数
    Number
    N



    [dx_value]
    单选题分值
    Number
    N



    [mul_num]
    多选题个数
    Number
    N



    [mul_value]
    多选题分值
    Number
    N



    [pd_num]
    判断题个数
    Number
    N



    [pd_value]
    判断题分值
    Number
    N



    [tk_num]
    填空题个数
    Number
    N



    [tk_value]
    填空题分值
    Number
    N



    [sa_num]
    简答题个数
    Number
    N



    [sa_value]
    简答题分值
    Number
    N



    [total_time]
    总时间
    Number
    N



    [total_value]
    总分
    Number
    N



    [user_times]
    使用次数
    Number
    N



    [status]
    是否授权
    Number
    N



    标准答案表t_stanswer



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [paper_num]
    试卷编号
    Number
    N
    外键


    [dx_answer]
    单选题答案
    Varchar2(50)
    N



    [mul_answer]
    多选题答案
    Varchar2(50)
    N



    [pd_answer]
    判断题答案
    Varchar2(50)
    N



    [tk_answer]
    填空题答案
    Varchar2(50)
    N



    [sa_ answer]
    简答题答案
    Varchar2(50)
    N



    答卷表t_answer



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [paper_num]
    试卷编号
    Number
    N
    外键


    [stu_id]
    用户id
    Varchar2(30)
    N
    外键


    [dx_answer]
    单选题答案
    Varchar2(50)
    N



    [mul_answer]
    多选题答案
    Varchar2(50)
    N



    [pd_answer]
    判断题答案
    Varchar2(50)
    N



    [tk_answer]
    填空题答案
    Varchar2(50)
    N



    [sa_ answer]
    简答题答案
    Varchar2(50)
    N



    成绩表t_grade



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [paper_num]
    试卷编号
    Number
    N
    外键


    [stu_id]
    用户id
    Varchar2(30)
    N
    外键


    [dx_value]
    单选题得分
    Number
    N



    [mul_value]
    多选题得分
    Number
    N



    [pd_value]
    判断题得分
    Number
    N



    [tk_value]
    填空题得分
    Number
    N



    [sa_ value]
    简答题得分
    Number
    N



    [total]
    总分
    Number
    N



    错题表t_error



    列名
    中文含义
    数据类型
    空值
    注释




    [id]
    Id
    Number
    N
    主键


    [paper_num]
    试卷编号
    Number
    N
    外键


    [stu_id]
    用户id
    Varchar2(30)
    N
    外键


    [dx_answer]
    单选题错题集
    Varchar2(50)
    N



    [mul_answer]
    多选题错题集
    Varchar2(50)
    N



    [pd_answer]
    判断题错题集
    Varchar2(50)
    N



    [tk_answer]
    填空题错题集
    Varchar2(50)
    N



    [sa_ answer]
    简答题错题集
    Varchar2(50)
    N



    3.4 系统模块实现3.4.1 注册、登录页面本系统对用户来说需要先注册,然后才能登录系统在线测试。而对于管理员来说可以直接登录系统进行一系列的管理和操作。注册页面如图3-17所示。
    用户注册页面

    用户登录页面

    管理员输入正确用户名和密码登录成功后,显示主页面如图3-19所示。

    用户输入正确用户名和密码登录成功后,显示主页面如图3-20所示。

    3.4.2 管理员用户管理模块管理员登录成功后,可以对用户进行管理,主要包括分页查看所有用户信息、对某一用户进行修改操作、删除选中用户、查看某一用户详细信息。分页查看所有用户信息,删除选中用户页面如图3-21所示。

    对某一用户进行修改操作页面如图3-22所示。

    查看选中用户详细信息如图3-23所示。

    3.4.3 管理员题库管理模块管理员登录系统后,可以往题库中添加不同题型的题目,题型包括选择题、多选题、判断题、填空题、简答题。系统将五种题型的添加页面集成到一个主页面,使得题型添加时更加清晰、直观,主页面如图3-24所示。

    在添加题目操作的过程中,有时难免会出现不合法的操作,例如:题目为空、单选题的某个选项为空、单选题的选项出现重复等,当出现这些操作时,系统会响应相应的触发条件通过ajax请求后台,后台会处理这些操作给管理员提示不合法的操作信息,使界面更加友好。不合法操作如图3-25所示。

    管理员将题目添加到题库后可以查看不同题型的题目列表,同样,系统将多种题型的题目查找集成在一个主页面,通过这个主页面,管理员可以对某一具体题目进行查看、删除操作。查看多种题型题目列表主页面如图3-26所示。

    查看某一具体题目详细信息如图3-27所示。

    3.4.4 管理员试卷管理模块管理员在系统中可以自动生成试卷也可以手动添加试卷,试卷添加分为六个步骤,第一个步骤是试卷的基本信息添加,主要包括试卷的名称、测试时间、题型分配情况等一些基本信息,剩下步骤为试卷各种题型题目选择性的添加,题目来源于系统题库中,试卷添加第一个步骤如图3-28所示。

    某种题型题目添加页面如图3-29所示。

    当试卷基本信息和各种题型题目添加完成后,会请求后台程序,此时后台需要将试卷的基本信息、试卷题型题目信息、试卷标准答案录入到数据库表中,这涉及到试卷表、试卷信息表、标准答案表这三张表,在试卷表中需要将各种题型的题目存入数据库中,这就需要将单个题型的题目编号集以某种规则存入数据库表中,当程序读取这些数据时,也需要按照同样的规则进行解码,将特殊字符串转换成某种题型题目的编号集。
    管理员可以对试卷进行管理,主要包括分页查询所有试卷、查看详细信息、删除等操作,试卷分页查询和删除页面如图3-30所示。

    查看页面详细信息如图3-31所示。

    3.4.5 管理员测试管理模块管理员添加完一套试卷后,用户是不能直接在浏览器上进行测试的,需要管理员对该套试题进行授权操作,用户才能进行测试,试卷授权页面如图3-32所示。

    3.4.6 用户我的测试管理模块当用户点击我的测试模块中在线测试,会展示所有可以进行测试的试题,当然同一个人只能测试某套试卷一遍,当再次操作时,会提示不能对试卷进行重复测试,在线测试试题列表如图3-33所示。

    当用户点击在线测试试题列表中开始考试,用户便可以开始一次测试,测试完成后,系统会自动的为这次测试给出理论上的评分。在线测试页面如图3-34所示。

    当用户测试完一套试卷后,点击提交试卷,如果存在没有作答的题目,系统会给出哪种题型第几题没有作答提示,全部作答完成后试卷便会提交到后台进行处理, 首先后台需要将用户的答案保存在答题表中;其次也是最重要的需要将用户答案与后台数据库中标准答案进行比对,然后得出用户每个题型的得分,并将结果存入到成绩表中;最后根据用户所提交的答案与后台标准答案比对后,将错题信息添加到错题表中,对于错题信息应包括错题题号、用户答案、标准答案、答案解析等基本信息。在开发本系统的过程中,存在着一大难点是客观题的匹配算法,一般主观题通过系统进行匹配很少出现误差的情况,而主观题不然,如今简答题的答案不是固定不变,用户答题可以从多个角度进行阐述,只要合理即可,所以给这方面的系统带来了很大的难度,主观题的批阅给出的分数只能是一个近似值,很难达到精确的地步,这类系统在开发过程中主观题一般设计为人工阅卷与系统阅卷相结合。
    本系统实现了简答题批阅的算法,但是也只能是一个近似值,该算法首先是由俄国科学家Levenshtein提出的,故又叫Levenshtein Distance,算法的实现原理为:两个字符串之间,由一个字符串转换成另一个字符串所需要的操作数,对字符串的操作包括插入、删除、替换,最后两字符串相似度可以表示为1-操作数/两字符串中较长字符串字符数。算法实现如下:
    public static float levenshtein(String str1,String str2) { //计算两个字符串的长度。 int len1 = str1.length(); int len2 = str2.length(); //建立一个二维数组用于计算操作数 int[][] dif = new int[len1 + 1][len2 + 1]; //对数组赋初值 for (int a = 0; a <= len1; a++) { dif[a][0] = a; } for (int a = 0; a <= len2; a++) { dif[0][a] = a; } //计算两个字符是否一样,计算左上的值 int temp; for (int i = 1; i <= len1; i++) { for (int j = 1; j <= len2; j++) { if (str1.charAt(i - 1) == str2.charAt(j - 1)) { temp = 0; } else { temp = 1; } //取三个值中最小的 dif[i][j] = min(dif[i - 1][j - 1] + temp, dif[i][j - 1] + 1, dif[i - 1][j] + 1); } } //计算相似度 float similarity = 1 - (float) dif[len1][len2] / Math.max(str1.length(), str2.length()); return similarity;} //该方法计算三个整数中最大数private static int min(int... is) { int min = Integer.MAX_VALUE; for (int i : is) { if (min > i) { min = i; } } return min; }
    3.4.7 用户成绩查询模块当用户点击成绩查询模块中最新成绩查询,系统会查出用户最近一次的测试信息,查看最新成绩页面如图3-35所示。

    同样当用户点击历史成绩查询时,会查出用户以前所有测试成绩列表。

    3.4.8 用户测试信息管理模块当用户点击测试信息中成绩排行时,用户可以很清楚的知道自己测试过的试题在所有测试过人中的排名,成绩排行页面如图3-37所示。

    当用户点击测试信息中我的错题时,可以查看测试试题中自己的错题情况,从而知道自己在哪些方面存在不足,需要加强学习。错题列表如图3-38所示。

    点击错题列表中查看详情,便可以查看选中试题的错题信息,错题详情页面如图3-39所示。

    3.5 测试测试在一个软件开发周期中起着重要的作用,一个好的软件是经过专业的测试人员无数次测试才会没那么多bug,测试是为了补充系统的不足,使系统更加完美,用户的体验更好,试想一下,如果你开发的软件没有经过严格的测试,而发布在互联网进行使用,那是多么可怕的一件事,用户随意点击页面便会出现很多错误,这给用户的感觉简直就是差劲!我认为这样的软件是失败的,因此测试与开发是同等重要的,并且测试人员与开发人员必须协调好才能开发出优秀的软件。
    测试方法主要包括黑盒测试和白盒测试,但软件测试有一个致命的缺陷,即测试的不完全、不彻底性,由于任何程序只能进行少量的有限的测试,在未发现错误时,是不能说明程序中没有错误。
    测试用例如下:

    管理员输入用户名:admin,密码:admin登入系统,点击用户管理系统,查看用户列表是否显示成功;在用户列表中点击修改、查询、删除操作看是否能够执行
    管理员输入用户名:admin,密码:admin登入系统,点击题库管理,查看题库列表是否显示成功;选择不同的题型后,查看题目列表是否显示成功;在题目列表中点击查看,是否能够显示题目的详情
    管理员输入用户名:admin,密码:admin登入系统,点击试卷管理,填写试卷基本信息后,看是否能够自动生成试卷,点击手动生成试卷看是否能添加成功
    管理员输入用户名:admin,密码:admin登入系统,点击试卷授权功能,当给某一试卷授权后,检测用户登入系统是否能够对该套试卷进行测试
    用户点击注册,填写用户名:123456,密码123456进行注册,注册完成后点击登录,看是否能够正常登录
    用户输入:123456,密码:123456登入系统,点击在线测试,选择试题后,看是否能够在线考试
    用户输入:123456,密码:123456登入系统,点击查看成绩看是否能够查看当前考试的成绩

    另外在系统设计和测试的过程中,发现系统存在以下几方面的不足:

    系统如果需要做的更完美,应该可以在线测试多个科目的试题
    在主观题的批阅过程中,始终无法达到精确的地步,所以算法需要做进一步改进优化
    计算机网络测试仍然存在着局限性,比如不能对计算机网络课程中画图题、连线题进行测试,所以这是需要改进的

    4 总结与展望在这次系统的设计与开发中我遇到了很多问题,像需求不是很明确、数据库设计出现问题、软件后台开发框架不能熟练的运用、简答题的批阅算法等,每一个问题都给我带来了巨大的困惑,起初需求不是很明确,当按照任务书上功能模块进行开发时,你会发现以前写的功能模块完全没有办法实现,原因是没有好好的理解需求和认真深入分析这个系统,不明确哪些功能模块可以实现,而哪些功能模块不能实现,所以我明白软件设计过程中需求分析、概要设计是相当重要的,可以直接导致一个软件设计的成败,终于理解前辈们通过自己亲身经历写下软件工程这本书的重要性,这是留给后人最宝贵的资料。然而在数据库的设计中也给我带来了不少麻烦,刚开始我便设计数据库,才发现一个不深入了解系统的人是很难设计出数据库的,于是我花了两三天的时间,认真专研系统,理清自己的逻辑思路,按照用户注册-登录-在线测试-查看成绩-查看错题这个流程渐渐的将数据库设计完成,当然在后期中也存在了一些改动,才会有今天这个成果。刚开始系统后台框架使用的是s2sh,但在一个简单的错误调试中花费了我大量的时间,让我无法专研到系统业务逻辑的实现,于是我选择了比较直接的jsp和mvc模式开发,这大大提高了我的开发效率,所以我认为系统实现的方法应该选择合理,不然会耽搁很多时间,不能在规定的时间完成任务。
    这个系统从需求分析、数据库设计、代码开发、测试都是自己独立完成,以前没有自己独立完成一个系统,当开发完成后,心里有特别大的成就感,在遇到问题-解决问题-遇到新问题这种重复模式中,自己的能力有了很大的提高,我想程序设计者应该要勇于面对问题,并且通过自己的方式寻找解决办法,在解决问题时,你往前又迈了一大步,这对自己是一种经验的积累,同时也会让自己走得更高更远。
    参考文献[1] 吕雯雯.网上报名与在线考试系统的设计与实现[J].电脑知识与技术,2012,8(7):43-47
    [2] 魏振,王婷,宫禹.基于JSP实验系统总体设计[J].黑龙江科学,2012,6(5):20-30
    [3] 朱静.基于WEB的在线考试系统的设计与实现[J].福建电脑,2007,4(23):14-25
    [4] 郑飞.基于J2EE的医药管理系统的设计与实现[J].信息技术,2012,6(5):12-14
    [5] 唐超礼,黄友锐.基于B/S模式的教师信息管理系统的设计与实现[J].中国科技信息,2006,3(8):19-36
    [6] 吴爽.教务管理的研究与设计[J].华东师范大学,2010:10-15
    [7] 冯彦.基于JSP和Struts框架动态Web开发技术研究以及实践[J].吉林大学,2005,6(7): 33-45
    [8] 赵高丽,冀红举,宋军平.基于SQL的高校考务管理系统的设计与实现[J].河南机电高等专科报, 2006,14(2):45-78
    [9] 靳新,李莹基.JSP的网络文件管理系统的设计与实现[J].沈阳理工大学,2007,5(7),20-21
    [10] 王妍.JSP的开发技术[J].科技创新与应用,2008,3(5):31-33
    [11] 蒋毅.WEB与数据库连接技术应用对比分析 [J].计算机光盘应用,2011,11(23):16-25
    [12] 李绍静,汤玉琛,王宝盼.基于JSP技术的就业信息网的架构与实现[J].计算机与现代化,2012,6(5):12-14
    [13] 张晓孪.基于SSH的团购网站的设计与实现 [J].电子设计工程,2009,3(8):19-23
    [14] 姜南.基于JSP技术的学生信息管理系统的设计与实现[J].计算机与现化,2010,3(8):10-15
    [15] 房明.基于JSP技术的教材管理信息系统设计分析[J].山西科学,2009,6(7):33-45
    [16] 陈月霞.浅谈在线考试系统的结构与实现[J].科技风,2007,14(2):22-28
    [17] Chen, Jing M., Josef Cihlar. Retrieving leaf area index of boreal conifer forest using landsat TM images [J]. Remote Sen. Environ, 1996, 55(2): 153-162
    [18] akehurst B C, Tobacco(Second edition). New York: Longman press, 1981: 51-58
    [19] Rafael C Gonzalez, Richard E Woods, Steven L Eddins. Digital Image Processing Using MATLAB.Beijing: Publishing House of Electronics Industry, 2004: 153-222
    [20] Mckee, G.W., A coefficient for computing leaf area in hybird corn. Agron. J. 1964, 56(2): 240-241
    [21] Debayle J, Pinoli J C. Multiscale image filtering and segmentation by means of adaptive neighborhood mathematical morphology[J]. Image Processing, 2005, 3(1 l-14): 537-540
    [22] Punt T. Entropic thresholding: A new approach[J]. CGIP, 1981, 16(21): 209-320
    [23] Meyer, Elsevier Trends Division. Computer & Security. Kidington, Oxford, UK, 1982
    [24] Bonanza Drive. Database. P.O.Box 70, Park City, UT 84060, USA, 1978
    [25] James A.O’Brien. Introduction to Information Systems[M]. McGraw-Hill, 2002
    1 评论 2 下载 2019-05-19 10:30:27 下载需要20点积分
  • 基于C++的学校人事管理系统

    1 需求分析某高校,主要人员有:在职人员(行政人员、教师、一般员工)、退休人员、返聘人员和临时工。现在,需要存储这些人员的人事档案信息:编号、姓名、性别、年龄、职务、职称、政治面貌、最高学历、任职时间、来院时间。
    程序的基本功能如下所示:

    添加删除功能:能根据学院人事的变动情况,添加删除记录查询功能:能根据编号和姓名进行查询修改功能:根据查询对相应的记录进行修改,并存储统计功能:能根据多种参数进行人员的统计(在职人数、党员人数、女工人数、高学历高职称人数)
    需求分析如下:
    人员有在职人员,退休人员,返聘人员等,他们都有编号、姓名、性别、年龄、职务、职称等信息。因此可以先定义一个包含上述信息的类,然后根据C++继承特性,让退休人员、在职人员继承基类,添加属于他们的特定的信息就能构成他们自己的类。注意到信息中包括时间的信息,因此另外定义了一个类,如果用到这个时间信息,则将这个时间类作为成员类。
    各个类除了有对各种数据成员设置和获取函数外,考虑到各个功能,还定义了各种功能函数,比如将在详细介绍中介绍的重复鉴别函数、信息判别函数、重载的输入、输出函数、以及从文件中读取信息和向文件中写入信息的函数。
    这些成员函数和数据成员将有助于对题目内容的实现。
    2 概要设计类之间的关系图

    功能模块图

    3 运行环境
    硬件环境
    PC机内存 256M
    硬盘40G
    软件环境
    操作系统:Windows 7

    4 开发工具和编程语言
    开发工具:Dev-C++
    编程语言:C++

    5 详细设计5.1 Display类的实现由于Display类主要用于输出信息,且在主函数调用,因此比较简单。部分代码如下:
    Display.h中的代码
    #ifndef DISPLAY_H#define DISPLAY_Hclass Display{ public: void display()const;//显示主菜单 void display1()const;//显示查找菜单 void display2()const;//显示更新菜单 void display2_1()const;//显示更新菜单的子菜单 更新的内容 void display3()const;//统计菜单 void display4()const;//初始化选择菜单 };#endif
    Display.cpp中的代码
    #include "Display.h"#include <iostream>using namespace std;void Display::display()const{ cout << "欢迎来到学校人事管理系统!" << endl; cout << "请选择您所需的功能:\n" ; cout << "查询信息请输入数字 1 \n"; cout << "修改信息请输入数字 2 \n"; cout << "统计信息请输入数字 3 \n"; cout << "初始化人事信息输入 4 \n"; cout << "输出所有职工信息请输入 5"<<endl; cout << "退出系统请输入数字 0 \n"; cout << "\n请输入您的选择 :\n";}void Display::display1()const{ cout << "请输入需要查询的类别 :"<<endl; cout << "按照编号查询请输入 1" <<endl; cout << "按照姓名查找请输入 2" <<endl; cout << "返回上一级菜单请输入 0" <<endl;}void Display::display2()const{ cout << "修改临时工请输入 1" << endl; cout << "修改教师请输入 2" <<endl; cout << "修改退休人员请输入 3" << endl; cout << "返回请输入 0" << endl; }void Display::display2_1()const{ cout << "添加请输入 1" << endl; cout << "删除请输入 2" <<endl; cout << "返回请输入 0" << endl; }void Display::display3()const{ cout << "统计党员人数请输入 1" << endl; cout << "统计高学历人数请输入 2" << endl; cout << "统计总人数请输入 3" << endl; cout << "统计女工人数请输入 4" << endl; cout << "返回上一菜单请输入 0" << endl;}void Display::display4()const{ cout << "请输入需要初始化的员工类型:\n"; cout << "初始化临时工请输入 1 \n"; cout << "初始化在职人员请输入 2 \n"; cout << "初始化退休人员请输入 3 \n"; cout << "返回上一菜单请输入 0 "<<endl; }
    5.2 Time类的实现考虑到许多的职工的信息都包括各种时间,因此定义一个Time类,为以后各种的职工的定义提供了一个很好的数据成员。Time类的部分代码如下:
    Time.h中的代码
    #ifndef TIME_H#define TIME_Hclass Time{ public: Time(int=0, int=0, int=0); void setDate(int , int , int); int getYear()const; int getDay()const; int getMonth()const; bool leapYear(int ); void print()const; private: int year;//年 int month;//月 int day;//日 static const int days[];//每个月的天数,不包括闰年 };#endif
    Time.cpp中的部分代码
    const int Time::days[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};Time::Time(int y, int m, int d)//构造函数 { setDate(y,m,d);}const int Time::days[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};Time::Time(int y, int m, int d)//构造函数 { setDate(y,m,d);}void Time::setDate(int y,int m,int d){ year = y > 1900&& y < 2100 ? y : 1900; month = m > 0 && m < 13 ? m : 1; if(m==2&&leapYear(y)) day = (d > 0 && d < 30) ? d : 1; else day = (d >0 && d <= days[m]) ? d : 1;}bool Time::leapYear(int year)//判断闰年 { return year%400==0||(year%100!=0&&year%4==0);}void Time::print()const//显示时间 { cout << getYear() << "- " << getMonth() << " - " << getDay();}
    5.3 Work类的实现Work作为基类实现主要是因为其中的数据成员其他类都要用到,因此为其他类的基类。成员函数有各个数据成员的获取和设置函数,还包括一些功能函数。Work的部分代码如下:
    Work.h中的代码
    #ifndef WORKER_H#define WORKER_H#include<iostream>using namespace std;#include <string>#include<fstream>class Worker{ friend ostream &operator<<(ostream&,const Worker*); friend istream &operator>>(istream&,Worker*); friend ofstream &operator<<(ofstream&,const Worker*); friend ifstream &operator>>(ifstream&,Worker*); public: Worker(int=0,string=0,int=0,int=0,string=0,string=0) ; void setNumber(int); void setName(string); void setSex(int); void setAge(int); void setPost(string); void setTitle(string); int getNumber()const; string getName()const; int getSex()const; int getAge()const; string getPost()const; string getTitle()const; bool isSame(int)const; bool isNameSame(string) const; protected: int number;//编号 string name;//姓名 int sex;//性别 0 = 男;1 = 女 int age;//年龄 string post;//职务 string title;//职称 };#endif
    Work.cpp中的部分功能函数
    Worker::Worker(int num,string na,int se,int ag,string po,string ti)//构造函数 { setNumber(num) ; //设置编号 setName(na);//设置姓名 setSex(se);//设置性别 setAge(ag) ;//设置年龄 setPost( po);//设置职位 setTitle(ti);//设置职称 }istream &operator>>(istream& input,Worker* worker)//重载输入 { cout << "请输入职工编号:\n" << endl; cin >> worker->number; cout << "请输入职工姓名:"<<endl; cin >> worker->name; cout << "请输入职工性别:(男 = 0; 女 = 1)" << endl; cin >> worker->sex; cout << "请输入职工年龄:" <<endl; cin >> worker->age; cout << "请输入职工职务:"<<endl; cin >> worker->post; cout << "请输入职工职称:"<<endl; cin >> worker->title; return input;}ostream &operator<<(ostream& output,const Worker*worker)//重载输出 { string a = worker->getSex() ? "女" : "男"; cout << "职工编号:" << worker->getNumber() << " 职工姓名:" << worker->getName() << " 职工性别:" << a << " 职工年纪:"<< worker->getAge() << " 职工职位: " << worker->getPost() << " 职工职称:"<< worker->getTitle(); return output;}ofstream &operator<<(ofstream&outWorker,const Worker*workers)//向文件中写信息的重载 { outWorker << workers->getNumber() << " " << workers->getName() << " " << workers->getSex() << " " << workers->getAge() << " " << workers->getPost() << " " << workers->getTitle()<<endl; return outWorker;}ifstream &operator>>(ifstream&in,Worker*workers)//从文件中读取信息的重载 { int number;//编号 string name;//姓名 int sex;//性别 0 = 男;1 = 女 int age;//年龄 string post;//职务 string title;//职称 in >> number >> name >> sex >> age >> post >> title; if(in) { workers->setNumber(number); workers->setName(name); workers->setSex(sex); workers->setAge(age); workers->setPost(post); workers->setTitle(title); } return in;}bool Worker::isNameSame(string name)const//判断是否有名字重复 { return getName().compare(name)==0;}bool Worker::isSame(int num)const//判断是否有编号重复 { return num == getNumber();}
    5.4 Teacher类的实现Teacher类继承与work类,主要是因为work类的所有数据成员在teacher类中都有,因此继承避免了大量的代码重复,提高了代码的可重用性。此外Teacher中特有的数据成员重新进行定义。Teacher类的定义文件不在给出,只给出其中的功能函数的实现。Teacher类的部分代码如下:
    Teacher::Teacher(int nu,string na,int se,int ag,string po, string ti,string pol, string edu,int y1,int m1,int d1,int y2,int m2,int d2)//构造函数 :Worker(nu,na,se,ag,po,ti),from(y1,m1,d1),sever(y2,m2,d2)//成员初始化其初始化继承的类 { setPolic(pol); setEdu(edu); } ostream& operator<<(ostream& output,const Teacher* teacher)//重载的输出函数 { string a = teacher->getSex() ? "女" : "男"; cout << "职工编号:" << teacher->getNumber() << " 职工姓名:" << teacher->getName() << " 职工性别:" << a << " 职工年纪:"<< teacher->getAge() << " 职工职位: " << teacher->getPost() << " 职工职称:"<< teacher->getTitle() << " 职工政治面貌:"<< teacher->getPolic() << " 职工学历:" << teacher->getEdu() << " 任教时间:" ; (teacher->getFromTime()).print(); cout << " 来院时间:"; teacher->getSeverTime().print() ; return output; } istream&operator>>(istream&input,Teacher*teacher)//重载的输入函数 { cout << "请输入职工编号:\n" << endl; cin >> teacher->number; cout << "请输入职工姓名:"<<endl; cin >> teacher->name; cout << "请输入职工性别:(男 = 0; 女 = 1)" << endl; cin >> teacher->sex; cout << "请输入职工年龄:" <<endl; cin >> teacher->age; cout << "请输入职工职务:"<<endl; cin >> teacher->post; cout << "请输入职工职称:"<<endl; cin >> teacher->title; cout << "请输入职工政治面貌:(中共党员:1 人民:0)"<<endl; cin >> teacher->politics; teacher->setPolic(teacher->getPolic()); cout << "请输入职工学历:(本科:1 硕士: 2 博士:3 院士:4)" << endl; cin >> teacher->education; teacher->setEdu(teacher->education); int y,m,d; cout << "请输入任教时间:(格式为: 年 月 日)"<< endl; cin >> y >> m >> d; (teacher->sever).setDate(y,m,d); cout << "请输入入职时间:(格式为: 年 月 日)"<< endl; cin >> y >> m >> d; (teacher->sever).setDate(y,m,d); return input; }ofstream &operator<<(ofstream&outTeacher,const Teacher*teachers)//重载的文件输出函数 { outTeacher << teachers->getNumber() << " " << teachers->getName() << " " << teachers->getSex() << " " << teachers->getAge() << " " << teachers->getPost() << " " << teachers->getTitle()<< " " << teachers->getPolic() << " " << teachers->getEdu() << " " << teachers->getSeverTime().getYear() << " "<< teachers->getSeverTime().getMonth() << " " << teachers->getSeverTime().getDay() << " " << teachers->getFromTime().getYear() << " " << teachers->getFromTime().getMonth() << " " << teachers->getFromTime().getDay() << endl; return outTeacher; }ifstream &operator>>(ifstream&in,Teacher *teachers)//重载的文件读取函数 { int number;//编号 string name;//姓名 int sex;//性别 0 = 男;1 = 女 int age;//年龄 string post;//职务 string title;//职称 string pol;//政治面貌 string edu;//学历 int year, month,day; int year1, month1,day1; int s; in >> number >> name >> sex >> age >> post >> title >> pol >> edu >> year >> month >> day >> year1 >> month1 >> day1 ; if(in) teachers->setNumber(number); teachers->setName(name); teachers->setSex(sex); teachers->setAge(age); teachers->setPost(post); teachers->setTitle(title); teachers->politics = pol; teachers->education = edu; teachers->getSeverTime().setDate(year,month,day); teachers->getFromTime().setDate(year1,month1,day1); return in;}
    5.5 Retire类的实现Retire类继承于Teacher类,提高了代码的可重用性。Retire类的部分代码:
    Retire::Retire(int nu,string na,int se,int ag,string po, string ti,string pol, string edu,int y1,int m1,int d1,int y2,int m2,int d2,int y3,int m3,int d3)//构造函数 :Teacher(nu,na, se,ag,po,ti,pol,edu,y1,m1,d1,y2,m2,d2),leave(y3,m3,d3)//初始化器 { }
    5.6 查找功能的实现查找功能的实现如下图3所示:

    由于按照姓名和按照编号查找基本相同,为避免赘述,只给出按照编号查找的代码:
    void searchName()//按照姓名查找 { int i, j = 1;//j为判断是否找到 string name; cout << "请输入您要查找的姓名:" << endl; cin >> name; for(i = 1;i < N;i++) if(workers[i]->isNameSame(name)) { cout << workers[i]<<endl; j = 0; } for(i = 1;i < N;i++) if(teachers[i]->isNameSame(name)) { cout << teachers[i]<<endl; j = 0; } for(i = 1;i < N;i++) if(retires[i]->isNameSame(name)) { cout << retires[i]<<endl; j = 0; } if(j) cout << "未查找到姓名为" << name << "的职工!!" <<endl;//如果没有找到 }
    5.7 修改功能的实现对数据的修改包括添加和删除,如下图4所示:

    增加和删除雷同,以下是增加的代码:
    void add2()//添加 { if(isRepeat2()) return;//如果没有要添加的人员信息 返回 int n = retires[0]->getNumber(); cin >> retires[++n]; retires[0]->setNumber(n);//人数增加1 }
    5.8 统计信息的实现统计信息包括统计职工中的党员人数,女工人数,高学历人数以及各个职工的人数。各个功能之间的关系如下图5所示:

    统计信息时判断符合条件的信息时均使用各个类的功能函数,使得类的功能更强大,代码的通用率更高,程序的逻辑结构更加易懂。统计其他职工的信息的代码与统计党员的基本相同,故略之。以下是统计党员人数的函数。
    void partyMembers()//统计党员信息 { int i, n, t = 0; cout << "党员为:"<<endl; for(i = 1;i < N;i++) if(teachers[i]->isPartMember()) { t++; cout << teachers[i] << endl; } for(i = 1;i < N;i++) if(retires[i]->isPartMember()) { t++; cout << retires[i] << endl; } cout << "一共有" << t << "位党员,占总教职工人数的" << (int)(t * 100.0 / teachers[0]->getNumber() ) << "%" << endl; }
    5.9 初始化人事信息的实现初始化人事信息功能图如下图6所示:

    初始化人事信息包括两个功能,一个是在程序启动时从文件中读出信息初始化,另一个是在运行过程中人为有选择性的进行初始化。运行代码如下:
    void initializeTeacher()//从文件中初始化老师信息 { int i = 0; for(i = 0;i < N;i++) { teachers[i] = new Teacher(0,"0",0,0,"0","0","0","0",0,0,0,0,0,0); } ifstream in; in.open("teachers.txt");//打开文件 if(!in) { cout << "文件打开失败!!!" <<endl; exit(0); } i = 0; do { i++; if(in) in >> teachers[i] ; //从文件中读入 }while(in) ; i--;//去除多读的最后一个 teachers[0]->setNumber(i);//设置读入的职工个数 in.close();//关闭文件 }void initialize_2()//初始化老师的信息 { int i = 0; int n= 0; initializeTeacher1();//把编号置为0,代表删除 cout << "请输入需要输入的人数 :"<<endl; cin >> n; teachers[0]->setNumber(n); for(i = 1;i <= n;i++) { cout <<"请输入第" << i << "个职工的信息:" <<endl; cin >> teachers[i]; } }
    5.10 输出所有职工信息的实现输出所有职工信息如下图7所示:

    输出职工信息只需要将各种种类的信息输出,然后根据信息查看每个人的信息,当需要查找不知道编号和姓名的职工时候,这个功能虽然较笨,但也是一种方法。代码如下
    void information()//输出信息 { int i; cout << "临时工信息:" << endl; for(i = 1;i < N;i++) if(workers[i]->getNumber()) cout << workers[i] << endl; cout << endl; cout << "老师信息:" << endl; for(i = 1;i < N;i++) if(teachers[i]->getNumber()) cout << teachers[i] << endl; cout << endl; cout << "退休人员信息:"<< endl; for(i = 1;i < N;i++) if(retires[i]->getNumber()) cout << retires[i] << endl; cout << endl;}
    5.11 退出并保存当使用完此系统后,需要退出此系统,并将所有职工的信息写入到各个职工所属的文件中。首先打开文件,写入信息后关闭文件。其中写入功能用到了重载的输出运算符函数。体现了类的封装性。程序流程如下图8所示:

    具体实现代码如下所示:
    void save()//保存信息 { ofstream outWorker, outTeacher, outRetire;//定义三个文件对象 outWorker.open("workers.txt");//打开 workers.txt outTeacher.open("teachers.txt");//打开 teachers.txt outRetire.open("retires.txt");//打开 retires.txt if(!outWorker||!outTeacher||!outRetire) { cout << "打开文件失败!!!" <<endl; exit(0); } int i; for(i = 1;i < N;i++)//将信息保存至文件 { if(workers[i]->getNumber()!=0) outWorker << workers[i]; if(teachers[i]->getNumber()!=0) outTeacher << teachers[i]; if(retires[i]->getNumber()!=0) outRetire << retires[i]; } outWorker.close();//关闭文件 outTeacher.close(); outRetire.close();}
    6 调试分析问题1 Time类中的问题

    问题描述: 设置日期,当闰年时判断错误。解决办法:在设置日期时,需要牵扯到闰年2月有29天,不是闰年2月有28天。一开始判断较复杂且易错。经过将判断闰年写成一个函数后就比较好理解了。当是闰年的时候就将2月设置成29天,否则就设置为全局变量中的各个月中的天数,这样就进行了日期格式的判断。
    问题2 把Time类作为Worker类中的数据成员

    问题描述:在Worker类的构造函数的函数体内初始化Time类,编译器总是报错。解决办法:经过检查,在排除了语法上面的错误之后,就怀疑是初始化的方法错误。于是又重新查阅了《C++大学基础教程》。发现初始化成员对象时,必须要用成员初始化器进行初始化。用成员初始化器后,问题迎刃而解了。
    问题3 读文件操作

    问题描述:从文件中初始化各个职工信息时,总是多读取最后一行的信息一次。解决办法:在读文件时,定义的ifstream对象打开文件时返回一个打开文件的指针。每读取一次,指针就指到读取文件的位置,当文件结束时,返回一个空指针,但是在读取到文件末尾时,并不进行判断,此时文件指针仍然不是空指针,当下一次读取时,文件指针才进行判断,如果后边没有信息,就将指针设置为空,基于上述文件指针的工作过程,从文件中读取信息总是有了眉目,先读取,但是需要在设置时进行一下判断,看是否此时文件指针是否是空,当文件指针非空的时候再进行设置。
    程序的改进

    起初写程序时,我并没有写Display类,而是将各个函数直接放在main函数中,这样看来比较杂乱,这时候我想到将各种菜单函数封装成一个Diplay类很容易理解而且用到了C++的类的知识。于是将各个菜单函数进行了封装。当基本完成程序的功能时,又检查了各个函数,发现许多函数是对类的操作,考虑到类的封装性与完成性,我便将各个用到的对类的操作函数设置成了类的成员函数,这样不仅缩短了程序的长度,而且将类的功能玩完善了,封装性更好、功能更加健全。在检查时有许多重复的代码,但是又和类没有关系,因此将这些代码写成一个函数,增加了代码的可重用性。
    7 测试结果主菜单示意图

    按照编号查询结果图

    按照姓名查找结果图

    添加清洁工示意图

    删除临时工示意图

    增加教师示意图

    删除教师示意图

    增加退休人员示意图

    删除退休人员示意图

    统计党员人数

    统计高学历人数

    统计各个职工的人数

    统计各个职工中女工的人数以及占总人数的百分比

    初始化临时工信息

    初始化教师信息

    初始化退休人员信息

    显示所有职工信息

    退出并保存示意图

    8 参考文献[1] H.M.Deitel. P.J.Deitel. C++大学基础教程(第五版)
    [2] C++文件操作(百度百科)
    [3] 伍俊良《C++Builder和Delphi课程设计与系统开发案例》 清华大学出版社 7-302-06072-X
    [4] 严华峰VisualC++课程设计案例精编 中国水利水电出版社 7-5084-2007-12004
    [5] 伍俊良VisualC++课程设计与系统开发案例 清华大学出版社 7-302-05968-32002
    2 评论 14 下载 2018-10-06 22:27:38 下载需要11点积分
  • 基于C语言的分区算法

    1 需求分析用C语言实现采用循环首次适应算法的动态分区分配过程alloc()和回收过程free()。其中,空闲分区通过空闲分区链表来管理,在进行内存分配时,系统优先使用空闲区低端的空间。采用循环首次适应算法进行内存块的分配和回收,同时显示内存块分配和回收后空闲内存分区链的情况。
    假设初始状态如下,可用的内存空间为640KB,并按照下列的请求序列进行内存的分配与回收:作业1申请130KB;作业2申请60KB;作业3申请100KB;作业2释放60KB;作业4申请200 KB;作业3释放100 KB;作业1释放130 KB;作业5申请140 KB;作业6申请60 KB;作业7申请50KB;作业6释放60 KB
    基本功能:设计与实现动态分区分配的数据结构与算法。根据作业大小,对空闲分区按照循环首次适应算法进行分配,回收分区时,按照回收算法进行合并回收。分配、回收后显示空闲分区状态。扩展功能:同时实现首次适应算法、最佳适应算法、最坏适应算法。通过绘制分区状态图更直观地显示分配和回收过程,对比各种算法的差异和优劣。
    2 概要设计2.1 总体结构在C语言面向过程编程方法中,常用分层方法进行编程,降低各模块之间的耦合度。在操作系统中,也用到了分层思想进行设计,每一步设计都建立在可靠的基础上,这样易于扩充和维护系统。
    在此次的课程设计中,同样也使用分层的方法,可以将各种算法很简单方便的一起实现。最底层是基本的数据结构,用来存储分区的信息。上一层是分配分区的函数alloc()和回收分区的函数free()。通过调用alloc()和free()函数可以实现四种算法。通过图形展示算法可以直观地显示分配和回收过程。最上一层是程序的界面,允许用户可以自由的对内存进行分配和回收,程序展示动态结果。
    总体结构图

    2.2 数据结构在实际的操作系统中,分配出去的内存记录在进程控制块中,为了加快内存的分配过程,动态分区最常采用的数据结构是空闲表或空闲链表,数据结构只记录未分配的内存分区。为了降低模拟程序的复杂度,本模拟将分配出去的和未分配出去的内存分区记录在同一个数据结构中,用一个标志表示是否已被分配。各分区按地址递增次序排列。内存的分配和回收只要是对数据结构做插入和删除操作,采用双向链表结构。
    为使程序具有扩展性灵活性,分区大小采用宏定义方式(#define MEMORY_SIZE 640),可修改分区的大小,展示在不同分区大小下的分配情况。
    typedef struct SubAreaNode *SubAreaList;struct SubAreaNode{ int addr; //分区起始地址 int size; //分区大小 int stat; //分区状态 宏定义 ALLOCED 1 FREE 0 int pid; //已分配分区的进程id SubAreaList pre; SubAreaList next;};SubAreaList head; //全局变量 分区链表首指针SubAreaList nowList; //当前位置分区指针 用于循环首次适应算法
    2.3 分区分配算法
    接口:int alloc(int pid, int psize, SubAreaList p);
    在链表位置p处为编号为pid,大小为psize的作业分配空间,链表p通过各种查找空闲分区算法(首次适应、循环首次适应、最佳适应、最坏适应)提供。
    返回本次分配成功与否。

    算法流程图

    2.4 回收分区算法
    接口:int freeAlloc(int pid);
    释放pid进程的分区空间,重新插入到空闲分区链表。返回值为本次回收是否成功。
    回收时先遍历链表,找到进程pid所在的位置p,如果存在,可能出现下面四种情况之一:

    回收区与前一空闲分区相邻,此时应将回收区与前一分区合并回收区与后一空闲分区相邻,此时应将回收区与后一分区合并回收区同时与前后两个空闲分区相邻,此时将三个分区合并回收区不相邻前后空闲分区,直接改为空闲分区

    算法流程图

    2.5 首次适应算法寻找分区位置
    接口:SubAreaList ffFindFreeSubArea(int psize);
    按照首次适应算法从分区链表中找到第一个不小于psize的空闲分区,返回此分区地址。如果找不到可用的空闲分区返回NULL。

    算法流程图

    2.6 循环首次适应算法寻找分区位置
    接口:SubAreaList nfFindFreeSubArea(int psize);
    按照循环首次适应算法从分区链表的当前位置开始寻找第一个不小于psize的空闲分区,返回此分区地址。寻找结束后更新当前位置。当链表循环一圈后仍没有找到合适的空闲分区则返回NULL。

    算法流程图

    2.7 最佳适应算法寻找分区位置
    接口:SubAreaList bfFindFreeSubArea(int psize);
    可以将所有空闲分区按照大小升序排列,从头寻找第一个符合要求的空间分区进行分配。在这里为简单起见,对链表线性搜索一轮,找到符合空间大小要求的最小的空闲分区。

    算法流程图

    2.8 最坏适应算法寻找分区位置
    接口:SubAreaList wfFindFreeSubArea(int psize);
    可以将所有空闲分区按照大小降序排列,从头寻找第一个符合要求的空间分区进行分配。在这里为简单起见,对链表线性搜索一轮,找到符合空间大小要求的最大的空闲分区。

    算法流程图

    2.9 绘制状态图算法
    接口:void disAllocGraph(int prec);
    用于绘制精度为prec的内存状态图。也即每MEMORY_SIZE/prec绘制一格。

    2.10 程序界面
    接口:void selectAlogrithm();
    可选择进入不同算法进行内存分配和回收的演示,每个算法既支持手动输入分配回收序列,也支持从文件中输入分配回收序列。每进行一步即展示当前这一步的分配结果。展示时内存分配表和分配图并排展示,可以更直观清晰的看到内存分配回收情况,加深对算法的理解程度。

    3 运行环境
    硬件环境:

    cpu: Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz × 4内存:8G
    软件环境:

    OS:Deepin Linux 15.6 64位Linux内核:Linux 4.15.0-21deepin-generic

    4 开发工具和编程语言
    编辑软件:

    Sublime Text 3
    编译软件:

    gcc version 7.2.0
    编程语言:

    C语言

    5 详细设计5.1链表初始化SubAreaList getASubArea() { return (SubAreaList)malloc(sizeof(struct SubAreaNode));}//对空闲分区链表进行初始化,一整块空间为空SubAreaList initSubArea() { SubAreaList p = getASubArea(); p->addr = 0; p->size = MEMORY_SIZE; p->stat = FREE; p->pid = -1; p->pre = NULL; p->next = NULL; return p;}
    5.2 分配分区函数//在链表位置p处为编号为pid,大小为psize的作业分配空间int alloc(int pid, int psize, SubAreaList p) { if (p == NULL) //无合适空间可分配 return 0; if (p->size == psize) { //分区整块分配 p->stat = ALLOCED; p->pid = pid; } else { //分割分区 SubAreaList newSubArea = getASubArea(); newSubArea->addr = p->addr + psize; newSubArea->size = p->size - psize; newSubArea->stat = FREE; newSubArea->pid = -1; p->size = psize; p->stat = ALLOCED; p->pid = pid; newSubArea->next = p->next; p->next = newSubArea; newSubArea->pre = p; } return 1;}
    5.3 回收分区函数int freeAlloc(int pid) { //寻找作业所在分区 SubAreaList p = head; while (p) { if (p->pid == pid) { break; } p = p->next; } if (p == NULL) return 0; //不是首块分区且与前一空闲分区相连 if (p != head && p->pre->stat == FREE && p->pre->addr + p->pre->size == p->addr) { SubAreaList preNode = p->pre; SubAreaList nextNode = p->next; preNode->size += p->size; preNode->next = p->next; nextNode->pre = preNode; //与后一空闲分区相连 if (p->next->stat == FREE && p->addr + p->size == p->next->addr) { preNode->size += nextNode->size; preNode->next = nextNode->next; nextNode->next->pre = preNode; free(nextNode); } free(p); } else { //不是最后一个分区且与后一空闲分区相连 if (p->next != NULL && p->next->stat == FREE && p->addr + p->size == p->next->addr) { SubAreaList nextNode = p->next; p->size += nextNode->size; p->next = nextNode->next; nextNode->next->pre = p; p->stat = FREE; p->pid = -1; free(nextNode); } else { p->stat = FREE; p->pid = -1; } } return 1;}
    5.4 首次适应算法SubAreaList ffFindFreeSubArea(int psize) { SubAreaList p = head; while (p) { if (p->stat == FREE && p->size >= psize) return p; p = p->next; } return NULL;}int ffAlloc(int pid, int psize) { return alloc(pid, psize, ffFindFreeSubArea(psize));}
    5.5 循环首次适应算法SubAreaList nfFindFreeSubArea(int psize) { SubAreaList tmp = nowList; while (nowList) { if (nowList->stat == FREE && nowList->size >= psize) { return nowList; } nowList = nowList->next == NULL ? head : nowList->next; if (nowList == tmp) return NULL; }}int nfAlloc(int pid, int psize) { int ret = alloc(pid, psize, nfFindFreeSubArea(psize)); nowList = nowList->next == NULL ? head : nowList->next; return ret;}
    5.6 最佳适应算法SubAreaList bfFindFreeSubArea(int psize) { SubAreaList p = head, minP = NULL; int minSize = MEMORY_SIZE + 1; while (p) { if (p->stat == FREE && p->size >= psize) { if (p->size < minSize) { minSize = p->size; minP = p; } } p = p->next; } return minP;}int bfAlloc(int pid, int psize) { return alloc(pid, psize, bfFindFreeSubArea(psize));}
    5.7 最坏适应算法SubAreaList wfFindFreeSubArea(int psize) { SubAreaList p = head, maxP = NULL; int maxSize = -1; while (p) { if (p->stat == FREE && p->size >= psize) { if (p->size > maxSize) { maxSize = p->size; maxP = p; } } p = p->next; } return maxP;}int wfAlloc(int pid, int psize) { return alloc(pid, psize, wfFindFreeSubArea(psize));}
    5.8 分配状态显示图与表//绘制内存分配图void disAllocGraph(int prec) { SubAreaList p = head; for (int i = 0; i < MEMORY_SIZE/prec; i++) printf("-"); printf("\n"); int addr[MAX_PRO]; int pid[MAX_PRO]; int minSize = MEMORY_SIZE; int n = 0; while (p) { addr[n] = p->addr; pid[n++] = p->pid; minSize = p->size < minSize ? p->size : minSize; p = p->next; } addr[n] = MEMORY_SIZE; pid[n++] = -1; if (minSize < 10) { printf("内存间隔过小,不显示分配图\n"); return; } for (int l = 0; l < 3; l++) { for (int i = 0, j = 0, k = 0; i < MEMORY_SIZE/prec; i++) { if (i == addr[j]/prec) { printf("|"); j++; } else printf(" "); if (l == 1 && i == addr[k]/prec + (addr[k+1]/prec-addr[k]/prec)/2) { if (pid[k] != -1) { printf("%d", pid[k]); i = pid[k] < 10 ? i+1 : i+2; } k++; } if (i == MEMORY_SIZE/prec - 2) printf("|"); } printf("\n"); } for (int i = 0; i < MEMORY_SIZE/prec; i++) printf("-"); printf("\n"); int cnt = 0; for (int i = 0, k = 0; i < MEMORY_SIZE/prec; i++) { int digit = 0; int tmp = addr[k]; while (tmp) { digit++; tmp /= 10; } if (i == addr[k]/prec - digit/2) { printf("%d", addr[k]); k++; cnt = digit; } else { if (cnt > 1) { cnt--; continue; } printf(" "); } } printf("\n");}void printSepLine() { printf("\n*************************************************\n\n");}void displayAlloc() { SubAreaList p = head; printf("\n%3s %3s %3s %3s %3s\n", "起始", "终止", "长度", "状态", "ID"); while (p) { printf("%3d %3d %3d %3d %3d\n", p->addr, p->addr + p->size-1, p->size, p->stat, p->pid); p = p->next; } printf("\n"); disAllocGraph(10); printSepLine();}
    5.9 输入分配回收序列控制函数:void inputCtrl(int (*allocAlogrithm)(int,int)) { system("clear"); printf("分配输入: A 作业号 大小\n"); printf("回收输入: F 作业号\n"); printf("退出输入: Q\n\n"); char T[5]; scanf("%s", T); while (T[0] != 'Q') { if (T[0] == 'A') { int pid, size; scanf("%d%d", &pid, &size); int ret = allocAlogrithm(pid, size); if (ret) { printf("作业号 %d 分配 %d KB\n", pid, size); displayAlloc(); } else { printf("\n内存不足 分配失败\n\n"); printSepLine(); } } else if (T[0] == 'F') { int pid; scanf("%d", &pid); int ret = freeAlloc(pid); if (ret) { printf("作业号 %d 已回收\n", pid); displayAlloc(); } else { printf("未找到相关作业,回收失败\n\n"); printSepLine(); } } else exit(0); scanf("%s", T); }}void fileInputCtrl(int (*allocAlogrithm)(int,int)) { freopen(FILE_NAME, "r", stdin); inputCtrl(allocAlogrithm); freopen("/dev/tty", "r", stdin);}
    6 调试分析分区分配与回收测试输入数据:
    A 1 130A 2 60A 3 100F 2A 4 200F 3F 1A 5 140A 6 60A 7 50F 6Q
    四种算法通过以上测试数据可以很正确的得出结果,分配状态图也可以清晰直观的显示分区状态。
    不足的是,如果请求分配的进程大小过于小或进程过多,会导致分区、碎片都比较小,这时状态图显示算法会错误显示。这里的解决方案是,如果分区间隔小于10就不做显示,只显示分区表。
    7 测试结果下面给出上述测试序列选用循环首次适应算法时的运行结果:






    参考文献[1] 汤子瀛,计算机操作系统(第四版),西安:西安电子科技大学出版社,2004.05,127-131
    [2] 梁红兵 汤小丹,计算机操作系统(第四版)学习指导与题解,西安:西安电子科技大学出版社,2005.02,97-98
    [3] Peter Baer Galvin、Greg Gagne著、 郑扣根译,操作系统概念(第七版),北京:高等教育出版社,2010.01,243-246
    [4] 严蔚敏 吴伟民,数据结构(C语言版),北京:清华大学出版社,2016.12,18-43
    [5] 邓曦辉,动态分区分配与回收算法的模拟[J],电脑开发与应用,2013,26(4),61-63
    2 评论 3 下载 2018-11-04 14:46:42 下载需要5点积分
  • 基于Android的天气预报APP

    摘 要随着移动通信技术的发展和无线数据业务的进步,手机已被赋予了除通话以外的其它许多功能。全新的手机软件领域已逐渐聚焦了众多软件开发商的目光,软件开发者和软件用户将共同面临这个振奋人心的新境界。
    本设计使用Android设计技术开发了一种运用在Android系统上的手机天气预报软件系统,本系统通过选择城市来获得天气,风向,风向,温度等信息。基于手机的天气预报系统软件可以使用户对于各地的天气情况的实时掌握,极大的方便了用户的出行和行程安排,避免了不必要的麻烦,具有很强的实用性。
    关键词:Android;手机天气预报软件。
    AbstractWith the development of science and technology, the mobile terminal gradually into the people’s attention, related to more widely, and play an increasingly important role in people’s daily lives. Therefore, the development of critical applications has become an important factor in the popularity of the mobile terminal, the design and development of practical, convenient application is of great significance and good market prospects. Android as the most popular operating platform, naturally, there are a lot of demand for application services.
    The study of this topic is the weather software, based on the Android platform is designed to help the user to query weather information and weather changes anytime, anywhere, to make life more comfortable and convenient. This paper describes the software interface design of the Android platform under the weather and exception handling part, including the contents of the interface implementation, the use of controls, the layout of the interface, and exception handling, combined with weather data of the China Meteorological Association, will be accurate weather conditions presented to the user-friendly way, allows the user to experience more enjoyable the service of this software.
    KEY WORDS:Android,interface,control,weather software
    1 绪论Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。Android操作系统最初由Andy Rubin开发,主要支持手机。2005年8月由Google收购注资。2007年11月,Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统。随后Google以Apache开源许可证的授权方式,发布了Android的源代码。第一部Android智能手机发布于2008年10月。Android逐渐扩展到平板电脑及其他领域上,如电视、数码相机、游戏机等。2011年第一季度,Android在全球的市场份额首次超过塞班系统,跃居全球第一。 2012年11月数据显示,Android占据全球智能手机操作系统市场76%的份额,中国市场占有率为90%。2013年09月24日谷歌开发的操作系统Android在迎来了5岁生日,全世界采用这款系统的设备数量已经达到10亿台。
    1.1 课题研究内容本课题研究的是基于Android平台下的天气软件,目的是使用户能随时随地的查询天气信息及天气变化情况,让生活更加舒适方便。本文讲述Android平台下天气软件的界面设计以及数据的获取和解析,主要包括界面的实现,控件的使用,界面的布局和数据处理等内容,结合中国气象网的天气数据,将准确的天气情况以友好的方式呈现给用户,使用户更加赏心悦目的体验本软件的服务。通过对界面的布局及控件的应用等相关内容的学习,使我们对Android平台下界面开发工作有一个初步的了解,并且经过这次开发过程,能够基本掌握这些内容。
    1.2 课题研究需求分析课题研究需要达到的基本要求:

    能够查询城市的天气情况
    系统能通过手机查看并显示天气数据
    系统必须具有安全性,可靠性,独立性

    1.3 研究目的和意义天气软件是一种非常实用的信息服务,随着智能手机的不断普及,各种智能手机平台下都有各种各样的天气软件。Android作为现在主流的智能手机之一,自然也需要这方面的软件。天气关系到人们的日常生活,如告知温暖,方便出行等。一款简单实用的天气软件会很吸引用户。
    基于Android平台的天气软件已经有很多,经过分析,用户第一眼往往是一个软件的外观,一个好看的界面才能让用户以一种爱美之心去尝试,才能进一步了解一个软件的好坏,所以吸引眼球的界面是争取用户的第一步。因此,界面设计工作对应用程序来说非常重要,在界面上吸引了用户,才能进一步让用户体验应用程序中的功能,使用这个软件。
    1.4 研究前景Android最吸引人的特点是开源特性,因其开源,允许所有人对其代码进行开发和修改,同时又由于其代码的简单易学性,Android在全世界拥有众多的粉丝。Android在中国的前景十分广阔,首先是有成熟的消费者,在国内,Android社区十分红火,这些社区为Android在中国的普及做了很好的推广作用。国内厂商和运营商也纷纷加入了Android阵营,包括中国移动,中国联通,中兴通讯,华为通讯,联想等大企业,同时不仅仅局限于手机,国内厂家也陆续推出了采用Android系统的产品,我们可以预见Android将会被广泛应用在国产智能上网设备上,将进一步扩大Android系统的应用范围。
    Android采用了软件层(Software stack)的构架,主要分为三个部分。底层以Linux为内核作为基础,由C语言开发,只提供基础功能,中间层次包话函数库和虚拟机,由C++开发。最上层是各种应用软件,包话通话程序,短信程序。应用软件可以由各公司或个人自行开发,以JAVA编写。
    2 Android开发环境及平台搭建2.1 Android开发环境介绍Android平台使用Java编程语言来开发应用程序,而Android提供了对Java的核心支持。考虑到Java虚拟机的执行效率和占用资源情况,Google重新设计了Java的编译器,命名为Dalvik。Dalvik是经过优化的Java编译器,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个Dalvik应用作为一个独立的Linux进程执行,独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。
    项目的开发在Eclipse环境中进行,由于进行的是Android应用程序的开发,需要在Eclipse安装ADT插件,即Android开发工具,这样Eclipse就可以和Android SDK建立连接,在Eclipse中启动Android模拟器、调试程序等工作。
    由以上分析可知,Android平台的搭建需要Android SDK、Java SDK、Eclipse和ADT四个软件。
    2.2 Android开发平台搭建在进行Android应用程序的开发前,要先搭建Android平台,然后才能在开发环境中进行编程。根据官方指导,对Android平台的搭建过程介绍如下:
    STEP1:在官方网址上下载JDK6.0并安装,网址是:
    http://www.oracle.com/technetwork/java/javase/downloads/index.html安装后设置系统环境变量JAVA_HOME、CLASS_PATH、PATH的值;
    STEP2:在官方网址上下载更新的SDK进行安装,官方网址为:
    http://development.android.com/sdk/index.html下载完后解压到指定文件夹,启动SDK Manager进行安装,选择需要的Android版本,然后更新,这次更新需要的时间比较慢,所以更新前要做好准备。安装完成后,将ADB命令所在的目录platform-tools的完整路径添加到系统的环境变量PATH中,就能够在命令中使用ADB命令了;
    STEP3:接下来要安装的是ADT插件,即Android开发工具。因为ADT在线安装容易遇到问题,增加一些不必要的麻烦所以需要下载后在本地安装。指定网址为:
    http://development.android.com/sdk/index.htmlSTEP4:下载Eclipse,建议选择Eclipse3.4以上版本,网址为:
    http://www.eclipse.org/downloads/解压到指定位置后运行,选择Eclipse菜单中的Help>Install New Software选项卡上的Available Software,点击右侧的Add,然后在Name框中填写Android,在Location框中选择上步下载的ADT文件,然后点击OK>Finish>Install All,这时关闭Eclipse再重新启动。重启后选择Eclipse菜单中的Window>Preferences,在左侧的Android项目中SDK Location中填入Android SDK解压后的目录,然后点击Apply。
    至此,整个平台的搭建工作就完成了,可以进行相应的安卓应用开发。
    3 项目分析3.1 用户界面分析根据应用程序的功能需要,对用户界面做如下分析:
    实时天气界面:显示城市当前的实时天气状况,包括城市名称、城市名片、天气情况、温度高低、星期等信息。界面左边有一列城市列表,显示中国各个城市名称,当用户想知道哪个城市的天气情况时,点击这个城市名就可以获取天气状况,考虑到使软件占用尽量小的内存,软件去掉了不必要的花哨,显示城市名称,城市名片,温度和天气情况,同时对未来6天的天气情况简要描述,简要显示星期、天气描述、温度高低等数据,使用户一目了然,使人们及时了解天气变化,对日常生活出行、穿衣做好准备。
    3.2 相关技术介绍3.2.1 Activity在Android应用程序中,一个活动Activity通常就是一个单独的界面。每一个界面都被实现为一个独立的类,并且从Activity基类中继承而来,Activity将会显示由空间组成的用户接口,并对事件做出响应。大多数的应用都是由多个Activity显示组成。
    简单的说,Activity代表一个用户所能看到的界面,主要用于处理应用程序的整体性工作,例如,监听系统事件如按键事件、触摸屏事件等,为用户显示指定的View,启动其他Activity等。所有应用的Activity都继承于android.app.Activity类,该类是Android提供的基层类,其他的Activity继承该父类后,通过父类的方法实现各种功能,这种设计在其他领域也较为常见。
    3.2.2 IntentAndroid基本的设计理念是鼓励减少组件间的耦合,因此Android提供了Intent,Intent提供了一种通用的消息系统,它允许在你的应用程序与其他的应用程序间传递Intent来执行动作和产生时间。使用Intent可以激活Android应用的三个核心组件:活动、服务和广播接收器。
    Intent可以划分为显示意图和隐式意图。显示意图调用Intent,SetClass方法明确制定了组件名的Intent为显示意图,显示意图明确制定了Intent应该传递给那个组件,在同一个应用内部使用的。隐式意图没有明确指定组件名的Intent为隐式意图,Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。
    Intent负责对应用中一次操作的动作、动作涉及数据和附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的结构。
    3.2.3 Service如果把Activity比喻为前台程序,那么Service就是后台程序,Service的整个生命周期都只会在后台执行。Service跟 Activity一样也由Intent调用,由于Service在后台运行,所以没有界面,用来处理耗时比较长,而且Service不是一个单独的进程,也不是一个单独的线程。Service有两种类型:

    本地服务(Local Service):用于应用程序内部
    远程服务(Remote Sercie):用于android系统内部的应用程序之间

    前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。后者可被其他应用程序复用,例如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。
    Service的生命周期,Service有startService和bindService两种启动Service方法,每种方法Service的生命周期是不一样的。
    通过startService()——Service会经历 onCreate —> onStartCommand(),stopService的时候直接onDestroy,如果是调用者直接退出而没有调用stopService的话,Service会一直在后台运行,下次调用者再起来仍然可以stopService;
    通过bindService()——Service只会运行onCreate()—>onBind() 这个时候调用者和Service绑定在一起 unbindService的时候onUnbind() —> onDestroyed(),调用者退出了,Srevice就会调用onUnbind() —> onDestroyed()。在这里需要注意的是Service的onCreate的方法只会被调用一次,就是你无论多少次的startService又 bindService,Service只被创建一次。如果先是bind了,那么start的时候就直接运行Service的onStart方法,如果先是start,那么bind的时候就直接运行onBind方法。如果你先bind上了,就stop不掉了,只能先UnbindService, 再StopService,所以是先start还是先bind行为是有区别的。
    3.3.4 Layout布局布局方式有很多种,比如线性布局(Linear Layout)、相对布局(Relative Layout)、表格布局(Table Layout)、网格视图(Grid View)、标签布局(Tab Layout)、列表视图(List View)和绝对布局(Absolute Layout)。本文设计主要采用相对布局(Relative Layout)、线性布局(Linear Layout),所以就相对布局和线性布局我们来做简单地介绍。
    相对布局 Relative:里面可以放多个控件,允许子元素指定它们相对于父元素或其他元素的位置(通过ID指定)。因此你可以按正确的顺序对齐两个元素,或者让一个视图在另外一个下面,居于屏幕中间,左边的中间,等等。元素通过给定顺序来绘制,因此如果第一个元素在屏幕中间,其他以它对齐的元素都会对齐到屏幕中间。同样,因为这个顺序,如果使用XML来指定这个布局,你将引用的元素(为了定位其它视图对象)必须被列在XML文件中,在你通过引用ID从其他视图中引用它之前。其中一些特性直接由元素支持,另外一些由它的LayoutParams成员变量支持(为所有这个屏幕中的元素子类化RelativeLayout,因为所有元素都是RelativeLayout父对象的子元素)。已定义的相对布局RelativeLayout参数是:width,height,below,alignTop,toLeft以及padding[Bottom|Left|Right|Top]和margin[Bottom|Left|Right|Top]。注意其中一些参数明确是相对于其他元素的布局位置,所以它们的数值必须是你的相对位置元素的ID。
    线性布局 LinearLayout:线性布局是所用布局中最常用的方式之一,RadioGroup, TabWidget,TableLayout,TableRow,ZoomControls类的父类。LinearLayout可以让它的子元素垂直或水平的方式排成一行(不设置方向的时候默认按照垂直方向排列)。LinearLayout以你为它设置的垂直或水平的属性值,来排列所有的子元素。所有的子元素都被堆放在其它元素之后,因此一个垂直列表的每一行只会有一个元素,而不管他们有多宽,而一个水平列表将会只有一个行高(高度为最高子元素的高度加上边框高度)。LinearLayout保持子元素之间的间隔以及互相对齐(相对一个元素的右对齐、中间对齐或者左对齐)。
    LinearLayout还支持为单独的子元素指定weight 。好处就是允许子元素可以填充屏幕上的剩余空间。这也避免了在一个大屏幕中,一串小对象挤成一堆的情况,而是允许他们放大填充空白。子元素指定一个weight 值,剩余的空间就会按这些子元素指定的weight比例分配给这些子元素。默认的weight值为0。例如,如果有三个文本框,其中两个指定了weight值为1,那么,这两个文本框将等比例地放大,并填满剩余的空间,而第三个文本框不会放大。
    3.3.5 控件介绍TextView——文本控件,可以用它来显示文字,就像一个标签一样,对TextView是怎么设置显示的文本,怎样设置字体的大小,字体的颜色,字体的样式。TextView包含以下子类:Button, CheckedTextView,Chronometer,DigitalClock,EditText。

    android:id —— 控件的标识符
    android:layout_width —— 设置控件的宽度
    android:layout_height —— 设置控件的高度
    android:layout_marginTop —— 设置文本的上外边距
    android:textSize —— 设置文本文字的的大小
    android:paddingLeft —— 设置元素左内边距

    Button——按钮控件,在button内部可以放置内容,比如文本或图像。<button>与</button>标签之间的所有内容都是按钮的内容,其中包括任何可接受的正文内容,比如文本或或多媒体。例如,我们可以在按钮中包括了一个图像和相关的文本,用它们在按钮中创建一个吸引人的标记图像。不过button禁止使用的元素是图像映射,因为它对鼠标和键盘敏感的动作会干扰表单按钮的行为。下面是Button的部分属性:

    android:id —— 控件的标识符
    android:layout_width —— 设置按钮的宽度
    android:layout_height —— 设置按钮的高度
    android:textSize —— 设置按钮里文字的大小
    android:layout_marginTop —— 设置按钮的上外边距
    android:text —— 设置按钮中的文字
    android:visibility —— 设置按钮里的元素是否可见

    EditText——文本编辑框,TextView的直接子类,所以EditText会继成父类TextView的一些方法。在布局中配置EditText也需同时配置一个Button,这样可以在代码中监听Button的事件,以便获取当前在EditView中输入的内容并且显示出来。在EditView可以限制输入的字符串类型。下面是EditText的部分属性:

    android:id —— 控件的标识符
    android:layout_width —— 设置输入框的宽度
    android:layout_height —— 设置输入框的高度
    android:layout_weight —— 设置输入框占父控件的比例
    android:inputType —— 设置输入框内的字符串类型
    android:hint —— 设置在输入框输入内容前默认的文字

    ImageView——标签可以显示任意图像,例如图标,图片等。ImageView类可以加载各种来源的图片,需要计算图像的尺寸,以便它可以在其他布局中使用,并提供例如缩放和着色等各种显示选项,在本文用来显示城市图片。下面是ImageView的部分属性:

    android:id —— 设置图片的标识符
    android:layout_width —— 设置图片的宽度
    android:layout_height —— 设置图片的高度
    android:visibility —— 设置图片是否可见性

    4 天气预报软件界面设计与实现4.1 Android平台用户界面的实现Android 提供的可变化的用户界面(UI)开发模块是基于XML 文件的。这些XML 文件放在工程/res/layout 下面。这个目录可包含所有应用程序所需的代码部分,比如图片、字符串、xml 文件。当要使用到这些资源时,在代码目录中打开R.java文件即可。在XML 文件里编辑界面的代码,实现起来不仅方便,使用时也会更加灵活。
    在Android 程序设计中要用到一些基本的Android UI 元素,通过使用Views、View Groups 和layouts 可为Activity 创建功能性的、富有直观力的UI.通常是使用Android SDK 中提供的一些控件,进行布局、扩展和定制这些控件,并使用ViewGroups 去组合Views,创建由相互作用的子控件组成的原子的、重复利用的UI 元素。也可以创建自己的Views,来实现显示数据和与用户交互的新途径;或使用一些继承自View Group 的Layout 管理器来组织Android UI中的单个元素到屏幕上。
    在一个Android 应用中,用户界面由View 和View Group对象构建。View 与View Group 有很多种类,而它们都是View类的子类。View 对象是Android 平台中用户界面的基本单元。View 类是widgets(工具)类的父类,它们提供了诸如文本输入框和按钮之类的UI 对象的完整实现。View Group 类是Layouts(布局)类的父类,它们提供了诸如流式布局、表格布局以及相对布局之类的布局架构。
    View 对象是一个数据体,它的属性存储了用于屏幕上一块矩形区域的布局参数及内容。并负责它所辖的这个矩形区域之中所有测量、布局、焦点转换、卷动以及按键/触摸手势的处理。作为一个用户界面对象,View 同时也担任着用户交互关键点以及交互事件接受者的角色。天气实时预报系统程序功能比较单一,其UI 也相对比较简单,只要有一个显示所有中国城市信息的列表,一个显示城市图片的Imageview即可。为了建立Android 平台的用户界面,首先要在Package Explorer 窗口中展开Layout 后新建xml 文件,用来对窗口界面进行布局,主要有系统运行的主配置文件activity_main.xml ,listview.xml和weatherfragment.xml。
    Layout 是一类特殊的ViewGroup 控件,它们本身没有任何可显示内容,存在的惟一原因就是其中的内部结构,能够更好地摆放它的子控件。比如Linearlayout,可将子控件按水平或垂直方向按顺序排列下去;Tablelayout,可以将子控件按照表格的形式,一枚枚放置好;Relativelayout 更灵活,可以设定各个控件之间的对齐和排列关系,适合定制复杂的界面。有了Layout 的存在,控件和控件之间不再是割裂地存在,而是更有机地结合在一起,设定起来也更为方便。在activity_main.xml 文件中主要是添加一些界面的布局设置。
    4.1.1 主要的项目工程文件为了给用户清晰,直观的体验,界面设计要做到简明,友好,因为考虑到各个城市的不同特点,所以给每个城市添加一张城市名片的图片,能使用户感觉更加友好,界面左边是城市列表,用户可以选择具体城市查看天气信息。考虑到软件的简洁明确性,只设定一个界面用来显示城市和天气信息,weather工程目录结构及其源代码文件如图1所示:

    4.1.2 创建中国城市列表根据天气预报系统功能需求分析,系统启动后,应在主界面上呈现出中国国内所有城市的列表数据,因此需要创建中国城市列表数据,包括获取、解析城市列表数据,并在用户界面上呈现出来。同时为了给用户更好的交互,每个城市对应显示城市名片,通过代码实现,具体代码如下:
    @Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLayoutInflater = LayoutInflater.from(this); cityList = (ListView) findViewById(R.id.citylist); cityImage = (ImageView) findViewById(R.id.cityImage); cityName = (TextView) findViewById(R.id.cityName); cityWeather = (TextView) findViewById(R.id.cityWeather); cityTemp = (TextView) findViewById(R.id.cityTemp); viewpager = (ViewPager)findViewById(R.id.viewpager); citys.add(new City(R.drawable.city1, "桂林", "101300501")); citys.add(new City(R.drawable.city2, "北京", "101010100")); citys.add(new City(R.drawable.city3, "哈尔滨", "101050101")); citys.add(new City(R.drawable.city4, "大连", "101070201")); citys.add(new City(R.drawable.city5, "南京", "101190101")); citys.add(new City(R.drawable.city6, "成都", "101270101")); citys.add(new City(R.drawable.city7, "广州", "101280101")); citys.add(new City(R.drawable.city8, "乌鲁木齐", "101130101")); citys.add(new City(R.drawable.city9, "香港", "101320101")); citys.add(new City(R.drawable.city10, "台北", "101340101")); citys.add(new City(R.drawable.city11, "沈阳", "101070101")); citys.add(new City(R.drawable.city12, "呼和浩特", "101080101")); citys.add(new City(R.drawable.city13, "济南", "101120101")); citys.add(new City(R.drawable.city14, "西安", "101110101")); citys.add(new City(R.drawable.city15, "兰州", "101160101")); citys.add(new City(R.drawable.city16, "武汉", "101200101")); cityadapter = new CityAdapter(); weatheradapter = new WeatherAdapter(getSupportFragmentManager()); cityList.setAdapter(cityadapter); viewpager.setAdapter(weatheradapter); cityList.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { // TODO Auto-generated method stub selectid = position; cityadapter.notifyDataSetChanged(); cityImage.setImageResource(citys.get(position).image); callHTTP(citys.get(position).code); } }); cityImage.setImageResource(citys.get(selectid).image); callHTTP(citys.get(selectid).code);}
    这段代码的作用是在创建城市列表的同时,将城市名称,城市名片和城市接口结合在一起,使得显示的时候同步,具体效果如图2所示:

    4.2 天气信息的获取基于Android 操作系统的天气实况预报系统设计的核心是通过调用通信协议SOAP(Simple Object AccessProtocol)的接口,从Web Service 提供商中提取天气预报的数据信息,为客户端服务。其基本功能是当用户运行天气预报系统程序时,在手机屏幕上显示出中国的城市名称,用户单击任意一个城市名,可获得该城市的天气实时预报信息。为此,需要解决的问题是手机终端从Web 服务器获取了所有类型的数据之后,将这些数据进一步交给Android 手机终端View 组件,在手机界面上显示给用户。
    4.2.1 天气信息数据的获取在开发中我们经常提到”接口”这个词,什么是接口呢?简单的说,接口其实就是一个http地址。一个标准的网络应用肯定需要两个部分,一部分是咱们正在学习的android开发,还有另一部分是服务器开发。
    大多数android程序都是基于网络的,比如基本上大家都在使用的QQ手机客户端。那么假设我们现在要开发一个类似QQ的通信客户端。第一步,需要开发一个登录界面来验证用户登录。很显然的,为了验证登录,我们需要和服务器进行通信,把用户输入的用户名和密码传递给服务器,然后服务器来判断这组用户名密码数据是否正确,并返回给客户端,告诉我们用户登录是否成功。一般接口由三部分组成:接口地址+接口名称+接口参数。比如下面这个是中国气象网提供的天气信息查询接口:http://www.weather.com.cn/data/cityinfo/101300501.html ,该接口提供的数据是实时天气情况,通过这个接口我们可以得到以下信息,如图3所示:

    代码实现接口获取数据如下:
    // 请求接口private void callHTTP(final String cityCode) { // 创建一个runnable Runnable runnable = new Runnable() { @Override public void run() { // step1 :创建HttpGet, 就是创建我们要访问的接口地址 HttpGet getMethod = new HttpGet("http://m.weather.com.cn/data/"+cityCode+".html"); // step2 :HttpClient, 我们要通过它来将step1创建出来的地址发送给服务器 HttpClient httpClient = new DefaultHttpClient(); try { // step3: 通过httpClient.execute()方法,我们把url发送给了服务器, // 而服务器返回的信息就会被保存在HttpResponse中了 HttpResponse response = httpClient.execute(getMethod); // 发起GET请求 // 用EntityUtils.toString把HttpResponse转换成string String result = EntityUtils.toString(response.getEntity(), "utf-8"); // 将返回的json字符串解析并显示出来 try { paresJson(result); } catch (JSONException e) { e.printStackTrace(); Log.v("TAG", "解析失败 "); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }; // 开启线程执行runnable new Thread(runnable).start();}
    4.2.2 解析数据从图3可以看出,我们获得了桂林的天气信息,但是这些数据看着很乱,为了使用户清晰的获得信息,我们可以采用json协议解析数据:
    // 将返回的json字符串解析并显示出来private void paresJson(String jsonString) throws JSONException { // 首先,把这个字符串转换成jsonobject JSONObject jsonObject = new JSONObject(jsonString); // { // "weatherinfo": { // "city": "桂林", // "cityid": "101300501", // "temp1": "28℃", // "temp2": "19℃", // "weather": "多云", // "img1": "d1.gif", // "img2": "n1.gif", // "ptime": "11:00" // } // } // 理解json格式我们可以把它当成window里的文件系统, 大括号表示文件夹 // 假设上面是字符串的内容, // 那么最外面的"文件夹"里包含着一个叫"weatherinfo"的子文件夹. // 然后weatherinfo文件夹里包含着许多文件, 有的叫city ,有的叫 temp1, // city 后面的 "桂林" 表示的是city这个文件的实际内容是"桂林" //
    4.3 在UI上显示天气信息当获得天气数据之后,就可以把它绑定到activity_main.xml 定义的ListView 组件上,在WeatherFragment.java 中的代码段为:
    public class WeatherFragment extends Fragment { Weather weather; @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); weather = (Weather)getArguments().getSerializable("weather"); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View view = inflater.inflate(R.layout.weatherfragment, null); TextView dayTextView = (TextView) view .findViewById(R.id.time); TextView tempTextView = (TextView) view .findViewById(R.id.yubaoTemp); TextView weatherTextView = (TextView) view .findViewById(R.id.yubaoWeather); dayTextView.setText(weather.day); tempTextView.setText(weather.temp); weatherTextView.setText(weather.weather); return view; }}
    5 软件测试5.1 天气预报软件在电脑模拟环境下测试软件编写完成,对其进行测试,首先将手机天气预报系统在电脑模拟环境下测试的方案,以下是对系统进行测试,在Eclipse 的Package Explorer 窗口中用鼠标右键选择weather工程名,在弹出的窗口中选择”Run As”→”Android Application”安装该应用程序到Android 模拟器并启动它,如图4所示:

    等待模拟器启动完成软件的安装,然后单击所要查询的城市名称列表项,稍等片刻便会显示出该城市的天气实况信息。电脑模拟测试结果如图5所示:


    通过网站查询桂林的天气情况如图6所示:

    通过对图5和图6的数据比较,可以知道软件获得的数据是正确的,说明软件的可行性基本满足要求。
    5.2 天气预报软件在Android手机下测试在工程名weather上点右键,然后选择“Run As”,然后选择“Android Application”。进入界面后,选择测试手机,如图7所示:

    等待程序安装完成,保证手机连接互联网的情况下,启动后可以得到各个城市的天气信息,如图8所示:




    该测试说明开发的天气预报软件可以独立在Android设备运行,满足设计要求的独立性,通过与网络的数据比较,可以发现,天气预报软件获取的数据与实际的天气情况非常接近,说明数据的准确性,实时性;从图9可以看出,当选择不同的城市时,软件可以通过网络获取不同城市的天气信息,说明该天气预报软件可以获取不同城市的气象信息,满足设计要求。
    6 总结在本次Android天气预报软件开发过程中,我通过学校的图书馆资料和网上查询,了解了Android的搭建、Intent、Activity、Service等知识。Android环境搭建的基本工作完成后,本文对界面的控件、布局和美观方面进行设计,对数据获取和解析做了分析,通过模拟器显示城市名片,实时天气情况和未来5天天气情况,这个软件还可以进一步发展,比如“短信预报”、“新闻模块”等功能,如果这些功能都能实现将会对用户有更多的帮助,使他们的生活更加愉悦和方便。Android 智能手机应用程序的开发涉及了它的整个体系结构,是一项非常复杂的工程。
    1 评论 1 下载 2019-05-18 15:31:02 下载需要15点积分
  • 基于JAVA的停车场管理系统

    第一章 概述1.1 项目背景车辆越来越多的今天,停车场只靠人工管理显然难度已经是提高很多,所以应该开发出便于管理记录的停车场管理系统来帮助对停车场进行管理。
    1.2 软件定义一款帮助停车场管理员对车辆进出进行管理的软件。
    1.3 开发环境
    Window10系统
    Eclipse java开发工具
    Oracle数据库

    第二章 需求分析2.1 题目要求2.1.1 问题陈述要求能够进行如下工作:

    车位基本信息维护(车位增加修改、收费标准变动等)
    交班报表功能(当班收费员收款总额)
    当前车位状况查询(车位状况分为:停用,占用和空闲)
    用户分级管理,人机界面良好

    2.1.2 功能描述该软件能对车辆进出进行管理,能计算停车时间并给管理员报出停车费用;能将流水显示给管理员;管理员能增加停车场会员、增减停车场车位;有一个客户面板给客户显示当前停车场的信息,如停车空位数。管理员分普通管理员和超级管理员,超级管理员能对普通管理员进行增删或者是修改管理员的权限将其改为超级管理员或者普通管理员。
    2.2 总体设计2.2.1 系统数据流图
    2.2.2 数据库E-R图
    第三章 数据库设计3.1 数据库表3.1.1 车位信息表t_parking


    字段名
    数据类型
    含义说明
    空值情况




    id
    varchar2(5)
    车位编号
    主键


    state
    varchar2(10)
    车位状态
    不为空


    type
    varchar2(10)
    车位类型
    不为空


    t_price
    number(6,2)
    临时单价(¥/h)
    不为空


    m_price
    number(6,2)
    会员单价(¥/m)
    不为空



    3.1.2 管理员表t_manager


    字段名
    数据类型
    含义说明
    空值情况




    id
    varchar2(10)
    工号
    主键


    pwd
    varchar2(20)
    密码
    不为空


    name
    varchar2(20)
    姓名
    不为空


    power
    number(1)
    权限
    不为空



    3.1.3 会员表t_Member


    字段名
    数据类型
    含义说明
    空值情况




    id
    varchar2(5)
    车位编号
    外键


    p_num
    varchar2(15)
    车牌号
    不为空


    name
    varchar2(20)
    姓名
    不为空


    tel
    varchar2(15)
    电话
    不为空



    3.1.4 会员收费表t_MemberFee


    字段名
    数据类型
    含义说明
    空值情况




    s_num
    varchar2(20)
    流水号
    主键


    id
    varchar2(5)
    车位编号
    外键


    p_num
    varchar2(15)
    车牌号
    不为空


    eff_date
    date
    生效期
    不为空


    ex_date
    date
    有效期
    不为空


    fee
    number(6,2)
    收费
    不为空


    m_id
    varchar2(10)
    收费员工工号
    外键



    3.1.5 临时用户收费表t_TempFee


    字段名
    数据类型
    含义说明
    空值情况




    s_num
    varchar2(20)
    流水号
    主键


    id
    varchar2(5)
    车位编号
    外键


    p_num
    varchar2(15)
    车牌号
    不为空


    en_time
    date
    进入时间
    不为空


    ex_time
    date
    退出时间
    可为空


    fee
    number(6,2)
    收费
    可为空


    m_id
    varchar2(10)
    收费员工工号
    外键



    3.1.6 停车场日常信息表t_infor_parking


    字段名
    数据类型
    含义说明
    空值情况




    today
    date
    日期
    主键


    en_num
    number(5)
    进入数
    不为空


    ex_num
    number(5)
    离开数
    不为空


    fee
    number(8,2)
    收费总额
    不为空


    m_id
    varchar2(10)
    收费员工工号
    外键



    其中t_Member的id是依赖于t_parking的id,t_MemberFee的m_id是依赖于t_manager的id,t_MemberFee的id是依赖于t_parking的id,t_TempFee的id依赖于t_parking的id,TempFee的m_id是依赖于t_manager的id,t_infor_parking的m_id是依赖于t_manager的id。
    第四章 软件功能设计4.1 程序设计4.1.1 程序工程文件结构
    4.2 详细设计4.2.1 dao文件dao文件定义了各个功能函数的接口,子目录imp文件中的类是对各个接口的实现,各个类定义了各个实体的相应操作,比如ManagerDao.Java就定义了对管理员的增减,权限修改,权限查询,信息查询等函数。
    /** * @Description:校验登录信息并返回登录人员是否能登录以及其权限 * @param tf * @param pf * @return HashMap<String,Object> */ public HashMap<String, Object> check(String tf, String pf); /** * @Description 判断权限 * @param tf * @return int */ public int judgeP(String tf); /** * @Description 增加员工 * @param manager * @return boolean */ public boolean add(Manager manager); /** * @Description 删除员工 * @param id * @return boolean */ public boolean delManager(String id); /** * @Description 查询员工 * @param id * @return String */ public String findManager(String id); /** * @Description 改变权限 * @param id * @return boolean */ public boolean upMP(String id,int power);}
    4.2.2 data文件data文件包含一个ConnOra.java,该类用于连接数据库,java连接Oracle数据库的基本模式为:
    public static Connection connOracle() { Connection con = null;// 创建一个数据库连接 try { Class.forName("oracle.jdbc.driver.OracleDriver");// 加载Oracle驱动程序 System.out.println("开始尝试连接数据库!"); String url = "jdbc:oracle:" + "thin:@127.0.0.1:1521:orcl";// 127.0.0.1是本机地址,XE是精简版Oracle的默认数据库名 String user = "C##U_32";// 用户名 String password = "zww0902150232";// 设置的密码 con = DriverManager.getConnection(url, user, password);// 获取连接 System.out.println("连接成功!"); } catch (Exception e) { System.out.println("未连接"); e.printStackTrace(); } return con; }
    4.2.3 table文件该文件包含了各个实体类。停车场日常信息InforParking.Java、管理员Manager.java、会员Membe.java、会员收费MemberFee.java、车位Parking.java、临时收费TemporaryFee.java。
    4.2.4 ui文件此文件包含了对各个ui界面的设计以及事件的监听和触发,DataChooser.java是时间选择界面,InforPanel.java是客户面板,Login.java是登录界面,ManagerUI.java是系统主界面。
    4.3 程序功能图
    第五章 界面设计5.1 登录界面
    输入输出时

    5.2 程序主界面
    普通管理员和超级管理员界面略有不同,超级管理员多了对管理员管理的菜单选项。



    车辆进入成功后弹出提示窗口,车辆离开时,弹出收费窗口



    增加会员,填写会员信息,点击时间会弹出时间选择界面


    车位增减


    查看流水


    用户面板


    管理员工


    更改员工权限
    3 评论 31 下载 2019-01-28 16:36:24 下载需要8点积分
  • 基于B/S模式的图书在线销售系统的设计与实现

    摘 要本文讲述了基于B/S模式的图书在线销售系统的设计与实现。所谓的图书在线销售系统是通过网站推广互联企业的图书和技术服务,并使客户随时可以了解企业和企业的产品,为客户提供在线服务和订单处理功能。
    从长期的战略目标来说,图书在线销售网站不仅是图书和服务的推广,而是通过Internet、企业内部网和企业外部网,将买家与卖家、厂商和合作伙伴紧密结合在了一起,因而消除了时间与空间带来的障碍。
    图书在线销售提供了多种检索途径,可以从分类、新品、特价等途径进行检索,快捷准确。与传统销售方式相比,在线销售能够提供海量数码产品信息。图书在线销售最突出的优点是:不再限制消费者的购买时段,扩大和巩固了客户群,从而增加了数码产品企业的核心竞争力,节省实际开店时需要投入的成本和租用费用。
    关键词:图书;在线销售;订单处理;
    AbstractThis thesis relate to the design and implementation of based on the mode of B/S and SSH technical on-line sales digital products system. The so-called on-line sales digital product system through the Web site to promote Internet business of digital technology products and services, customers can learn more about the business and enterprise products, providing customers with the functions of online services and order processing.
    From the long-term strategic objectives, sales of digital products on-line site is not just digital products and services promotion, through the Internet, intranet and extranet make buyers and sellers, manufacturers and partners in the close connection together, thus eliminating the obstacles of time and space.
    Online sales of digital products that provide a variety of ways to retrieve, such as classification, new products and bargain products, the search way is faster and more accurate. Compared with the traditional way of marketing, online sales of digital products that can provide mass information. The most prominent advantage of online sales digital products are: no longer limit the consumers’ time to buy, consolidate and expand the customer base, thus increase the competitive ability of digital product business, and save the cost and rental cost of opening a shop actually.
    Keywords: digital products online sale order processing 
    第1章 绪论1.1 课题背景互联网的兴起从本质上改变了整个社会的商品交易方式,国内各大企业从上个世纪90年代互联网兴起之时,就产生了通过网络进行销售经营商品的想法。但是由于在互联网上企业的信誉难以认证、网络的法规政策不健全、物流不发达等一系列的原因,限制了网上交易发展的步伐。进入21世纪以后,随着整个社会的发展、进步,制约网上交易的各个瓶颈问题逐一被击破,各企业也纷纷的加入到电子商务的洪潮之中。
    中国互联网协会网络营销工作委员会调查显示,随着国内产业环境和消费市场的成熟,网络购物尤其是以数码产品为代表的网购将在今年实现更大发展。
    根据会员企业艾瑞咨询集团的预测,2008年我国网络购物交易将同比增长125.1%,交易总量将达1263亿,形成了中国网络购物的快速增长浪潮。其中,图书消费人群成为推动此浪潮的一大主力。究其原因,除了该人群对网络购物等新兴的购物模式接受程度较高之外,相比其他细分行业和产品,图书网络购物有着更加完备的产业链条和发展后劲,为其高速增长提供了保障。
    网络购物这一消费方式给人们生活带来的变化,除了购物场所的改变以外,更重要的是大大改变了传统的消费行为习惯,无论是否在网上购物,上网查看产品的相关信息,已经成为购物决策环节的重要组成部分,这一环节对购物行为的实际发生起到了至关重要的指导作用。
    1.2 目的和意义在互联网上所有产品的分类信息中,电子类的产品信息无疑是最丰富的,一大批电子资讯类网站从中国互联网诞生初期就开始为网友提供大量一手信息。以天极网为例,该网站的导购平台拥有260条各类图书线、17万条产品报价信息,涉及6400多个品牌和11万款产品。如此庞大并仍在持续增长的信息量远非其他产品类别能及,极大地满足了用户对图书信息的需求。只需动动鼠标即可从资讯页面跳转到购物页面的便捷网购模式,使得信息收集与购物行为之间无缝对接。
    随着近年来电子资讯网络媒体与网络购物平台的合作加深,消费者从获取资讯到发生购物行为的时空距离被进一步缩短,由此带来的巨大经济效益使得各大网购平台越来越重视数码产品销售。淘宝网将“手机数码”放在首页导航栏细分频道的第一位,而易趣网的14个热门搜索关键词中图书类占了5个。
    与传统方式销售相比在线销售有很多的优点如:

    检索便捷:在线销售提供了多种检索途径,可以从分类、新品、特价等途径进行检索,快捷准确
    信息量大:与传统销售方式相比,在线销售能够提供海量产品信息
    成本低,风险小,无地域限制:网络销售最突出的优点是:不再限制消费者的购买时段,扩大和巩固了客户群,从而增加了企业的核心竞争力,节省实际开店时需要投入的成本和租用费用

    图书在线销售系统的主要目的就是通过网站来推广互联企业的图书和技术服务,并使客户随时可以了解企业和企业的产品,为客户提供在线服务和订单处理功能。从长期的战略目标来说,网站不仅仅是产品和服务的推广,而是通过Internet、企业内部网(Intranet)和企业外部网(Extranet),将买家与卖家、厂商和合作伙伴紧密结合在了一起,因而消除了时间与空间带来的障碍。
    1.3 系统设计思想对于典型的数据库管理系统,尤其是对于像图书在线销售系统这样的数据流量特别大的网络管理系统,必须要满足使用方便、操作灵活等要求。本系统在设计时应该满足以下几个目标

    采用人机对话的操作方式,界面美观、友好,信息查询灵活、方便,数据存储准确、安全可靠
    全面展示所有数码产品,并可展示最新数码产品和特价数码产品
    便于顾客快捷地进行数码产品信息查询
    会员可以随时修改自己的基本资料
    实现网上购物的功能
    实现图书销售排行功能,以方便顾客了解本在线销售系统内的热销图书及帮助企业领导者做出企业营销方案
    系统公告公布图书在线销售系统网站内的最新信息
    顾客可以随时查看自己的订单信息
    对顾客输入的数据,系统进行严格的数据检验,尽可能排除人为的错误
    系统最大限度地实现了易维护性和易操作性
    系统运行稳定、安全可靠

    1.4 本文的结构本文具体内容包括:可行性分析、需求分析、系统总体设计、系统详细设计与实现、系统的测试。
    本文着重描述了图书在线销售系统的组成与结构,阐述了系统的设计方案、实现方法以及所采用的开发工具和相关技术,另外,重点剖析了部分环节的开发过程。
    本系统在一定的环境下对系统的重要模块进行了模拟测试,证实了系统的可用性、可靠性。
    第2章 可行性分析网络平台已经成为企业经营管理中不可忽视的一个重要的方面,拥有一个全面的、功能强大的、操作简单的在线销售系统网站,已经成为企业营销发展的一个必然趋势。图书在线销售系统网站的建立,从销售方面来讲,不仅给图书企业增加了一个新的销售渠道,而且方便了顾客购买与了解公司的图书及新的销售方向。从图书企业宣传方面来讲,不仅扩大了企业知名度,还更直观地展示出企业的数码产品。拥有一个B2C的图书在线销售系统网站,已经成为图书企业网络销售进程中的一个重要环节。
    2.1 业务流程图根据图书在线销售系统的具体情况,调查管理业务流程是顺着系统信息流动的过程逐步地进行,内容包括各环节的业务处理、信息来源、处理方法、计算方法、信息流经去向、信息提供的时间和形态(报告、单据等)。
    系统业务流图描述如下:

    顾客浏览网站 顾客通过浏览器登录到本图书在线销售系统网站后,可以通过新品上架、特价产品、销售排行的模块查看数码产品及详细信息,同时顾客也可以按类别查看图书。另外,顾客可以浏览公告,销售排行榜等模块
    用户注册及登录 顾客如要购买图书,需要进行用户注册,注册成功并登录后,用户可以购买图书
    购物车处理 用户通过浏览数码产品信息选择要购买的产品时,可以将产品放入购物车,并可以添加至购物车、查看购物车、移除购物车中的数码产品、修改购物车中图书数量、清空购物车
    收银台处理 当用户决定购买购物车中的图书时,可以通过收银台结账填写相应的订单信息,确定所填写的订单信息无误后,系统将产生此次订单的编号,完成在线下达订单,并且用户可以查看到订单
    管理员后台处理 系统管理员登录后可以查看到已受理和未受理的订单及详细信息。另外,管理员能够对系统的各项信息进行维护处理

    系统业务流图如图2-1所示。

    新系统的目标确定后,可以从经济可行性、技术可行性和运行可行性三个方面对能否实现新系统目标进行可行性分析。
    2.2 经济可行性软件的经济可行性是指软件所能带来的经济效益与开发设计所需要的投资相比,是否相适宜,同时还要看此软件能否真正给用户带来足够的经济效益,我们开发的这套系统正是考虑为数码产品在线销售系统的使用者提高工作效率,节省工作时间,方便操作与管理而设计。
    本系统的开发在经济上是完全可行的。开发此软件不需要大量经费,而且是个人独立设计,可以节省许多费用,同时也可提高个人的实际动手能力。
    2.3 技术可行性根据该系统目标来衡量所需的技术是否具备,一般可从硬软件的性能要求、环境条件、操作人员水平和数量等方面去考虑和分析。
    考虑到系统实施的可行性,在软件方面选择了如今较流行的MyEclipse工具来进行开发管理平台的设计,使用SQL server 2005数据库存储数据。
    在硬件方面,则选择空间较大,硬件的配置越高,系统的开发与运行会更流畅。考虑到如今的家用或商用电脑硬件的整体配置水平,系统在硬件方面是可行的。
    在软件方面,由于MyEclipse和SQL server 2005是两个非常成熟的开发工具,无论在安全性、可用性、可靠性方面都毫无置疑,因此软件方面是可行的。
    2.4 运行可行性在现今社会,顺着Internet在中国的迅速发展,人们日常生活中越来越多地使用Web技术来为自己的工作和学习服务。许多企业为了扩大他们的规模,将他们的生意范围涉及到了出口生意,由于企业的客户很多,而且分布于各地,甚至还有国外,在线销售图书有着对顾客的地域无限制等诸多的优点,可以成功地解决企业所面临的难题。
    本图书在线销售系统操作简单易行,所以使用前的培训也比较容易,此系统网站的管理人员对开发此应用项目的态度确定而且管理方面的条件都比较成熟。经过以上分析,运行方面是可行的。
    2.5 本章小结可行性分析的任务是明确应用项目开发的必要性和可行性。本章主要对系统开发的可行性进行具体的分析,从用户方角度考虑本系统是否可行,主要通过有力的数据和软件运行环境方面作为依据。通过经济可行性、技术可行性、运行可行性等方面的分析说明本工程的技术成熟、完备,测试手段可靠,具有良好的市场拓展,它追求的是简单、易学、易懂、易用,因此,本系统具有一定的开发前景,具有开发的价值。
    第3章 需求分析3.1 电子商务的产生和发展情况中国电子商务始于1997年。中国商品订货系统(CGOS)、中国商品交易中心(CCEC)、虚拟“广交会”等大型电子商务项目也在1997年相继推出,拉开了中国电子商务的序幕。1998年“首都电子商务工程”的展开和1999年“8848网上超市”的出现,标志着中国电子商务开始进入快速发展时期,中国电子商务由此正式启动。
    据统计,目前全国已有4万家商业网站,其中网上商店700余家。电子商务项目大量推出,几乎每天都有各类电子商务咨询网站、网上商店、网上商城、网上专卖店、网上拍卖等诞生。电子商务应用与发展的地域也由北京、上海、深圳等极少数城市,开始向各大中城市发展。据IDC预测,2000年中国大陆网上交易额将达4000万美元,到2003年将达38亿美元。
    可以说,中国电子商务已经由表及里、从虚到实,从宣传、启蒙和推广阶段进入到了务实的发展实施阶段。
    政府推进 环境改善
    我国政府正全面、积极、稳妥地推进中国电子商务的发展。1998年以来,政府对电子商务的支持与协调力度明显增加。我国电子商务发展的总体框架(包括整体战略、发展规划、发展措施、技术体制标准以及相关法律法规)的推出,将会使电子商务有一个更加规范有序的应用与发展环境。不少地方政府也都对电子商务给予了前所未有的关注与支持,开始将电子商务作为重要的产业发展方向。
    制约瓶颈 开始突破
    网上支付、实物配送和信用等作为电子商务系统工程中的重要环节,被视为制约中国电子商务应用与发展的瓶颈。1999年以来,网上支付的瓶颈正在迅速得到解决。在这方面较为成功的,有“8848”网上超市提供的包括网上支付在内的多元化支付方式,有首都电子商城电子商务支付平台等。
    应用模式 日趋多元
    在BtoC模式中,网上书店和网上商场在增加网上支付功能、完善各项服务后以更大的势头发展;网上拍卖、网上商城、网上邮购等面向消费者的电子商务网站大量推出。不少电子商务企业和工商企业开始酝酿企业间电子商务。证券电子商务也有所发展,网上炒股对于有些股民已经成为现实。网络是一片独特的天空,中国国情又有其特殊性。怎样将结合Internet和中国国情,充分发挥电子商务的优越性,实现极富意义的电子商务技术和商务模式的创新,是摆在中国电子商务业界人士面前的一大课题。
    内外融合 渐成大势
    具有外资背景的电子商务企业和项目日益增加。其表现的形式是双向的:既有海外风险投资直接进入国内的电子商务企业,也有国内企业通过海外上市吸收海外资金。在不少电子商务企业内,外籍或具有外资企业背景的高级管理人员显著增加。与此同时,海外电子商务企业开始直接进入中国市场。随着中国加入世界贸易组织的前景日趋明朗,基于超越国界的Internet的电子商务不可逆转地走上了世界经济一体化的道路。
    3.2 图书在线销售系统的需求分析经过对各大图书购物网站及实际数码产品企业销售过程的考察、分析,要求本系统具有以下功能

    统一友好的操作界面,保证系统的易用性,方便用户的操作
    具备图书信息的展示功能,方便浏览者对图书信息进行浏览与比较
    规范的图书分类,方便浏览者分类查找图书
    完善的购物车功能与用户结账功能
    设置网站公告信息模块,使浏览者能够及时了解网站的各项动态变化,及销售的新品、特价活动等信息
    图书销售排行功能
    订单信息查询功能、产品信息查询功能
    全面的后台管理功能,以方便管理员对网站信息进行更新与管理

    3.3 数据字典数据字典的作用是在软件分析和设计的过程中给人提供关于数据的描述信息。它主要是对数据流图中的数据流、处理逻辑、外部实体、数据存储和数据项等方面进行具体的定义。数据流程图配以数据字典,就可以从图形和文字两个方面对系统的逻辑模型进行完整的描述。
    系统数据项定义



    序号
    名称
    别名
    类型
    长度(字符)




    I01-01
    goods_id
    图书编号
    Int
    4


    I01-02
    goods_name
    图书名称
    varchar
    50


    I01-03
    goods_miaoshu
    图书描述
    varchar
    5000


    I01-04
    goods_pic
    存放图书图片
    Varchar
    50


    I01-06
    goods_shichangjia
    图书市场价
    int
    4


    I01-07
    goods_tejia
    图书特价
    int
    4


    I01-08
    goods_isnottejia
    普通商品
    varchar
    50


    I01-09
    goods_catelog_id
    图书种类号
    int
    4


    I01-10
    catelog_id
    种类编号
    Int
    4


    I01-11
    catelog_name
    种类名称
    Varchar
    50


    I01-12
    catelog_miaoshu
    种类描述
    Varchar
    5000


    I01-13
    order_id
    订单ID
    Int
    4


    I01-14
    order_bianhao
    订单编号
    Varchar
    50


    I01-15
    order_date
    订单生成日期
    varchar
    50


    I01-16
    order_zhuangtai
    订单状态
    varchar
    50


    I01-17
    order_jine
    总的消费金额
    Int
    4


    I01-18
    order_songhuodizhi
    送货地址
    Varchar
    50


    I01-19
    order_fukuangfangshi
    付款方式
    Varchar
    50


    I01-20
    order_user_id
    用户ID
    Int
    4


    I01-21
    orderItem_id
    订单明细编号
    Int
    4


    I01-22
    order_id
    订单编号
    Int
    4


    I01-23
    goods_id
    商品编号
    Int
    4


    I01-24
    goods_quantity
    购买数量
    Int
    4


    I01-25
    user_id
    用户ID
    Int
    4


    I01-26
    user_name
    用户名
    Varchar
    50


    I01-27
    user_pw
    用户密码
    Varchar
    50


    I01-28
    user_realname
    真实姓名
    Varchar
    50


    I01-29
    user_address
    住址
    Varchar
    50


    I01-30
    user_sex
    性别
    Varchar
    50


    I01-31
    user_tel
    联系电话
    Varchar
    50


    I01-32
    user_email
    用户邮箱
    Varchar
    50


    I01-33
    user_qq
    用户QQ
    Varchar
    50


    I01-34
    userId
    管理员ID
    int
    4


    I01-35
    userName
    管理员名称
    Varchar
    50


    I01-36
    userPw
    管理员密码
    Varchar
    50


    I01-37
    gonggao_id
    公告编号
    Int
    4


    I01-38
    gonggao_title
    公告标题
    Varchar
    50


    I01-39
    gonggao_content
    公告内容
    Varchar
    5000


    I01-40
    gonggao_data
    公告创建时间
    Varchar
    50


    I01-41
    gonggao_fabuzhe
    发布人
    Varchar
    50


    I01-42
    liuyan_id
    留言id
    Int
    4


    I01-43
    liuyan_title
    留言标题
    Varchar
    50


    I01-44
    liuyan_content
    留言内容
    Varchar
    5000


    I01-45
    liuyan_date
    留言时间
    Varchar
    50


    I01-46
    liuyan_user
    留言客户
    Varchar
    50



    数据流定义

    数据流编号:D1-01

    数据流名称:图书基本信息维护数据流来源:系统管理员数据流去向:P1数据流组成:I01-01+I01-02+I01-03+I01-04+I01-05+I01-06+I01-07+I01-08+I01-09
    数据流编号:D1-02

    数据流名称:管理图书信息操作数据流来源:F1、P1数据流去向:P1、F1数据流组成:I01-01+I01-02+I01-03+I01-04+I01-05+I01-06+I01-07+I01-08+I01-09
    数据流编号:D2-01

    数据流名称:订单信息操作数据流来源:系统管理员数据流去向:P2数据流组成:I01-13+I01-14+I01-15+I01-16+I01-17+I01-18+I01-19+I01-20+I01-21+I01-22+I01-23+I01-24
    数据流编号:D2-02

    数据流名称:订单信息数据流来源:F2、P2数据流去向:P2、F2数据流组成:I01-13+I01-14+I01-15+I01-16+I01-17+I01-18+I01-19+I01-20+I01-21+I01-22+I01-23+I01-24
    数据流编号:D3-01

    数据流名称:公告信息维护数据流来源:系统管理员数据流去向:P3数据流组成:I01-37+I01-38+I01-39+I01-40+I01-41
    数据流编号:D3-02

    数据流名称:管理公告信息操作数据流来源:F3、P3数据流去向:P3、F3数据流组成:I01-37+I01-38+I01-39+I01-40+I01-41
    数据流编号:D4-01

    数据流名称:留言信息管理数据流来源:系统管理员数据流去向:P4数据流组成:I01-42+I01-43+I01-44+I01-45+I01-46
    数据流编号:D4-02

    数据流名称:管理留言信息操作数据流来源:F4、P4数据流去向:P4、F4数据流组成:I01-37+I01-38+I01-39+I01-40+I01-41
    数据流编号:D5-01

    数据流名称:客户信息管理数据流来源:系统管理员数据流去向:P5数据流组成:I01-25+I01-26+I01-27+I01-28+I01-29+I01-30+I01-31+I01-32+I01-33
    数据流编号:D5-02

    数据流名称:管理客户信息操作数据流来源:F5、P5数据流去向:P5、F5数据流组成:I01-25+I01-26+I01-27+I01-28+I01-29+I01-30+I01-31+I01-32+I01-33
    数据流编号:D6-01

    数据流名称:用户信息数据流来源:客户数据流去向:P6数据流组成:I01-25+I01-26+I01-27+I01-28+I01-29+I01-30+I01-31+I01-32+I01-33
    数据流编号:D6-02

    数据流名称:管理客户信息操作数据流来源:P6数据流去向:F5数据流组成:I01-25+I01-26+I01-27+I01-28+I01-29+I01-30+I01-31+I01-32+I01-33
    数据流编号:D7-01

    数据流名称:留言信息数据流来源:客户数据流去向:P7数据流组成:I01-42+I01-43+I01-44+I01-45+I01-46
    数据流编号:D7-02

    数据流名称:客户留言信息数据流来源:P7数据流去向:F4数据流组成:I01-42+I01-43+I01-44+I01-45+I01-46
    数据流编号:D8-01

    数据流名称:公告信息数据流来源:P8数据流去向:客户数据流组成:I01-37+I01-38+I01-39+I01-40+I01-41
    数据流编号:D8-02

    数据流名称:公告信息数据流来源:F3数据流去向:P8数据流组成:I01-37+I01-38+I01-39+I01-40+I01-41
    数据流编号:D9-01

    数据流名称:商品信息数据流来源:客户数据流去向:P9数据流组成:I01-01+I01-02+I01-03+I01-04+I01-05+I01-06+I01-07+I01-08+I01-09
    数据流编号:D9-02

    数据流名称:订单信息数据流来源:P9数据流去向:F2数据流组成:I01-01+I01-02+I01-03+I01-04+I01-05+I01-06+I01-07+I01-08+I01-09
    数据流编号:D10-01

    数据流名称:商品信息数据流来源:P10数据流去向:客户数据流组成:I01-01+I01-02+I01-03+I01-04+I01-05+I01-06+I01-07+I01-08+I01-09
    数据流编号:D10-02

    数据流名称:商品信息数据流来源:F1数据流去向:P10数据流组成:I01-01+I01-02+I01-03+I01-04+I01-05+I01-06+I01-07+I01-08+I01-09

    3.3 本章小结需求分析报告是对系统需求的全面分析,是软件生存周期中最关键的一步,是建立软件开发的基础。经过需求分析要得到系统将要“做什么”,同时理解在做什么的基础上抽取出其“怎么做”的本质。本章首先介绍了电子商务近年来的发展状况,然后具体说明了需求分析的内容,详细描述了数据流图和数据字典的组成,为下一章的总体设计打下基础。
    第4章 总体设计4.1 系统模块总体设计利用层次图来表示系统中各模块之间的关系。层次方框图是用树形结构的一系列多层次的矩形框描绘数据的层次结构。树形结构的顶层是一个单独的矩形框,它代表完整的数据结构,下面的各层矩形框代表各个数据的子集,最底层的各个矩形框代表组成这个数据的实际数据元素(不能再分割的元素)。随着这种结构的精细化,层次方框图对数据结构也描绘得越来越详细,这种模式非常适合于需求分析阶段的需要。从对顶层的信息的分类开始,沿着图中每条路径反复细化,直到确定了数据结构的全部细节为止。
    本系统一共分为前台和后台两大模块,两个模块之间虽然在表面上是相互独立的,但是在对数据库的访问上是紧密相连的,各个模块访问的是同一个数据库,只是所访问的表不同而已。每个模块的功能都是按照在调研中搜集的资料进行编排制作的。依据上述功能分析,系统在两个模块的基础上每一个模块又分为几个模块。
    前台系统功能模块分为:

    图书展台模块:通过新品上架,分页显示特价图书,图书销售排行展示网站的所有图书
    图书查询模块:按图书的类别查询图书的相关信息
    购物车模块:用户添加图书至购物车,查看购物车中的图书,从购物车中移除不满意的图书,清空购物车中的产品,修改所要购买的图书的数量
    收银台模块:用户满意购物车中的产品后进行结账并填写订单信息
    用户维护模块:为用户提供了用户注册、用户登录、用户资料修改以及找回密码的功能
    订单查询模块:用户通过查看订单能够了解到自己的当前订单信息及历史订单记录
    公告浏览模块:用户通过浏览公告信息,能够及时了解到网站最新的各种信息
    留言模块:客户可以进行留言给我们提意见,我们在不断地改进中前进

    系统前台用户功能结构图如图4-1所示。

    后台系统功能模块分为:

    图书管理模块:按类别查看图书,对图书的信息进行维护
    用户管理模块:为了保护用户的信息,此模块与前台用户维护的区别是管理员只能查看用户信息和删除操作
    管理员维护模块:这是对管理员的信息进行维护,可以修改管理员的信息
    订单管理模块:管理员查询订单,查看订单详细信息,删除订单信息,进行订单受理
    公告管理模块:管理员公告浏览,公告信息维护
    留言模块:管理员可以查看客户的留言,对留言进行维护

    系统后台管理员功能结构图如图4-2所示。

    4.2 数据库设计对于一个电子商务网站而言,为了支持较大的访问量带来的数据访问需求,使用桌面型的数据库管理系统是不能满足需要的,而且安全性也没有充分保障。因此,需要使用大型商业化企业级服务用途的数据库管理系统,如SQL Server,Oracle等。本系统采用Microsoft SQL Server 2005 数据库管理系统。
    4.2.1 数据分析对于本系统的数据库的需求而言,由于其主要是用于信息的提供、保存、更新和查询等。因此,需要分析该系统功能所隐含的对数据应用的需求,从而确定数据库的结构。

    用户注册、登录、验证等功能需要对用户信息建立数据表,其中的数据项可能包括用户E_mail、昵称、密码、住址等
    查看图书分类信息和图书详细信息等功能既需要对图书大小类别进行管理,也需要针对每一个图书进行管理,因此至少需要两张数据表
    用户购物后产生的订单需要进行管理,这里也包括订单的基本信息和详细信息等
    订单生成后,在订单处理的过程中,需要出货等,因此可能需要记录订单的发送情况
    需要系统管理员对该系统进行管理,因而需要建立管理员信息数据表,其中的数据项包括管理员ID、密码等
    客户要进行留言,所以必须建立留言表,其中包括留言标题、留言日期等

    这样,至少要创建如下的数据结构和数据项

    用户信息,包括用户ID,用户名等数据项
    管理员信息,包括管理员ID,密码等数据项
    图书信息,包括图书ID,产品名称、单价、特价等数据项
    图书类别信息,包括电子ID,类别名称等数据项
    订单信息,包括订单ID,用户编号,订货地址等数据项
    订单明细信息,包括订单ID,数码产品ID,订货时间等数据项
    公告信息,包括公告ID,公告名称及内容等数据项
    留言信息,包括留言标题,留言日期,留言内容等

    4.2.2 数据库的详细设计在设计数据库时,应考虑以下事项:

    数据库的用途及该用途将如何影响设计,应创建符合用途的数据库计划
    数据库规范化规则,防止数据库设计中出现错误
    对数据完整性的保护
    数据库和用户权限的安全要求
    应用程序的性能需求,设计数据库时必须利用 Microsoft SQL Server 2005 中能够提高性能的功能。对于性能而言,在数据库大小和硬件配置之间权衡也是很重要的
    数据库维护

    数据库E-R如图4-3所示。

    根据此数码产品在线销售系统的实际情况,本系统的数据库命名为db_shoping,db_shoping数据库中共分为8张数据表。
    图书信息表
    此表用于记录网站所有数码产品的基本信息,是与图书相关联的图书的类别表。如表4-1所示。



    序号
    名称
    别名
    类型
    长度(字符)




    1
    goods_id
    编号
    Int
    4


    2
    goods_name
    图书名
    varchar
    50


    3
    goods_miaoshu
    图书描述
    varchar
    5000


    4
    goods_pic
    存放商品图片
    varchar
    50


    6
    goods_shichangjia
    市场价
    int
    4


    7
    goods_tejia
    特价
    int
    4


    8
    goods_isnottejia
    普通图书
    varchar
    50


    9
    goods_catelog_id
    商品种类号
    int
    4



    图书类别信息表
    此表用于记录数码产品类别的基本信息,为方便用户查询数码产品和管理员管理数码产品信息而设立。如表4-2所示。



    序号
    名称
    别名
    类型
    长度(字符)




    1
    catelog_id
    种类编号
    Int
    4


    2
    catelog_name
    种类名称
    Varchar
    50


    3
    catelog_miaoshu
    种类描述
    Varchar
    5000



    订单信息表
    此表用于记录用户的基本订单信息,使用户方便查看自己的订单信息同时也为管理员出货提供基本订单信息。如表4-3所示。



    序号
    名称
    别名
    类型
    长度(字符)




    1
    order_id
    订单ID
    Int
    4


    2
    order_bianhao
    订单编号
    Varchar
    50


    3
    order_date
    订单生成日期
    varchar
    50


    4
    order_zhuangtai
    订单状态
    varchar
    50


    5
    order_jine
    总的消费金额
    Int
    4


    6
    order_songhuodizhi
    送货地址
    Varchar
    50


    7
    order_fukuangfangshi
    付款方式
    Varchar
    50


    8
    order_user_id
    用户ID
    Int
    4



    订单明细信息表
    此表用于记录用户订单的详细信息,为用户提供详细的图书订单信息,同时也为管理员出货提供用户所订的图书的具体信息。如表4-4所示。



    序号
    名称
    别名
    类型
    长度(字符)




    1
    orderItem_id
    订单明细编号
    Int
    4


    2
    order_id
    订单编号
    Int
    4


    3
    goods_id
    商品编号
    Int
    4


    4
    goods_quantity
    购买数量
    Int
    4



    用户信息表
    此表用于记录用户的基本信息,是用户购买数码产品的权限基础,为用户维护和管理员管理用户提供信息。如表4-5所示。



    序号
    名称
    别名
    类型
    长度(字符)




    1
    user_id
    用户ID
    Int
    4


    2
    user_name
    用户名
    Varchar
    50


    3
    user_pw
    用户密码
    Varchar
    50


    4
    user_realname
    真实姓名
    Varchar
    50


    5
    user_address
    住址
    Varchar
    50


    6
    user_sex
    性别
    Varchar
    50


    7
    user_tel
    联系电话
    Varchar
    50


    8
    user_email
    用户邮箱
    Varchar
    50


    9
    user_qq
    用户QQ
    Varchar
    50



    管理员信息表
    此表用于记录不同权限管理员的基本信息,可以管理系统的所有信息。如表4-6所示。



    序号
    名称
    别名
    类型
    长度(字符)




    1
    userId
    管理员ID
    int
    4


    2
    userName
    管理员名称
    Varchar
    50


    3
    userPw
    管理员密码
    Varchar
    50



    公告信息表
    此表用于记录公告的基本信息,为用户提供系统网站的最新信息。如表4-7所示。



    序号
    名称
    别名
    类型
    长度(字符)




    1
    gonggao_id
    公告编号
    Int
    4


    2
    gonggao_title
    公告标题
    Varchar
    50


    3
    gonggao_content
    公告内容
    Varchar
    5000


    4
    gonggao_data
    公告创建时间
    Varchar
    50


    5
    gonggao_fabuzhe
    发布人
    Varchar
    50



    留言信息表
    此表用于记录客户的留言信息,以及对商品的建议等。如表4-8所示。



    序号
    名称
    别名
    类型
    长度(字符)




    1
    liuyan_id
    留言id
    Int
    4


    2
    liuyan_title
    留言标题
    Varchar
    50


    3
    liuyan_content
    留言内容
    Varchar
    5000


    4
    liuyan_date
    留言时间
    Varchar
    50


    5
    liuyan_user
    留言客户
    Varchar
    50



    4.3 本章小结本章介绍了对本系统的总体设计,给出了图书在线销售系统的功能结构图、E-R图等,说明了各子系统的之间的联系。本章完成了系统数据库的数据需求分析的过程,说明了数据库由概念结构设计转换成逻辑结构设计的过程,并把各个物理数据模型结合起来形成了一个整体的关系数据库模型,为系统详细设计作好了充足的准备工作。
    第5章 详细设计与实现5.1 系统运行平台设置本系统的运行平台设置分为硬件环境和软件环境。
    5.2 运行环境硬件环境
    系统的硬件环境配置为处理器Pentium III800,内存512M,硬盘1G。
    软件环境
    系统的软件环境配置为Windows XP操作系统,SQL Server 2005数据库,JDK1.5、MyEclipse5.1开发工具包和Tomcat6.0服务器。
    5.3 开发工具及技术简介以下内容是对本系统所采用的开发工具和技术进行的简单介绍。
    5.3.1 开发工具简介MyEclipse企业级工作平台(MyEclipse Enterprise Workbench ,简称MyEclipse)是对Eclipse IDE的扩展,利用它我们可以在数据库和J2EE的开发、发布,以及应用程序服务器的整合方面极大的提高工作效率。它是功能丰富的J2EE集成开发环境,包括了完备的编码、调试、测试和发布功能,完整支持HTML, Struts, JSF, CSS, Javascript, SQL, Hibernate。
    在结构上,MyEclipse的特征可以分为7类:

    J2EE模型
    WEB开发工具
    EJB开发工具
    应用程序服务器的连接器
    J2EE项目部署服务
    数据库服务
    MyEclipse整合帮助

    对于以上每一种功能上的类别,在Eclipse中都有相应的功能部件,并通过一系列的插件来实现它们。MyEclipse结构上的这种模块化,可以在不影响其他模块的情况下,对任一模块进行单独的扩展和升级。
    简单而言,MyEclipse是Eclipse的插件,也是一款功能强大的J2EE集成开发环境,支持代码编写、配置、测试以及除错。
    SQL Server 2005是一种采用T-SQL语言,基于C/S模式的关系型数据库管理系统。SQL Server 2005存储和管理数据有以下优点:

    每个数据项都存储在中央位置,所有用户都可在这个位置使用它们
    各个客户端上不单独存储数据项复本,从而消除了因用户不得不确保使用的信息相同所带来的麻烦。系统不需要确保使用当前值更新所有数据复本,因为中央位置仅有一个复本
    可以在服务器上一次性定义业务和安全规则,并对所有的用户平等执行
    可以在数据库内通过使用约束、存储过程和触发器来强制执行规则。还可在服务器应用程序中执行规则,因为这些应用程序也是许多客户端访问的中央资源
    关系数据库服务器只返回应用程序所需要的数据,优化了网络流量
    最大程度地降低硬件的成本,由于数据不是存储在每个客户端上,客户端不必耗费磁盘空间来存储数据。客户端无需在本地增加管理数据的功能,同时,服务器不需将处理能力耗费在显示数据上
    可以配置服务器以优化检索数据所需的磁盘输入/输出容量,配置客户端以优化从服务器检索数据的格式
    可以将服务器存储在一个相对安全的位置,并配备如不间断电源供应系统这样的设备,这比完全保护每个客户端更经济
    维护任务(例如备份和恢复数据)得到简化,因为这些任务都可以集中在中央服务器上执行

    5.3.2 技术简介本系统采用MVC框架,MVC(Model-View-Controller)是一种设计 模式,它强制性地把应用程序的输入、处理和输出分开。MVC把应用程序分成3个核心:模型层、视图层和控制层,它们分别担负不同的任务。其中视图层向用户显示相关的数据,并能接受用户的输入数据,但是它并不进行任何实际的业务处理。模型层表示业务数据和业务逻辑。控制层接收用户输入并调用模型和视图去完成用户的需求。
    本系统需要用到的Java相关技术有jsp技术、servlet技术、jdbc技术、SSH框架。其中,关键的技术难点在于Struts技术的运用。Struts技术是基于MVC的Web应用框架。在Struts框架中,模型层由实现业务逻辑的JavaBean组件构成,控制层由ActionServlet和Action来实现,视图层由一组JSP文件构成。
    5.4 系统首页设计本系统网站的主界面设计结构采用了上左右的结构,上部分为主功能菜单区,主要是显示网站的主功能,左侧为用户注册、登录,公告浏览,图书查询,右部分为信息显示区,销售排行榜 主要是为方便用户提供了一些最新上架的数码产品信息。界面设计如图5-1所示。

    5.5 系统前台基本功能设计与实现本节对系统前台主要功能设计进行详细的说明。
    5.5.1 用户维护模块设计与实现由于网上购物必须保证用户的正确性、购物的安全性,需要对用户资料进行有效的管理,因此用户管理是电子商务网站的重要内容。它主要包括用户注册、登录和验证、用户注册资料的修改更新和用户注销等功能。
    注册实现目标
    用户单击注册后需要输入密码和确认密码、用户真实姓名、住址、性别、E_mail、QQ。用户只须填写一个Web表单。这里需要用户通过E_mail注册是考虑到两点:

    第一,用户的E_mail是惟一的
    第二,通过用户的E_mail可以很方便快捷的与用户取得联系

    用户在提交注册信息后,系统会对注册页面填写的正确性进行检查。对于不符合要求的填写会给出必要的提示,并返回修改;对于符合要求的注册表单,用户提交信息后也要返回相应的欢迎信息,用户提交的正确注册信息将被存入系统的数据库中。界面的设计如图5-2所示。

    实现过程
    所属页面名:userReg.jsp
    表单属性:name=”form1” action=”<%=path%>/userReg.action” method=”post”页面设计如表5-2所示。



    名称
    类型
    含义




    userName
    Text
    输入用户名称


    password
    Password
    输入密码


    passwordOne
    Password
    输入确认密码


    userRealname
    Text
    输入真实姓名


    userAddress
    Text
    输入住址


    userSex
    radio
    选择性别


    userTel
    Text
    输入联系方式


    E-mail
    Text
    输入E-mail地址


    确定
    Button
    提交用户信息


    取消
    Button
    取消注册



    登录和验证用户登录程序流程描述
    当用户输入用户名和密码后首先要进行身份验证,如果用户存在,则成功登录,反之,如果用户不存在,提示错误信息“输入的用户名或密码不存在,请注册”,返回登录界面重新输入用户名和密码。用户登录的程序流程图如图5-3所示。

    实现目标
    对于本系统的购物过程而言,在用户浏览图书时,可以不进行登录,只有在使用购物车时,才需要登录,以完成整个购物过程。用户登录用于验证用户的用户名和密码,然后决定顾客进入系统进行操作,如进行用户修改的操作,购物车和结帐的操作等。界面的设计如图5-4所示。

    实现过程
    所属页面名:index.jsp
    页面设计如表5-3所示。



    名称
    类型
    含义




    userName
    Text
    输入用户名


    password
    Password
    输入密码


    注册
    button
    注册新用户


    登录
    button
    登录网站



    用户修改和注销实现目标
    已注册的用户只要登录本系统后便可以通过单击用户修改按钮进行用户修改操作,在此页面中用户可以更改自己的帐户和详细信息,如可以修改密码、修改Email地址等个人信息。通过点击提交按钮完成修改操作。界面的设计如图5-5所示。

    为了保证用户购物的安全性,系统提供了不关闭浏览器而退出图书在线销售系统的功能,注销功能是清除用户在使用或登录系统期间的所有Session信息。
    实现过程
    所属页面名:userXinxi.jsp
    表单属性:action=”<%=path%>/userEdit.action” name=”form1” method=”post”
    页面设计如表5-4所示。



    名称
    类型
    含义




    userName
    Text
    输入用户名称


    password
    Password
    输入密码


    passwordOne
    Password
    输入确认密码


    userRealname
    Text
    输入真实姓名


    userAddress
    Text
    输入住址


    userSex
    radio
    选择性别


    userTel
    Text
    输入联系方式


    E-mail
    Text
    输入E-mail地址


    确定
    Button
    提交用户信息


    取消
    Button
    取消注册



    5.5.2 产品展示模块设计与实现实现目标
    为了方便顾客选购图书,本系统采用了两种展示产品的方式。一种是以类别查询为基础查看图书,另外一种是新品上架、特价产品和销售排行的展台。以销售排行查看数码产品为例,顾客在首页的的销售排行即可查看销售排行,方便顾客查看畅销的数码产品相关信息及详细信息。界面的设计如图5-6所示。

    实现过程
    所属页面名:index.jsp
    通过查询t_orderItem表中按销售额字段goods_quantity降序排列实现。
    5.5.3 购物车模块的设计与实现购物车程序流程描述
    用户选购图书后添加到购物车中,在购物车中进行查看,同时对不满意的产品可以进行移除,对要购买的产品可以调整数量,移除产品和清空产品。用户决定购买产品后可以去收银台进行结账。购物车流程图如图5-7所示。

    实现目标
    用户购买产品的核心功能是购物车和订单提交。购物车模块的设计包括:顾客添加图书到购物车和顾客对购物车的管理,如更新购买的图书数量、清空购物车和将购物车中图书从购物车中移除等。购物车要具有持续性,而且不限制用户购买图书的数量,也就是购物车可以显示很多图书。界面的设计如图5-8所示。
    实现过程
    所属页面名:myCart.jsp核心代码参见附录3
    页面设计如下图所示。

    5.5.4 收银台模块的设计与实现实现目标
    用户选择完图书后,需要确认购物车中内容,即结帐,点击下一步,此时页面跳转到结账页面。在结帐页面,需要用户填写联系地址、联系电话、付款方式和送货方式和备注信息,以便生成订单。当完成一次交易所需要的用户方面的信息都已齐全,只须生成订单即可进入配送过程。如果用户所填写的订单信息正确,系统会返回给用户此次交易所产生的订单号码。界面的设计如图5-9所示。

    实现过程
    所属页面名:orderQuren.jsp
    表单属性:action=”<%=path%>/orderSubmit.action” name=”f” method=”post”
    页面设计如表5-5所示。



    名称
    类型
    含义




    userName
    Text
    收货人账号


    userRealname
    Text
    收货人姓名


    userTel
    Text
    收货人联系电话


    userAddress
    Text
    收货人地址


    odderSonghuodizhi
    Text
    送货住址



    5.5.5 查看订单模块的设计与实现实现目标
    用户填写完订单并提交成功后可以通过查看订单按钮看到自己的订单及详细信息。界面的设计如图5-10所示。

    实现过程
    所属页面名:myOrder.jsp
    5.5.6 客户留言模块的设计与实现实现目标
    为了能够了解客户对我们的图书的满意程度,我们设计了留言模块,让用户能够在第一时间将问题反映给我们,以便我们及时改进。界面的设计如图5-12所示。

    实现过程
    所属页面名:liuyanAll.jsp
    首先通过判断session中的userName是否为空,如果为空,则只能先登录才能进行留言。如果不为空,则留言人中显示userName,使用获取系统时将来给留言时间赋值。客户在输入标题和内容后,将其存储到数据库中,在客户查看时再将其调出。
    5.6 系统后台管理功能设计与实现本节对系统后台功能设计进行详细的说明。
    5.6.1 基本信息管理设计与实现实现目标
    该功能主要分布在管理员信息、用户信息、图书类别信息,订单信息,公告信息和留言信息的处理。对这些信息操作的主要功能详细设计包括对它们的添加、删除、更新和查询等操作,需要分别在基本信息中的每一个页面中设计这些功能。当对这些基本信息进行添加、删除和更新操作时,需要将这些操作所执行的结果返回到本系统的数据库中,并能够在相应的页面中刷新显示新的结果集。需要用SQL语句将这些信息添加到数据库中。模块的输出是操作信息成功的提示信息。对于在某一页面中的查询功能,此页面要能够刷新显示出此查询结果信息。以客户信息管理理为例。界面的设计如图5-13所示。

    实现过程
    所属页面名:userMana.jsp
    客户管理主要是使用userDAO中下的findById和findAll方法来删除和获取数据库中的数据。进入客户管理界面时通过findAll方法来显示所有用户的信息,点击删除时,通过findById方法获取指定的用户ID,使用sql语句进行操作。
    5.6.2 订单信息管理设计与实现实现目标
    该模块是针对用户订单信息和订单明细信息的管理功能进行的详细设计,主要是对用户订单信息和订单明细信息的查看、删除和受理订单的操作。管理员应该可以查看系统中已处理的订单和未经处理的订单信息,用户订单信息和订单明细信息在不同的页面显示。界面的设计如图5-14所示。

    实现过程
    所属页面名:orderMana.jsp
    订单管理模块使用了buyAction中的方法,当用户提交订单时,订单状态默认为未受理。管理员查看订单时调用了orderMana()方法将订单显示到页面中,点击删除时调用orderDelByAd()方法将通过订单的ID对指定的订单进行那个删除操作,点击受理订单时调用orderShouli()方法将订单状态改为已受理。管理员查看订单明细时通过 orderDetail()方法通过订单ID将指定的订单明细显示到页面中。
    5.6.3 图书信息管理设计与实现实现目标
    在图书管理模块中除了基本的信息管理功能外,为了方便顾客浏览到图书的真实外貌,在添加图书模块中增加上传图书图片的功能。
    管理员在图书添加页面中输入添加的图书基本信息,点击提交后进入上传图片页面。在图书信息管理中,我将图书分为特价和非特价图书来管理。此页面中能够显示出已输入的特价图书基本信息,在上传图片位置上添加文件后点击提交,提交成功后有提示信息弹出。在管理员查看图书信息时,将鼠标放到查看图片上就可以查看图片界面的设计如图5-15所示。

    实现过程
    所属页面名:goodsManaYesTejia.jsp
    本模块主要是对图书表进行管理,所以就是一些查询和删除操作,我在做的时候,主要讲图书分为特价和非特价图书,在管理时也是分开管理,主要通过判断goodsIsnottejia来区分是否为特价图书。
    5.6.4 留言信息管理设计与实现实现目标
    客户对商城的图书有任何意见,都可以在留言模块中进行留言,方便管理员查看,商城会及时处理问题。界面的设计如图5-17所示。

    实现过程
    所属页面名:liuyanMana.jsp
    留言功能,主要先依靠liuyanDAO.findAll方法来获取所有留言,然后调用liuyanMana来显示,管理员的添加操作是调用liuyanAdd方法实现的,留言的时间定义是用获取系统时间的方法来定义的。删除留言时则调用liuyanDel方法来实现。
    5.7 本章小结本章进行了此系统的详细设计的介绍,我们可以对本系统的设计有了一个细致全面的了解。前台模块详细介绍了用户维护、销售排行、购物车、结账、查看订单、留言模块和公告浏览模块的设计和实现的过程,同时后台模块介绍了客户信息管理、订单管理、图书信息管理、公告管理和留言管理的设计和实现的过程。本系统详细设计的原则是采用结构化的设计方法,改善控制结构,降低程序的复杂程度,从而提高程序的可读性、可测试性和可维护性。
    第6章 系统测试与性能分析6.1 软件测试经过需求分析、设计和编码等阶段的开发后,得到了源程序,开始进入到软件测试阶段。然而,在测试之前的各阶段中都可能在软件产品中遗留下许多错误和缺陷,如果不及时找出这些错误和缺陷,并将其改正,这个软件产品就不能正常使用,甚至会导致巨大的损失。目前,程序的正确性证明尚未得到根本的解决,因此软件测试仍是发现软件中错误和缺陷的主要手段。
    系统整体测试步骤:
    单元测试
    单元测试是整体测试中的第一步,通常在编码阶段进行。在源程序代码经过编译、评审、确认没有语法错误之后,便可开始进行单元测试。
    集成测试
    集成测试在单元测试完成之后,将所有的模块概要设计要求组装成系统时进行的测试,主要目标是发现与接口有关的问题。
    确认测试
    经过集成测试之后,接口错误已经发现被发现并改正了,接下便要进行确认测试。所谓确认测试就是验证所开发软件的功能性及其他特性是否符合软件需求规格说明书的要求。所以,确认测试又被称为有效性测试。
    系统测试
    系统测试是更大范围内进行测试,它将经过确认测试的软件作为整个基于计算机的系统的一个元素,在实际运行环境下,对系统进行的一系列集成和确认测试。
    6.2 本系统测试为了测试系统的正确性和完整性,本节将对系统中重点模块的测试进行介绍。
    6.2.1 前台首页的测试查询模块的测试
    首先在主页中的查询产品中的下拉列表中单击某一类别,然后在文本框中输入要查询的图书关键字,在右边显示菜单中查询到图书,则说明查找成功。通过对系统的反复大量的测试,该模块测试成功。
    图书分类浏览模块的测试
    测试过程是单击页面左边的图书类别,选中某一类别后,就可以在页面右边显示该类别下的所有图书。通过对该功能的重复大量测试,该模块能够准确地实现此项功能。
    6.2.2 购物车模块的测试在本模块中首先对修改数量单元进行了测试,所修改的数量如果是有效数字,则修改所购数码产品数量成功,否则修改失败,系统自动将图书数量重置为“1”。通过随机测试了几组数据,其修改的数量和累计的金额均正确。如果客户购买了同一个图书,则就会进行该图书购买数量的累加,不会重复出现。然后针对购物车应该不限制顾客购买数码产品的数量这一原则进行测试,通过大量向购物车中添加数码产品来进行测试,测试结果为购物车中可以显示所添加的所有数码产品信息,测试结果取得了预期的效果。
    6.2.3 用户注册模块的测试在用户注册模块中涉及到了三项数据,项目分别为密码和确认密码、用户真实姓名、住址、性别、E_mail、QQ。测试这个模块准备的数据有:

    sang、123、123、—、哈尔滨道里区、女、bing@123.com、37472
    sa、123、12、张三、哈尔滨道外区、男、bzhi@123.com、6434634
    be、123、123、李四、哈尔滨香坊区、男、bli@123.com、53658403

    首先进入注册页面,输入第一组数据,单击注册按钮系统会提示表单信息不能为空,因为表单信息要全部填写,而真实姓名没有写值。然后测试第二组数据,可以明显看出所输入的密码与确认密码是不一致的。然后测试第四组数据,其中九项均是系统正确的数据,因此测试通过。在填写用户名时,用户可以查看自己的用户名是否可以使用。
    6.2.4 图书管理模块的测试添加功能的测试
    对数码产品添加模块准备的图书名、图书描述、图书图片、图书颜色、市场价、特价、图书种类,分别准备的测试数据为:摩托罗拉W220、翻盖手机,好用。1680、1500。其中类别的选择是通过下拉列表框来选择,颜色也是通过下拉列表来选择,图片单击上传图片后,找到图片的地址点击确定就可以上传,单击添加按钮,执行添加操作,数据提交后,就完成了图书的添加。之后,进行了几项测试,如漏填了几项数据、上传图片格式不正确,这些数据的操作结果都是失败。
    删除功能的测试
    以编号为4的这条记录为例,通过单击该条记录上的“删除”链接按钮,对数码产品信息进行删除的操作,数据提交后,系统提示“删除图书信息成功”,通过对该模块的浏览,该信息的确已被删除,查无此条记录,说明此模块运行无误,信息删除成功。如果是删除图书类别,假如该类别下还有图书,则会提示不能删除,如果类别下没有图书,则可以进行删除。
    查询功能的测试
    本系统中的查询功能都是通过点击链接实现的。将数码产品管理的编码进行了测试,输入管理员的密码登录后台后点击数码产品设置就可以直接看到查询出的数码产品信息。点击查看产品图片后查询出了数码产品是否上传了图片,系统没有出现错误,查询成功。
    6.3 本章小结软件测试是软件开发中的重中之重,在项目管理过程中,强调的是每个过程的每一个环节都要进行测试,保证系统在每个阶段可以控制。本章着重对前台首页、购物车模块、用户注册模块和图书管理模块进行了详细的测试说明。通过反复大量的测试,每个模块均测试成功。
    结论图书在线销售系统采用了比较流行的B/S模式,使用当前较流行的SSH框架和拥有较高安全性与稳定性的数据库SQL Server 2005来完成系统的设计与开发。系统充分考虑了用户的需求,最终达到了预期效果,并添加了一些附加功能,使系统更加人性化。操作者可以随时对所有的信息进行查询,并且每个模块都提供信息浏览的功能。
    本系统实现了图书企业通过互联网向消费者推销自己的图书和服务,在图书在线销售系统网站消费的顾客可以通过计算机网络搜索到自己需要的信息,购买自己需要的图书,在线下达订单。然后由图书在线销售系统后台来处理相关的订单信息、网站维护等信息。
    由于本人在知识、经验方面都存在着不足,在整个开发的过程中时间也比较仓促,因此该系统必然会存在一些缺陷和不足。本系统在图书信息管理等方面还有不足之处,由于对其具体功能分析的不够透彻,以至于在实现功能上不够细化,不够详尽,所以有待以后将其更加完善。
    参考文献
    汪建文.我国零售企业的商务电子化应用商场现代化.2008.(04):56-60
    胡燕.软件工程与标准化.信息技术与标准化.2004.(12):17-21
    盛仲飙.JSP中数据库访问的性能优化研究.微型电脑应用.2008,(9):16-17
    董纪阳.软件设计中的需求分析.电脑知识与技术.2008.(28):56-57
    林华灵.基于Strut框架技术的Web应用.中国新技术新产品.2008,(14):9-11
    何玉洁.数据库原理与应用教程.机械工业出版社.2003:23-78
    杨文红,赵德平,刘柯剑.基于MVC模式Struts框架研究与应用.硅谷.2008.(20):45-46
    赵蕾,程明定,刘琳.J2EE模型中Struts框架技术的研究和应用.中国博览.2004.(12):25-26
    桃子.数码产品市场前瞻.微型计算机.2007.(13):89-90
    周建儒.JSP中自定义标签的实现与部署.科技信息(科学教研).2008.(23):51-53
    Mcleod.Management Information system management in practice.Prentice Hall.1998:43-55
    Raghu Ramakrishnan.Johannes Gehrke.Database Management System.McGraw-Hill Professional. 2007:180-213
    Cassidy A.Information systems strategic planning.Bocaraton.Flrida.St.Luicepress.1998:12-31
    Dionysios Tsichritzis C.Data Base Management Systems.1977:150-53
    hristopher P.Ben light.A critical success factors model for eprimplement.IEEE software.1999:16-30
    1 评论 4 下载 2019-05-18 10:35:41 下载需要12点积分
  • 基于Python和SQL SERVER数据库实现的实验信息综合管理系统

    1 需求分析1.1 需求来源本系统是对于实验综合信息进行管理的系统。
    1.1.1 功能需求
    学生用户:修改系统登陆密码、查询选择的课程、查询选择课程对应的实验课表、导出查询到的课程数据、实验课表数据
    教师用户:修改系统登陆密码、修改个人联系方式、查询教授的课程、查询实验安排、增加课程信息、增加实验信息、按学号查询出勤率、按班级查询出勤率、导出查询到的数据记录
    管理员用户:增加学生信息、修改学生信息、增加教师信息、修改教师信息、增加课程信息、修改课程信息,增加实验信息、修改实验信息,增加实验室信息、修改实验室信息,更新实验打卡信息

    1.1.2 数据需求系统涉及的数据表为8个表,管理员信息表(ADMINB)、教师表(JSB)、教师课程表(JSKCB)、课程表(KCB)、实验打卡表(SYDKB)、实验室表(SYSB)、实验信息表(SYXXB)、学生表(XSB)。
    其中管理员信息表包含的基本属性为管理员用户名、登陆密码。教师表包含的几本书新为教师姓名、联系方式、登陆密码。教师课程表包含的基本属性为教师姓名、课程代码。课程表包含的基本属性为课程代码、课程名称、开课学院。实验打卡表包含的基本属性为实验编号、学生学号、打卡状态。实验室表包含的基本属性为实验中心、实验分室、上课地点。实验信息表包含的基本属性为实验编号、课程代码、实验项目、上课老师、辅助教师、上课日期、星期几、上课地点。学生表包含的基本属性为学号、姓名、班级、登陆密码。
    1.1.3 性能需求
    要求系统在本地访问时数据具有可靠性、运行速度快,简单快捷
    要求系统能在多系统(Windows、Linux)、多终端(PC、手机)

    1.2 设计目的利用服务器和大容量存储等最新的硬件设备,以及数据库和网络技术所开发出的实验信息管理系统使用户能对大量的实验综合信息进行高效的管理。通过实验信息管理系统,信息录入、查询等原先繁复枯燥的工作的效率得到了显著的提升;更重要的是数据的准确性和安全性也同时得到了保证。
    1.3 设计要求不同类型的用户能够通过本系统使用不同的功能,对实验综合信息进行管理。
    1.4 开发工具及相关技术通过采用Microsoft SQL Server等大型关系型数据库,实验的各项数据的存储更为规范和完整。数据库技术也使得实验数据的备份和恢复变得简单便捷。而在硬件方面,采取RAID5等存储解决方案组成的磁盘阵列,以极低的存储成本极大的提高了数据的安全性。通过采用python平台开发,采用了基于B/S的三层开发结构(UI、BLL、DAL)。同时运用tkinter等GUI的最新技术,提供美观实用的系统界面和顺畅的用户体验。
    2 总体设计2.1 总体结构设计为了满足实验综合信息管理系统各方面信息的管理功能,需要明确用户的各个功能。数据库中应该有教师、学生以及管理员的基本信息,这些来自于本系统。教师、学生只能在客户端进行操作。管理员可以使用管理端操作,修改、删除、增加教师、学生的信息。此类权限不对教师、学生用户开放。除此之外,还要通过登录名和密码严格限定登陆者的身份并且控制相应的操作权限,只有管理员有权限修改账户以及密码,防止其他密码泄露造成的其他问题。
    2.1.1 模块设计系统模块设计:

    2.2.2 模块功能描述“管理员用户”子系统针对管理员用户的日常工作流程,分为“学生管理”,“教师管理”,“课程管理”,“实验管理”,“实验室管理”等子模块。其模块具体功能描述如下:

    “学生管理”模块:该模块对学生信息进行维护,如对增加新入学学生的信息,为转专业学生更改班级信息,为改名学生更改姓名信息,删除退学、毕业学生信息,为忘记登陆密码的学生用户重新设置用户密码等
    “教师管理”模块:该模块对教师信息进行维护,如对增加新入职老师的信息,删除离职老师的信息,为忘记登陆密码的教师用户重新设置登陆密码等
    “课程管理”模块:该模块对课程信息进行维护,如对课程名称、开课学院等信息系的修改,增加新开设课程的信息
    “实验管理”模块:该模块对实验信息进行维护,如对实验下属各种信息的修改调整、增加新的实验信息、更新实验打卡信息等
    “实验室管理”模块:该模块对实验室信息进行维护,如对实验中心、实验分室、实验教师信息的修改、增加等

    “教师用户”子系统针对教师用户的日常使用流程,分为“学生管理”模块,“课程管理”模块,“实验管理”模块、“个人管理”模块。其模块具体功能描述如下:

    “学生管理”模块:该模块对学生信息进行查询,如对班级整体实验打卡记录的查询,对指定具体学号的学生实验打卡记录的查询,对查询到的信息进行导出等
    “课程管理”模块:该模块对课程信息进行查询与维护,如将新教授的课程信息录入系统,查询正在教授的课程信息等
    “实验管理”模块:该模块对实验信息进行查询与维护,如查询已安排为授课教师的实验信息,添加新的实验信息等
    “个人管理”模块:该模块对教师个人信息进行维护,如修改自己的登陆密码、修改个人的联系方式等

    “学生用户”子系统针对学生用户的日常使用流程,分为“个人管理”模块,“课程管理”模块,“实验管理”模块等。其模块具体功能描述如下:

    “个人管理”模块:该模块对学生用户个人信息进行维护,如修改自己的登陆密码等
    “课程管理”模块:该模块对课程信息进行查询,如查询自己选择的课程信息等
    “实验管理”模块:该模块对实验信息进行查询,如查询自己选择的课程所安排的实验信息等

    2.2 数据库设计2.2.1 概念结构设计
    管理员信息表(ADMINB)主要用于在系统中储存管理员信息,包含了管理员的登陆ID、密码,其中登陆ID是主键
    教师表(JSB)主要用于在系统中储存教师信息,包含了教师用户的姓名、密码、联系方式,其中姓名是主键。管理员用户可对该表进行维护
    教师课程表(JSKCB)主要用于在系统中储存教师授课信息,包含了教师姓名、课程代码。管理员用户、教师用户可对该表进行维护
    课程表(KCB)主要用于储存课程信息,包含了课程代码、开课学院、课程名称,其中课程代码是主键。管理员用户可对该表进行维护
    实验打卡表(SYDKB)主要用于储存学生打卡信息,包含了实验编号,学生学号、打卡状态。管理员用户可对该表进行维护,教师用户可对该表进行查询
    实验室表(SYSB)主要用于储存实验室信息,包含了实验中心、实验分室、实验教室,其中实验教室是主键。管理员用户可对该表进行维护
    实验信息表(SYXXB)主要用于储存实验信息,包含了实验编号、课程代码、实验项目、上课老师、辅助教师、上课日期、星期几、上课地点,其中实验编号是主键。管理员用户、教师用户可对该表进行维护
    学生表(XSB)主要用于储存学生信息,包含了学号、姓名、班级、登陆密码,其中学号是主键。管理员用户可对该表进行维护

    系统E-R图

    2.2.2 逻辑结构设计根据E-R模型转换关系结构:

    教师实体集(JSB)可以转换化为关系:
    教师用户(姓名,联系方式,登陆密码)

    管理员实体集(ADMINB)可以转化为关系:
    管理员用户(登陆ID,密码)

    课程实体集(KCB)可以转化为关系:
    课程(课程代码,开课学院,课程名称)

    实验室实体集(SYSB)可以转化为关系:
    实验室(实验分室、实验中心、实验教室)

    实验信息实体集(SYXXB)可以转化为关系:
    实验信息(实验编号、课程代码、实验项目、上课老师、辅助教师、上课日期、星期几)

    学生实体集(XSB)可以转换为关系:
    学生(姓名、学号、班级)

    教师与课程之间是n:m的联系,可以转化为一个关系:
    教师课程(JSKCB)(教师姓名、课程编号)

    学生与实验打卡信息之间是1:m的联系,可以对学生关系进行拓展,但由于打卡信息较多,进行扩展会导致数据库冗余信息较多,故单独转化为一个关系:
    学生打卡(XSDKB)(学号、实验编号、打卡信息)

    实验室与实验信息之间是n:m的联系,可以对实验信息进行拓展,不必单独转为一个关系:
    实验信息(实验编号、课程代码、实验项目、上课老师、辅助教师、上课日期、星期几、实验教室)
    2.2.3 物理结构设计教师表(JSB)



    字段名称
    数据类型
    字段长度
    是否为空
    备注




    姓名
    varchar
    20
    No
    主码


    联系电话
    varchar
    20
    Yes



    登陆密码
    varchar
    255
    Yes



    教师课程表(JSKCB)



    字段名称
    数据类型
    字段长度
    是否为空
    备注




    课程代码
    varchar
    20
    No



    上课教师
    varchar
    20
    No



    课程表(KCB)



    字段名称
    数据类型
    字段长度
    是否为空
    备注




    课程代码
    varchar
    20
    No
    主码


    开课学院
    varchar
    20
    No



    课程名称
    varchar
    255
    No



    **实验打卡表(SYDKB)



    字段名称
    数据类型
    字段长度
    是否为空
    备注




    实验编号
    varchar
    20
    No



    学号
    varchar
    20
    No



    实际上课时间
    varchar
    255
    No



    状态
    varchar
    255
    No



    实验室表(SYDKB)



    字段名称
    数据类型
    字段长度
    是否为空
    备注




    实验中心
    varchar
    255
    No



    实验分室
    varchar
    255
    No



    实验教室
    varchar
    255
    No
    主码



    实验信息表(SYXXB)



    字段名称
    数据类型
    字段长度
    是否为空
    备注




    实验编号
    varchar
    255
    No
    主码


    课程代码
    varchar
    255
    No



    实验项目
    varchar
    255
    No



    上课老师
    varchar
    255
    No



    辅助教师
    varchar
    255
    Yes



    上课日期
    varchar
    255
    No



    星期几
    varchar
    255
    No



    实验教室
    varchar
    255
    No



    学生表(XSB)



    字段名称
    数据类型
    字段长度
    是否为空
    备注




    姓名
    varchar
    20
    No



    学号
    char
    11
    No
    主码


    班级
    varchar
    255
    No



    登陆密码
    varchar
    255
    Yes



    管理员表(XSB)



    字段名称
    数据类型
    字段长度
    是否为空
    备注




    登陆ID
    varchar
    20
    No
    主码


    登陆密码
    varchar
    255
    No



    3 详细设计3.1 数据库的创建create database SYDK
    3.2 表的创建import pyodbccnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=127.0.0.1;DATABASE=SYDK;UID=sa;PWD=test')cursor = cnxn.cursor()cursor.execute(""" Create Table XSB ( 班级 varchar(20), 学号 char(11), 姓名 varchar(20), 登陆密码 varchar(255) ) """)#学生表cursor.execute(""" Create Table KCB ( 课程代码 varchar(20), 课程名称 varchar(255), 开课学院 varchar(20) ) """)#课程表cursor.execute(""" Create Table JSB ( 姓名 varchar(20), 联系电话 varchar(20), 登陆密码 varchar(255) ) """)#教师表cursor.execute(""" Create Table SYXXB ( 实验编号 varchar(20), 课程代码 varchar(20), 实验项目 varchar(20), 上课老师 varchar(20), 辅助教师 varchar(20), 上课日期 varchar(255), 星期几 varchar(20), 实验中心 varchar(255), 实验分室 varchar(255), 上课地点 varchar(255) ) """)#实验信息表cursor.execute(""" Create Table SYDKB ( 实验编号 varchar(20), 学号 varchar(20), 实际上课时间 varchar(255), 状态 varchar(255) ) """)#实验打卡表cursor.execute(""" Create Table SYSB ( 实验中心 varchar(255), 实验分室 varchar(255), 上课地点 varchar(255) ) """)#实验室表cursor.execute(""" Create Table JSKCB ( 课程代码 varchar(20), 上课老师 varchar(20) ) """)#教师课程表cursor.execute(""" Create Table ADMINB ( id varchar(20), password varchar(20) ) """)#管理员表cursor.commit()cursor.close()
    3.3 数据设定本系统对接南京信息工程大学实践教学综合管理平台,通过访问平台接口,以正则表达式的方法,获取得到教师信息、学生信息、实验信息,从其内含的依赖关系衍生出实验打卡表,实验室表,课程表,教室课程表。同时,管理员用户通过本系统,也可调用该程式对数据库中信息进行维护工作。核心代码如下:
    cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=127.0.0.1;DATABASE=SYDK;UID=sa;PWD=test') cursor = cnxn.cursor() cursor.execute("SELECT * FROM SYXXB WHERE 实验编号="+str(i)) row = cursor.fetchall() print(i) if (len(row)!=0): cursor.close() continue url="http://sjjx.nuist.edu.cn/syjx/admin/experiment/looksyzx.aspx?type=kb&id="+str(i) try: req=urllib.request.Request(url) resp=urllib.request.urlopen(req) except: print("oppops") continue data=resp.read().decode('GBK') w1='<td width=\'610\' height=\'25\' style=\'padding-left:5px;\'>' w2='</td></tr>' pat=re.compile(w1+'(.*?)'+w2,re.S) sybz=pat.findall(data) if(len(sybz)==0): continue del(sybz[9]) w1='<td height=\'25\' style=\'padding-left:5px; width: 82px;\'>' w2='</td>' pat2=re.compile(w1+'(.*?)'+w2,re.S) syb=pat2.findall(data) del(syb[9]) for j in range(0,len(syb)): print (syb[j]+':'+sybz[j]) if(sybz[4].find("(")!=-1): tmp=sybz[4] tmp=tmp[0:tmp.find("(")] sybz[4]=tmp print(sybz[4]) print(sybz[5]) w1='<td align=\'center\'>' w2='</td>' pat3=re.compile(w1+'(.*?)'+w2,re.S) xsbz=pat3.findall(data) cursor.execute("SELECT * FROM JSB WHERE 姓名=\'"+sybz[4]+"\'") row = cursor.fetchall() if (len(row)==0): cursor.execute("insert into JSB values ("+"\'"+sybz[4]+"\'"+",\'"+sybz[5]+"\'"+",\'\')") cursor.execute("SELECT * FROM KCB WHERE 课程代码="+sybz[0])cursor.commit();cursor.close();
    3.4 模块设定3.4.1 登陆模块本模块供不同类型的用户登陆使用,通过单选框的选择,可以选择登陆的用户类型,输入账号密码后,登陆本系统。系统访问数据库判断密码情况,若密码错误则无法成功登陆,访问请求被系统拒绝,若密码正确则进入对应的综合管理模块。

    其核心代码如下:
    from tkinter import *from CoCenter import *import tkinter.messageboxclass LoginFrame (Frame): def __init__(self,master): def ButtonClick(self): s1 = self.ent1.get() s2 = self.ent2.get() if(self.v.get() == 0): self.login(s1,s2,"XSB","学号") elif(self.v.get() == 1): self.login(s1,s2,"JSB","姓名") elif(self.v.get() == 2): self.login(s1,s2,"admin") else: showinfo(title = '错误', message = '未选择登陆方式!') def login(self,name,pwd,tbname="XSB",ab="学号"): if(tbname=="admin"): import pyodbc cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=127.0.0.1;DATABASE=SYDK;UID=sa;PWD=test') cursor = cnxn.cursor() cursor.execute("SELECT password FROM ADMINB WHERE id =\'" +name+"\'") row = cursor.fetchall() cursor.close() if(len(row)==0): tkinter.messagebox.showinfo(title = '错误', message = '用户名不存在') else: if(getVal(str(row[0]))==pwd): tkinter.messagebox.showinfo(title = '成功', message = '登陆成功')
    3.4.2 综合管理模块学生用户管理模块
    学生用户登陆成功后,则可以进入学生用户管理模块,通过点击学生用户管理模块上的按钮,可以调用相应的信息维护模块。

    其核心代码如下:
    self.button=tk.Button(frame,text = "更改登陆密码",pady=10,command = self.XSinfoUpdate)self.button.grid(row = 0,column = 0,padx=10)self.button1=tk.Button(frame,text = "查询个人选课",pady=10,command = self.XSCrouseQry)self.button1.grid(row = 0,column = 1,padx=10,pady=15)self.button2=tk.Button(frame,text = "查询实验课表",pady=10,command = self.XSCrouseQry2)self.button2.grid(row = 0,column = 2,padx=10)self.geometry('310x80')
    教师用户管理模块
    教师用户登陆成功后,则可以进入教师用户管理模块,通过点击教师用户管理模块上的按钮,可以调用相应的信息维护模块。

    其核心代码如下:
    self.button=tk.Button(frame, text = "更改个人信息",pady=10,command = self.JSinfoUpdate)self.button.grid(row = 0,column = 0,padx=10,pady=10)self.button1=tk.Button(frame,text = "更改登陆密码",pady=10,command = self.JSPwdUpdate)self.button1.grid(row = 0,column = 1)self.button2=tk.Button(frame,text = "查询所教课程",pady=10,command = self.JSCrouseQry)self.button2.grid(row = 1,column = 0,padx=10,pady=10)self.button3=tk.Button(frame,text = "查询实验信息",pady=10,command = self.JSExpQry)self.button3.grid(row = 1,column = 1)
    管理员用户管理模块
    管理员用户登陆成功后,则可以进入管理员用户管理模块,通过点击管理员用户管理模块上的按钮,可以调用相应的信息维护模块。

    其核心代码如下:
    self.button=tk.Button(frame,text = "添加学生信息",pady=10,command = self.AdStuAdd)self.button.grid(row = 0,column = 0,padx=10,pady=10)self.button1=tk.Button(frame,text = "修改学生信息",pady=10,command = self.AdStuUpdate)self.button1.grid(row = 0,column = 1,padx=10,pady=10)self.button2=tk.Button(frame,text = "添加教师信息",pady=10,command = self.AdJSAdd)self.button2.grid(row = 1,column = 0,padx=10,pady=10)self.button3=tk.Button(frame,text = "修改教师信息",pady=10,command = self.AdJSUpdate)self.button3.grid(row = 1,column = 1,padx=10,pady=10)self.button4=tk.Button(frame,text = "添加课程信息",pady=10,command = self.AdKCAdd)self.button4.grid(row = 2,column = 0,padx=10,pady=10)self.button5=tk.Button(frame,text = "修改课程信息",pady=10,command = self.AdKCUpdate)self.button5.grid(row = 2,column = 1,padx=10,pady=10)self.button6=tk.Button(frame,text = "添加实验信息",pady=10,command = self.AdExpAdd)self.button6.grid(row = 3,column = 0,padx=10,pady=10)self.button6=tk.Button(frame,text = "修改实验信息",pady=10,command = self.AdExpUpdate)self.button6.grid(row = 3,column = 1,padx=10,pady=10)self.button6=tk.Button(frame,text = "添加实验室信息",pady=10,command = self.AdExpPlaceAdd)self.button6.grid(row = 4,column = 0,padx=10,pady=10)
    3.4.3 信息维护模块用户信息维护模块
    根据不同用户,调用不同的信息维护模块,具体描述如下:
    学生用户调用本模块对登陆密码进行维护

    其核心代码如下:
    Sql("EXEC XS_INFO_UPDATE \'"+self.name+"\',\'"+str(self.newp.get())+"\'",2)tk.messagebox.showinfo('提示','修改成功')
    教师用户调用本模块对登陆密码、联系方式进行维护。

    其核心代码如下:
    Sql("EXEC JS_PWD_UPDATE \'"+self.name+"\',\'"+str(self.newp.get())+"\'",2)tk.messagebox.showinfo('提示','修改成功')
    管理员用户调用本模块对学生的所有属性、教师用户的所有属性进行维护。

    其核心代码如下:
    if(self.element=="STUDENT"): if(self.flag=="ADD"): Sql("INSERT INTO XSB VALUES (\'"+str(self.clsname.get())+"\',\'"+str(self.id.get())+"\',\'"+str(self.name.get())+"\',\'"+str(self.pwd.get())+"\')",2) else: Sql("UPDATE XSB SET 班级=\'"+str(self.clsname.get())+"\',姓名=\'"+str(self.name.get())+ "\',登陆密码=\'"+str(self.pwd.get())+"\' \n WHERE 学号=\'"+str(self.id.get())+"\'",2)if(self.element=="TEACHER"): if(self.flag=="ADD"): Sql("INSERT INTO JSB VALUES (\'"+str(self.id.get())+"\',\'"+str(self.tel.get())+"\',\'"+str(self.pwd.get())+"\')",2) else: Sql("UPDATE JSB SET 联系电话=\'"+str(self.tel.get())+ "\',登陆密码=\'"+str(self.pwd.get())+"\' \n WHERE 姓名=\'"+str(self.id.get())+"\'",2)
    课程信息维护模块
    不同用户对于课程信息维护模块具有不同的权限,具体如下:
    学生用户具有对课程信息的查询权限,对于查询到的课程信息,学生用户可以选择是否导出为excel表格形式:

    其核心代码如下:
    row=Sql("EXEC XS_Course_Qry1 \'"+ self.stuid+"\'",1)table=PrettyTable(["课程代码","课程名称","开课学院"])row1=getVal(row)for i in range(0,int(len(row1)/3)):table.add_row([row1[i*3],row1[i*3+1],row1[i*3+2]])tk.messagebox.showinfo(title = '课程', message = table)a=tk.messagebox.askokcancel('提示', '是否导出选课表')
    教师用户具有对课程信息的查询、创建权限,对于查询到的课程信息,教师用户可以选择是否导出为excel表格形式:

    核心代码如下:
    row=Sql("EXEC JS_Course_Qry \'"+ self.stuid+"\'",1)table=PrettyTable(["课程代码","课程名称","开课学院"])row1=getVal(row)for i in range(0,int(len(row1)/3)):table.add_row([row1[i*3],row1[i*3+1],row1[i*3+2]])tk.messagebox.showinfo(title = '课程', message = table)
    管理用户具有对课程信息的所有权限:

    其核心代码如下:
    if(self.element=="CROUSE"): if(self.flag=="ADD"): Sql("INSERT INTO KCB VALUES (\'"+str(self.id.get())+"\',\'"+str(self.name.get())+"\',\'"+str(self.inst.get())+"\')",2) elif(self.flag=="UPDATE"): Sql("UPDATE KCB SET 开课学院=\'"+str(self.inst.get())+ "\',课程名称=\'"+str(self.name.get())+"\' \n WHERE 课程代码=\'"+str(self.id.get())+"\'",2) else: Sql("INSERT INTO KCB VALUES (\'"+str(self.id.get())+"\',\'"+str(self.name.get())+"\',\'"+str(self.inst.get())+"\')",2) tmp=str(self.flag).split("2") Sql("INSERT INTO JSKCB VALUES (\'"+str(self.id.get())+"\',\'"+str(tmp[1])+"\')",2)
    实验信息维护模块
    根据不同用户,调用不同的信息维护模块,具体描述如下:
    学生用户对于实验信息具有查询权限,对于查询到的实验信息,可以选择是否导出为EXCEL表格

    其核心代码如下:
    row =Sql("EXEC XS_Course_Qry2 \'"+ self.stuid+"\'",1) table=PrettyTable(["实验编号","课程代码","实验项目", "上课老师","辅助教师","上课日期","星期几", "实验中心","实验分室","上课地点"]) row1=getVal(row) for i in range(0,int(len(row1)/10)): table.add_row([row1[i*10],row1[i*10+1],row1[i*10+2], row1[i*10+3],row1[i*10+4],row1[i*10+5], row1[i*10+6],row1[i*10+7],row1[i*10+8],row1[i*10+9]]) tk.messagebox.showinfo(title = '课表', message = table) a=tk.messagebox.askokcancel('提示', '是否导出课表')
    教师用户对于实验信息具有查询、修改权限,对于查询到的实验信息,可以导出为EXCEL表格

    其核心代码如下:
    if(self.element=="EXP"): if(self.flag=="ADD"): Sql("INSERT INTO SYXXB VALUES (\'"+str(self.id.get())+"\',\'"+str(self.kcdm.get())+"\',\'"+str(self.syxm.get())+"\',\'"+str(self.skls.get())+"\',\'" +str(self.fzjs.get())+"\',\'"+str(self.skrq.get())+"\',\'"+str(self.xqj.get())+"\',\'"+str(self.syzx.get())+"\',\'"+str(self.syfs.get())+"\',\'"+str(self.skdd.get())+"\')",2) tk.messagebox.showinfo('提示','更新成功!')
    同时,教师用户对于实验打卡信息具有查询权限,可以通过学生学号查询打卡信息,也可以通过所教班级查询打卡信息,并将打卡信息导出到EXCEL表格。

    其核心代码如下:
    for i in range(0,len(row1)): if(len(row1[i])==11): row=Sql("EXEC JS_STU_QRY5 \'"+self.name+"\',\'"+row1[i]+"\'",1) if(len(row)==0): continue else: row=Sql(""" declare @f1 float declare @f2 float EXEC JS_STU_Qry2 \'"""+str(row1[i])+"\',\'"+self.name+"""\',@f1 output,@f2 output SELECT @f1,@f2""",1) row2=getVal(row) table.add_row([str(row1[i]),str(row2[0]),str(row2[1])]) tk.messagebox.showinfo(title = '查询结果', message =table)
    管理员用户对于实验信息具有全部权限

    核心代码如下:
    Sql("UPDATE SYXXB SET 课程代码=\'"+str(self.kcdm.get())+"\',实验项目=\'" +str(self.syxm.get())+"\',上课老师=\'" +str(self.skls.get())+"\',辅助教师=\'" +str(self.fzjs.get())+"\',上课日期=\'" +str(self.skrq.get())+"\',星期几=\'" +str(self.xqj.get())+"\',实验中心=\'" +str(self.syzx.get())+"\',实验分室=\'" +str(self.syfs.get())+"\',上课地点=\'" +str(self.skdd.get()) +"\' \n WHERE 实验编号=\'"+str(self.id.get())+"\'",2)
    实验室信息维护模块
    管理员用户对实验室信息具有全部权限

    其核心代码如下:
    if(self.element=="EXPPLACE"): if(self.flag=="ADD"): Sql("INSERT INTO SYSB VALUES (\'"+str(self.syzx.get())+"\',\'"+str(self.syfs.get())+"\',\'"+str(self.skdd.get())+"\')",2) else: Sql("UPDATE SYSB SET 实验中心=\'"+str(self.syzx.get())+ "\',实验分室=\'"+str(self.syfs.get())+"\' \n WHERE 上课地点=\'"+str(self.skdd.get())+"\'",2)
    4 总结整个系统的设计过程对于我来说算是个学习、探索的过程,通过实践和对比别人开发程序的过程。在整个设计过程中,出现过很多的问题,很多繁琐的东西都需要反复的修改,主要是前期工作不彻底,对系统的需求分析的要求认识不够清楚,使得在后边的工作中不得不经常反复去修改。使我体会到设置中每一步的重要性。所以在分析一个问题时,我们需要站在一个有远见的高度。
    虽然时间紧迫但我学会了很多,也感到自身知识的贫乏,希望在日后的努力中能做出更完善的系统。
    4 评论 24 下载 2018-10-24 21:35:32 下载需要11点积分
  • 基于B/S架构的OA系统的设计与实现

    摘 要一个企业实现办公自动化的程度是衡量其实现现代化管理的标准。办公自动化(OA: OFFICE AUTOMATION)就是采用Internet技术,基于工作流的概念,使企业内部人员方便快捷地共享信息,高效协同工作。本文采用结构化与原型法结合的系统开发方法。整个系统分为用户登录验证模块、员工信息管理模块、日程管理模块、论坛模块、审批流转模块等。该系统的应用改变了过去复杂、低效的手工办公方式,实现迅速、全方位的信息采集、信息处理,为企业的管理和决策提供科学的依据。
    关键词:办公自动化 SSH Activiti5
    AbstractThe extent of an enterprise’s realization of office automation is the standard of its realization of the modernization management. AUTOMATION OA: (OFFICE) is the use of Internet technology, based on the concept of workflow, so that the enterprise internal personnel to quickly and easily share information, and efficiently work together. In this paper, the structure and the prototype method of the system development method. The whole system is divided into user login verification module, employee information management module, schedule management module, forum module, approval and transfer module, etc.. The application of this system has changed the complicated and inefficient manual office methods, and realized the information collection and information processing, which can provide scientific basis for the management and decision of enterprise.
    Key words:Office automation; SSH;Activiti5
    1 引言1.1 研究背景及意义OA系统,它利用先进计算机网络的技术,使人的各种办公业务活动逐步由各种设备、各种人、机信息系统来协助完成,达到充分利用信息,从而提高工作效率、工作质量。信息自动化由70年代末80年代初在我国提出,到现在已有近二十年的发展历史。信息自动化技术的发展速度不断提高,办公自动化新产品越来越多,办公自动化有越来越多的新含义。
    办公软件给办公职员带来的方便是毋庸置疑的,现在的办公软件已经不仅仅减轻员工的工作量,更重要的是将员工从繁琐的事务性工作中解放出来,把重心放到最重要的事情上去,提高整体员工的工作效率,提高企业的效率,增强企业实力。在这种软件的协同下,企业的组织结构更简化,各部门之间的信息交流更方便、快捷、准确,企业的战略决策可以更好更快的跟进。从这些意义上讲,在市场竞争越来越激烈的今天,办公自动化己经不再是一种手段、一种工具,而成为决定企业生存发展的命脉。
    办公自动化是信息社会的一种新型办公方式,它将现代化办公和计算机网络功能结合。随着信息技术的发展,办公自动化在行政企事业单位的管理、经营活动中发挥着日益重要的作用。通过网络,组织机构内部的员工可跨越时间、地点协同工作。通过办公自动化系统所实施的交换式网络应用,使信息的传递更加快捷和方便,从而极大地扩展了管理手段,实现了运营的高效。
    1.2 OA系统的发展第一代OA:数据处理自动化阶段。自80年代中期开始,伴随传统MIS(管理信息系统)的兴起与发展,OA进入以数据处理自动化为标志的第一代OA阶段。它的最大特点是应用基于文件系统和关系型数据库系统,以结构化数据为存储和处理对象,强调对数据的计算和统计能力。
    第二代OA:C/S(Client/Server)架构下的工作流自动化阶段。伴随企业内部局域网的兴起和发展,第二代OA开始关注并实施企业不同部门间工作流程的自动化。不同部门及各员工间的协作大大加强,从而使企业办公的效率得到较大的提高。因此这是真正意义上”办公自动化”的开始。
    第三代OA:无障碍工作流自动化阶段。90年代中期开始,随着互联网(Internet)的兴起与发展,办公自动化管理模式获得极大的突破。以Internet为基础,第三代OA实现了移动办公,企业资源不再受到通讯技术的限制。然而,由于受到企业传统的文化环境、管理模式和业务流程的束缚,协同工作的模式难以建立,工作流程自动化的效益也难以全部实现。
    第四代OA:协同工作型办公自动化(KM1代)。90年代末期开始,随着协同管理思想(Collaboration)的兴起,旨在实现项目团队协同、部门之间协同、业务流程与办公流程协同、跨越时空协同的第5代协同工作型OA开始兴起。第四代OA的核心是KM(知识管理),实现方式是Workflow(办公流程自动化)及KM(知识管理)相结合的信息系统。
    第五代OA:协同发展型办公自动化(KM2代)。第五代OA已经超越了传统办公的狭义范畴,它是一种领先的企业管理思想。在实现方式上,它仍然以工作流程自动化Workflow(办公流程自动化)及KM(知识管理)为核心。从两者的关系来看,工作流程自动化是实现协同的重要手段。而KM仍然是OA的核心。但与第4代OA中的KM(KM1代)相比较,KM2代的涵义发生了重大的变化。KM2代的优势在于,其注重知识的收集、积累与继承,最终目标是要实现企业及员工的协同发展,而不是关注办公事务本身与企业本身的短期利益。
    1.3 研究内容本系统采用ssh,activiti5等技术,完成了OA系统的设计。主要实现了系统管理、个人办公、网上交流、审批流转等功能。系统管理主要分为部门管理、用户管理、角色管理等功能;个人办公主要实现了日程管理等功能;网上交流主要实现了论坛、邮件等功能;审批流转主要实现了用户请假等功能。本系统经过多次开发、修改及测试后,功能基本满足企业的正常使用。
    2 系统分析与建模2.1 系统总体目标在当前很多企业中,存在下列情况:有的工作流程不清晰、不建全;员工、部门之间沟通与协作效率较低;业务动态进展监控难;审批周期长,遇领导出差或事务繁忙审批效率低;缺少多层次沟通平台,通知、公告、领导随机交办的临时事件等信息,传达不顺畅;多项目同时运作,跨部门、跨地域协调成本高,集中管控难度大等等其他实际工作中存在的问题。
    利用OA系统实现协同办公,可以在任何地点、任何时间、以任何方式协同处理任何人的事件,领导出差在外、采购人员外出办业务、人力专员参加招聘会等情况,虽然本人不在办公室,均可随时、随地登录协同平台,处理公务,如:领导签字审批、查看通知、发送邮件,全体人员共享一个办公平台,缩短办事时间、大大提高工作效率。
    2.2 需求分析为适应企业的协同办公,增强领导、员工之间的交流,方便员工使用,充分发挥办公系统的优越性,本系统实现了日程管理,员工管理,论坛管理,审批管理等模块。本系统主要有2种用户角色,管理员和普通用户。
    管理员具有系统管理,在线用户管理,论坛后台管理等功能。用例图如图1所示。

    用户具有基本的查看公司基本信息功能,如公司员工,部门等,可以有自己的日程功能,记录基本的日程,可以在论坛发表自己的主题,讨论工作上的技术难题,可以发送邮件,请假等。用例图如图2所示。

    2.3 主要技术介绍本系统主要采用了struts2,hibernate4,spring4来搭建开发框架,使用c3p0连接池,log4j日志记录工具,activiti5等技术。表现层上使用了fullcalendar来做日程管理模块,用treeview插件进行权限的树状显示,ajax局部刷新,js验证用户输入,确保客户端数据库的合理,并且使用bootstrap进行页面的响应式设计。
    2.3.1 Struts2Struts2是一个具有很好实用价值的Web MVC框架,它减少了直接运用MVC模式来开发Web应用的周期。重要的是它是一个开源框架,方便开发者深入研究了解其机制,越来越广泛的接受和应用。而且它提供一个好的控制器和一套定制的标签库Taglib,着力在控制器和视图上的应用,完美的体现了MVC设计思想。提供集中统一的权限控制、国际化提示和消息、输入校验和日志记录等技术支持。另外,它对其他技术和框架具有良好的融合性。如能与EJB、JDBC和Hibernate等数据库访问技术相结合,利用集成技术减少数据库的工作量。
    2.3.2 HibernateHibernate是轻量级Java EE应用的持久层解决方案,是流行的ORM框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以用面向对象的方式来操纵数据库。Hibernate不仅管理Java类到数据库表的映射,还提供数据查询和获取数据的操作,可以减少人工使用SQL和JDBC处理数据的时间。
    Hibernate实际上是一个提供数据库服务的中间件。Hibernate的持久化解决方案将用户从繁琐的JDBC访问中解脱出来,底层数据库连接获取,数据访问的实现、事务控制都无须用户关心,这种体系结构,将应用层从底层的JDBC/JTA API中抽象出来。
    2.3.3 SpringSpring是从实际开发中抽取出来的开源框架,为企业的开发提供一个轻量级的解决方案。该解决方案包括:基于IOC(控制反转)的核心机制,以及AOP(面向切面编程)的思想,能与多种持久层技术的整合,是优秀的Web MVC框架等。Spring致力于Java EE应用各层的解决方案而不是仅仅专注于某一层的方案,它贯穿表现层、业务层、持久层,降低各层组件的耦合度,实现软件各层的解耦。
    2.3.4 Activiti5Activiti项目是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN 2.0标准,包括支持对象管理组(OMG),面对新技术的机遇,诸如互操作性和云架构,提供技术实现。
    Activiti 流程引擎重点关注在系统开发的易用性和轻量性上。每一项 BPM 业务功能 Activiti 流程引擎都以服务的形式提供给开发人员。通过使用这些服务,开发人员能够构建出功能丰富、轻便且高效的 BPM 应用程序。
    3 系统设计3.1 解决方案设计本系统采用Java EE的三层架构设计,分为表示层,业务逻辑层,数据访问层。表示层包括jsp,html,servlet,jquery,bootstrap等;业务逻辑层包括spring,service,pojo等;数据访问层包括jdbc,hibernate,mybatis等。SSH的系统架构图如图3所示。

    3.2 功能权限流程设计由于系统是具有多种角色身份的用户使用,所以必须对用户身份进行验证。拥有不同角色身份的用户可以看见不同的视图,使用不同的功能。在整个系统中,用户登录系统首先进行身份(普通用户和管理员)的验证,当身份验证成功后,分别进入不同的界面进行不同的操作,具体的流程图如图4所示。

    在管理员进入系统后,可以执行系统的所有功能,拥有最高的权限,具体的流程图如图5所示。

    在普通用户进入系统时,会根据对应的角色查询所拥有的具体功能,最普通的用户功能如流程图6所示。

    3.3 数据库设计3.3.1 概念结构设计E-R方法是“实体-联系方法”(Entity-Relationship Approach)的简称。它是描述现实世界概念结构模型的有效方法。是表示概念模型的一种方式,用矩形表示实体型,矩形框写明实体名;用椭圆表示实体的属性,并用无向边将其与相应的实体型连接起来;用菱形表示实体型之间的联系,在菱形框内写明联系名,并用无向边分别与有关实体型连接起来,同时在无向边旁标上联系的类型(1:1,1:n或m:n)。系统的E-R图,如图7所示。

    3.3.2 物理结构设计合理的数据库结构设计可以提高数据储存效率,保证数据的完整性和一致性。设计数据库系统时应该首先充分了解用户各个方面的需求,包括现有的以及将来可能增加的需求。
    部门表:用于系统保存部门基本信息。表结构如表1所示。



    列名
    数据类型
    长度
    主键?
    非空?
    自增?
    注释




    id
    bigint
    20



    部门主键


    name
    varchar
    50



    部门名称


    note
    varchar
    50



    部门简介


    managerid
    bigint
    20



    部门经理id



    员工表:用于系统保存员工基本信息。表结构如表2所示。



    列名
    数据类型
    长度
    主键?
    非空?
    自增?
    注释




    id
    bigint
    20



    主键


    loginname
    varchar
    50



    登录名


    password
    varchar
    50



    密码


    realname
    bigint
    20



    真实姓名


    gender
    varchar
    50



    性别


    phonenumber
    varchar
    50



    电话号码


    email
    varchar
    50



    邮箱


    age
    int
    11



    年龄


    imageaddress
    varchar
    50



    头像地址


    education
    varchar
    50



    学历


    note
    varchar
    200



    备注


    departmentid
    bigint
    20



    部门id



    角色表:用于保存角色信息。表结构如表3所示。



    列名
    数据类型
    长度
    主键?
    非空?
    自增?
    注释




    id
    bigint
    20



    主键


    name
    varchar
    50



    名称


    note
    varchar
    100



    简介



    员工-角色表:用于系统保存员工-角色对应信息。表结构如表4所示。



    列名
    数据类型
    长度
    主键?
    非空?
    自增?
    注释




    userid
    bigint
    20



    员工外键


    roleid
    bigint
    20



    角色外键



    日程表:用于系统保存日程基本信息。表结构如表5所示。



    列名
    数据类型
    长度
    主键?
    非空?
    自增?
    注释




    id
    bigint
    20



    主键


    userid
    bigint
    20



    用户id


    title
    varchar
    50



    内容


    start
    varchar
    50



    开始时间


    end
    varchar
    50



    结束时间


    allday
    int
    11



    全天


    color
    varchar
    50



    背景颜色



    权限表:用于系统保存权限基本信息。表结构如表6所示。



    列名
    数据类型
    长度
    主键?
    非空?
    自增?
    注释




    id
    bigint
    20



    主键


    url
    varchar
    100



    访问地址


    name
    varchar
    50



    名称


    icon
    varchar
    50



    图标


    parentid
    bigint
    50



    父权限id



    角色-权限表:用于系统保存角色-权限对应信息。表结构如表7所示。



    列名
    数据类型
    长度
    主键?
    非空?
    自增?
    注释




    roleid
    bigint
    20



    角色id


    privilegeid
    bigint
    20



    权限id



    论坛表:用于系统保存论坛基本信息。表结构如表8所示。



    列名
    数据类型
    长度
    主键?
    非空?
    自增?
    注释




    id
    bigint
    20



    主键


    name
    varchar
    50



    名称


    note
    varchar
    200



    内容


    imagename
    varchar
    50



    图片地址


    position
    int
    11



    位置


    topiccount
    int
    11



    主题数量


    articlecount
    int
    11



    文章数量


    lasttopicid
    bigint
    20



    最后发表主题id



    主题表:用于系统保存论坛主题基本信息。表结构如表9所示。



    列名
    数据类型
    长度
    主键?
    非空?
    自增?
    注释




    id
    bigint
    20



    主键


    title
    varchar
    50



    标题


    content
    longtext




    内容


    faceicon
    varchar
    50



    头像


    posttime
    datetime




    发表时间


    ipddr
    varchar
    50



    ip地址


    type
    int
    11



    主题类型


    replycount
    int
    11



    回复数量


    lastupdatetime
    datetime




    最后更新时间


    authorid
    bigint
    20



    用户id


    forumid
    bigint
    20



    版块id


    lastreplyid
    bigint
    20



    最后回复id



    回复表:用于系统保存主题回复基本信息。表结构如表10所示。



    列名
    数据类型
    长度
    主键?
    非空?
    自增?
    注释




    id
    bigint
    20



    主键


    title
    varchar
    50



    标题


    content
    longtext




    内容


    faceicon
    varchar
    50



    头像


    posttime
    datetime




    回复时间


    ipddr
    varchar
    50



    ip地址


    authorid
    bigint
    20



    用户id


    topicid
    bigint
    20



    主题id



    邮件表:用于系统保存邮件基本信息。表结构如表11所示。



    列名
    数据类型
    长度
    主键?
    非空?
    自增?
    注释




    id
    bigint
    20



    主键


    username
    varchar
    50



    发件人用户名


    password
    varchar
    50



    发件人密码


    server
    varchar
    50



    邮件服务器


    mailfrom
    varchar
    50



    发件邮箱


    mailto
    varchar
    50



    收件邮箱


    subject
    varchar
    50



    主题


    content
    content
    50



    内容


    date
    datetime




    发送时间


    userid
    bigint
    20



    用户id











    请假表:用于系统保存请假单基本信息。表结构如表12所示。



    列名
    数据类型
    长度
    主键?
    非空?
    自增?
    注释




    id
    bigint
    20



    主键


    days
    int
    11



    请假天数


    content
    varchar
    200



    请假内容


    leavedate
    datetime




    离开时间


    note
    varchar
    200



    备注


    state
    int
    11



    请假审批状态


    userid
    bigint
    20



    用户id



    4 系统实现4.1 开发环境
    操作系统:Windows 7
    网站服务器:Tomcat7.x
    数据库管理系统:MySQL5.x
    开发工具:jdk7.x myEclipse

    4.2 主要业务功能实现用户登录时,密码会进行md5加密,在数据库中验证,用户输入的验证码提交到后台,会与存储在session中的验证码进行比较,验证成功后则登录成功。登录界面如图8所示。

    baseDao的公共代码抽取项目中会用到很多实体,其中会涉及到很多的增删改查,可以通过反射技术将公共代码提取出来,核心代码如下:
    protected Class<T> clazz; public BaseDaoImpl() { ParameterizedType pt = (ParameterizedType)this.getClass().getGenericSuperclass(); this.clazz = (Class) pt.getActualTypeArguments()[0];}
    4.2.1 个人办公模块本模块主要是日程管理功能,使用jquery的FullCalendar插件实现,通过查看FullCalendar的官方文档,大体理解开发步骤。首先导入需要的FullCalendar的js,css文件,jquery.js文件。在fullCalendar中方法中进行日历的初始化及相应的算法操作。header:初始化日历头部信息,events:执行查询,dayClick:执行新建,eventClick:执行修改,eventDrop:执行拖动,eventResize:执行缩放。效果如图9所示。

    4.2.2 系统管理模块本模块包含基本的部门管理,管理员可以进行增删改查操作,通过系统的权限拦截,普通用户只有查看的权限。用户管理中,通过ajax技术检验用户名是否可用,通过js代码对所添加的各项信息进行正则验证,只有全部通过后才能向服务器提交数据,头像上传功能,使用apache commons-io的FileUtils.copyFile方法。用户列表显示界面,通过struts的迭代标签进行显示,效果如图10所示。

    岗位管理中,管理员有个设置权限功能,可以给用户分配相应的权限,受保护的权限采用jquery的treeview插件进行树形显示。效果如图11所示。

    具体细节:选中一个权限时,应该选中他的所有直系上级权限,选中他的所有直系下级;取消选择一个权限时,应该取消选择他的所有直系下级;如果同级的权限都是未选择状态,就应该取消选中他的直接上级,并向上做这个操作;全选/取消全选;默认选中当前岗位已有的权限。
    权限选择时的判断代码如下:
    $("[name=privilegeIds]").click(function(){ $(this).siblings("ul").find("input").prop("checked",this.checked); if (this.checked) { $(this).parents("li").children("input").prop("checked",true); }else { if ($(this).parent().siblings("li").children("input:checked").size() == 0) { $(this).parent().parent().siblings("input").prop("checked", false); var start = $(this).parent().parent(); if (start.parent().siblings("li").children("input:checked").size() == 0) { start.parent().parent().siblings("input").prop("checked", false); } } }});
    4.2.3 网上交流模块本模块主要实现了论坛功能和邮件功能如下:
    论坛功能,管理员可以实现版块的上下移动,实现思路:每个Forum的position都要有值,取本条数据的id值;显示数据时按position排序(升序);上下移动就是交换position的值,然后在重新排序。
    由于主题都有引用,删除时不直接删除回复,而是做一个已删除的标记,显示时还有此楼,不过把内容显示为“此帖已被管理员删除”。
    楼层显示策略:在显示回复列表时实时的计算出楼层。方式为:${(page.currentPage-1)*page.size+status.count}楼,根据楼层数值进行楼主,沙发,板凳,地板的显示主题排序策略:根据置顶帖,精华帖,普通帖和最后回复时间进行排序,对应hql语句为:from Topic t where t.forum=? order by (case t.type when 2 then 2 else 0 end) desc,t.lastUpdateTime desc。
    用户查看主题时,效果如图12所示。

    论坛会涉及到特殊属性的维护,如表13所示。





    说明
    发表新主题
    发表新回复




    Forum
    topicCount
    主题总数
    加1



    articleCount
    文章总数
    加1
    加1



    lastTopic
    最后回复主题
    更新为当前的新主题




    Topic
    replyCount
    回复总数
    0



    lastReply
    最后回复
    null
    更新为当前的新回复



    lastUpdateTime
    最后更新时间
    本主题的发表时间
    更新为当前的新回复的 发表时间



    用fckeditor插件,增加用户的体验效果。关键代码如下:
    var oFCKeditor = new FCKeditor( 'content' ) ; oFCKeditor.BasePath = "fckeditor/" ; oFCKeditor.ToolbarSet = "bbs" ;oFCKeditor.ReplaceTextarea();
    邮件发送,SMTP协议-发邮件协议,全称为Simple Mail Transfer Protocol(简单邮件传输协议),它定义了邮件客户端软件与SMTP服务器之间、以及两台SMTP服务器之间的通讯规则。端口一般为25。
    POP3协议-收邮件协议:全称为Post Office Protocol(邮局协议),它定义了邮件客户端软件与POP3服务器的通讯规则。端口一般为110。
    Session用于设置服务器,协议类型和密码等。表示会话,是JavaMailApi的最高层入口类。Session对像从Properties中获取信息,如IP、协议、用户名密码等。
    Javax.mail.Message类,它的一个重要子类为MimeMessage。Message类表示电子邮件的正文部分。一封电子邮件包含以下内容:地址信息、标题、日期、正文。
    Java.mail.Address:收件人地址,表示邮件的地址。常用的子类为:javax.mail.internet.InternetAddress。
    Javax.mail.Transport:负责发送邮件,指定邮件发送的协议。通常为SMTP。它的静态方法send(Message)负责发送邮件。
    4.2.4 审批流转模块通过myeclipse集成activiti5的 Activiti BPMN 2.0 designer,绘制请假流程图,并部署流程图到activiti5的工作流引擎中。部署一次会生成一个版本号,启动流程实例时,会启动最新的版本号,部署一次,可以执行多次请假。
    员工请假时先填写请假单,当申请时,会首先启动流程实例,通过startProcessInstanceByKey(pdkey,businessKey,user)启动,每个businessKey只能启动一次流程实例,所以businessKey可以通过pdkey和请假单id来组合。启动流程实例后,工作流引擎中就会生成流程实例,会生成相应的Task,通过piid和user可以获得对应的任务,在通过processEngine.getTaskService().complete()完成请假任务。请假任务完成后,首先更改请假单状态为正在审批,流程会执行到部门经理审批,由于部门经理是动态的,在绘图时指定一个ManagerTaskListener,这样流程到达时会触发此监听器,从而获得部门经理,执行审批流程。
    部门经理审批时,需要查询待办任务列表,获得所有的待办任务,通过Task可以获得piid,通过piid和办理人则可以确定申请人,请假单,首先在前端页面进行请假信息的回显,部门经理可以添加自己的审批信息,并提交。审批信息会保存到act_hi_comment表中,后台完成任务的同时,添加批注: processEngine.getTaskService().addComment(task.getId(),processInstance.getId(), manageNote);流程执行到总经理审批。
    总经理审批时,需要获得请假单信息,部门经理审批结果等信息,并添加自己的审批结果,后台处理完后,更新请假单状态为审批完成。总经理审批界面如图13所示。

    在请假单审批过程中,员工可以通过查看流程图,来查看审批进度;可以查看审批结果看申请是否通过。员工在查看流程图时,后台会根据请假单id得到businessKey,从而得到pdid,piid,在获得当前的执行节点:
    ProcessDefinitionEntity processDefinitionEntity=(ProcessDefinitionEntity) processEngine.getRepositoryService().getProcessDefinition(pi.getProcessDefinitionId());ActivityImpl actImpl=processDefinitionEntity.findActivity(pi.getActivityId());
    jsp页面上通过pdid获得图片输出流,div标签对当前节点进行加上红色边框:
    <img src="leaveApply_getProcessPic?procDefId=${procDefId}" style="position:absolute; left:0px; top:0px;"> <div style="position:absolute; border:2px solid red;left:${coordinateObj.x-1 }px;top:${coordinateObj.y-1 }px;width:${coordinateObj.width }px;height:${coordinateObj.height }px;"></div>
    员工在查看流程图时,效果如图14所示。

    员工在查看审批结果时,后台会根据businessKey获得HistoricProcessInstance,再获得HistoricActivityInstance,通过HistoricActivityInstance获得Task,最终获得所有的Comment,员工通过查看页面的审批结果,可得知自己请假是否被批准。
    4.3 基于角色的权限设计与实现项目中会涉及到用户,部门经理,管理员等多个角色,所以必须基于角色提供一个左侧的动态树形菜单,在添加用户时为其赋予相应的角色,在用户登录时,通过其对应的角色相关联的权限进行菜单的显示。为了提高效率,减少对数据库的访问次数,项目中使用缓存技术,在项目启动时将所有的权限集合查询出来缓存在项目中,以后用户登录时直接在缓存中查找即可。
    左侧菜单中只显示到2级菜单,3级菜单中的权限通过tag替换技术实现显示与否,重写struts的s:a标签,在项目下添加org.apache.struts2.views.jsp.ui.AnchorTag,这样在项目启动后会加载自定义的struts标签了,标签判断权限关键代码:
    public int doEndTag() throws JspException { User user=(User) pageContext.getSession().getAttribute("user"); String privilegeUrl; if(action!=null){ privilegeUrl=action; }else{ privilegeUrl=includeParams; } int pos=privilegeUrl.indexOf("?"); if(pos>-1){ privilegeUrl=privilegeUrl.substring(0,pos); } if(user.hasPrivilegeByUrl(privilegeUrl)){ return super.doEndTag(); }else { return EVAL_PAGE; }}
    为了系统的安全,静态页面放入WEB-INF目录下,受servlet的安全机制保护,不可以输入地址直接访问,但是还需要对action进行访问拦截。拦截器需要继承AbstractInterceptor,通过ActionInvocation获得访问地址,判断当前用户是否登录,若没登录,返回登录界面;若用户已经登录,则需判断是否有改url的访问权限,若有,让其访问,若无,让其返回原始页面。
    5 系统测试系统测试,英文是System Testing。是将已经确认的软件、计算机硬件、外设、网络等其他元素结合在一起,进行信息系统的各种组装测试和确认测试,系统测试是针对整个产品系统进行的测试,目的是验证系统是否满足了需求规格的定义,找出与需求规格不符或与之矛盾的地方,从而提出更加完善的方案。系统测试发现问题之后要经过调试找出错误原因和位置,然后进行改正。是基于系统整体需求说明书的黑盒类测试,应覆盖系统所有联合的部件。对象不仅仅包括需测试的软件,还要包含软件所依赖的硬件、外设甚至包括某些数据、某些支持软件及其接口等。
    5.1 系统测试的原则
    测试工作应该是采用普通用户来进行盲目测试,让这些没有接触过项目的人进行随即测试
    设计测试方案时,要验证输入数据的格式,以及是否有权限的设置,确保这些数据是在系统中是否有效
    测试用例要考虑每一种发生的情况,每种情况包括正常的情况和不正常的情况
    不仅要检验程序是否做了该做的事,还要检查程序是否同时做了不该做的事
    保留测试用例,作为系统文档的组成部分

    5.2 系统测试用例为保证系统的正常使用,对系统进行了大量的测试,其中部分测试用例如表14-18所示。
    登录测试用例



    功能描述
    登录界面





    用例目的
    测试用户能否正常登录



    前提条件
    登录界面正常运行



    输入/动作
    期望的输出/相应
    实际情况


    用户名:user1,密码:123, 验证码:2567
    登录失败
    用户名或密码错误!


    用户名:user1,密码:123456, 验证码:2567
    登录失败
    验证码错误!


    用户名:user1,密码:123456, 验证码:5512
    登录成功
    与期望吻合



    论坛测试用例



    功能描述
    论坛测试





    用例目的
    测试用户能否正常使用论坛功能



    前提条件
    系统正常运行



    输入/动作
    期望的输出/相应
    实际情况


    点击论坛进行查看
    可以看到论坛主题内容
    正常查看


    点击发表主题
    可以发表主题
    正常发表,吻合


    点击主题名称,查看主题内容
    可以查看主题内的所有回复
    功能正常,吻合


    点击回复,发表回复
    正常发表回复,fakeditor插件功能正常
    与期望吻合


    多次点击回复,发表回复
    分页正常,楼层显示正常
    与期望吻合



    员工请假测试用例



    功能描述
    登录界面





    用例目的
    测试员工能否正常使用请假功能



    前提条件
    系统正常运行,员工拥有请假权限



    输入/动作
    期望的输出/相应
    实际情况


    员工点击请假
    正常显示请假单
    正常显示


    员工填完请假单后,点击提交
    正常保存
    正常


    员工点击申请
    申请正常
    与期望吻合


    员工点击查看流程图
    正常显示流程图,高亮显示执行的节点
    查看流程图正常


    员工点击查看审批结果
    可以看到审批结果
    与期望吻合



    部门经理审批请假单测试用例



    功能描述
    登录界面





    用例目的
    测试部门经理能否正常审批请假单



    前提条件
    系统正常运行



    输入/动作
    期望的输出/相应
    实际情况


    部门经理点击办理
    显示请假单详细
    正常显示


    部门经理填完批注后点击提交按钮
    正常办理任务
    办理任务正常



    总经理审批请假单测试用例



    功能描述
    登录界面





    用例目的
    测试总经理能否正常审批请假单



    前提条件
    系统正常运行



    输入/动作
    期望的输出/相应
    实际情况


    总经理点击办理按钮
    显示请假单详细,和部门经理审批结果
    显示正常


    总经理点击办理按钮
    正常办理任务
    办理任务正常



    6 总结本系统采用了ssh,activiti5等技术,实现了OA系统的设计与开发,主要有用户管理、论坛、日程、审批流转等功能。在日程管理上,使用了日历插件开发,增强了页面的显示效果及用户体验。在请假审批流程中,使用activiti5开发,用户可以时时查看请假进程。在系统的开发过程中,我进一步熟悉了系统建模流程,数据库优化技术,编码能力也有了很大的提高。
    由于开发设计能力有限,开发经验不足,系统仍存在很多不足:

    系统采用配置文件方式开发,造成配置文件内容臃肿
    审批流转模块还需要添加报销审批等功能

    在以后的学习及项目开发中,我会积极吸取本次开发积累的经验,努力开发出更好的项目。
    参考文献[1] 刘晓华. JSP应用开发详解[M]. 北京:电子工业出版社,2007:76-85.
    [2] 王立. UML与软件工程基础[M]. 北京:高等教育出版社,2004:33-55.
    [3] 叶达锋. Eclipse编程技术与实例[M]. 北京:人民邮电出版社,2006:23-32.
    [4] 王中兵. Java Web主流框架整合[M]. 北京:电子工业出版社,2008:55-86.
    [5] 范斯瓦尼. MySQL 完全手册[M]. 北京:电子工业出版社,2005:67-156.
    [6] 张基温,曹渠江. 信息系统开发案例[M]. 北京:清华大学出版社,2003:23-45.
    [7] 丁宝康. 数据库实用教程[M]. 北京:清华大学出版社,2003:342-376.
    [8] 郑玲. 计算机专业毕业设计指导[M]. 北京:清华大学出版社,2007:123-143.
    [9] 蔡剑,景楠. Java Web应用开发[M]. 北京:高等教育出版社,2005:24-78.
    [10] 邱哲,马斗. Struts设计开发大全[M]. 北京:清华大学出版社,2006:212-232.
    [11] 耿祥义,张跃平. JAVA 2实用教程[M]. 北京:清华大学出版社,2004:343-384.
    [12] 刘晖. 基于B/S架构的OA办公平台的设计与实现[D]. 河北:河北科技大学,2008:15.
    [13] 田华. 基于工作流和b/s结构的oa系统研究[D]. 青岛:青岛大学,2012:10.
    [14] 金庆勇. B-S模式的可扩展OA系统研究设计与实现[D]. 北京:北京化工大学,2009:12.
    1 评论 3 下载 2019-05-17 11:24:52 下载需要17点积分
  • 基于WinPcap的网络包截获和分析系统

    前言1,基于WinPcap的网络包截获和分析系统2,需要安装winpcap包,WinPcap中文技术文档 http://www.ferrisxu.com/WinPcap/html/main.html3,配置winpcap编程环境(VC6.0 或者VS2008)可参见 开发文档或者 google “vc++ winpcap配置”4,程序使用的皮肤库为 skin#
    可执行程序Npcas.exe在Release 目录下(程序运行在windows平台下),使用程序前需要安装winpcap。
    摘要​ 随着计算机网络技术的飞速发展,网络为社会经济做出越来越多的贡献,可以说计算机网络的发展已经成为现代社会进步的一个重要标志。但同时,计算机犯罪、黑客攻击、病毒入侵等恶性事件也频频发生。网络数据包捕获、监听与分析技术是网络安全维护的一个基本技术同时也是网络入侵的核心手段。通过基于网络数据包的截获和协议分析,对网络上传输的数据包进行捕获,可以获取网络上传输的非法信息,对维护网络安全起到重大作用。
    ​ 本论文依次介绍了网络包截获和分析的研究背景和意义、WinPcap技术介绍及系统开发坏境搭建、系统开发的理论基础、系统的分析与设计、系统的实现方法、系统的测试等。
    ​ 系统提供了网络数据包的捕获、网络协议分析、包捕获过滤设置等功能模块。最终利用VC++实现了基于WinPcap的包截获和分析系统,该系统可以捕获链路层的数据包如Ethernet II,网络层的数据包如IP、ARP / RARP、ICMP,传输层的数据包如TCP、UDP,应用层的数据包如HTTP、DNS。此外系统可以对网络数据包进行细粒度的分析和原始数据包的再现。
    1 系统分析与设计1.1 系统需求分析
    支持多种网络接口的包捕获(以太网,令牌环网,ATM…);及时有效的捕获网络上传送的数据包,高效的处理捕获到得数据包并友好的显示给用户,让用户捕获到他想要的数据;能够保存实时捕获到的网络数据包,供以后系统进一步参考和考证;可以设置过滤规则,减少捕捉的包的容量;可以捕获多种协议的网络数据包,并且软件系统能够提供和用户交流的平台,达到和用户互动的效果,并能够及时改正软件系统的不足之处;良好的图形界面,让用户用起来方便和良好的视觉体验;
    1.2 包截获与分析的基本过程系统基本流程概括如下:
    ① 选择网络接口,首先获得主机的网络设备列表,然后用户通过列表选择自己需要截获哪个网络接口上的网络数据包。
    ② 编译、设置过滤规则,用户如果想捕获特定的网络数据包,就需要设置过滤规则,过滤规则其实就是一个字符串,在WinPcap中使用函数pcap_compole()和pcap_setfilter()分别编译和设置过滤规则。
    ③ 开始捕获网络数据包,循环捕获网络数据包。
    ④ 保存捕获到的数据,根据用户要求实时保存截获的网络数据包,方便进一步的考证。
    ⑤ 处理捕获到的网络数据包,对捕获的网络数据包进行分解处理,从链路层到应用层,层层分解处理。
    ⑥ 把第5步中层层分解得到的数据包信息显示到软件界面,并且根据用户的一些要求细化所截到数据包信息的显示。
    本系统的包截获和分析的基本过程简化为下图所示。

    1.3 系统功能模块设计​ 此系统主要包括六大模块,如图:

    网络包截获模块:
    ​ 用一个线程来捕获网络数据包和协议分析。此模块主要是完成了网络接口的选择,编译过滤规则并设置过滤规则和网络数据包的实时捕获,并且实时保存截获到的网络数据包(注:此时主要把截获到的网路数据包保存到临时的缓冲文件中temp.pcap)。
    网络数据包分析模块:
    ​ 在这一模块中主要对上一模块中捕获的网络数据包进行协议分析。由于TCP/IP采用分层的结构,这样在传输数据的时候,在网络接收端是分解的过程,而发送端是一个封装的过程。
    要发送一个数据包,数据包必须进行层层封装,最终形成以太网数据最终发送到网络物理介质上进行传送。当接收数据包是与发送相反。通过封装,分解,并根据报文的协议字段或标识字段进行协议的分析,最终能够分析以太网Ⅱ、IP,ARP/RARP、ICMP、TCP、UDP、HTTP、DNS等协议。
    截获的数据包保存、打开模块:
    ​ 在这个模块中主要完成对实时截获到的网络数据包进行保存,其根据用户需要把文件保存到具体什么位置,然后保存此文件。打开文件模块主要是创建一个文件打开线程,对脱机文件进行网络协议的分析,并把分析结果准确的显示给用户。
    过滤规则设置模块:
    ​ 过滤规则设置模块主要在系统工作前的过滤规则设置,此模块可以记录一些常用的过滤规则名和过滤语句,并且应该能够编辑和删除相应的过滤规则。当用户选定某一常用过滤规则或者填写自己的过滤语句后单击”开始”按钮后,系统能及时反映此过滤规则是否符合过滤语句语法。
    网络数据包显示模块:
    ​ 系统截获网络数据包是为了显示截获的数据,此模块能够高效及时显示所截获的网络数据包,并能够通过列表,树图,编辑框等多种形式显示给用户,让用户更直观的了解捕获到的网络数据包。当用户选择其要查看的网络信息的某条信息时能够对词条信息进行详细显示。
    软件界面设计模块:
    ​ 好的软件系统不仅有较好的功能,并且需要有友好的界面,和不同的界面显示给用户,用户根据自己的喜好可以更改自己的软件界面。
    1.4 系统的配置设计由于系统要用到一些动态链接库和皮肤库,和过滤规则库,因此能够设计好良好的系统配置信息是必须的。此系统将把所有需要的动态链接库和配置文件放在config目录下,而所需要的系统皮肤文件放在skin目录下。系统启动之前必须具备这两个目录下的文件。否则将达不到预期的系统效果。
    2 系统实现2.1 模块功能介绍本系统是基于WinPcap的网络包截获与分析系统。根据课题设计需要实现的功能如下:
    ① 网络包截获模块。可以截获经过此主机的网络数据包。
    ② 网络协议分析。此模块可以对不同层的网络协议的分析。
    ③ 过滤规则设置模块。此模块可以设置常用规则并且可以直接设置规则进行相应的包截获过滤语句的设置。
    ④ 网络数据包显示模块。此模块可以有多种方法层次化的显示所截获的网络数据包,包括列表形式的显示,树形显示,编辑框显示等,让用户直观的获得所截获的网络数据包协议信息。
    ⑤ 能够实时保存捕获到的网络数据,并且用户可以选择保存到自己想保存的目录下。此外用户可以根据需要打开以前截获到的.pcap文件,实现数据分析和取证。
    ⑥ 软件界面设计模块,此模块能够满足用户换肤,程序托盘,有一个比较好的图形界面接口呈现给用户。
    2.2 功能实现方法在这一小节中,介绍了系统的主要的功能模块和其实现方法的大致描述,详细内容请见本系统的源代码,系统源代码已经做了比较详细的注解。
    2.2.1 系统基本要素此系统无需安装,只要系统必需要素具备即可运行。其中config目录下有filter.ini配置文件及SkinH.dll动态链接库。skin目录下为系统所需的皮肤文件。
    系统基本要素如图所示。

    2.2.2 系统启动界面系统启动时动画界面显示启动界面。

    实现方法:
    方法其实比较简单,创建一个兼容的内存DC放置位图,把启动画面分成一个大网格,一个20*20的网格,每个网格内存放分割的位图,并用数组记录已显示过的位图。何时显示哪个小网格中的图片则采用随机数(两个1 – 20
    的随机数,这样就可以用二维数组来记录是否显示过此位图),所以感觉是动画的。
    2.2.3 系统换肤和良好的图形界面
    上图 所示这是系统的工作界面。此系统可以根据自己的喜好实现系统皮肤的切换。点击系统右上方的图标即可实现系统的换肤,如下图所示。

    实现方法:
    实现由美丽的程序界面和换肤的功能其实也不是太复杂。主要借助第三方库,此系统借用的是比较好用的skin#库,下载此库的.dll文件和你喜好的皮肤库。
    此系统我们采用程序运行时动态链接的方法加载皮肤库。
    /*宏定义函数指针类型 */typedef int ( WINAPI *SKINH_ATTACHEX)(LPCTSTR strSkinFile,LPCTSTR strPassword);// 取得SKINH_ATTACHEX函数的地址SKINH_ATTACHEX pSkinFun=(SKINH_ATTACHEX)::GetProcAddress(LoadLibrary("config\\SkinH.dll"),"SkinH_AttachEx");
    2.2.4 过滤规则设置模块 在开始捕获数据包前可以根据自己的需要来设置自己想要的数据包过滤语句,单击过滤规则模块如下图所示。可以根据自己的需要添加和删除自己的过滤规则。

    实现方法:
    先定义一个关于过滤规则的结构体如下:
    typedef struct FILETER_ { char FilterName[256]; // 过滤规则名称 char FilterValue[256]; // 过滤规则语句表达式 // 重载赋值运算符 const FILETER_ & operator=( const FILETER_ temp ) { ZeroMemory(FilterName,256); ZeroMemory(FilterValue,256); strcpy(FilterValue,temp.FilterValue); strcpy(FilterName,temp.FilterName); return *this; } }FILETER_DATA ,*PFILETER_DATA;
    然后定义一个此结构体类型的向量typedef vector<FILETER_DATA> Filter_Vector。
    当用户设置过滤规则时,通过LoadUserFilter()函数加载用户自己的过滤规则库,其中此函数为自己实现的,为从一个我们之前定义的配置文件中读取常用规则并写入到向量Filter_Vector 中,并显示在我们的窗口上。用户可以添加和删除常用规则,此时同时反映在Filter_Vector中,当用户退出过滤规则设置时对话框时系统将同时读取到过滤语句,并且通过我们自定义的SaveUserFilter()把我们的过滤规则存回配置文件.ini中。配置文件的功能主要用到win API GetPrivateProfileString 和WritePrivateProfileString。
    帮助模块的功能实现方法比较简单,实现连接到网站的功能主要利用到了Win API ShellExecute函数实现,其它的实现方法不再敷述。
    2.2.5 截获的包保存和文件打开模块此模块能够实时保存捕获到的网络数据,并且用户可以选择保存到自己想保存的目录下。此外用户可以根据需要打开以前截获到的.pcap文件,实现数据分析和取证。
    效果如下图所示。


    实现方法:
    保存文件:首先就是在截获网络数据包时,把截获到的网络数据包实时的保存到临时的缓冲文件temp.pcap中,然后根据用户是否保存文件,若用户选择保存此文件到一个指定的路径下,则系统创建一个CFileDialog文件对话框,获得用户指定的路径及文件名,然后把保存的缓冲临时文件拷贝到用户指定的目录下,这个主要利用函数CopyFile()来实现。这样即可实现文件的保存。
    打开文件:它的实现方法主要是创建一个文件读取线程ThreadReadFile(),这个线程中主要函数为DumpFileOperation(),在这个函数中首先创建一个CFileDialog文件对话框,然后根据用户的选择的文件利用GetFileName()函数获得文件路径及名字,然后就是根据WinPcap的编程模型的一些具体的常见步骤,最后pcap_loop()读取真正的网络数据文件,在这个pcap_loop()函数里我们定义了ProcessProtocolPacketFromDumpFile()这个回调函数。这个回调函数里包括原始的数据包,并且实现了对其的解析。详见下一小节的数据包分析功能模块。
    2.2.6 包截获和分析功能模块系统使用多线程技术,来实现捕获数据包和数据包的显示同步进行,提高系统的性能。
    此模块主要实现了网络数据包的截获和分析。过滤规则设置后,单击系统的开始按钮选择所需监听的网卡。如下图所示,系统把所截获的信息实时的显示给用户,用户可以根据自己的需要查看相应的协议数据信息。

    实现方法:
    数据包的捕获主要采用WinPcap编程技术实现的,然后对捕获到的数据包进行各种协议的分析,把分析的网络信息显示在主程序界面中。本模块主要采用多线程技术,创建一个线程用来捕获数据包和协议分析,然后把协议分析结果传送给网络数据包显示模块。
    ​ 其中文件Protocol.h中主要定义了相关协议的数据结构,文件sniffer.h定义了捕获线程和分析数据包所用到的自定义的原始数据包结构。此功能模块主要的核心功能函数的调用过程如下图所示。

    在网络数据包协议解析和数据包的信息显示中有一个比较重要的数据结构如下:
    //程序内部保存的数据包结构,即原始数据typedef struct{ pcap_pkthdr PktHeader; //包头部信息结构指针 u_char* pPktData; //包数据指针 u_int ip_seq; //网络层截获的包Ip序号 u_int tcpOrUdp_seq;//传输层截获的包序号} RAW_PACKET;
    这个RAW_PACKET结构记录了所捕获的网络数据包的原始数据以及它的网络层、传输层的包序号(即在列表框中已经解析的协议),这样当再次解析这个原始数据包时就可以直接调用之前已经解析过的信息,这样可以达到功能复用的效果,提高程序的效率。
    下面具体介绍包截获和分析线程的具体实现方法:
    首先创建一个包捕获线程:UINT ThreadPacketCapture(LPVOID pParam);
    在这个函数里我们定义一个包捕获函数CapturePacket(),在这个函数里我们按照WinPcap捕获数据包的方法进行编程(详细请见系统源码,在此不再敷述),在CapturePacket()函数中比较实质的网络数据包捕获函数就是pcap_loop()函数,它实现了循环捕获网络数据包。int pcap_loop(pcap_t p, int cnt, pcap_handlercallback, u_char user);
    这个函数参数p表示WinPcap句柄,cnt表示捕获的个数,负数表示无限捕获,参数callback表示回调函数(注意着个函数很重要,稍后再介绍),user表示传递给回调函数的参数,如果无就无NULL,回调函数我们定义为typedefvoid (pcap_func_t)(unsigned char , const struct pcap_pkthdr, const u_char)这样的类型,第一个参数就是从pcap_loop中传进来的用户参数,第二个参数就是捕获到的网络数据包的简单信息,是由WinPcap设定的,有数据结构pcap_pkthdr表示,第三个参数表示捕获到的真正的网络数据包,它存储了网络数据包的原始数据,后面所有的分析其实就是对这个原始数据包进行分析。
    ​ 在包截获函数CapturePacket()中我们定义一个pcap_handler类型的句柄变量Handler,我们把这个变量赋值为我们自定义的pcap_loop()的回调函数的指针并调用它如下代码所示:
    /* 每次捕获到数据包时,libpcap都会自动调用这个回调函数 */ Handler = (pcap_func_t)ProcessProtocolPacket; /* 开始捕获 */ pcap_loop(PcapHandle, number, Handler, (unsigned char *)PcapFile);
    在回调函数ProcessProtocolPacket(unsigned char user,const struct pcap_pkthdr h,const unsigned char* packetdata)中我们把截获到的数据包(即此函数第2、3个参数所包含的数据)保存到在堆中申请的内存中(此时用用到自定义的数据结构RAW_PACKET中),此时我们就有了捕获到的这个数据包的简单信息和存放自定义数据结构信息在堆的指针,然后调用ParseEthernet(packetdata, pRawPacket)函数分析截获到的以太帧数据,在函数ParseEthernet()中可以进行IP,ARP等网络层的协议分析,依次类推我们可以根据本层的协议字段来进一步分析传输层、应用层的协议信息。具体请见sniffer.cpp文件中的线程函数和数据包分析函数。
    4.2.7 数据包分析结果显示功能模块本系统采用三种形式把数据显示给用户,首先用户可以根据自己的需要点击Tab页的网络协议按钮,查看各个网络层次的网络协议。相关的指定的协议信息在列表框中分条显示出来。其次用户可以在列表框框中选择自己需要查看的某条网络数据包的详细信息,鼠标单击此条即可查看此条数据包的相对完整信息,即从链路层的网络信息到你所查看的协议层的信息或者全部的链路层包括所负载的网络信息。用户可以单击右键复制你所需要的某一列的信息。最后用户可以单击左下角树图控件的节点查看比较具体协议信息的解析。用户可以鼠标双击树节点,这样可以在右下角的编辑控件中的十六进制字码中查看原始的网络数据包(分别是相应的十六进制和可显示字符),此时的原始数据包在编辑框中被选中,这样方便用户进行网络协议的分析。如下图所示。

    实现方法:
    在分析网络协议信息时要把协议信息实时的显示到程序的界面。我们用自定义消息来实现,一共定义了有关协议显示的9条消息。当捕获到数据包后就对其进行相应的协议分析,然后通过发送自定义的消息通知程序界面模块显示分析后的协议数据。自定义消息如下:
    #define WM_MY_MESSAGE_COMMON (WM_USER+100) //显示数据包一些常用的协议消息#define WM_MY_MESSAGE_ARP (WM_USER+101) //显示ARP/RARP协议信息消息#define WM_MY_MESSAGE_IP (WM_USER+102) //显示IP协议信息消息#define WM_MY_MESSAGE_TCP (WM_USER+103) //显示TCP协议信息消息#define WM_MY_MESSAGE_UDP (WM_USER+104) //显示UDP协议信息消息#define WM_MY_MESSAGE_ICMP (WM_USER+105) //显示ICMP协议信息消息#define WM_MY_MESSAGE_ETHERNET (WM_USER+106)//显示以太网信息消息#define WM_MY_MESSAGE_HTTP (WM_USER+107) //显示HTTP协议信息消息#define WM_MY_MESSAGE_DNS (WM_USER+108) //显示DNS协议信息消息
    这些自定义的消息有自己自定应的函数,比如WM_MY_MESSAGE_ETHERNET对应的消息自定义函数消息映射ON_MESSAGE(WM_MY_MESSAGE_ETHERNET, OnEthernet)可以知道当操作系统捕获到WM_MY_MESSAGE_ETHERNET消息就会调用OnEthernet函数在对应的Tab页(即以太网信息Tab也)中的列表框中显示详细的协议解析信息。其它的协议显示过程和此同理。
    在协议分析过程中,以太网协议分析是第一步。首先分析以太网协议部分,然后根据以太网中的协议字段再分析其它的协议数据。比如在2.2.6小节中ParseEthernet(packetdata, pRawPacket)函数,首先强制转化指向自定义的数据结构指针的参数pRawPacket,LPARAM lp=(LPARAM)pRawPacket(这样为了PostMessage),此时向系统发送消息,表示截获到以太帧,::PostMessage(g_hWnd, WM_MY_MESSAGE_ETHERNET, 0, lp),其中g_hWnd为系统主界面窗口句柄,他将捕获到的以太消息放入到与主界面线程相联系的消息队列里,用来显示其协议信息。参数lp即是指向堆中的原始网络数据包指针,它在显示函数中会用API SetItemData()添加附加据,即将列表项与存放原始数据包的堆地址指针关联,这样为了方便以后的处理某一列显示在树控件和编辑框中所用。
    ​ 此外当系统分析到网络层、传输层,在显示函数如OnIp()、OnTcp ()、OnUdp(),中修改pRawPacket所指结构RAW_PACKET中的ip_seq,tcpOrUdp_seq的序号(它们即是这个pRawPacket所指原始数据包中对应的数据包的网络层、传输层在对应Tab中的某一行的序号),这样当再使用这个原始数据包时,可以通过对应协议的Tab页中的列表框直接使用已经解析过的数据包结果,可以提高程序的效率达到复用的效果。
    ​ 当用户单击列表框的某一行时,系统就处理相应的NM_CLICK消息事件,在处理鼠标单击事件的函数中调用显示数据包信息的函数比如ShowPacketInfo(RAW_PACKET* pRawPacket)、ShowIpInfo(int nItem)、ShowTcpInfo(int nItem)、ShowUdpInfo(intnItem)等来进一步详细的显示包信息。
    ​ 其中ShowPacketInfo()就是通过我们关联到列表框每一行的原始数据来进行树控件中MAC的显示,以及右下角编辑框中的原始数据的显示,ShowIpInfo()、ShowTcpInfo()、ShowUdpInfo()函数则利用我们定义的RAW_PACKET结构中的ip_seq,tcpOrUdp_seq序号来直接读取列表框中的关于此数据包中网络层或者传输层的协议分析结果,把从列表框中读取的信息显示到左下角的树控件中去,这样做就可以把列表框中某一行的数据包信息更精细的显示到树控件和编辑框中。
    参考文献:http://www.ferrisxu.com/WinPcap/html/main.html
    [1] The WinPcap Team .WinPcap中文技术文档. Torino:CACETechnologies,Translated By CoffeeCat Studio 2007.7
    [2] 郭军. 网络管理(第3版).北京:北京邮电大学出版社,2008.3
    [3] 武孟军、等. Visual C++开发基于SNMP网络管理软件(第2版)..北京:人民邮电出版社,
    2009.4
    [4] 王艳平. Windows 网络与通信程序设计.北京:人民邮电出版社,2009.4
    [5] 侯俊杰. win32多线程编程.武汉. 华中科技大学出版社,2002.1
    [6] 辛长安.VisualC++权威剖析—MFC原理、机制与开发实例.清华大学出版社, 2008-4-25
    [7] 胡滨.基于Windows平台的底层数据包截获技术[J].计算机工程与设计.2005(11):179-180,223
    [8] 谢希仁.计算机网络(第五版).北京:电子工业出版社,2008.1
    0 评论 0 下载 2019-05-17 11:23:47 下载需要9点积分
  • 基于C语言实现的图书管理系统

    一、设计目的通过C语言实现图书管理的功能,而且能够实现账户的注册、登录、以及账户权限的区分,比如在管理员权限下的增加图书、查找图书、修改图书信息、删除单个图书信息、借书功能、快速还书、还有全部删除、一键保存的功能。这些基础的功能都是管理员管理时使用的实用功能。当然对于用户即同学来说,功能限制到只有查找、借书、还书三大功能!因为对于用户来说他的权限不足以支持他做出破坏数据的操作。
    二、设计内容
    登录程序管理员登录:新增图书;查询图书;修改图书;删除图书;借出图书;归还图书;全部删除;一键保存;退出程序用户登录:查询图书;借出图书;归还图书;退出程序
    注册账号管理员注册用户注册
    退出程序

    三、概要设计功能模块图如下所示:

    3.1 各个模块详细的功能描述。登录功能
    登录界面时一样,管理员与用户没有区别,但是登录成功时,系统将会根据权限生成不同的使用界面,以及功能限制。

    管理员功能
    管理员权限为高级,管理员可以对图书数据进行一系列的管理:

    新增图书时可以进行添加图书的各种信息查询图书时可以对书号、书名、作者、出版社、类别进行模糊搜索,届时所有符合条件的结果都会出现修改时只能对某一确定的书籍进行修改,以具体的书号或书名进行检索,可以在修改时跳过某项即不修改删除图书与修改时相同,只能对某一确定书籍进行删除操作借出图书时对某一确定书籍进行检索,如果借出会提示借出,并显示归还时间,否则将只需要输入归还时间,借出时间自动生成为当天时间归还时只需要将归还的图书书名输入即可归还图书全部删除时会进行最多三次的询问,询问是否继续删除,防止误删操作一键保存会将所有图书信息保存在固定的位置退出程序将会退出使用

    用户功能
    用户功能由于权限不同、其他功能不对用户开放,用户也不能按对应的键进行操作。

    注册账号
    注册账号时有两种注册方式、管理员注册、用户注册,但是其实在输入昵称,密码时候都是同样的,两次密码不一致会进行重新输入,且密码必须大于6位小于等于16位。当注册时会提示是否为管理员,如果是管理员则会要求输入管理员内码,否则直接跳过提示是否注册,这时系统会自动生成一个账号,然后返回登录注册界面。

    四、详细设计4.1 功能函数的调用关系图
    4.2 各功能函数的数据流程图struct book *read() //读取文件中信息到链表

    struct book *creat(int j,int k,int type,struct book *goost)//插入数据到链表,新增图书

    void visitall()//查询某一本书的信息

    int compare(char str[],struct book *key)//返回1表示条件符合模糊,0不符合

    void deletebook(int type)//删除图书//type表示删除类型//1为单个删除//2为全部删除

    4.3 重点设计及编码//返回1表示条件符合模糊,0不符合int compare(char str[],struct book *key) { int size,sizenumber,sizename,sizekind,sizeadress,sizeauthor,i,j,success[5]= {0,0,0,0,0}; size=strlen(str);//获取关键信息的长度 sizenumber=strlen(key->number);//获取书号的长度 sizename=strlen(key->name);//获取书名的长度 sizekind=strlen(key->kind);//获取类别的长度 sizeadress=strlen(key->adress);//获取出版社的长度 sizeauthor=strlen(key->author);//获取作者的长度 for(i=0;i<sizenumber-size+1;i++)//对书号进行模糊判定 { success[0]=1; for(j=0;j<size;j++) { if(str[j]!=key->number[j+i]) { success[0]=0; } } if(success[0]==1) { break; } } for(i=0;i<sizename-size+1;i++)//对书名进行模糊判定 { success[1]=1; for(j=0;j<size;j++) { if(str[j]!=key->name[j+i]) { success[1]=0; } } if(success[1]==1) { break; } } for(i=0;i<sizekind-size+1;i++)//对书类进行模糊判定 { success[2]=1; for(j=0;j<size;j++) { if(str[j]!=key->kind[j+i]) { success[2]=0; } } if(success[2]==1) { break; } } for(i=0;i<sizeadress-size+1;i++)//对出版社进行模糊判定 { success[3]=1; for(j=0;j<size;j++) { if(str[j]!=key->adress[j+i]) { success[3]=0; } } if(success[3]==1) { break; } } for(i=0;i<sizeauthor-size+1;i++)//对作者进行模糊判定 { success[4]=1; for(j=0;j<size;j++) { if(str[j]!=key->author[j+i]) { success[4]=0; } } if(success[4]==1) { break; } } if((success[0]+success[1]+success[2]+success[3]+success[4])!=0)//如果有一项满足情况,则返回1,否则即所有项都不符合,则返回0 { return 1; } else { return 0; }}
    //在合适合法输入字符串//i,j表示光标的定位//type表示要求达到的目的 void cuowu(int i, int j,int type,char str[]){ char str1[40];//定义中间传递字符串 fflush(stdin); if(type==0)//类型0表示字符串内没有值,输入回车光标返回继续执行输入 { gotoxy(i,j); gets(str1); while (str1[0] == 13 || str1[0] == 10 || str1[0] == 0) { gotoxy(i, j); gets(str1); fflush(stdin); } sprintf(str,"%s",str1);//将合法字符串打印到目标字符串 } else//类型为1表示目标字符串有值,回车后跳过输入,进入下一个 { gotoxy(i,j); gets(str1); if(str1[0]!=13&&str1[0]!=10&&str1[0]!=0) { sprintf(str,"%s",str1); } } fflush(stdin);}
    //头插法//i,j定位光标//type为类型//1为输入//2为修改//3为借出,通过输入type使三个功能合而为一,公用代码!struct book *creat(int j,int k,int type,struct book *goost) { struct book *pnew; time_t timep; struct tm *p; int howtype=0;//区别的输入类型变量 if(type==1||type==2) { if(type==1)//1时进行输入操作,创建新的链表节点,并提示输入 { pnew=(struct book*)malloc(sizeof(struct book)); book_num++; if(book_num==1) { phead=pnew; phead->next=NULL; phead->last=NULL; } else if(book_num==2) { phead->next=pnew; pnew->last=phead; pnew->next=NULL; } else { pnew->next=phead->next; phead->next->last=pnew; pnew->last=phead; phead->next=pnew; } gotoxy(k,j++); printf("书号:"); gotoxy(k,j++); printf("书名:"); gotoxy(k,j++); printf("作者:"); gotoxy(k,j++); printf("类别:"); gotoxy(k,j++); printf("出版社:"); gotoxy(k,j++); printf("价格:"); gotoxy(k,j++); printf("是否借出?(在库为是;借出为否):"); } else { howtype=1;//通过howtype进行控制输入的方式,即修改时与新增数据的不同 } cuowu(k+6,j-7,howtype,pnew->number); cuowu(k+6,j-6,howtype,pnew->name); cuowu(k+6,j-5,howtype,pnew->author); cuowu(k+6,j-4,howtype, pnew->kind); cuowu(k+8,j-3,howtype, pnew->adress); cuowu(k+6,j-2,howtype, pnew->price); cuowu(k+34,j-1,howtype, pnew->type); while(strcmp(pnew->type,strno)!=0&&strcmp(pnew->type,strok)==0)//非法字符串返回重新输入 { cuowu(k+34,j-1,howtype, pnew->type); } } if(strcmp(pnew->type,strno)==0) { if(type==3)//借出图书直接显示借出时间,并提示输入归还时间 { time(&timep); p=localtime(&timep); sprintf(pnew->lendtime,"%4d.%2d.%2d",(1900+p->tm_year), (1+p->tm_mon),p->tm_mday);//获取当天日期,作为借书日期 gotoxy(k, j-2); printf("借出时间(例:2015.06.02):%s",pnew->lendtime); gotoxy(k, j-1); printf("归还时间(例:2015.06.02):"); cuowu(k+25,j-1,1, pnew->backtime); } else//否则进行正常的输入 { gotoxy(k, j++); printf("借出时间(例:2015.06.02):"); gotoxy(k, j++); printf("归还时间(例:2015.06.02):"); cuowu(k+25,j-2,howtype, pnew->lendtime); cuowu(k+25,j-1,howtype, pnew->backtime); } } else { sprintf(pnew->lendtime,"0000.00.00"); sprintf(pnew->backtime,"0000.00.00"); } allsort();//进行排序 return phead;}
    五、测试数据及运行结果5.1 正常测试数据和运行结果要求提供3组正常测试数据和运行结果



    开始界面
    管理员注册
    用户注册










    登录界面

    管理员界面和用户界面



    管理员界面
    用户界面









    三组图书输入数据



    输入数据1
    输入数据2
    输入数据3










    修改图书和修改后查询



    修改图书
    修改后查询









    借出已被借图书和借出在库图书



    借出已被借图书
    借出在库图书









    归还图书

    删除图书和删除后查询



    删除图书
    删除后查询









    一键保存和全部删除



    一键保存
    全部删除









    5.2 异常测试数据及运行结果多次错误登陆,显示拜拜

    新增图书时按回车视为非法,不进行换行

    输入非法字符串时不执行下一步,返回

    查询时查询没有的书目

    借出时借出没有的书目

    进行下一步判断执行时输入非法操作,返回继续输入

    六、调试情况,设计技巧及体会6.1 改进方案对自己的设计进行评价,指出合理和不足之处,提出改进方案;

    合理之处:在规避非法输入的时候考虑到了有可能会有人不小心点到回车键执行了换行操作,导致数据输入发生错误是别的问题,为此特意写了void cuowu(int i, int j,charstr[]);函数,并且在新增图书、修改图书、借出图书时将众多的功能实现在一个struct book *creat(int j, int k, int type, struct book *goost)函数里,当然在搜索时使用模糊搜索使得搜索更加方便。
    不足之处:在规避非法输入的时候没有考虑到字符串长度的问题,如果违规输入过长的字符串将会导致整个系统的崩溃,应该改进void cuowu(int i, int j, char str[]);函数,再加上一个参数把字符串的长度限制加上,使字符串不会出现越界问题。

    6.2 体会对设计及调试过程的心得体会。
    在这次课设最初开始的时候我想做的是一个通讯录管理系统,因为当时我的通讯录已经写了670行程序也就是四分之三的样子,但是在开始之后我发现通讯录写起来的意义不怎么大,于是我选择了图书管理系统下手,最开始的两天课设我的定位是做出最基本的功能先,因为其他的功能都是可以作为后期添加加上的。在最初的三天我只是把所有的功能写完,但是我一次都没有进行调试,我觉得我的逻辑是对的,一起调试也是可以的,于是后面两天基本上都是在调试中度过,因为我做的是文本界面,有需要光标随意的移动,所以写起来需要有一个大局观,因为整个屏幕的光标移动都是需要考虑的,整个程序只要涉及到标准的输入输出时都是需要跟踪光标位置的,所以在调试的时候大多数时间都是在调试跟踪光标。
    经过这次课设,我对各种C函数的理解更加深入,课设过程中让我懂得了许许多多。作为一个程序来说,程序员首先要做得就是定义它的基本框架,否则注定是写出一堆乱码,有一个大致的目标才好去实现!在写程序的时候也要考虑的更加全面一些,让程序的容错性更强,因为对于使用者来说,总有各种各样的操作是不可避免的,所以我们能做的就是考虑各种极限情况,把可能发生的事情全部都考虑到位!
    3 评论 17 下载 2018-10-06 21:47:48 下载需要13点积分
  • 基于JSP的小区物业管理系统设计与实现

    摘 要对于小区物业管理来说,其工作流程的繁杂性、多样化、管理复杂、收缴费用与设备维护繁琐。计算机已完全能够胜任物业管理工作,而且更加准确、方便、快捷、高效、清晰、透明,它完全可以克服以上所述的不足之处。这将给项目查询和管理带来很大的方便,从而给物业管理工作带来更高的效率,这也是物业管理正规化、现代化的重要标志。
    因此,开发一套高效率、无差错的小区物业管理系统软件十分必要。本系统的主要目的是告别帐本,安全、快捷的保存数据信息。由于小区物业管理涉及到费用问题,为了增强系统的保密性,使业主利益不受损害,使业主能够对自家的物业费用和投诉等情况提供透明化、直观的了解。
    本毕业设计的内容是设计并且实现一个基于web技术的小区物业管理系统,故而系统主要以J2EE作为开发基础,主要使用了Struts2+Spring+Hibernate等多种框架的结合使用,用Myeclipse作为开发工具,以SQL Server作为数据库,以Macromedia公司的Dreamweaver作为界面美化工具,使用JAVA语言开发,页面采取JSP动态页面开发技术。该系统界面简单、操作方便,容易维护。
    关键词:小区物业管理系统;SSH;JSP动态页面开发
    AbstractFor residential property management, the complexity of the work flow, diversification, management of complex, tedious collection costs and equipment maintenance. The computer is fully qualified to work in property management, and more accurate, convenient, fast, efficient, clear, transparent, it can overcome the shortcomings mentioned above. This will give the project inquiry and management bring great convenience, to the property management work more efficient, this is also the regularization of property management, an important symbol of modernization.
    Therefore, the development of an efficient, error-free residential property management system software is very necessary. The main purpose of this system is to bid farewell to the books, safe, fast and the preservation of data. Because the plot estate management costs involved, in order to enhance the system security, so that the interests of owners from damage, to the property owner can own property costs and complaints, provide transparent, intuitive understanding of.
    The content of graduation design is to design and implement a web based residential property management system, so the system is mainly to j2EE as a development base, the main use of struts2+spring+hibernate and other frame used in combination, using MyEclipse as a development tool, using SQL Server as the database, with Macromedia’s Dreamweaver as the interface landscaping tools, the use of JAVA language development, page take JSP dynamic page technology. This system interface is simple, convenient operation, easy maintenance.
    Keywords: District property management system SSH JSP dynamic page
    第1章 绪论1.1 课题背景科学技术日新月异,信息化时代的来临,以计算机为基础的信息科学在经济和社会生活各个领域得到了极为广泛的应用,尤其在信息管理方面,计算机已是必不可少的管理工具。
    目前,信息已成为继劳动力、土地、资本之后的又一大资源。谁控制的信息越多,谁利用信息资源的效率越高,谁就会在各方面的竞争中占有一席之地,谁就会有更多的优势。从微观上讲,建立一套管理信息系统能够加快信息的周转速度,提高生产效率,从而加强了管理的信息化手段,提高了本单位的经济效益。从宏观上讲,顺应了社会的信息化、社会化潮流,加快了社会的发展速度。据统计,美国在信息管理管理方面80-100%的信息处理由计算机完成;计划管理是80—90%;在计算机应用发展较快的国家中,计算机应用于经济管理的占80%;用于科技计算的占8%,用于生产过程控制的占12%;由此可以看出,信息管理是计算机应用的主要领域。
    1.2 课题目的和意义由于种种原因,我国的信息资源建设水平远远落后于信息基础设施的建设的水平。长期以来,我国信息资源的开发管理未能与信息资源的增长同步进行。我国的计算机应用要比西方国家落后十几年。因此,现在信息资源的开发和利用已被确立为国民经济信息的核心内容,利用现有的信息基础设施,重点开发和推广应用于各类科技、经济等数据库和网络资源服务系统,已经取得巨大的社会效益和经济效益。
    对于小区物业管理来说,其工作流程的繁杂性、多样化、管理复杂、收缴费用与设备维护繁琐。计算机已完全能够胜任物业管理工作,而且更加准确、方便、快捷、高效、清晰、透明,它完全可以克服以上所述的不足之处。这将给项目查询和管理带来很大的方便,从而给物业管理工作带来更高的效率,这也是物业管理正规化、现代化的重要标志。
    因此,开发一套高效率、无差错的小区物业管理系统软件十分必要。本系统的主要目的是告别帐本,安全、快捷的保存数据信息。由于小区物业管理涉及到费用问题,为了增强系统的保密性,使业主利益不受损害,本系统具有仅管理员式的保密功能,还有查询、录入、修改、删除、以及对物业设备统计等功能,使业主能够对自家的物业费用和投诉等情况提供透明化、直观的了解。
    1.3 系统设计思想本系统采用Jsp技术,基于MVC模式开发,使用SSH框架(Struts2、Spring、Hibernate)来增加系统的开发速度。所谓的MVC模式是”Model-View-Controller”的缩写,中文翻译为”模式-视图-控制器”。程序就是用Struts2和Hibernate这两个框架来实现模型层和控制器这两层,Jsp实现视图这一层。一般来说程序就是在数据库和页面之间起桥梁作用的,Jsp页面请求先到action,再到dao,再回到action,回到Jsp页面,action主要处理来自页面的请求,dao主要是和数据库的交互,Struts2主要用在action,处理来自页面的请求,处理完请求后跳转回页面。Hibernate主要用在dao,包括对数据库的增、删、改、查的操作,Spring控制程序的流程。
    SSH框架是J2EE应用中Struts2+Spring+Hibernate三大免费开源框架的结合使用, 它可以看成工具,也是中间件。他是用来提高我们的开发效率,提高我们软件产品的可维护性、可扩展性乃至敏捷性的。他们里面有很多优秀的设计理念及模式应用。比如,Struts属于MVC框架,关键是要了解MVC的概念及大致原理;而Hibernate属于ORM系统,属于持久层的解决方案,同样需要对ORM的概念及原理有一个总体的了解。而Spring属于应用程序框架,其核心是IOC容器以及AOP,Spring中还集成了很多适用东西,比如对JDBC的封装、自己的MVC、对动态语言的简洁访问等,它由以下3个框架构成:
    1.3.1 Struts2框架Struts2是Apache组织的一个开放源码项目。Struts2是一个比较好的MVC框架,提供了对开发MVC系统的底层支持,它采用的主要技术是Servlet,JSP和Custom tag library。
    1.3.2 Spring框架Spring 的核心是个轻量级(Lightweight)的容器(Container),它是实现IoC(Inversion of Control)容器、非侵入性(No intrusive)的框架,并提供AOP(Aspect-oriented programming)概念的实现方式,提供对持久层(Persistence)、事务(Transaction)的支持,提供MVC Web 框架的实现,并对一些常用的企业服务API(Application Interface)提供一致的模型封装,是一个全方位的应用程序框架(Application framework),除此之外,对于现存的各种框架(Struts、JSF、Hibernate 等),Spring 也提供了与它们相整合的方案。
    1.3.3 Hibernate框架Hibernate 是一个开放源码的 ORM 持久层框架。作为优秀的持久层框架实现,Hibernate 框架提供了强大、高性能的对象到关系型数据库的持久化服务,开发人员可以使用面向对象的设计进行持久层开发。简单的说,Hibernate 只是一个将持久化类与数据库表相映射的工具,每个持久化类实例均对应于数据库表中的一个数据行而已。用户只需直接使用面向对象的方法操作此持久化类实例,即可完成对数据库表数据的插入、删除、修改、读取等操作。
    第2章 可行性分析管理信息系统的强大功能越来越被物流行业内的相关人士所重视,通过系统企业能够更直接、清晰的看到数据。管理系统全面的、周到的信息服务使之逐渐成为物流行业发展前进的风向标。信息管理系统,主要用于对公司的信息进行存储,有高效、快速、不易丢失的好处,也帮助公司解决了大数据量的存储。
    2.1 经济可行性经济可行性包括两个方面的内容:一是某一备选方案占有和使用经济资源的可能性,进而实现政策目标的可能性;二是实施某一政策方案所需花费的成本和取得的收益。政府的财政资源是有限的,任何政策方案占有和使用的经济资源也是有限的。因此,任何一项公共政策都存在一个争取公共经济资源的问题。一般说来,“公共政策的经济资源的占有量与其政策目标的期望值成正比例关系。”当然,这还涉及到一个成本效益问题。如果某一方案的成本大于收益,显然这项政策是不可行的。
    在开发小区物业管理系统之前实地考查开发所需条件以及使用中所需要的耗费维护资金,在系统投入使用后带来的受益是否值得花费所需要花费的资金以及资源去进行开发。
    在我的小区物业管理系统中,开发阶段只需要一台带XP系统的电脑以及My eclipse、SQL Server 2008数据库,系统开发周期为五至八周,个人独立完成。
    在投入使用后需要物业管理人员对其进行操作、维护等日常管理,只需这些投入便可以使小区物业管理实现初步的信息化,
    2.2 技术可行性该系统由管理员和业主两种不同的功能并在两者之间进行交互操作,所以系统采用B/S模式来实现。JSP在服务器端执行,通常返回给客户端的就是一个HTML文本,因此客户端只要有浏览器就能浏览,很适合做B/S模式的WEB系统,JSP具备了Java技术的简单易用,完全的面向对象,具有平台无关性且安全可靠,主要面向因特网的所有特点。所以JSP技术对于该系统完全可行。
    2.3 系统流程图在数据库设计过后,接着就应该考虑功能实现,通过功能描述的分析,构思出系统整体结构,采用业务流程图的方式具体介绍系统大概的处理方式,以下为系统的业务流程。
    投诉信息管理系统流程图
    投诉流程由业主发起投诉信息,管理员收到信息后处理反馈,用户再对反馈信息进行察看核实,如图2-1所示。

    登陆系统流程图
    系统分为管理员与业主类型登陆,登陆后根据功能略有不同,具体的操作流程图如2-2图所示:

    缴费信息管理系统流程图
    系统缴费流程由管理员添加缴费信息后,用户查看到自己有未缴费信息进行缴费后管理员确认缴费,具体操作如图2-3所示:

    2.4 本章小结可行性分析是在系统调查的基础上,针对新系统的开发是否具备必要性和可能性,对新系统的开发分别从经济可行性、技术可行性和社会因素可行性,对本系统进行多方面的分析。根据经济、技术和需求等方面的可行性分析,可以确定本系统的开发是完全有必要的,而且是可行的,可以立项开发。
    第3章 需求分析软件需求分析工作是软件生存周期中重要的一步。只有通过需求分析才能把软件功能和性能的总体概念描述为具体上的软件需求规格说明,从而奠定软件开发的基础。软件需求分析工作也是一个不断认识和逐步细化的过程。该过程将软件调研阶段的需求资料进行分析和设计,使软件范围逐步细化到详细定义的程度,并分析出各种不同的软件元素,然后为这些元素找到可行的解决办法。本章将从不同角度的需求分析问题,讲述软件需求类型,分析过程,并部分给出了数据字典和数据流图。
    3.1 物业管理的发展成因改革开放以来,住宅建设飞速发展。我国城镇现有住宅已近80亿平方米。仅79年至99年城镇新建住宅52.5亿平方米。大量住宅小区投入使用,带来了管理工作的变化。除了对房屋进行维修外,还必须对附属物、设备、场地、环卫绿化、道路、治安进行专业化管理,以保持新建住区的完好,发挥其整体功能和综合效益。国外和香港对住宅区和其它物业实施专业化管理的经验被引入,取得了较好的效果,带动了全国物业管理工作的起步和发展。
    住房制度改革的逐步深化。随着房改的步步深化,城镇居民住房自有率已经超过75%,形成一个住区内,一幢房子里的产权多元化格局。房管所及单位房管处(科)的管房体制已经完全不能适应。对管理的社会化形成了客观的要求。物业管理从体制上克服了房改后形成的多个产权单位多头、多家管理,各自为政、扯皮推诿等旧管理体制的弊端。
    体制改革的推动。随着计划经济体制加快向社会主义市场经济体制的转轨,政府职能的转变,以前那种由政府行政福利型直接管理房屋,政府对住区环境、社区服务直接负责的办法,已经不能适应形势的变化。一个由业主自治与物业公司专业化管理结合,由物业管理企业实施经营型管理和有偿服务,使管理得以以业养业、自我发展、良性循环,既减轻了政府的压力和负担,又使得管理经费有了稳定来源的机制,日益显示其新体制的优越性。
    人民群众生活水平的不断提高。居民对住房问题的关切从有无转为大小,继而更加关注环境和社区服务。同时,广大住户拥有了自己的产业,对保持房产和附属设施的完好,以达到保值、增值的观念也逐步树立,使得物业管理的好坏已经成为居民选购住房考虑的重要因素,物业管理为越来越多的人接受,其行业地位不断攀升,外部环境逐步改善。
    3.2 小区物业管理系统需求分析信息管理系统(Information management system)是为了满足客户的需求,对公司货物的信息进行一个统计,高效、快速、方便的存储在数据库当中,不仅节省了人力,还节省了时间,对公司未来发展有着不可估量的好处。
    随着时代的发展、生活节奏的加快、买卖之间的数据量越来越大,现有的靠人工管理的模式已经越来越跟不上当今商务飞速发展的脚步。计算机辅助管理势在必行。
    3.2.1 数据流图数据流图(Data Flow Diagram):简称DFD,它从数据传递和加工角度,以图形方式来表达系统的逻辑功能、数据在系统内部的逻辑流向和逻辑变换过程,是结构化系统分析方法的主要表达工具及用于表示软件模型的一种图示方法。数据流是指处理功能输入或输出,用一个水平箭头或垂直箭头表示。数据存储是数据保存的地方。数据源去向表示数据的来源或数据的流向。

    管理员处理用户提交的投诉、维修信息
    管理员添加缴费信息用户查看缴费后进行处理

    小区物业管理系统由管理员添加以及处理缴费信息,业主对其进行查看确认是否缴费,另外业主进行投诉与维修等上报,管理员获取信息后进行处理反馈结果,用户获取反馈结果,该系统的顶层数据流图如图3-1所示。

    小区物业管理系统一共包括六个表:用户信息表、缴费信息表、投诉信息表、维修信息表、用户信息表、房产信息表。分别有六个数据流,具体如图3-2所示。

    3.2.2 数据字典数据字典(Data dictionary)是一种用户可以访问的记录数据库和应用程序源数据的目录。主动数据字典是指在对数据库或应用程序结构进行修改时,其内容可以由DBMS自动更新的数据字典。被动数据字典是指修改时必须手工更新其内容的数据字典。
    它是关于数据的信息的集合,也就是对数据流图中包含的所有元素的定义的集合。数据字典的作用是在软件的分析和设计过程中提供关于数据的描述信息。一般说来,数据字典应该由下列四类元素构成:数据元素,数据流,数据存储和数据处理数据字典的作用是在软件分析和设计的过程中给人提供关于数据的描述信息。它主要是对数据流图中的数据流、处理逻辑、外部实体、数据存储和数据项等方面进行具体的定义。数据流程图配以数据字典,就可以从图形和文字两个方面对系统的逻辑模型进行完整的描述。
    数据项定义
    数据元素也称为数据项,是不可再分的数据单位,是数据的最小组成单位,具体内容如表3-1所示。



    编号
    数据项名称
    名称
    NULL
    备注




    I01-1
    房产编号
    id
    no
    主键


    I01-2
    备注信息
    beizhu
    yes
    备注


    I01-3
    时间
    createtime
    yes
    添加时间


    I01-4
    是否删除
    fangshanlock
    no
    是否删除标志


    I01-5
    结构
    fangwujiegou
    yes
    房屋结构


    I01-6
    门牌号
    menpaihao
    yes
    门牌号


    I01-7
    面积
    mianji
    yes
    房屋面积


    I01-8
    设备
    shebei
    yes
    设备


    I01-9
    住址
    zhuzhi
    yes
    住址


    I01-10
    房产关联业主
    zhuhuid
    yes
    关联的业主ID


    I01-11
    投诉编号
    id
    no
    主键


    I01-12
    投诉反馈
    chulifankui
    yes
    处理反馈


    I01-13
    投诉结果
    chulijieguo
    yes
    处理结果


    I01-14
    投诉内容
    content
    yes
    投诉内容


    I01-15
    投诉时间
    createtime
    yes
    添加时间


    I01-16
    投诉标题
    title
    yes
    投诉标题


    I01-17
    删除标志
    tousulock
    no
    是否删除标志


    I01-18
    投诉关联业主
    zhuhuid
    yes
    关联的业主


    I01-19
    维修编号
    id
    no
    主键


    I01-20
    维修信息
    chulifankui
    yes
    处理反馈


    I01-21
    维修结果
    chulijieguo
    yes
    处理结果


    I01-22
    维修内容
    content
    yes
    维修内容


    I01-23
    维修时间
    createtime
    yes
    添加时间


    I01-24
    维修标题
    title
    yes
    维修标题


    I01-25
    删除标志
    weixiulock
    no
    是否删除标志


    I01-26
    维修关联业主
    zhuhuid
    yes
    关联的业主ID


    I01-27
    业主编号
    Id
    no
    主键


    I01-28
    业主电话
    dianhuahaoma
    yes
    电话号码


    I01-29
    业主身份证
    huzhufz
    yes
    业主身份证


    I01-30
    业主姓名
    huzhuxingming
    yes
    姓名


    I01-31
    业主入住时间
    ruzhushijian
    yes
    入住时间


    I01-32
    是否删除标志
    zhuhulock
    no
    是否删除标志


    I01-33
    业主住址
    zhuzhi
    yes
    住址


    I01-34
    用户编号
    id
    no
    主键


    I01-35
    用户添加时间
    createtime
    yes
    添加时间


    I01-36
    用户密码
    password
    yes
    密码


    I01-37
    用户权限设定
    role
    no
    用户权限


    I01-38
    用户姓名
    truename
    yes
    真实姓名


    I01-39
    是否停用
    userlock
    no
    是否停用标志


    I01-40
    用户姓名
    username
    yes
    用户名


    I01-41
    用户关联业主
    zhuzhiid
    yes
    关联的业主ID


    I01-42
    缴费编号
    id
    yes
    主键


    I01-43
    备注
    beizhu
    yes
    备注


    I01-44
    费用
    feiyong
    no
    费用


    I01-45
    费用周期
    feiyongzhouqi
    yes
    周期


    I01-46
    是否删除标志
    jiaofeilock
    no
    是否删除


    I01-47
    缴费类型
    leixing
    yes
    类型


    I01-48
    缴费时间
    shoufeishijian
    yes
    时间


    I01-49
    缴费状态
    shoufeizhuangtai
    no
    是否已交费


    I01-50
    房产id
    fangchanid
    yes
    关联房产


    I01-51
    用户id
    zhuhuid
    no
    关联用户




    数据流编号:D1—01

    数据流名称:房产信息数据流来源:管理员数据流去向:F6数据流组成:I01-01+I01-02+I01-03+I01-04+I01-05
    数据流编号:D1—02

    数据流名称:用户信息数据流来源:F1数据流去向:F5数据流组成:I01-34+I01-36+I01-38+I01-40
    数据流编号:D1—03

    数据流名称:缴费信息数据流来源:管理员数据流去向:F2数据流组成:I01-42+I01-43+I01-44+I01-45+I01-46+I01-47
    数据流编号:D1—04

    数据流名称:业主信息数据流来源:管理员数据流去向:F1数据流组成:I01-1+I01-2+I01-3+I01-4+I01-5
    数据流编号:D1—05

    数据流名称:投诉信息数据流来源:F1数据流去向:F3数据流组成:I01-11+I01-12+I01-13+I01-14+I01-15+I01-16+I01-17+I01-18
    数据流编号:D1—06

    数据流名称:维修信息数据流来源:F1数据流去向:F4数据流组成:I01-19+I01-20+I01-21+I01-22+I01-23+ I01-24+I01-25

    需求分析是一项重要的工作,也是最困难的工作。该阶段工作有以下特点:

    供需交流困难:在软件生存周期中,其它四个阶段都是面向软件技术问题,只有本阶段是面向用户的。需求分析是对用户的业务活动进行分析,明确在用户的业务环境中软件系统。但是在开始时,开发人员和用户双方都不能准确地提出系统。因为软件开发人员不是用户问题领域的专家,不熟悉用户的业务活动和业务环境,又不可能在短期内搞清楚;而用户不熟悉计算机应用的有关问题。由于双方互相不了解对方的工作,又缺乏共同语言,所以在交流时存在着隔阂。
    需求动态化:对于一个大型而复杂的软件系统,用户很难精确完整地提出它的功能和性能要求。一开始只能提出一个大概,模糊的功能,只有经过长时间的反复认识才逐步明确。有时进入到设计,编程阶段才能明确,更有甚者,到开发后期还在提新的要求。这无疑给软件开发带来困难。
    后续影响复杂:需求分析是软件开发的基础。假定在该阶段发现一个错误,解决它需要用一小时的时间,到设计,编程,测试和维护阶段解决,则要花2.5,5,25,100倍的时间。

    因此,对于大型复杂系统而言,首先要进行可行性研究。开发人员对用户的要求及现实环境进行调查,了解,从技术,经济和社会因素三个方面进行研究并论证该软件项目的可行性,根据可行性研究的结果,决定项目的取舍。
    3.3 本章小结本章对物流管理系统的需求进行分析,通过本章的论述对整个系统的设计有更加详细的了解。熟悉所依据的系统流程,根据系统流程图画出系统的数据流程,根据系统的数据流程写出所用到的数据字典,本章为整个系统的需求分析部分需求分析阶段结束之后进入总体设计阶段。
    第4章 系统设计4.1 系统功能设计需求分析说明小区物业管理系统主要为了物业管理员与业主设计的,架构在web的内部服务器上面。管理员对业主以及缴费信息进行管理,业主可以查看或者提交投诉维修等信息。整个系统就是这样的一个组织结构模式。
    依据上述功能的分析,系统中模块分别为:业主管理、用户管理、缴费管理、投诉管理、维修管理、房产管理。
    各功能模块的具体功能如下:

    业主管理:管理员对业主信息进行添加修改等功能
    用户管理:管理员对业主的用户信息是否停用进行控制,业主可以自己对自己所有用户进行密码修改等业务
    缴费管理:管理员添加以及处理缴费信息,业主查看自己所有已缴费和未缴费的信息详情
    投诉、维修管理:用户提交投诉、维修信息后,管理员查看到及时进行处理反馈结果,用户可以通过查看投诉、维修信息得知结果。具体如图4-1所示


    该系统主要包括系统管理员与业主俩个界面,系统管理员与业主分别具有不同的功能,分为两个不同的界面,之间存在信息交互等操作。
    4.2 数据库设计直到现在,我们可以设计的数据库必然是有结构的数据, 譬如说,我们已经确定了许多张表。但为什么会得到引起结构呢? 答案很简单,在数据库设计时数据库的结构是确定的,然而,进行数据库的设计,可能非常复杂。为了开发一个系统满足该组织的信息需求,要求采取不同办法在文件系统中,那里的工作为个别部门推动了应用的需要。在方法中的这种改变被子称为模式转变。为了使系统可以被用户最终接受,数据库的设计活动是至关重要的。一个没设计好的数据库中会产生错误, 这可能造成严重后果的组织。另一方面,以有效的方式精心设计制作的数据库,可以提供正确的资料。
    总之,在数据库开发中,设计的好坏是决定后续工作顺得与否的关键。
    我们小区物业管理系统使用SQL Server数据库,在数据库中考虑到几大功能模块所需数据创建了房产、维修、投诉、缴费、业主、用户这六个表。
    4.2.1 数据分析根据数据库中表的设计,数据应该是清晰的、具体的、并且要是一个合理的数据。在我们使用数据时,需要考虑到数据是否符合我们的需求,对于数据的使用我们也要遵循一定的规则。
    在我们系统中每一个表的数据类型、主键、NULL以及是否唯一等都按照系统所需分别设置,充分考虑到我们对于该系统的需求以及实现功能,为我们系统的数据正确性提供保证。
    4.3 数据库的详细设计数据库中重点为表的设计与表间的关联,在一个项目的实施过程中前期的数据库设计没有设计好就是大副度的减化系统开发的进度。分析表与表间的关系也可以帮助我们在开发项目时建立良好的流程,具体的功能和业务实现。
    数据库存在表与表间的关系,有三种形式:一对一关联,一对多关联,多对多关联,他们是对自然联接等方式来对表进行关联。表自身间的关系也是一种关联,在数据库设计中,我们不仅要对数据库中的数据类型进行了合理定义,还要对应的建好表与表间的关系才能作好数据库的设计。
    在设计数据库前应对现有类似系统的数据库进行仔细研究,找出它的不足以完善自己所设计的数据库。
    在设计前,应考虑以下事项:

    定义标准的对象命名规范
    工欲善其事,必先利其器。选择理想的数据库设计工具
    了解你的业务。根据业务需要创建数据表
    创建数据字典和E-R图表
    数据库维护

    4.3.1 数据表的设计对于小区物业管理系统,数据基本上都是使用数据库进行管理。数据库设计是对保存管理系统数据的数据库结构进行设计,对整个系统的开发具有非常重要的作用,我们一共包括以下这些表。
    房产表
    数据项包括:房产编号、备注、添加时间、是否删除标志、房屋结构、门牌号、房屋面积、设备、住址、关联业主ID,如表4-1所示。



    名称
    类型

    备注




    id
    bigint(20)
    no
    主键


    beizhu
    varchar(255)
    yes
    备注


    createtime
    datetime
    yes
    添加时间


    fangshanlock
    int(11)
    no
    是否删除标志


    fangwujiegou
    varchar(255)
    yes
    房屋结构


    menpaihao
    varchar(255)
    yes
    门牌号


    mianji
    varchar(255)
    yes
    房屋面积


    shebei
    varchar(255)
    yes
    设备


    zhuzhi
    varchar(255)
    yes
    住址


    zhuhuid
    bigint(20)
    yes
    关联的业主ID



    缴费表
    数据项包括:缴费编号、备注、添加时间、费用、费用标题、是否删除标志、缴费类型、收费时间、缴费状态,如表4-2所示。



    名称
    类型

    备注




    id
    bigint(20)
    no
    主键


    beizhu
    varchar(255)
    yes
    备注


    createtime
    datetime
    yes
    添加时间


    feiyong
    varchar(255)
    yes
    费用


    feiyongzhouqi
    varchar(255)
    yes
    费用标题


    jiaofeilock
    int(11)
    no
    是否删除标志


    leixing
    varchar(255)
    yes
    缴费类型


    shoufeishijian
    datetime
    yes
    收费时间


    shoufeizhuangtai
    varchar(255)
    yes
    缴费状态


    fangchanid
    bigint(20)
    yes
    关联的房产ID


    zhuhuid
    bigint(20)
    yes
    关联的业主ID



    投诉表
    数据项包括:投诉编号、处理反馈、处理结果、投诉内容、添加时间、投诉标题、是否删除标志、关联业主信息,具体如表4-3所示。



    名称
    类型

    备注




    id
    bigint(20)
    no
    主键


    chulifankui
    varchar(255)
    yes
    处理反馈


    chulijieguo
    varchar(255)
    yes
    处理结果


    content
    varchar(255)
    yes
    投诉内容


    createtime
    datetime
    yes
    添加时间


    title
    varchar(255)
    yes
    投诉标题


    tousulock
    int(11)
    no
    是否删除标志


    zhuhuid
    bigint(20)
    yes
    关联的业主信息



    维修表
    数据项包括:维修编号、处理反馈、处理结果、维修内容、添加时间、维修标题、是否删除标志、关联业主ID,具体如表4-4所示。



    名称
    类型

    备注




    id
    bigint(20)
    no
    主键


    chulifankui
    varchar(255)
    yes
    处理反馈


    chulijieguo
    varchar(255)
    yes
    处理结果


    content
    varchar(255)
    yes
    维修内容


    createtime
    datetime
    yes
    添加时间


    title
    varchar(255)
    yes
    维修标题


    weixiulock
    int(11)
    no
    是否删除标志


    zhuhuid
    bigint(20)
    yes
    关联的业主ID



    业主表
    数据项包括:业主编号、电话号码、业主身份证、姓名、入住时间、是否删除标志、住址,具体如表4-5所示。



    名称
    类型

    备注




    id
    bigint(20)
    no
    主键


    dianhuahaoma
    varchar(255)
    yes
    电话号码


    huzhufz
    varchar(255)
    yes
    业主身份证


    huzhuxingming
    varchar(255)
    yes
    姓名


    ruzhushijian
    varchar(255)
    yes
    入住时间


    zhuhulock
    int(11)
    no
    是否删除标志


    zhuzhi
    varchar(255)
    yes
    住址



    用户表
    数据项包括:用户编号、添加时间、密码、用户权限、真实姓名、用户名、关联业主ID,具体如表4-6所示。



    名称
    类型

    备注




    id
    bigint(20)
    no
    主键


    createtime
    datetime
    yes
    添加时间


    password
    varchar(255)
    yes
    密码


    role
    int(11)
    no
    用户权限


    truename
    varchar(255)
    yes
    真实姓名


    userlock
    int(11)
    no
    是否停用标志


    username
    varchar(255)
    yes
    用户名


    zhuzhiid
    bigint(20)
    yes
    关联的业主ID



    4.3.2 数据库的E-R图设计E-R图为实体-联系图,提供了表示实体型、属性和联系的方法,用来描述现实世界的概念模型。构造E-R图的基本要素是实体型、属性和联系的方法。由属性构成实体型,标明实体型的PK,用菱形来表示联系通过连线写明互相之间的对应关系。实体型是具有相同属性的实体具有相同的性质和特征,用实体名及其属性名集合来抽象和刻画同类实体;属性是实体所具有的某一特征,一个实体有若干个属性来刻画;联系也称为关系,信息世界中反映实体内部或实体之间的联系。
    在E-R图中联系可分为三种类型:

    一对一联系(1:1)
    一对多联系(1:N)
    多对多联系(M:N)

    一个较好的系统在设计时要做好分析工作,并且要按照一定的次序将其完成,首先做好数据的分析,设计好数据库。在分析数据库的建设问题时,首先就要从需求分析中获取系统中要用的数据,将其规化好,抽取实体及其属性,建立模型。以下为系统所有要使用的数据,以E-R图的形式表示如图4-7所示。

    系统E-R类图包括本系统六个表:业主表、用户表、房产表、投诉表、缴费表与维修表。
    在小区里,每个业主能够拥有多套房产,所以业主表与房产表属于一对多的包含关系;每个业主拥有一个用于用户端登录的用户账户密码,所以用户表与业主表是一对一的包含关系;在投诉与维修上报上是一样的,每个业主能够发起多个投诉与维修信息,所以投诉表跟维修表与业主表的关系都是一对多的生成关系;最后还有一个缴费表,每个业主每个月都会有多项缴费信息,每个业主应该对应多项缴费信息并且业主对缴费信息只允许进行查看不允许修改,所以业主表与缴费表是一对多的查看关系
    4.4 本章小结根据本章系统设计的分析,我们可以清楚知道我们的系统通过需求分析后做出了业主与管理端两个不同的界面,其中管理员有八个功能模块,而用户有七个功能模块。我们对系统所需做出了对应的数据库设计,用六个表来存储我们系统的数据。
    第5章 系统实现JavaBeans是用java语言编写的可重用的软件组件。使用javaBeans组件,以使用可视的应用程序开发工具将它们编写到java程序中。javaBeans规范为java开发人员提供了一种“组件化”其java类的方法,是实现代码重用的一个很好的机制。同时它也被广泛地应用到jsp技术中实现代码的重用,还可以实现显示和逻辑的一定程度上的分离,在实际应用中得到广泛的应用。
    5.1 系统和数据库的配置系统按通用的B/S(浏览器、服务器)模式进行设计(如图4-1)

    数据库在一个信息管理系统中占有非常重要的地位,数据库结构设计的好坏将直接对应用系统的效率,以及实现的效果产生影响。合理的数据库结构设计可以提高数据存储的效率,保证数据的完整和一致。
    5.2 数据库逻辑模型
    房产表(主键、备注、添加时间、是否删除标志、房屋结构、门牌号、房屋面积、设备、住址、关联的业主ID)
    缴费表(主键、备注、添加时间、费用、费用标题、是否删除标志、缴费类型、收费时间、缴费状态、关联的房产ID、关联的业主ID)
    投诉表(主键、处理反馈、处理结果、投诉内容、添加时间、投诉标题、是否删除标志、关联的业主信息)
    维修表(主键、处理反馈、处理结果、维修内容、添加时间、维修标题、是否删除标志、关联的业主ID)
    业主表(主键、电话号码、业主身份证、姓名、入住时间、是否删除标志、住址)
    用户表(主键、添加时间、密码、用户权限、真实姓名、是否停用标志、用户名、关联的业主ID)

    5.3 系统设计5.3.1 用户登录的设计与实现对于用户登录的设计需要用户输入正确的登录用户名、密码后台利用Ajax自动判断用户的权限,并进入相应的页面。
    用户登录程序流程描述
    在进入登录界面时,需要用户输入正确的用户名和密码,选择权限,如果用户名或密码为空时,会返回到登录界面重新输入,错误时也是,当输入正确时就会进入管理系统的主界面中。
    实现过程
    index.jsp页面合法用户的核查页面,即起到Login.jsp页面与数据库之间的一个桥梁作用,将index.jsp页面中输入的用户名、密码送入到StudentServlet中通过SQL语句与数据库中的用户名、密码进行对比,找到后即为合法用户,说明可以进入系统,在此页面中需要引入一个BaseDbOper.java文件,它起到连接数据库和对数据库的访问。
    5.3.2 系统功能的设计与实现**业主信息管理设计
    管理员应能够添加新主以及对原有业主进行查看、修改或者删除等功能,所以界面设计如图5-2所示。

    同时,在用户端应可以查询到自己的业主信息但不能查询到他人信息并且不允许进行修改,所以界面设计如图5-3所示。

    房产信息管理设计
    在房产信息管理上,管理员应该可以对业主添加、修改、删除以及查看,所以房产信息管理界面应图5-4所示。

    业主可以查看到自己的房产信息而不能查看其他人的信息,并且不允许进行修改操作,所以房产信息管理在业主节目应如图5-5所示。

    缴费信息管理设计
    缴费信息管理在管理员界面中有两次处理,一次是添加、修改等操作添加新的缴费信息,然后再运营中的收费管理进行查看以及确认缴费,在用户界面中能够查看到缴费信息但无法进行修改等操作。所有已缴费和未缴费信息是显示在一起,管理员界面中显示所有的缴费信息,用户界面中只显示自己的缴费信息,这样的方式可以给用户隐私带来保障,不允许他人查看到自己的信息。
    在添加缴费信息时先进行格式判定,缴费信息为空时不符合格式要求添加失败需要重新输入,判定成功后添加到缴费信息表中。在确认缴费信息时候如果不确认则保持未缴费状态,确认缴费后该缴费数据项的缴费状态更改为已缴费。具体如图5-6所示。

    管理员统一添加每月缴费信息后,查看确定是否有误,需要修改删除等操作,所以缴费信息管理页面如图5-7所示。

    在添加缴费信息后业主可以查看到缴费信息,业主缴费信息界面如图5-8所示。

    在业主查看到自己未缴费的信息后进行缴费,管理员应该对其进行确认缴费,如图5-9所示。

    投诉信息管理的设计
    投诉信息由业主发起投诉信息,所以业主投诉界面应该设计如图5-10所示。

    在业主发起投诉后由管理员对投诉信息进行查看处理以及反馈结果,所以投诉信息管理界面应该设计如图5-11。

    5.4 本章小结到现在为止,我们的系统功能模块基本实现完成。在数据库方面,我们有业主、用户、房产、缴费、维修以及投诉六张表,我们做出了这六张表的实体对应关系,可以让我们很清楚的知道表与表之间联系。其后我们按照需求设计了合理的系统界面,让我们的系统功能更加合理、完善。
    第6章 系统测试信息技术的飞速发展,使软件产品应用到社会的各个领域,软件产品的质量自然成为人们共同关注的焦点。不论软件的生产者还是软件的使用者,生存在竞争的环境中,软件开发商为了占有市场,必须把产品质量作为企业的重要目标之一,以免在激烈的竞争中被淘汰出局。用户为了保证自己业务的顺利完成,当然希望选用优质的软件。质量不佳的软件产品不仅会使开发商的维护费用和用户的使用成本大幅增加,还可能产生其他的责任风险,造成公司信誉下降,继而冲击股票市场。在一些关键应用 (如民航订票系统、银行结算系统、证券交易系统、自动飞行控制软件、军事防御和核电站安全控制系统等) 中使用质量有问题的软件,还可能造成灾难性的后果。
    6.1 软件测试的目的软件测试的目的,第一是确认软件的质量,其一方面是确认软件做了你所期望的事情,另一方面是确认软件以正确的方式来做了这个事件。
    第二是提供信息,比如提供给开发人员或程序经理的反馈信息,为风险评估所准备的信息。
    第三软件测试不仅是在测试软件产品的本身,而且还包括软件开发的过程。如果一个软件产品开发完成之后发现了很多问题,这说明此软件开发过程很可能是有缺陷的。因此软件测试的第三个目的是保证整个软件开发过程是高质量的。
    软件质量是由几个方面来衡量的:一、在正确的时间用正确的的方法把一个工作做正确。二、符合一些应用标准的要求,比如不同国家的用户不同的操作习惯和要求,项目工程中的可维护性、可测试性等要求。三、质量本身就是软件达到了最开始所设定的要求,而代码的优美或精巧的技巧并不代表软件的高质量。四、质量也代表着它符合客户的需要。作为软件测试这个行业,最重要的一件事就是从客户的需求出发,从客户的角度去看产品,客户会怎么去使用这个产品,使用过程中会遇到什么样的问题。
    6.2 软件测试的任务在软件投入生产性运行之前,尽可能多地发现并排除软件中潜藏的错误,最终把一个高质量的软件系统交给用户使用。软件测试是保证软件软件质量的关键步骤,它是对软件规格说明、设计和编码的最后复审。软件测试的结果也是分析软件可靠性的重要依据。具体包括登录是否成功、缴费添加是否合理、缴费处理是否有反馈、投诉维修等信息添加后是否能够回馈回去信息等操作。
    6.3 测试环境Apache提供的Web服务器Tomcat 6.0使得用户可以在Windows 2000以上操作系统下发布自己设计的动态网页。因此对论坛的调试工作主要是利用Tomcat 6.0的强大功能在本机下完成的。为了在本机下浏览Web页面,首先在创建该系统的站点上(该系统使用的是Web的默认站点)将IP地址设定为127.0.0.1,它的缺省域名值为localhost。然后向IE浏览器输入本地动态网页的URL,Web服务器在收到浏览器传送的URL之后找到网页文件,并在服务器端执行该文件后将此文件以HTML文件的形式返回该浏览器。
    6.4 本系统测试设计测试方案是测试阶段的关键技术问题。所谓测试方案包括预定要测试的功能。应该输入的测试数据和预期的结果,目标是设计一组可能发现错误的数据。本系统中,我应用了如下测试方案:白盒测试、黑盒测试。
    对于测试过程我只列出缴费与投诉两个部分,给出了单元测试部分的实例。
    6.5 测试用例在系统测试中有很多种测试方法,现在我们针对系统部分功能进行一次测试记录下来。
    首先,进入缴费信息管理添加新的缴费信息。添加后自动返回缴费信息管理界面,这时候到运营的收费管理中确认下是否已经添加进入,并确认收费。
    现在我们对缴费信息进行添加,添加时候对缴费名称、费用以及备注进行测试是否能够为空、特殊字符以及测试是否有字符数的限制,测试添加功能是否符合我们的需求,如果有限制时候是否对限制有警告处理信息。
    添加缴费信息测试时发现缴费名称不允许为空,所有项可以未任何字符。能够符合当前对该系统的需求。添加缴费信息测试通过,没有存在任何问题。下面添加完成,查看缴费信息管理页面的其他功能以及添加后的现实情况。具体软件缴费实例如表6-1所示。



    动作
    期望结果
    实际情况




    添加缴费信息
    缴费信息界面添加上新的缴费信息
    与期望相吻合


    查看缴费信息
    打开所查看的缴费项的信息,表示出它的所有信息
    与期望相吻合


    确认缴费
    缴费信息状态更改为已缴费
    与期望相吻合


    删除缴费信息
    所要删除项的缴费信息全部被删除
    与期望相吻合



    结论:经测试,小区物业管理系统缴费功能不存在BUG,功能已全部实现。
    6.6 本章小结软件测试是软件开发中的重中之重,没有一点可以马虎的,在项目管理过程中,强调的是每个过程的每一个环节都要进行测试,保证系统在每个阶段可以控制。因为软件测试中考虑的问题基本上是项目管理中需要考虑的问题。具体说,软件测试是事务性的,而项目管理是策略性,一些策略性的东西必须在一些事务性的事务上来实现。
    结论至此,小区物业管理系统设计与实现顺利完成。在几天的试运行的过程中,在连接数据库时一度出现过错误,经过调试改正后错误点全部清楚,此系统可以按着设计思想和需求功能正常运行。
    由于当今的物业管理部门还不能有一个很统一的模式化,所以本系统仅考虑到一般小区所需要的物业管理的基本和主要的几项功能,一个完好的小区物业管理系统还需要更多更复杂的功能要求。由于开发周期短和开发人员等局限性,不能将本套系统尽善尽美。希望在以后能够对小区的物业做更深一步的调研,在原由系统的基础上不断添加新功能。最终能够开发出一套完善的小区物业管理系统。
    本系统在开发过程中,在固定的物业管理要求的模式下还添加了一些人性化的,个人的构思和创意。
    本套小区物业管理系统符合基本需求功能,易于操作,应该可以在简单化模式下的小区内应用,存在要改进的地方再以后会进一步完善。希望本系统能够给用户带来方便。
    在这次毕业设计论文撰写过程中,时间很紧迫。由于已经参加实习工作,很多计划使得没有充分的时间去实习,去准备。希望在以后能够进行二次开发,继续完善它,使投入使用后更变得有实用价值。
    参考文献
    李春葆.数据库原理与应用.北京:清华大学出版社,2012
    普西金.深入体验JSP项目开发.北京:机械工业出版社,2011
    邹劲松.物业管理信息系统. 北京:清华大学出版社,2010
    季如进.物业管理(修订第二版). 北京:机械工业出版社,2010
    陈朗钦.图书管理信息系统设计. 北京:人民邮电出版社,2011
    萨师煊.数据库系统概论. 北京:清华大学出版社,2010
    张建.基于WEB的人力资源管理系统的设计与实现.大连:吉林大学出版社,2013
    王国辉.JSP项目开发全程实录(第2版).北京:清华大学出版社,2013
    韩万江.软件项目管理案例教程(第二版).机械工业出版社.2011
    Paul Nielson .Microsoft SQL Server 2008 Bible.[M]. Neurology,2011
    Jan L.Hamington.SQL Clearly Explained.[M].JRD,2011
    Thomas Kyte.Programming Techniques and Solutions[M].BeiJin:Posts& Telecom Press,2013
    Ted Neward.Server-based Java Programming.[M].JIDD,2012
    Bryan Basham.Head First Servlets and JSP .中国电力出版社,2010
    Jeremy Keith.JAVAScript DOM.人民邮电出版社,2011
    1 评论 2 下载 2019-05-16 11:49:58 下载需要15点积分
  • 基于WIN32 API界面编程实现的扫雷小游戏

    1项目介绍1.1 开发介绍
    操作系统:Windows 7 及以上版本系统
    开发环境:VS2010

    1.2 扫雷操作
    鼠标操作
    1.3 胜利标准
    将所有的雷找到
    1.4 游戏规则通过鼠标左键单击即可挖开方块,显示数字为周围八个区域的炸弹数。通过推理可以找到地雷,然后通过鼠标右键可以进行标记。如果发现标记错误,可以再次单击鼠标右键进行标记消除。如果点开了地雷,则游戏结束,显示对话框,游戏结束。
    2 方案2.1 方格方格的存储为二维数组。每一个方格又为一个结构体,结构体中存储了两个属性,一个是是否含雷,另一个是周围含雷个数。
    2.2 雷的放置雷的随机放置是由随机函数Srand((unsigned)time(NULL));实现的,然后随机产生二维数组的行列值,再进入循环,如果之前没有生成该坐标,则进行布雷;如果之前生成过该坐标,则重新生成。
    srand((unsigned)time(NULL));while(count){ i = rand() % 9 + 1; j = rand() % 9 + 1; if(Block[i][j].containMine == error) { Block[i][j].containMine = ok; count--; }}
    2.3 雷数的确定雷数的确定由一个个的列举找出。如果该数组不处于四周边界,则周围八面挨个遍历;如果在边界,则排除掉没有数组的地方。运用条件:i>0; j>0; i<COLS; j<ROWS等。
    2.4 对话框生成对话框的生成调用,MessageBox函数。
    2.5 炸弹与红旗的生成炸弹与红旗的生成,分别用两个数组DONE[i][j]、NUM[i][j]来存储该方格是否别左键和右键点过。分别初始化-1,如果被点过,则更改值为1。
    2.6 流程设置边框,初始化每一个小方格,初始化DONE和NUM数组,存放用户是否点过方格和以何种方式点的方格的属性,设置红旗数量为0,加载图片。绘制窗口,如果没有被用户以任何方式点过的小方格,绘制成灰色的小方块。被左键点击过的小方格如果不是地雷则绘制该点周围所含雷数的图片,如果是炸弹则绘制成炸弹,并调用对话框函数。被右键单数次点击过的方格绘制成红旗,双数次点击过的方格绘制成灰色小方块。
    3 关键技术3.1 加载并显示图片#define BITMAP_FILE_BK1 "bomb.bmp"hbmpBomb = LoadImage(NULL, _T("bomb.bmp"),IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);SelectObject(hdcBitmapSrc,hbmpBomb);GetObject(hbmpBomb, sizeof(BITMAP), &bmp);StretchBlt(hdcmem,rectBoundary.left + i*CELL_PIXEL, rectBoundary.top + j*CELL_PIXEL, 50, 50,hdcBitmapSrc,0, 0, bmp.bmWidth, bmp.bmHeight,SRCCOPY);
    3.2 左键右键点击检测函数case WM_LBUTTONDOWN: if(wParam && MK_LBUTTON) { x = LOWORD(lParam); y = HIWORD(lParam); }
    3.3 左键右键点击的小方块位置的确定void adjust(int* x,int* y){ (*x) = (*x-10)/50; *y = (*y-10)/50;}
    4 最终效果最后程序基本完成了预期目标。效果如下:



    5 总结与不足扫雷是我一直很喜欢的一款游戏,比起其他游戏,扫雷有着编写容易,易于上手的特点。由于学习C语言的时候不是很精通,导致编写游戏的时候存在了很多问题,后来也是一个一个查阅资料以及问同学等各个渠道解决的。
    在设计游戏左键右键检测的时候不知道如何调用,造成了很长时间的错误,后来才想到用二维数组存放是否被点击过的属性。调用窗口的函数,图片加载等都是按照老师给的源码改编的。编程过程中,中英文的切换用于写代码和注释,有时切换不及时,也导致了一些错误,不过vs自带报错功能解决了很多问题。编程的时候还遇到过一些外部解析的错误,其中有一个是需要把控制台性质转换为了窗口性质;还有一个是因为进程中存在了运行的exe文件,打开任务管理器结束该进程就可以继续运行了,这些方法都是上网搜索到的,网络对我的帮助也很大。
    在扫雷的游戏中还是有很多功能没有完善,例如不能自己选择扫雷的游戏难度,双击挖开方块不能自动展开,游戏不能保存等。希望在以后的学习中,可以不断完善自己的能力,充实自己的知识结构。同时也老师和同学们给我的帮助表示感谢!
    1 评论 11 下载 2018-11-05 16:07:58 下载需要8点积分
  • 基于SSM的网上购物系统的设计与开发

    摘 要本论文主要对网上购物商城的设计与开发进行了一些论述,包括了系统的设计和实现一共两个大部分,设计部分主要对系统和数据库的分析与设计进行了描述;实现部分主要包括系统的各个功能的实现。
    网上购物商城包括两大模块:前台用户模块和后台管理员模块,前台用户可以通过浏览器客户端页面进行登陆和一系列的购物操作。后台管理员可以查看所有用户的所有信息;可以对网站中所有的商品分类进行修改,同时也可以对所有用户的订单状态进行查看。
    系统前台通过JSP页面来来展示数据,后台基于java技术和eclipse (朱诺)和tomcat 7.x开发,前台运用html+css技术渲染页面,后台使用springmvc、spring、myBatis对数据进行封装和操作,该系统运用MySql 5.X 数据库进行数据的维护。页面美观,使用方便。
    关键词:MySql数据库; JAVA; SSM;网上购物商城
    AbstractThis paper mainly focuses on the clothing sales system design and development of a number of paper, including the system design and implementation of a total of two parts, part of the system design and database analysis and design were described; the realization part includes the various functions of the system.
    Clothing sales system includes two modules: front user module and the background administrator module, the front desk users can browse through the browser client page and a series of shopping operations. The background administrator can view all the information of all users can be on the site of all the clothing category to modify, but also for all users to view the order status.
    In front of the system through the JSP page to display the background data, Java technology and based on eclipse (Zhu Nuo) and Tomcat 7.x development, the use of html+css technology to render the page, the background using springmvc, spring, myBatis package and operation of data, the system uses MySql 5.X database for data maintenance. Beautiful page, easy to use.
    Keywords: MYSQL DB;JAVA;SSM;CLOTHING SALES SYSTEM
    1 绪论1.1 研究背景在如今这个信息时代,“网上购物”这种购物方式已经为越来越多的人所接受。在这种背景之下,一个安全稳定并且强大的网络购物平台不可或缺,在这种成熟的市场需求的推动下,在先进的信息技术的支持下,商品产品销售系统应运而生。它可以使消费者和商家更紧密地联系起来,以更快地满足顾客的需求,也可以让用户选择自己真正喜欢的商品。目前市面上已经有此类的网上购物商城,但是现有商品网站系统或多或少存在着功能比较单一、维护比较复杂、操作比较繁琐等问题。有的系统甚至直接采用静态网页发布商品商品信息,这些因素在一定程度上限制了网上购物商城在目前市场上的推广。如何开发出费用低廉、功能强大的系统正是我们需要解决的课题。
    1.2 目的和意义本软件旨在降低商品销售商家的工作强度,提高工作效率,大大地减少了操作员手工录入数据的工作量,极大限度的避免了人力浪费,有效避免重复操作时间消耗;而且此软件方便了用户对自己所需商品的查询和购买,打破了传统的销售模式,极大限度的方便了用户。商家应用此软件之后,可以拓展销售门路,增加销售业绩。应用此软件是为了在传统销售模式之外,再开辟一条销售通路,减少库存堆积,利用网络共享和互动的优点,结合地面销售的优点,借助数据库管理技术,开发此平台,是为了实现规范化、个性化、人性化的商品网上销售。此软件的数据统计分析功能灵活完善,稳定安全、使用方便、界面友好、操作简单,可以成为一个能真正帮助商品销售行业管理发展的有力工具。
    1.3 开发工具及技术该网上购物商城前端使用了jsp来实现数据的展示,后端通过java代码来对数据进行一系列的操作,前端使用了原生的html页面技术进行渲染,同时也加入了jquery技术制作了一下控件效果,后端使用了经典的spring技术对整个系统进行统一调度,使用springMvc框架实现了前端和后端的交互。开发工具使用了Eclipse以及tomcat服务器,同时使用了Mysql数据库对数据进行存储和维护。
    在该系统实现的过程中,使用spring和springMvc的同时后端还使用了MyBatis技术对数据进行封装和操作。前端还采用了dtree框架规范了页面的显示。整个系统的架构也是基于经典的mvc设计模式来设计的。
    Mybatis是一个经典的后端开源框架,它的前身就是iBatis,MyBatis的执行原理是应用程序根据XML配置文件创建出SqlSessionFactory,然后SqlSessionFactory根据配置文件或者注解创建出SqlSession,SqlSession这个对象包含了所有的执行sql所需要的所有方法,可以通过SqlSession这个实例执行所有的方法对数据库进行操作,操作结束后执行相应的事物控制,本系统中的事物控制全部交由spring容器进行统一调度,本次采用的是spring的申明式 方式。MyBatis相对于 其他的ORM框架具有很多的优点,比如mybatis本身属于轻量级框架简单易学,没有第三方的依赖。mybatis比较灵活,开发人员可以自己编写sql语句来对数据进行操作。mybatis提供了xml标签,支持编写动态sql.
    dtree框架就是一个简单的树形菜单js组件,开源免费,自身不需要复杂的操作,同时也支持动态的将数据引入jsp页面。
    MVC模式是一种软件架构模式。它将系统分为三个部分:模型,视图和控制器。MVC模式出现的目的就是方便了后续程序的修改和扩展简化,同时使系统中某一段代码的重复利用成为可能。此模式降低了模块之间的耦合度,对自身各个部分进行了分离的同时也使得各个部分具备了应有的功能。
    Spring是从实际开发中抽取出来的开源框架,为企业的开发提供一个轻量级的解决方案。该解决方案包括:基于Ioc(控制反转)的核心机制,以及AOP(面向切面编程)的思想,能与多种持久层技术的整合,是优秀的Web MVC框架等。Spring致力于Java EE应用各层的解决方案而不是仅仅专注于某一层的方案,它贯穿表现层、业务层、持久层,降低各层组件的耦合度,实现软件各层的解耦.Spring内部最核心的就是IOC了,动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟xml Spring的配置文件来动态的创建对象,和调用对象里的方法的。还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象 进行监督和控制(也就是 在调用这类对象的具体方法的前后去调用你指定的 模块)从而达到对一个模块扩充的功能。这些都是通过配置类达到的。Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能。
    2 需求分析2.1 功能需求分析2.1.1 网站前台功能
    首页:提供一个网站首页,显示该企业的商标,该网站用户的登录,注册,所有商品的一级分类,热门商品和最新商品的展示等
    用户的注册:针对还未注册的用户完成注册功能的使用,在注册的过程中涉及数据的合法性校验,以及利用ajax完成用户名是否已被注册的异步校验
    用户的登录:对于已经注册并且激活的用户提供的登录操作
    用户的退出:对于已经登录的用户,退出系统
    首页商品展示:展示出最新商品和热门商品
    分类页面商品展示:根据一级分类和二级分类去展示该分类下的所有商品
    商品详情展示:点击某个商品时可以展示该商品的具体详细信息
    购物车:用于存放用户的购物内容,用户可根据自己的情况修改自己的购物车
    订单:对于已经登录的用户可以对购物车内容进行付款生成订单,可以为自己的订单进行付款或者查看
    留言评价分享:网站单独开辟了留言分享区域,供登录的用户自由发表评价分享心得信息,进行交流互动

    2.1.2 网站后台功能
    管理员登录:管理者根据账户和密码进行登录
    商品一级、二级分类管理:管理者可以对前台显示的一级、二级分类进行管理,包括添加、删除、修改操作
    商品管理:管理者可以对前台显示的商品进行管理包括添加,修改,删除,查询的功能,也可以上传商品的图片
    用户管理:管理者可以查看该网站中已经注册过的所有用户的所有信息

    2.2 性能分析响应时间:忽略网络、硬件以及插件的因素,以本地测试为准,前台响应时间为0.8秒,后台操作响应时间:0.9秒。
    2.3 系统用户用例图用户用例图
    用户为系统的使用者,可以通过前台注册激活登录后进行一系列的购物操作。

    管理员用例图
    管理员是整个系统的最高权限拥有者,他用于对所有用户的所有信息的查看,网站商品显示的增删改查,更换图片,所有商品所属一级二级分类的修改。

    3 系统设计3.1 系统的总体设计该系统的开发采用B/S模式,整个系统的构建基于ssm(Spring+SpringMvc+MyBatis)整合框架。
    深入研究JavaEE体系结构,所项目的技术选型中选取的个个框架分别进行分析和研究。SpringMvc是一个web端框架。Mybatis是一个轻量级的持久层框架,以面向对象的方式提供了持久化类到数据库之间的映射,是一种优秀的ORM框架。Spring也是一种轻量级框架,它的IOC和AOP思想,值得架构师学习。通过三大框架的整合,可以很方便的构建出可扩展,可移植,可维护的软件系统。
    SSM框架是目前J2EE领域中最热门而且用的比较成熟的一套开源框架,它是基于MVC设计模式之上,充分发挥了MVC的优点。SSM是一套轻量级框架,相对于EJB而言,SSM继承了它的优点的同时,在开发和执行效率上也有了明显的提高,而对于开发者而言,它比EJB更加易学和掌握。目前SSM框架也正在不断地进行优化和维护,运行也是越来越稳定。
    根据以上功能分析,得到系统功能模块结构图如图3-1所示:

    3.2 数据库的分析与设计数据库,我们可以形象的将它称为一个仓库,因为它一般被用来存放汉字、字符、数据、货币、日期等信息,并且对这些信息按照一定规则存放,对数据进行安全、低冗余性、规范的进行集成化管理。从发展的历史历程来看,数据库可以看成是由文件管理系统发展而来的。
    数据库的基本结构可以分为三个层次包括物理数据层、概念数据层、逻辑数据层。数据库不同层次之间的联系是通过映射进行转换的,数据库的特点包括实现数据共享、减少数据的冗余度、数据的独立性、数据实现集中控制、数据一致性和可维护性。
    本系统采用的的数据库是Mysql5.0,本系统所有与数据库相关的开发都遵循Mysql5.0数据库开发原则。
    3.2.1 数据库概念设计用户实体
    用户实体包括编号、用户账号、姓名、联系方式、性别、用户状态、用户邮箱和密码等属性。用户实体的实体联系图(E-R图)如下所示:

    管理员实体
    管理员实体包括编号、账号和登录密码属性。管理员实体的实体联系图(E-R图)如下所示:

    商品实体
    商品实体包括商品id、商品名称、市场价、商场价、商品图片、商品描述、上架日期、所属二级分类id。商品实体的实体联系图(E-R图)如下所示:

    订单实体
    订单实体主要包括订单id、订单总价、订单状态、收货人、收货地址、收货电话、下单时间、购买者id、购买商品id。订单实体的实体联系图(E-R图)如下所示:

    3.2.2 数据库物理结构为该系统设计了7张表,在这里列出7张表分别为如下所示:



    数据表
    描述




    adminuser
    后台管理员表


    category
    一级分类表


    categorysecond
    二级分类表


    orderitem
    订单项表


    orders
    订单表


    product
    商品表


    user
    前台用户表



    管理员表主要记录了管理员的基本消息,表结构如表3-1所示。



    字段
    数据类型
    允许空值(默认NO)
    自动递增
    备注




    id
    int(11)
    YES
    YES
    账号


    username
    varchar(1000)
    NO
    NO
    用户名


    password
    varchar(1000)
    NO
    NO
    密码



    一级分类表主要记录了一级分类的基本信息,表结构如图3-2所示。



    字段
    数据类型
    允许空值(默认NO)
    自动递增
    备注




    cid
    int(11)
    YES
    YES
    一级分类ID


    cname
    varchar(1000)
    NO
    NO
    一级分类名



    二级分类表主要记录了二级分类的基本信息,表结构如图3-3所示。



    字段
    数据类型
    允许空值(默认NO)
    自动递增
    备注




    Csid
    int(11)
    YES
    YES
    二级分类id


    Csname
    varchar(1000)

    NO
    二级分类名称


    cid
    varchar(1000)

    NO
    所属一级分类id



    订单项表主要记录了订单项的基本信息,表结构如图3-4所示。



    字段
    数据类型
    允许空值(默认NO)
    自动递增
    备注




    Oiid
    int(11)
    YES
    YES
    订单项id


    count
    varchar(1000)


    购买数量


    subtotal
    double


    单项总价id


    Pid
    int(11)


    所购商品id


    cid
    int(11)


    所属订单id



    订单表主要记录了订单的基本信息,表结构如图3-5所示。



    字段
    数据类型
    允许空值(默认NO)
    自动递增
    备注




    oid
    int(11)
    YES
    YES
    订单id


    money
    double


    订单总价


    state
    Int(11)


    订单状态


    Receiveinfo
    Varchar(255)


    收货地址


    phonum
    Varchar(255)


    收货人电话


    Order_time
    datetime


    下单时间


    Uid
    Int(11)


    所属用户id



    商品表主要记录了商品的基本信息,表结构如图3-6所示。



    字段
    数据类型
    允许空值(默认NO)
    自动递增
    备注




    Pid
    int(11)
    YES
    YES
    商品id


    Pname
    Varchar(255)


    商品名称


    Market_price
    Int(11)


    市场价


    Shop_price
    Varchar(255)


    商城价


    image
    Varchar(255)


    商品图片


    Pdesc
    Varchar(255)


    商品描述


    Is_hot
    int(11)


    是否热门


    Pdate
    datetime


    商品上架日期


    csid
    int(11)


    所属二级分类id



    前台用户表主要记录了前台用户的基本信息,表结构如图3-7所示。



    字段
    数据类型
    允许空值(默认NO)
    自动递增
    备注




    Uid
    int(11)
    YES
    YES
    用户id


    Username
    Varchar(255)


    用户名


    password
    Varchar(255)


    用户密码


    Name
    Varchar(255)


    用户真实姓名


    Email
    Varchar(255)


    用户游戏


    Phone
    Varchar(255)


    用户手机号


    Addr
    Varchar(255)


    用户地址


    State
    int(11)


    用户状态



    3.3 小结本章主要是对数据库进行了设计和说明。对数据库的概念设计思路和物理结构进行了详细的说明,并对数据库中涉及到的实体进行了说明。
    4 系统主要功能实现4.1 系统注册页面实现4.1.1 客户端用户注册用户登录网站出现页面,点击“注册”,进入注册页面,填写数据,点击注册按钮进行注册,注册完之后保存数据库表中,即可登录网站。
    注册效果如图4-1所示:

    var username = document.getElementById("username").value;var xmlHttp = creatXMLHttpreauest();xmlHttp.open("GET","${pageContext.request.contextPath}/registFindByid.action?username="+ username, true); xmlHttp.send(null); xmlHttp.onreadystatechange = function() { if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { document.getElementById("span1").innerHTML = xmlHttp.responseText;
    服务器端二次数据合法性校验(此处采用的配置文件加注解的方式)
    user.username.length.error=用户名的名字的长度必须是1至30user.email.notNull=邮箱不可为空@Size(min=2,max=30,message="{user.username.length.error}") private String username; @NotNull(message="{user.email.notNull}") private String email;
    4.2 系统登录页面实现4.2.1 用户登录用户在注册后,在客户端登录页面输入正确的用户名和密码,进入网站进行购物。 程序运行如下图4-2所示:

    设计思路
    编写用户登录的页面login.jsp,用户在首页点击“登录”按钮后,浏览器跳转到登录页面,用户可以填写用户名和密码进行登录,当用户填写用户名并使光标移开 时,触发onblur()事件,进行ajax异步请求,判断用户名是否可以登录,用户在填写验证码时可以点击图片,进行跟换验证码,触发onclick=”change()” 事件进行更换,当用户点击“登录”按钮时,服务器进行数据判断,如果用户名和密码都正确则跳转到首页并显示该用户的用户名,如果有错误则跳转到msg.jsp全局页面显示错误消息。
    4.2.2 管理员用户登录后台管理员通过访问正确的路径之后进入到管理员登录页面,如果访问的不是正确页面但出现了admin路径则自动跳转到admin页面,然后输入正确的用户名和密码进行登录,如果出错,服务器会将错误信息回显到登录页面,如果正确则跳转到管理员页面。
    程序运行结果如图所示,图4-3显示了管理员登录的页面,图4-4则是管理员登录成功后的主页面:


    4.3 系统前台功能实现系统前台页面包括以下几个部分:首页一级分类,热门商品,最新商品的显示,二级分类的显示,已登录用户的订单以及用户所操作过的购物的展示,其中一级分类和二级分类在各个页面中都有所设计,因此这里采用的是页面包含技术。
    4.3.1 一级分类模块查询一级分类描述
    本系统中首页显示的一级分类都是存放于数据库中,当用户访问该网站首页的同时就查询了一级分类。一级分类显示效果如图4-5所示:

    设计思路
    一级分类展示于系统的首页,当用户访问index.action时,最终跳转至系统首页即index.jsp,跳转之前,服务器内部已经进行了一级分类的查询,并将已经查询到的以及分类存放于List集合中,最终存放于session域中。
    查询某个一级分类描述
    用户在进入系统首页时,当点击一级分类时就要求查询系统在下一个页面中显示出该一级分类中包含的所有二级分类。查询某个二级分类的效果图如图4-6所示:

    设计思路
    当用户点击首页中的一级分类时系统则根据此一级分类的id查询出该一级分类下所有的二级分类,并存放于session域中,将页面进行跳转,并进行展示。
    主要代码
    request.getSession().setAttribute("cid",cid);PageBean<Product> proPageBean = productService.findProductyBycid(cid,page);model.addAttribute("pageBean",proPageBean);return "category";
    4.3.2 商品模块查询最热商品描述
    当用户访问该网站时,首先显示的是网站的首页,首页中将显示本网站中最热的商品。程序运行结果如图4-7所示:

    设计思路
    用户访问首页index时,根据路劲“/index.action”首先调用的是系统的index.action,最后跳转至系统的首页index.jsp,因为最热商品显示于首页中,因此在页面跳转之前必须前往数据库查询出本系统中所有的热门商品,因此使用了findHotProduct()这个方法,由于首页中仅仅显示了最新商品中的前十个,因此这里是使用的分页查询,最终查询的结果是一个list集合,最终保存在Model中。
    前段控制层代码
    List<Product> hList= productService.findHotProduct();
    service层代码
    List<Product> list = productMapper.selectByExample(example);
    查询最新商品描述
    当用户访问该网站时,首先显示的是网站的首页,首页中将显示本网站中最新的商品。程序运行结果如图4-8所示:

    设计思路
    用户访问首页index时,根据路劲“/index.action”首先调用的是系统的index.action,最后跳转至系统的首页index.jsp,因为最新商品和最热商品一样都是显示于首页中,因此在页面跳转之前必须前往数据库查询出本系统中所有的最新商品,因此使用了findNewProduct()这个方法,查询最新商品的依据是商品被上传的时间,根据时间来进行排序,由于首页中仅仅显示了最新商品中的前十个,因此这里是使用的分页查询,最终查询的结果是一个list集合,最终保存在Model中。
    前端控制层代码
    List<Product> nList =productService.findNewProduct();
    service层代码
    ProductExample example = new ProductExample();ProductExample.Criteria criteria = example.createCriteria();example.setOrderByClause("pdate DESC");example.setBeginPage(0);example.setEnd(10);
    查询分类商品描述
    用户在点击首页的一级分类时,系统自动跳转页面,同时要求在右面显示某个二级分类下的商品。程序运行结果如图4-9所示:

    设计思路
    首先导入页面,页面和查询二级分类下的商品使用的是同一个页面category.jsp。当用户点击按钮时,客户端向服务器请求发送请求并携带一级分类的主键id,因此服务器端应该接受参数并使用这个参数来调用方法然后去数据库进行查询数据,最后将查询出的数据把保存于Model中,最后跳转页面。
    由于页面大小的关系,这里仅仅显示12个商品,因此这里采用了分页查询,并在右下角设置相应的按钮,方便用户来回查看该分类下所有的商品。
    前端控制层接收参数并调用service层代码
    //根据一级目录查找二级目录下面的商品productService.findProductyBycid(cid,page);model.addAttribute("pageBean",proPageBean);
    Servive层代码
    int totlePage = 0;totlePage = productMapper.countProducyByCid(cid);if(Math.ceil(totlePage % limitPage)==0){totlePage=totlePage / limitPage;}else{totlePage=totlePage / limitPage+1;pageBean.setTotlePage(totlePage);int beginPage= (page-1)*limitPage;
    查询二级分类商品用户在点击首页的一级分类时,系统自动跳转页面,并且在页面的左面显示所有一级分类包含的二级分类,同时要求在右面显示某个二级分类下的商品。程序运行结果如图4-10所示。

    设计思路
    首先编写页面category.jsp,这个页面用来显示某个二级分类下的所有的商品,当用户点击二级分类时系统访问对应的action,并且携带参数(相应二级分类的主键id),到前端控制层,然后findCategorySecond1()方法接收主键id和分页的数目去product表查询商品,最终将查询到的结果存放于Model中。由于页面大小的关系,这里仅仅显示12个商品,因此这里采用了分页查询,并在右下角设置相应的按钮,方便用户来回查看该分类下所有的商品。
    前端控制层接收参数并调用service层
    // 根据csid来分页查询商品PageBean<Product> proPageBean = productService.finbProductByCsid(csid,page);model.addAttribute("pageBean",proPageBean);
    查询商品信息用户再浏览该商场,查看某个商品的详细信息。程序运行结果如图4-11所示:

    设计思路
    首先编写页面,这里使用的是product.jsp,在这个页面中显示了以及分类的信息,还有每个一级分类下的二级分类,右下方是某个商品的具体信息,其中包括商品的名称,商品的商城价和市场价,包括一个选择框,用于用户选择购买数量,最下面则是商品的具体介绍。当用户点击某个想要查看的商品图片时,其实就是点击了某个超链接,向服务器发送链接并携带参数(商品的主键id),服务器端接收这个参数,并使用这个参数去数据库中查看这个商品的具体信息最后封装于product中,最终存放于Model中。
    前端控制层接收参数并调用service层,Service层直接调用Mybatis提供的mapper接口
    //根据pid来查询商品Product product = prodcutService.productFindByPid(pid);model.addAttribute("product", product);
    4.3.3购物模块添加到购物车对于已经登录的用户,可以将看中的商品具体信息保存于自己的购物车中。

    设计思路
    首先编写cart.jsp用于显示登录用户的购物车,如果用户没有登录会有提示,用点击查看商品的详情之后会出现一个“加入购物车”按钮,当点击此按钮时,自动访问服务器,并通过隐藏表单携带参数(商品的主键id),服务器端在接受此参数,并接收用户选购的数量,最终保存于我们为每个用户在session域中创建的cart。最后进行页面跳转,在cart.jsp中展示购物车的信息,主要包括:商品的具体信息和每项的价格和购物车的总价。对于已登录用户的页面,可以看到一个购物车的图标,用户可以查看自己的购物车。
    主要代码
    //添加到购物车Product product = productService.finbProductByPid(pid);//存进一个购物项CartItem cartItem = new CartItem();cartItem.setCount(count);cartItem.setProduct(product);cartItem.setSubtotle(count*product.getShopPrice());//存进购物车Cart cart=getCart(request);cart.addCart(cartItem);
    从购物车中移除商品用户点击购物车页面中每个购物项后面的删除按钮即可删除该购物项。程序运行结果如图4-13所示:

    设计思路
    当用户点击 “删除”按钮时,向服务器端进行请求,并携带参数(商品的主键id),服务器端在设计购物车时采用的是用Map集合存储的,key值即商品的id,因此删除的时候只需从session中拿到购物车直接根据主键删除,最后将页面重定向到cart.jsp.
    主要代码
    Cart cart=getCart(request);cart.delProFromCart(pid); //删除某个购物项
    清空购物车用户点击“清空购物车”按钮,购物车里面的购物项全部删除。程序运行结果如图4-17所示:

    设计思路
    当用户点击 “清空购物车”按钮时,向服务器端进行请求,服务器端收到请求之后,从session域中取出cart购物车,由于cart在设计的时候使用的是Map集合,所以只需调用Map中的clear()方法即可,并且还需将购物车的总价改为0,最后将页面重定向到cart.jsp.
    主要代码
    // 清空购物车Cart cart=getCart(request);cart.clearCart();
    4.3.4 订单模块生成订单当用户点击“生成订单”按钮时,页面跳转至order.jsp,并让用户填写相关信息。程序运行结果如图4-15所示:

    设计思路
    首先编写order.jsp页面,其中包含用户的购物信息和收货地址、收货人和联系方式。当用户点击cart.jsp中的生成订单按钮时,向服务器发送请求,服务器端从session域中拿到cart中的信息,并将这些信息保存于order表中,此时,需要清空购物车并且将订单信息保存到session域中,最后跳转到order.jsp页面让用户填写相关信息,并付款。
    主要代码
    Orders orders = new Orders();Cart cart = (Cart) request.getSession().getAttribute("cart");User loginUser = (User) request.getSession().getAttribute("loginUser");if(loginUser==null){ model.addAttribute("message", "对不起您还没有登录"); return "msg";}//生成订单
    我的订单用户对自己的选购的商品所生成的订单项进行付款。即可生成订单,进入我的订单列表界面;程序运行结果如图4-16所示:

    设计思路
    为订单付款页面还是使用的是order.jsp,当用户点击cart.jsp中的提交按钮时,页面进行跳转并显示相关的订单信息,此时,用户可以暂时不对订单进行付款,此时订单的状态为0。如果用户在生成订单的同时一并付款,或者点击用户的最上方右边的红色字体“我的订单”时,页面会进行跳转,并显示该用户的所有订单和订单的状态,此时想要付款则点击按钮“付款”,也会跳转到order.jsp,此时需要用户填写订单的具体信息,包括收货地址、收货人、联系方式以及付款的银行,此时客户端和服务器端一样会进行非空和数据合法性校验,当用户填写好信息并点击“付款”按钮时,其实就是服务器端拿订单的具体信息,并将订单的状态改为“1”,同时将用户填写的关于收货的信息保存于数据库order表中,最终服务器端会将页面重定向到orderList.jsp,向用户展示他的所有的订单以及订单的具体信息。在orderList.jsp中展示该用户的所有订单时采用的是分页查询,在订单的右下角同时也设置了按钮,方便用户查看自己的所有按钮。
    4.3.5 留言模块留言板当用户点击“留言板”按钮时,页面跳转至messageList.jsp,并让用户填写相关信息。程序运行结果如下图所示:

    4.4 系统后台功能实现4.4.1 用户模块查询用户管理员进入后台管理页面之后,当他点击“用户管理”按钮时,则在主页面中显示所有用户的详细信息。程序运行结果如图4-17所示:

    设计思路
    先编辑list.jsp页面,当用户点击“用户管理”按钮时,服务器端收到请求,调用service层的admin_findAll()方法由service 层调用myBatis提供的mapper接口,返回一个list集合,最终所有信息封装于Model中将页面跳转到list.jsp并进行展示。
    主要代码
    if(adminuserLogin==null){ request.getSession().setAttribute("message","对不起您还没有登录"); return "admin/index";
    4.4.2 一级分类模块添加一级分类此功能属于管理员的权限范围内,用户管理员为网站添加新的一级商品系别。程序运行结果如图4-18所示:

    设计思路
    首先编写add.jsp页面,当用户在一级分类list.jsp页面点击“添加”按钮时, 服务器将页面跳转至add.jsp,在此页面共有三个按钮,“确定”按钮用于提交信息,“重置”按钮清空表单中的内容,“返回”按钮返回前一个页面。当用户填写好要添加的一级分类的名称之后点击“确定”按钮,服务器端接收此表单中的内容,然后调用service层的addCategory()方法,将新增的一级分类保存到数据库category表中,最后将页面重定向到list.jsp页面,展示所有的一级分类。
    主要代码
    Category addCategory = new Category();addCategory.setCname(cname);categoryService.addCategory(addCategory);
    修改一级分类此功能属于管理员的权限范围内,管理员用户修改网站中各大服饰的一级分类的名称。程序运行结果如图4-19所示:

    设计思路
    首先编写edit.jsp页面,当用户在一级分类list.jsp页面点击“添加”按钮时, 服务器将页面跳转至edit.jsp,在此页面共有三个按钮,“确定”按钮用于提交信息,“重置”按钮清空表单中的内容,“返回”按钮返回前一个页面。当用户填写好要修改的一级分类的名称之后点击“确定”按钮,服务器端接收此表单中的内容,然后调用service层的adminCategory_update()方法,将修改的一级分类更新到数据库category表中,最后将页面重定向到list.jsp页面,展示所有的一级分类。
    删除一级分类后台管理员点击每个一级分类后面的删除按钮即可删除该一级分类。程序运行结果如图4-20所示:

    设计思路
    当用户点击每个一级分类后面的“删除”按钮时,服务器接收到请求然后接收携带过来的参数(一级分类主键id),当我们准备删除一级分类时,如果删除了改一级分类那么相应的二级分类和二级分类下的商品就得全部删除,因此我们根据myBatis的规则。先根据外键删除二级分类然后再删除一级分类,因此首先调用adminCategorySecond_deleteByCid(cid)删除二级分类然后再调用categoryService.deleteCategoryByCid(cid);删除一级分类,最终将页面重定向到list.jsp页面。
    主要代码
    categorySecondService.adminCategorySecond_deleteByCid(cid); categoryService.deleteCategoryByCid(cid);
    查询一级分类管理员点击“一级分类管理”按钮时,展示所有的一级分类的详细信息。程序运行结果如图4-21所示:

    设计思路
    首先编写list.jsp页面,当管理员用户点击“一级分类管理页面”按钮时,服务器端接收请求然后调用adminbFindCategory()方法最终由service层调用myBatis提供的Mapper接口将所有的一级分类的信息查询出来保存到list集合中,最终保存到Model中并将信息进行展示。考虑到一级分类比较多,这里使用了分页查询,在页面展示的效果就是每页显示固定的个数,并在右下角提供了相应的按钮方便用户进行查看其他的一级分类。
    主要代码
    List<Category> categoryList = categoryService.adminbFindCategory();model.addAttribute("categoryList", categoryList);
    4.4.3 二级分类模块添加二级分类管理员用户为新增加的一级分类添加二级分类。程序运行结果如图4-22所示:

    设计思路
    首先编写二级分类添加页面add.jsp,管理员用户点击“添加”按钮时,页面跳转到add.jsp,同时服务器端将查询出所有的一级分类的名称,用于管理员选择新增的二级分类的归属,这在add.jsp页面中通过一个下拉列表进行显示。管理员用户在填写好新增的二级分类的名称并选择好所属的一级分类之后点击“确定”按钮,服务器端接收新增的二级分类名称和所属的一级分类的主键id,然后调用adminCategorySecond_save()方法将新增的Categorysecond保存于数据库的categorysecond表中。最后将页面重定向到二级分类的list.jsp页面进行展示。
    主要代码
    Categorysecond categorysecond = new Categorysecond();categorysecond.setCsname(csname);categorysecond.setCid(cid);categorySecondService.adminCategorySecond_save(categorysecond);
    修改二级分类管理员用户可以为网站中所有的二级分类的名称进行编辑。程序运行结果如图4-23所示:

    设计思路
    首先编写二级分类修改页面edit.jsp,管理员在list.jsp点击“编辑”按钮时,页面跳转到edit.jsp页面,跳转之前,服务器端查询到对应的二级分类的名称并将二级分类的名称保存到edit.jsp对应的表单中,这样方便用户知道自己修改的是哪个二级分,增加了用户体验度
    查询出对应的二级分类的名称存放于表单中,增加了用户体验
    Categorysecond findByCsid = categorySecondService.findByCsid(csid);model.addAttribute("findByCsid", findByCsid);
    更新修改的二级分类
    Categorysecond categorysecond = new Categorysecond();categorysecond.setCsname(csname);categorysecond.setCsid(csid);CategorySecondService.adminCategorySecond_update(categorysecond);
    删除二级分类后台管理员根据查询出的二级分类列表对二级分类进行操作,根据系统的要求,管理员用户在删除二级分类的同时应该删除该二级分类下的所有商品。
    设计思路
    管理员用户在点击“二级分类用户”按钮时,在管理员页面展示所有的二级分类,当用户点击“删除”按钮时,服务器端收到客户端发来的请求,并接受客户端传来的数据(二级分类的主键id),然后根据二级分类的主键id调用adminCategorySecond_delete(csid)方法,删除二级分类,然后根据外键删除商品。最后将页面重定向到二级分类的list.jsp页面。
    主要代码
    // 删除二级分类,二级分类关联二级分类下面的商品categorySecondService.adminCategorySecond_delete(csid);categorySecondService.adminProduct_deleteByCsid(csid);
    查询二级分类管理员通过点击“二级分类管理”来查看网站中所有的二级分类。程序运行结果如图4-24所示:

    设计思路
    首先得编写二级分类的list.jsp页面。管理员用户点击“二级分类管理”按钮时,给服务器发送请求,并携带分页参数,服务器端接收此参数之后开始查询所有的二级分类,这里创建了一个pageBean对象用于封装查询出来的数据,包括二级分类的集合,当前的页数,一共的页数等信息,最后直接返回一个pageBean对象,因为二级分类较多,这里采用了分页查询,需要用到这些数据因此直接封装在了pageBean对象里。用户可以通过二级分类的list.jsp页面右下方的按钮来查看所有的二级分类。
    4.4.4 商品分类模块添加商品管理用户通过点击商品展示页面list.jsp上的“添加”按钮可给网站添加新的商品。程序运行结果如图4-25所示:

    设计思路
    首先编写商品添加页面add.jsp。管理员用户点击商品展示页面list.jsp上的“添加”按钮之后客服端跳转到add.jsp页面,在客户端页面跳转之前,服务器端需要查询出所有商品的二级分类,方便上传用户选择该商品所属的二级分类。管理员需要填写页面上的信息包括商品名称、选择是否热门、市场价格、商城价格、上传商品图片、选择所属二级分类和编写商品描述这些信息。管理员用户点击“确定”按钮之后客户端将数据提交给服务器,客户端在上传上传组件时必须将上传组件表单type设置为file类型,这样服务器端才能正确的识别。最后服务器端接收到数据之后封装于product对象中,并调用adminProduct_save(product);将新上传的product保存到数据库中的product表中,最后将页面重定向到商品的list.jsp页面。
    主要代码
    product.setPdate(new Date());if (file != null) { String path = request.getServletContext().getRealPath("/products"); String uploadFileName = file.getOriginalFilename(); String fileName = UUIDUtiils.getUUID()+uploadFileName; File diskFile = new File(path + "//" + fileName); product.setImage("products/" + fileName);
    删除商品管理员用户点击“商品管理”来到展示所有商品页面,通过点击页面上的删除按钮即可删除指定的商品。
    设计思路
    这个功能是基于商品的展示页面list.jsp进行开发的,展示用户页面时pageBean里面封装了product的所有信息,当用户在点击“删除”按钮时即向服务器发送请求并携带参数(商品的主键id),服务端在接收到请求之后,根据客户端传来的参数进行删除该商品,最终将页面重定向到商品的展示页面list.jsp.
    jsp页面方法主要代码
    function deletecs(pid) { window.location.href = " ${pageContext.request.contextPath}/ admin/adminProduct_deletecs.action?pid="+pid;
    查询商品管理员通过点击“商品管理”按钮来查看本网站中所有的商品信息。程序运行结果如图4-26所示:

    设计思路
    首先编写商品下面的list.jsp页面,管理员用户在点击“商品管理”按钮时,给服务器发送请求,并携带分页参数,服务器端接收此参数之后开始查询所有的商品信息,这里创建了一个pageBean对象用于封装查询出来的数据,包括商品的集合,当前的页数,一共的页数等信息,最后直接返回一个pageBean对象,因为商品个数较多,这里采用了分页查询,需要用到这些数据因此直接封装在了pageBean对象里。用户可以通过商品文件夹里面的list.jsp页面右下方的按钮来查看所有的是商品信息。
    主要代码
    // admin的商品管理(查询所有的商品)PageBean<Product> allProPageBean = productService.findAllProduct(page);model.addAttribute("allProPageBean", allProPageBean);
    4.4.5 留言管理模块管理用户通过点击留言管理链接,即可打开前台顾客的留言列表界面,并且可以删除不合时宜的留言信息。程序运行结果如图4-26所示:

    5 系统测试与维护5.1 系统测试环境5.1.1 硬件环境
    CPU:英特尔酷睿四核
    内存:4G

    5.1.2 软件环境
    操作系统:windows 7
    服务器:Tomcat 7
    浏览器:Mozilla Firefox 和chrome

    5.2 系统测试内容使用eclipse编程软件编写Java源程序是遇到语法错误会自动报错,需要及时修改错误。对系统进行测试视为系统能有效运行并且没有异常产生。
    在程序模块编写时,每编写完一个模块需要进行模块单元测试,保证单元模块功能正常,在所有单元测试进行结束之后,需要进行整个系统的集成测试。本系统需要做如下的测试:

    登录注册测试:多次注册用户并且登录。则表达式检验的文本框输入错误信息,检测代码是否可行,注册成功后,检验用户是否可以正常显示,并查看数据库,检验数据是否成功插入。登录时,交叉使用正确和错误的密码进行登录测试,校验是否有异常
    查询一级分类测试:测试当用户访问index.action时,是否可以至系统首页即index.jsp,测试成功
    查询二级分类测试:测试用户在点击首页的一级分类时,系统是否会自动跳转页面,并且在页面的左面显示所有一级分类包含的二级分类
    购物车测试:测试已登录的用户是否可以将商品添加到购物车、移除购物车内商品、清空购物车
    订单模块测试:测试是否可以正常生成订单、取消订单、为订单付款

    5.3 系统维护系统维护是为了让系统能够在正常运行的基础上,对系统中的一些小问题进行修复并且不断完善的过程,通过系统维护能够使系统保证在不同的运行环境下均可以正常的工作,各个模块功能正常运行。
    由于本系统的本质就是一个电子商城,所以难免会有很多过期的没用的数据。所以需要定期进行“垃圾”信息的删除,对于系统中重要的一些内容如用户和商品等。要定期对数据库备份,保证数据的正确性。本系统的维护就是为了使本系统能够稳定的运行,所以需要定期维护,并且备份数据。
    小结:本章首先介绍了系统的测试环境,接下来详细介绍了单元模块测试的方法和整体集成测试的主要内容,最后介绍了系统维护的方案。
    6 总结如今,JavaEE是一个非常优秀的企业信息化开发平台,由于其拥有一些很好的性质包括稳定的性能、良好的开发性和非常高的安全性因此被广泛运用于企业级开发。这篇论文基于当前比较流行的电商系统为项目背景,遵循javaEE应用软件的规则进行开发,将系统划分为四个层次包括模型model层,持久层,业务逻辑service层和表现层,并整合了目前在企业中广泛运用的spring、springMvc和myBatis框架进行开发。Spring用于整个系统的统一调度,贯穿于各层之间,springMvc框架着重于mvc模式的实现,myBatis框架完成数据的映射和持久化工作,myBatis的逆向工程极大的方便了dao层的开发,也方便了系统dao层的维护。
    本论文主要完成了以下的任务:

    正确分析了电商目前的发展形势,特别是对网购的发展进行了深入的调查和研究
    深入明确了系统的总体架构,在技术选型上选取了三个主流的框架,对三者的功能,整合做了详细的描述
    系统项目的开发严格遵循软件的开发规范,制定了详细的系统开发步骤,开发之前做了大量的工作包括:需求分析、技术选型、架构设计等
    完成了预期赋予系统的功能的实现

    本文虽然完成了预期研究和目标,但后期还有很多工作需要完成:,随着web应用的快速发展,处于信息时代下会有更多的技术应运而生,不光需要对框架进行深入学习和研究还要对系统的架构进行研究。目前客户端技术正在崛起,我们需要认真做调查和研究做出一能让用户体验度更好的产品。以上只是目前的构想,接下来会继续深入研究并作进一步的完善和设计开发。
    7 参考文献[1] 杨开振等. Java EE互联网轻量级框架整合开发— —SSM框架(Spring MVC+Spring+MyBatis)和Redis实现[M]. 电子工业出版,2017.07.
    [2] 李俊民.HTML 5+CSS 3网页设计经典范例[M].电子工业出版,2010.
    [3] 邹红霆. 基于SSM框架的Web系统研究与应用[J]. 湖南理工学院学报(自科版), 2017, 30(1):39-43.
    [4] 王珊 萨师煊 数据库系统概论[M] 北京:高等教育出版社 2007
    [5] 陈雄华 Spring企业级应用开发详解[M] 北京:电子工业出版社 2009
    [6] 原著施奈德 成栋翻译 电子商务[M] 北京:机械工业出版社 2008
    [7] 阿里巴巴网络技术有限公司 中小企业电子商务之路[M] 北京:清华大学出版社 2007
    [8] 刘克强 电子商务平台建设[M] 北京:人民邮电出版社 2007
    [9] 程杰 大话设计模式[M] 北京:清华大学出版社 2010
    [10] 雷之宇 朱训雨 张麟 JAVA实用组件集[M] 北京:电子工业出版社 2008
    1 评论 6 下载 2019-05-15 16:25:48 下载需要17点积分
显示 30 到 45 ,共 15 条
eject