分类

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

资源列表

  • 分布式文件系统研究与应用

    摘 要分布式文件系统,在当今集群存储中起着重要的作用,其中moosefs更是当中的佼佼者,他是一种分布式网络系统,它分布在多个计算机节点上面,每个节点只会存储整个文件的一部分内容,它有多重备份,易于部署,方便扩容等诸多的优点,而且它能够统一接口,使用它就像使用普通的文件系统一样,而且它对小文件的处理,性能优秀。它采用当今主流的Master /Chunk 设计,而且有强大的日志功能,数据恢复更有保证。
    本文所提及实现的是一个基于分布式文件系统的网盘,主要是通过大量的分布式存储节点提供存储服务,再通过指定的服务器进行挂在到本地,对外提供存储服务。提供统一的开放接口,提供给开发者使用。
    此分布式网盘,可以提供数据自动备份,将数据备份为3份,备份到不同的节点至上,从而使得数据的安全性大大的提高。
    整个开放分布式网盘,主要由三个部分组成,Moosefs,分布式网盘,分布式网盘开放接口。Moosefs主要提供分布式存储,备份,冗余等功能,分布式网盘主要提供逻辑上的操作,开放接口,是分布式网盘对外提供服务的桥梁,开发者通过API来使用分布式网盘,从而提高分布式网盘的使用范围。
    关键字: 分布式文件系统,Moosefs,数据恢复
    AbstractThe distributed file system plays an important role in today’s clustered storage, which moosefs is the leader among them, it is a distributed network system, it distribution in multiple computer take nodes above, each node only will store the entirepart of the contents of the file, it has multiple backup, easily deploy, convenient expansion, and it to unified interface, use it just like ordinary file system,and its small file handing, performance is excellent. It takes the Master/Chunk of today’s mainstream design, and robust logging functionality, data recovery is more assured.
    This article is a reference implementation of a distributed is a network-base distributed file system disk, primarily through a large number of distributed storage nodes providing storage services, and then by the specified server hanging on to local , to provide storage service.
    This distributed network that provides automatic data backup, data backup 3, first backup to a different node so that greatly improve data security.
    Open distributed Web site as a whole, is composed of three key components, Moosefs, distributed networks, distributed network of open interfaces. Moosefs primarily provide a distributed storage, backup, redundant functions, operation on a distributed network disk provides a logical, open interfaces, distributed Web site provides services that bridge developer API to use a distributed network, so as to improve the use of distributed network disk.
    Key words: distributed file system; Moosefs; data recovery
    1 引言1.1 课题背景与现状现在网络技术的发展和深入的应用,互联网上的信息呈现爆炸式的增长,大数据,大批量的小文件等等的处理能力越来越重要,尤其是以javascript,css,图片,音频,和视频等文件形式的小中型数据的增长尤为迅速,如何高效的,方便的,安全的,存储和管理这些数据,并且快速的读取,写入等等,已经成为了业界一个难题。
    现在计算机技术,人们的需求,正在迅速的发展,几百万亿字节的存储,已经是司空见惯了,cpu,内存等等指标正在不断的提高,但是磁盘的存储能力却一直很难有质的飞跃,对于大数据,大量的文件的处理,人们一直为之头疼。人们对于存储系统的速度,容量以及可靠性提出了极高的要求。
    由此,分布式文件系统油运而生,若能解决这个问题,则未来几年的存储将会不再是Internet发展的瓶颈或者是制约因素,而且基于大数据的应用,更加能够促进国民经济的发展。
    1.2 选题价值与意义关与分布式存储,将信息分布式存储,首先对骨干网络的带宽相对要求较低,其次是有较高的容错性能,之后,分布式存储,相对于集中式存储,每个节点相对独立,而且数据分散,数据的安全性的得到了保证。
    选择研究分布式存储,当前,最火的词汇就是云存储,移动与联网,而这两个东西,都离不开分布式存储,因为他们都会产生大量的数据,大量的数据就需要好的存储系统,对存储要求更高。而本地文件系统由于是单个节点本身的局限性,已经很难满足海量数据存取的需求了,因此,不得不借助分布式文件系统来解决这一难题,把系统的负载转移到多个节点之上。如果我能在学校了解到这方面的知识,将会更好的适应外面的企业。符合外面企业的要求。
    1.3 研究内容在这个课题中,我主要的研究内容是基于Moosefs的分布式存储,其他的内容也会涉及,和Moosefs进行对比。而且我更侧重与中小文件的性能,对大文件的要求不高。
    1.4 论文结构本文第一章为引言主要是介绍技术的背景和现状,研究这个问题的意义所在。第二章主要是进行分布式文件系统基础知识的讲解,包括流行的hadoop,GFS,TFS等当前流行的文件系统的介绍。第三章主要是将Moosefs文件系统的系统架构,包括它系统架构,机器架构等相关的知识介绍。第四章主要是介绍的基于Moosefs文件系统搭建的网盘实现,包括系统分析,设计,实现等核心技术问题。第五章主要是对搭建的网盘进行测试。
    2 分布式文件系统的介绍2.1 研究方法和技术路线当前的存储分为两大类型,分别是分布式存储和集中式存储。
    关于集中式共享存储,这类多处理机在目前至多有几十个处理器。由于处理器数目较小,可通过大容量的Cache和总线互连使各处理器共享一个单独的集中式存储器。因为只有一个单独的主存,而且从各处理器访问该存储器的时间是相同的,所以这类机器有时被称为UMA(Uniform Memory Access)机器。它的优点就是数据集中,方便管理,但是也存在许多的缺点,其中由于数据太集中,容灾性差,是它致命的缺点,如下图2.1.1是它的基本架构图。

    而关于分布式存储,它具有分布的物理存储器。为支持较大数目的处理器,存储器必须分布到各个处理器上,而非采用集中式,否则存储器系统将不能满足处理器带宽的要求。系统中每个结点包含了处理器、存储器、I/O以及互连网络接口。随着处理器性能的迅速提高和处理器对存储器带宽要求的不断增加,甚至在较小规模的多处理机系统中,采用分布式存储器结构也优于采用集中式共享存储器结构(这也是不按规模大小进行分类的一个原因)。当然,分布式存储器结构需要高带宽的互连。

    将存储器分布到各结点有两个好处,其一,如果大多数的访问是针对本结点的局部存储器,则可降低对存储器和互连网络的带宽要求,其二,对局部存储器的访问延迟低。分布式存储器体系结构最主要的缺点是处理器之间的通信较为复杂,且各处理器之间访问延迟较大。
    通常情况下,I/O和存储器一样也分布于多处理机的各结点当中。每个结点内还可能包含较小数目(2~8)的处理器,这些处理器之间可采用另一种技术(例如通过总线)互连形成簇(cluster),这样形成的结点叫做超结点。采用超结点对机器的基本运行原理没有影响。由于采用分布式存储器结构的机器之间的主要差别在于通信方法和分布式存储器的逻辑结构方面,所以本章将集中讨论每个结点只有一个处理器的机器。
    2.2 Hadoop中HDFS介绍Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。它和现有的分布式文件系统有很多共同点。但同时,它和其他的分布式文件系统的区别也是很明显的。HDFS(Hadoop Distributed File System)是一个高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。HDFS放宽了一部分POSIX约束,来实现流式读取文件系统数据的目的。HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。(陆嘉桓 etc 2012),以下是HDFS的架构图。

    HDFS中进行数据存储的时候,将数据分成多分存储到不同的节点中。如下图2.2.2 所示,HDFS有如下的有点,如硬件故障检测和自动快速恢复,因为HDFS设计之初就以大量的廉价机器为设计初衷,它把硬件故障认为是常态而不是异常。其次,流式数据的数据访问模型,HDFS是被手机城市和处理批量的,而不是用户交互式,它的重点是数据的吞吐量,而不是数据的反应时间。再者,大数据集,典型的HDFS文件大小是GB到TB的级别,他提供了很高的聚合数据带宽,一个集群之中支持数百个节点,故而保证了可以支持到大数据集,而且有简单的一致性模型,HDFS设计之初,就对文件操作进行了定位,为一次写多次读取的操作模式,一个文件一旦被创建,写入,关闭之后就不需要修改。通过这个简单化的数据一致性问题和并使得高吞吐量的数据访问变成了可能。先进的NameNode 和DataNode设计,HDFS是一个主从结构,一个HDFS由一个NameNode,它是管理文件命名空间和调节客户端访问文件的主服务器,还有许许多多的DataNode,他是管理对应节点的存储,HDFS对外开放文件命名空间,而且允许用户数据源文件的形式进行存储。优秀的文件系统的元数据的持久化功能,HDFS的命名空间是由NameNode节点来存储。NameNode使用叫做EditLog的事务日志来持久记录每一个对文件系统数据的改变,从而保证文件系统的持久化。

    当然,HDFS也有一些缺点,如对小文件处理较为困难,因为HDFS默认64M,只有当本地机器存储超过此空间才会将数据写入到HDFS中,所以若遇到大量的小文件,就相对吃力了,而且如果访问大量的小文件,需要从一个DataNode跳到另外一个DataNode,从而严重影响性能。再者,访问有一定的延时,主要是两个方面,由于HDFS设计之初,就是以吞吐量为重点,从而相对忽略了延时问题,其二是Java本身效率不高。最后,也是最为人诟病的,只能支持单个Master,如Master出现了故障,整个集群将不能提供服务,从而造成不能预计的损失
    2.3 传统NFS文件系统介绍NFS是Network File System的简写,即网络文件系统.网络文件系统是FreeBSD支持的文件系统中的一种,也被称为NFS. NFS允许一个系统在网络上与他人共享目录和文件。通过使用NFS,用户和程序可以像访问本地文件一样访问远端系统上的文件。
    NFS至少有两个主要部分:一台服务器和一台(或者更多)客户机。客户机远程访问存放在服务器上的数据。为了正常工作,一些进程需要被配置并运行。
    NFS 有很多实际应用。下面是比较常见的一些,多个机器共享一台CDROM或者其他设备。这对于在多台机器中安装软件来说更加便宜跟方便。在大型网络中,配置一台中心 NFS 服务器用来放置所有用户的home目录可能会带来便利。这些目录能被输出到网络以便用户不管在哪台工作站上登录,总能得到相同的home目录。几台机器可以有通用的/usr/ports/distfiles 目录。这样的话,当您需要在几台机器上安装port时,您可以无需在每台设备上下载而快速访问源码。
    以下是NFS最显而易见的好处,本地工作站使用更少的磁盘空间,因为通常的数据可以存放在一台机器上而且可以通过网络访问到。用户不必在每个网络上机器里头都有一个home目录。Home目录 可以被放在NFS服务器上并且在网络上处处可用。诸如软驱,CDROM,和 Zip(是指一种高储存密度的磁盘驱动器与磁盘)之类的存储设备可以在网络上面被别的机器使用。这可以减少整个网络上的可移动介质设备的数量。
    当然NFS也有很多的缺点,容错性不佳,和其他分布式文件系统相比,NFS不具备数据备份功能,而且日志功能较为简单,很难进行数据恢复。最不好的是他的可扩展性能,NFS只能支持类UNIX系统,对windows系统不支持,而且同时使用用户较低。
    2.4 闭源的GFS介绍GFS是一个可扩展的分布式文件系统,用于大型的、分布式的、对大量数据进行访问的应用。它运行于廉价的普通硬件上,但可以提供容错功能。它可以给大量的用户提供总体性能较高的服务。
    GFS 也就是 google File System,google公司为了存储海量搜索数据而设计的专用文件系统。以下是GFS的体系架构图。

    GFS有点很多高可用性,如果一个GFS客户失效,数据可以通过其它的GFS高效访问,可扩展性能,不需要中心数据中心,容易扩展存储的容量和访问的带宽,对大数据处理能力强。容错能力强,它的数据同时会在多个chunk server上进行备份,具有相当的容错性能。
    当然GFS也有许多的缺点,如没有实现像POSIX那样标准的API,从而若使用GFS,则很多上层的应用需要修改。文件在目录中按层次组织起来并有路径名标示,对大量的小文件处理不佳,当大量的小文件访问的时候,将严重的影响性能,单Master设计,Master会压力过大,可能会让整个集群宕机。
    2.5 开源的TFS介绍TFS(Taobao File System)是一个高可扩展、高可用、高性能、面向互联网服务的分布式文件系统,主要针对海量的非结构化数据,它构筑在普通的Linux机器集群上,可为外部提供高可靠和高并发的存储访问。TFS为淘宝提供海量小文件存储,通常文件大小不超过1M,满足了淘宝对小文件存储的需求,被广泛地应用在淘宝各项应用中。它采用了HA架构和平滑扩容,保证了整个文件系统的可用性和扩展性。同时扁平化的数据组织结构,可将文件名映射到文件的物理地址,简化了文件的访问流程,一定程度上为TFS提供了良好的读写性能。
    TFS有不少有优点,首先,它是由两个NameServer节点组成(一主一备)和多个DataServer组成,而且这些服务程序是作为一个用户级别的程序运行在普通Linux机器上面,它是将大量的小文件合并为一个大文件来进行存储 。同时为了容灾,NameServer采用HA结构,即两台机器互为热备份,同时运行,一主一备,当主机宕机后,迅速切换到备份NameServer中,对外提供服务。TFS设计是针对小文件设计的而且会将写请求尽可能的均匀的分布在不同的DataServer之中,而且用平滑的扩容机制,当需要系统扩容时,只需要对将相对应的心DataServer部署好,启动即可。
    当然也有不少缺点,如对大文件处理不佳,因为TFS大小的块大小为64M,设计初衷是为小文件设计,所以大文件处理不佳。
    2.6 较新Moosefs文件系统介绍Moosefs是一款网络分布式文件系统,它把数据分散在多台服务器上,但是对用户来讲,看到的只是一个源。MFS也像其他类Unix文件系统一样,包含了层次结构(目录树),存储着文件属性(权限,最后访问和修改时间),可以创建特殊的文件(块设备,字符设备,管道,套接字),符号连接,硬链接等。
    MooseFS文件系统结构包括以下四种角色:管理服务器managing server (master),元数据日志服务器Metalogger server(Metalogger),数据存储服务器data servers(chunkservers),客户机挂载使用client computers。
    Moosefs拥有以下的特性,首先,它是免费的,因为它支持的是GPL协议,其次它拥有通用文件系统,不需要修改上层应用就可以使用,可以直接挂载到本地,像使用本地文件一样,并且可以在线扩容,体系架构可伸缩性极强。(官方的case可以扩到70台了!),而且部署简单,只需要修改一下配置文件就能运行了。高可用,可设置任意的文件冗余程度,提供比raid1+0更高的冗余级别,而绝对不会影响读或者写的性能,只会加速!可回收在指定时间内删除的文件,“回收站”提供的是系统级别的服务,不怕误操作了,提供类似oralce 的闪回等高级dbms的即时回滚特性!提供netapp,emc,ibm等商业存储的snapshot特性,可以对整个文件甚至在正在写入的文件创建文件的快照,google filesystem的一个c实现。
    MFS 的读取数据过程:

    Client当需要一个数据的时候,首先向master server发起查询请求
    管理服务器检索自己的数据,获取到数据所在的可用的数据服务器位置ip|port|chunkid
    管理服务器将数据服务器的地址发送给客户端
    客户端向具体的数据服务器发起数据获取请求
    数据服务器发送给客户端

    如下图所示,MFS读取数据时原理图。

    MFS的写数据过程:

    当客户端有数据写需求时,首先向管理服务器提供文件元数据信息请求存储地址(元数据信息如:文件名|大小|份数等)
    管理服务器根据写文件的元数据信息,到数据服务器创建新的数据块
    数据服务器返回创建成功的消息
    管理服务器将数据服务器的地址返回给客户端(chunkIP|port|chunkid)
    客户端向数据服务器写数据
    数据服务器返回给客户端写成功的消息
    客户端将此次写完成结束信号和一些信息发送到管理服务器来更新文件的长度和最后修改时间
    一个写操作就此完成

    下面是MFS 写数据原理图如图2.6.2 所示:

    MFS的删除文件过程:

    客户端有删除操作时,首先向Master发送删除信息
    Master定位到相应元数据信息进行删除,并将chunk server上块的删除操作加入队列异步清理
    响应客户端删除成功的信号
    MFS修改文件内容的过程
    客户端有修改文件内容时,首先向Master发送操作信息
    Master申请新的块给.swp文件
    客户端关闭文件后,会向Master发送关闭信息
    Master会检测内容是否有更新,若有,则申请新的块存放更改后的文件,删除原有块和.swp文件块
    若无,则直接删除.swp文件块

    MFS重命名文件的过程:

    客户端重命名文件时,会向Master发送操作信息
    Master直接修改元数据信息中的文件名;返回重命名完成信息

    MFS遍历文件的过程:

    遍历文件不需要访问chunk server,当有客户端遍历请求时,向Master发送操作信息
    Master返回相应元数据信息
    客户端接收到信息后显示

    2.7 各种分布式文件系统的概要分析首先,文本首先对需求进行分析,对这个文件系统的定位是大量普通用户使用的一个海量存储文件系统。正常情况下,普通用户的文件以文档,图片,音频,视频居多。大部分文件在10M以下。
    其次,普通的用户,一般情况下以上传信息居多。而且文件系统要易于扩展,方便扩容,再者文件系统要有较强的容错性,最好自身带有备份功能。
    关于Hadoop的分析,HDFS上,每一个文件都需要在namenode上建立一个索引,一个索引大约150byte,当小文件比较多的时候(小于一个block被HDFS视为一个小文件),就会产生许许多多的索引文件,一方面,会大量的占用NameNode的内存空间,另一方面,就是索引文件过大,会让索引速度变得很慢。HDFS的设计思路是多次读,少量写操作,这个和我们定位有所不同。
    关于NFS的分析,NFS 搭建简单,但是可扩展性能差,NFS不带备份功能。NFS 可以搭建的最大容量有限。
    关于GFS的分析,由于是GFS闭源,即使性能很优秀,但是不能使用。
    关于TFS的分析,对小文件处理优秀,但对稍大的文件处理困难。
    关于Moosefs的分析,MFS自带备份功能,MFS对小文件处理能力强,MFS对大文件处理能力强,MFS自带日志功能,MFS可扩展性能强。
    综上所述,选择Moosefs。原因如下,首先,它对大文件,小文件的支持力度较高,其次它有着较强的可扩展性能,再者容错备份功能齐全。故而选之。
    3 文件系统的架构3.1 平台要求目前Moosefs只能支持类UNIX操作系统,如Linux内核的操作系统,Unix如Solaris,MacOx等,不支持Windows。
    若是Linux内核,建议使用2.6或者以上内核,才能很好的支持到FUSE功能,可以将Moosefs很好的挂在到本地使用。
    3.2 机器架构
    Moosefs主要是由四种类型的角色,它们分别是Master(主控服务器),主要负责各个数据存储服务器的管理,文件读写调度,文件空间回收以及恢复,多节点的拷贝等等功能,Metalogger(日志服务器)主要负责Master服务器的变化的日志文件,若Master Server出现问题的时候,可以接替进行工作,ChunkServers负责管理服务器,听从Master调度,并提供存储空间,为客户提供数据传输,Client,主要是通过fuse内核接口挂接远程的Master服务器上面,看起来共享的文件系统和本地的Uinx文件系统使用效果一样。
    3.3 文件系统架构
    Moosefs分布式文件系统,主要是通过一个master来管理多个chunkservers进行分布式存储,让整个chukservers群中的存储空间得到共享,通过metalogger服务器进行日志记录和数据删除后的回滚。用户通过fuse来将分布式文件系统挂载到本地,想访问普通的文件系统一样,提工一个抽象,使得用户在不需要更改上层应用的情况下,可以使用分布式文件系统。
    3.4 分布式文件系统的搭建采用了8台主机搭建实验使用的分布式文件系统,一台主服务器,作为Master,一台日志服务器,用于日志备份和记录,四台ShunkServer,用于存储数据,之后将MFS挂载在两台机器上面,有两台clinet对外提供服务。
    以下是文件系统的架构图,如下图3.5.1所示。它们统一安装的Archlinux 内核版本是Linux 3.8,java版本是JDK7,安装了FUSE。

    3.5 性能测试


    二级100*100目录
    创建
    列表
    删除




    单片15k.5 ext3 client单进程
    real 0m0.762s user 0m0.048s sys 0m0.261s
    real 0m0.179s user 0m0.036s sys 0m0.125s
    real 0m0.492s user 0m0.036s sys 0m0.456s


    单片15k.5 ext3 client 10并发进程
    real 0m0.724s user 0m0.015s sys 0m0.123s
    real 0m0.057s user 0m0.006s sys 0m0.025s
    real 0m0.226s user 0m0.010s sys 0m0.070s


    6chunkserver cache client单进程
    real 0m2.084s user 0m0.036s sys 0m0.252s
    real 0m4.964s user 0m0.043s sys 0m0.615s
    real 0m6.661s user 0m0.046s sys 0m0.868s


    6chunkserver cache client 10并发进程
    real 0m1.422s user 0m0.007s sys 0m0.050s
    real 0m2.022s user 0m0.008s sys 0m0.108s
    real 0m2.318s user 0m0.008s sys 0m0.136s



    进行小文件性能测试,采取的是两级目录,1000*1000的方式。



    二级1000*1000目录
    创建
    列表
    删除




    单片15k.5 ext3 client单进程
    real 11m37.531s user 0m4.363s sys 0m37.362s
    real 39m56.940s user 0m9.277s sys 0m48.261s
    real 41m57.803s user 0m10.453s sys 3m11.808s


    单片15k.5 ext3 client 10并发进程
    real 11m7.703s user 0m0.519s sys 0m10.616s
    real 39m30.678s user 0m1.031s sys 0m4.962s
    real 40m23.018s user 0m1.043s sys 0m19.618s


    6chunkserver cache client单进程
    real 3m17.913s user 0m3.268s sys 0m30.192s
    real 11m56.645s user 0m3.810s sys 1m10.387s
    real 12m14.900s user 0m3.799s sys 1m26.632s


    6chunkserver cache client 10并发进程
    real 1m13.666s user 0m0.328s sys 0m3.295s
    real 4m31.761s user 0m0.531s sys 0m10.235s
    real 4m26.962s user 0m0.663s sys 0m13.117s



    由此分析可见,当进行单盘多进程操作的时候,性能提升的空间有限,主要是IO瓶颈制约,甚至消耗了大量的系统调用,当进行多盘的时候,性能有了巨大的提升。
    4 开放网盘的实现方式4.1 需求分析首先我们对本系统进行定位,系统供开发者使用,他们一般都具备一定的计算机水平,可以熟练的操作计算机,数据库,操作系统等等。而且要具备如下的功能,具有上传,下载功能的开放接口,具有权限控制的接口,具有安全快捷认证的用户接口,具有注册用户,修改用户信息的接口,具有显示目录信息的接口具有删除文件,目录的接口,具有移动文件,目录的接口,具有数据删除后恢复功能,并提供开放接口。而且要自动帮用户进行数据备份。
    4.2 系统分析系统主要用例,开发者通过用户的授权,获取权限,进行操作,如修改文件的目录,获取文件的信息,下载文件,修改文件内容,移动文件等操作。

    Aouth2.0授权顺序图

    开发者首先向系统请求一个临时令牌,系统验证开发者的身份后,授予一个临时的令牌,开发者获取了临时令牌后,通过自己的信息和临时令牌,将用户引导至系统的授权页面请求用户的授权,在这个过程中临时令牌和开发者毁掉连接发送给系统,用户在系统提供的页面输入用户名和密码,然后授权该开发者访问锁请求的资源,授权成功后,系统将引导用户返回到开发者的页面,开发者根据临时令牌,从系统中获取访问的临牌,系统根据临时临牌和用户的授权情况授予开发者访问令牌,开发者获得令牌后,访问系统中用于受保护的资源。
    用户获取目录信息顺序图,如下图 4.2.3所示,用户请求获取指定目录的信息,系统首先查看请求中是否含有授权,若有授权则通过,否则将拒绝。当权限允许的时候,调用封装好的Driver进行访问指定的路径,获取目录信息,若不存在目录,则返回空,存在则将之保存为对象传给xml生成器,xml生成器生成xml,并将之返回给Servlet,Servlet将生成xml的响应回复给用户。

    以下是上传文件顺序图用户请求上传指定文件,系统首先验证用户的请求是否合法,若有授权则通过,否则将拒绝,当权限允许的时候,首先对文件的类型进行检测,是否符合系统要求,不符合则拒绝,之后获取上传文件列表,将文件上传至指定的目录中,首先判断目录是否存在,若不存在则递归的创建目录,并上传,最后生成上传报告,并将上传报告返回给用户。

    4.3 网盘的架构普通用户,通过开发者的应用来进行使用网盘,开发者同过网盘提供的API来进行访问网盘,进行操作,而网盘和分布式文件系统相对独立,网盘调用分布式文件系统中封装好的接口,进行分布式文件系统的使用。
    总体来说,设计的时候,把网盘分成了3层架构,分别是存储层,逻辑层(基础管理层),应用接口交互层。
    存储层采用Moosefs来做为存储实现的。由Moosefs来进行存储,将其挂在到本地使用,对外提供服务。
    逻辑层,首先有一些本地I/O的底层驱动,还有和数据库访问的驱动封装,其他的就是网盘的核心部分,包括用户认证,上传下载文件,数据封装等等。
    最表层的是应用接口层,主要是通过API来调用逻辑层的实现,从而可以使用到网盘。

    网盘的架构图,本文采用的是MVC架构模型。

    View:主要是通过jsp 和servlet来进行展现,主要是用于和API进行交互
    Control:主要是自己进行写逻辑,DAO是主要是实现简易的与mysql进行通讯的,而FSDriver主要是封装了很多常用的访问文件系统的接口
    Model:主要使用的JavaBean


    4.4 数据表结构用户注册的实现中,我们采取的是简单的认证体制,我们建立一个数据库表。
    我们当获取了规定用户的密码必须上传为SHA1,不能上传明文默认是以ID为主键,而且ID可以自己增长,不需要有默认值,用户名默认不支持中文,优先使用英文,关于密码,我们将密码进行了SHA1加密,当获得了密码后立刻进行SHA1加密,故系统本身不知道密码,从而保证用户的隐私,UserKey,是用于存储用户访问令牌,通过这个和表UserKey表进行关联,从而获取用户的访问令牌,保证用户同时可以拥有多个访问令牌。
    User Table



    名称
    类型
    长度
    是否允许空值
    默认值
    是否是主键
    说明




    ID
    Int
    64



    编号


    UserName
    Char
    40

    Null

    用户名


    Password
    Char
    60

    Null

    密码


    Sex
    Char
    10



    性别


    UserKey
    Char
    60

    Null

    访问的令牌



    对于开发者,我们创建了另外一个表来存储信息,ID是表的主键,用于区别不同的开发者,而且不需要有是否有空,AppKey 用于当开发者申请开发者身份的时候获取的唯一绝对的认证,可以通过这个AppKey来确定一个开发者,AppSecret,主要使用Aouth认证的时候,通过AppSecret获得唯一的认证的临时令牌。
    Developer Table



    名称
    类型
    长度
    是否允许空值
    默认值
    是否是主键
    说明




    ID
    Int
    64



    编号


    UserName
    char
    40

    Null

    用户名


    Password
    Char
    60

    Null

    密码


    Sex
    Char
    10



    性别


    AppKey
    Char
    60

    Null

    应用的key


    AppSecret
    Char
    60

    Null

    应用的密码



    为了保证多个开发者可以为同一个用户服务,而创建的这个表,其中存储的主要是用户的授权UserKey 和AppKey的对应关系。
    User Table



    名称
    类型
    长度
    是否允许空值
    默认值
    是否是主键
    说明




    ID
    Int
    64



    编号


    UserName
    char
    40

    Null

    用户名


    UserKey
    Char
    60

    Null

    用户令牌


    AppKey
    Char
    60

    Null

    应用的key



    4.5 核心代码实现上传功能上,我们采用的是FileUpload这个开源库,FileUpload 是 Apache commons下面的一个子项目,用来实现Java环境下面的文件上传功能。它可以支持上传一个或者是多个文件,并且支持控制缓存空间的控制,可以手动的控制缓存的位置,是在硬盘或者是内存都是可以实现的。还可以限制上传文件的大小。支持RFC 1867标准。而且API简单易学。下面是使用FileUpload的核心代码,实现以下功能,包括进行文件类型过略,上传文件列表,设置缓存,进行目录检测,设置响应体格式等等工作。当上传成功后,将会生成上传日志,并将上传的日志展示给用户,让用户知道自己上传成功。
    PrintWriter out = response.getWriter(); if(!ServletFileUpload.isMultipartContent(request)){ return ; }List<FileItem> filelist = null; try{ filelist = sfu.parseRequest(request); }catch(FileUploadException ex){ out.println("upload file error "+ex.toString());} if (filelist ==null || filelist.size() ==0){ out.println("could not find the file "); return; } Iterator fileItr = filelist.iterator(); while(fileItr.hasNext()){ FileItem fileItem = null; String path = null; long size = 0; fileItem = (FileItem)fileItr.next(); if(fileItem == null||fileItem.isFormField()){ continue; }String t_ext = t_name.substring(t_name.lastIndexOf(".") + 1); int allowFlag = 0; int allowedExtCount = allowedExt.length;for (; allowFlag < allowedExtCount; allowFlag++) { if (allowedExt[allowFlag].equals(t_ext)) break; path = fileItem.getName(); size = fileItem.getSize(); if("".equals(path)||size == 0){ out.println("Upload file error"); return ; } String t_name = path.substring(path.lastIndexOf("\\") + 1); String t_ext = t_name.substring(t_name.lastIndexOf(".") + 1); int allowFlag = 0; int allowedExtCount = allowedExt.length; for (; allowFlag < allowedExtCount; allowFlag++) { if (allowedExt[allowFlag].equals(t_ext)) break; } if (allowFlag == allowedE String u_name = request.getRealPath("/") +"imagesUploaded/"+t_name; if(!new File(request.getRealPath("/")+"imagesUploaded").isDirectory()) new File(request.getRealPath("/")+"imagesUploaded").mkdirs();}
    删除文件功能,即删除用户对应的文件或者目录,删除完成后,返回是否删除成功。代码首先判断文件是否存在,之后判断文件权限是否允许,最后才决定是否删除,删除后会有返回信息产生。
    以下是删除文件的核心代码:
    public void removefiles(HttpServletRequest request, HttpServletResponse response) throws IOException{ /*获得writer*/ PrintWriter out = response.getWriter(); RemoveFile remove = new RemoveFile();/创建一个removed的类/ String RemovePath = (String) request.getAttribute("RemovePath"); if (RemovePath == null){ out.println("path is null"); return ; } String temp = null; try { temp = "/mnt/mfs"+ RemovePath; remove.RmFile(temp); } catch (InterruptedException e) { // TODO Auto-generated catch block out.println("remove file error"+RemovePath); System.out.println("remove file error" +temp);}/*信息返回*/ out.println("OK to remove " + RemovePath); }
    获取文件信息,当用户想知道自己某个目录的信息的时候,可以调用此接口,它将获取目录的信息,进行过滤加工,将信息封装为xml返回给用户。
    我主要是用的是一个javax中原生的xml库,来生成xml,生成了xml之后,再将xml发送给用户。
    首先我获取文件的相关信息,把它们通过正则表达式来进行切割,分到不同的数组中,之后利用javax.xml下面的类来进行生成xml。
    下面是关键代码:
    通过系统调用,获取对应的文件目录信息,保存在对象之中。
    while ((lineStr = inBr.readLine()) != null) { /*对获取的信息进行整理*/ temp = lineStr.split("\\s{1,10}"); if (temp.length >5){ if (Permission.charAt(0) =='d'){ Dirctory = true; }else{ Dirctory = false; } Group = temp[2]; User = temp[3]; Size = temp[4]; CreateDate = temp[5]+" "+temp[6]+" "+temp[7]; Name = temp[8]; result.add(new NetDiskFile(Name,User,CreateDate,Size,Permission,Dirctory)); }}
    以下是生成xml的核心代码:
    Public static Document generateXml(List<NetDiskFile>list){ try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); doc = builder.newDocument(); root = doc.createElement("NetDiskFileInfo"); doc.appendChild(root); } catch (Exception e) { e.printStackTrace(); return null;//如果出现异常,则不再往下执行 } int len = list.size() ; Element element ; for (int i = 0; i < len; i++) { NetDiskFile NetDiskFile=list.get(i); element=doc.createElement("FileInfo"+(i+1)); element.setAttribute("fileName",""+NetDiskFile.getName()); element.setAttribute("User",NetDiskFile.getUser()); element.setAttribute("Group",NetDiskFile.getGroup()); element.setAttribute("Permission",NetDiskFile.getPermission()); element.setAttribute("Size",String.valueOf(NetDiskFile.getSize())); element.setAttribute("CreateDate",NetDiskFile.getCreateDate()); element.setAttribute("Dirctory",String.valueOf(NetDiskFile.getDirctory())); root.appendChild(element); } return doc;}
    5 测试用例由于做的主要是开放接口,故测试程序写的比较简陋。
    5.1 用户认证需要以下信息 用户名 密码 以及用户授权的key_number,首先,开发者通过引导用户到系统的授权页面,如下

    当用户授权后,若用户通过验证,则提示用户是否授权,如下图5.1.3 所示,其中,里面包含了许多的信息,比如你的用户名,你网盘里面的部分照片,开者者将获取的权限等等信息都会显示出来。若认证失败,则出现如下图 5.1.2所示。


    若认证成功则提供一串授权码,但必须是开发者去访问系统,则能得到一个授权码,也就是我们所说的令牌,如下图 5.1.4所示。

    经过测试 结果正确。
    5.2 上传下载上传文件功能测试:
    上传文件,只能上传指定类型的文件,如MP3,jpg等等,这是没有上传前,存储目录的情况 ,如下图 5.2.1 所示。

    首先我们测试上传一张图片,如图 5.2.2所示。

    上传后,网盘目录信息如图5.2.3所示可见,网盘是可以实现上传图片等功能,可以上传到指定的目录之中,而且可以获得文件的大小,修改时间,文件类型等内容。
    现在测试上传失败,上传一个vsd的绘图文件,来进行测试,结果如图所示,当我们上传文件时,如图 5.2.4所示,当上传之后,由于失败的到的结果是如图5.2.5 所示,显示上传失败,之后我们在查看目录信息,如图5.2.6所示,依旧是没有添加,据此,我们可以得到网盘实现了过略文件类型的功能。



    现在我们查看目录的信息,可以看到,目录中没有添加到刚才上传文件的任何信息,和刚才一样,所以可以据此判断,网盘具有拒绝指定类型的文件上传的功能。

    上传失败,和预期一样,所以网盘实现了拒绝指定文件类型的功能。符合要求。
    5.3 获取目录信息现在测试显示目录信息的接口,若访问,则显示目录的信息,如下图5.3.1 所示。

    如图所示,可以获取目录的相关信息,并生成对应的xml文件,其中包含了文件名称,大小,权限,时间等信息,符合要求。
    5.4 数据恢复功能现在测试数据恢复功能,首先删除刚才上传的图片,在回收站中,会有如下页面,如图 5.4.1所示。

    当选中需要恢复的文件后,单击恢复按钮,就能恢复。之后查看目录的信息,如下图5.4.2 所示,所以由此可见,网盘具有删除恢复功能。

    6 总结与展望大数据和分布式存储,是将来互联网发展所必须的,现在,微软对它旗下的Skydirver进行了全面的升级,国内的金山,有道,坚果等网盘巨头,都对自己的网盘进行了升级,可以相信,将来网盘将变成一种必须的工具,他方便访问,随时读取,没有地域的限制。所以,我相信,网盘和分布式将会大行其道。分布式的存储,将更加的流行,未来是大数据的时代,分布式能够很好的解决这个问题。
    参考文献
    董黎刚.分布式系统中的调度与缓存技术[M] .浙江工商大学出版社,2010
    明日科技编著. JSP开发技术大全[M]. 人民邮电出版社,2007
    麻志毅.面向对象分析与设计[M]. 机械工业出版社,2008
    陆嘉桓. Hadoop实战[M]. 机械工业出版社,2012
    刘振安,董兰芳. 面向对象技术与UML. 北京: 机械工业出版社,2007
    张晓东. Java 数据库高级教程[M]. 北京: 清华大学出版社, 2004
    周忠,吴威. 分布式虚拟环境[M],科学出版社
    刘军. 文件系统原理,机械工业出版社,2005
    淘宝核心技术. 淘宝文件系统[EB/OL] 2013 http://tfs.taobao.org/index.html
    George Coulouris .分布式系统概念与设计[M].机械工业出版社,2013
    Amand Rajarman,Jeffrey David Ullman Mining of Massive Datasets[M],人民邮电出版社
    Michat Borgchowski . Installing Moosefs Step by Tutorial[EB/OL] Gemius SA 2010 http://www.moosefs.org/tl_files/manpageszip/moosefs-step-by-step-tutorial-cn-v.1.1.pdf
    1 评论 1 下载 2019-10-14 11:30:45 下载需要15点积分
  • 基于Java Web开发方式实现的Android二维码支付系统APP

    一、产品设计思想模拟基于加密的二维码实现电子交易的系统,实现交易的迅速便捷,可以在web浏览器和移动端同时使用。采用Google.zxing接口实现二维码的生成和解析,采用加密协议传送,产品类似webapp形式呈现。开发利用DAO的设计模式,由javabean的VO,预先设定各项操作的接口类,真正实现操作的代理类和集成各项代理的工厂类,该设计模式使工程构造简明清晰,并且减少了耦合度。

    代码运行环境

    IDE:Eclipse Mars.1 Release (4.5.1)Jdk: 1.8
    数据库:mysql 5.7
    前端外部插件:bootstrap,jquery,
    后端外部插件:Google.zxing
    编辑工具

    eclipsewebstormDreamweaver

    二、采用的安全技术
    采用Google的zxing二维码生成与读取接口对信息进行加密,可以将支付信息保存入二维码中
    采用MD5加密算法,获取用户标识的不可逆散列值
    使用时间戳,限制二维码使用周期
    传输过程中使用SSL加密传输,保证传输过程安全

    三、验证过程
    如图所示,收款人提出收款后,根据其当前的用户名和时间戳分别产生HASH散列值,将散列值相拼接,然后使用Google的Zxing工具转化为二维码;付款人拍摄到二维码后,根据固定位数分离出收款人用户名的散列值和二维码生成时间的散列值,在数据库中遍历所有用户的的用户名的MD5散列值与目标对比,若匹配,则找到收款人,否则没有收款目标,拒绝收款,并打印警告;再使用当前时间段的时间戳生成MD5散列值,与目标MD5散列值比较,若相等,则说明支付时间与收款码生成时间在同一个时间间隔中,否则二维码过期,不进行交易。只有在找到收款人且二维码未过期的前提下才进行交易。
    后来增加了Tomcat的传输过程安全保护机制,又在本地使用JDK 自带的 keytool工具生成证书,将证书应用于Tomcat,在Tomcat服务器中配置启动了HTTPS协议替代HTTP协议,使用8443端口替代了8080端口,传输过程中的数据是用SSL协议加密后的密文,这样就增强了传输过程中的安全性。
    四、主要数据结构4.1 用户类用来存储用户信息
    public class user { private String username; private String password; private double balance; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; }}
    4.2 历史支付记录类用来存储
    public class payhistory { private String payer; private String accepter; private int money; private Timestamp time; public String getPayer() { return payer; } public void setPayer(String payer) { this.payer = payer; } public String getAccepter() { return accepter; } public void setAccepter(String accepter) { this.accepter = accepter; } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } public Timestamp getTime() { return time; } public void setTime(Timestamp time) { this.time = time; }}
    五、主要数据库表5.1 用户表
    Userid:用户标识
    Password:用户密码
    Balance:用户账号余额


    5.2 支付历史记录表
    Id:主键,唯一标识一次记录,无实际含义,自增
    Payer:付款人用户标识
    Accepter:收款人用户标识
    Money:交易金额
    Time:交易完成时间


    六、主要代码解析本项目使用DAO设计模式,代码框架如下

    Vo中保存映射数据表的简单java类;dao定义需要实现操作的接口;Impl中是接口的真实实现类,完成的是数据库的具体操作,但是不负责数据库的打开与关闭;Proxy,代理类,主要是完成数据库的打开、关闭,并且调用真实实现类对象操作;factory,工厂类,通过工厂类取得一个DAO的实例化对象;main,实现具体的服务。
    Css保存样式文件,js保存JavaScript文件,image保存生成的二维码图片文件,image_accept保存需要解析的收款二维码的照片/图片,web.xml是servlet映射文件,lib中保存引入的jar包。
    实现的主要功能如下:
    6.1 收款收款功能通过生成与收款人和交易时间相匹配的二维码来实现。用户登录之后使用用户名进行MD5加密,获取对应的散列值,再加上当前时间(使用currentTimeMillis方法获取,其得到与1970年一月一日之间的时间差,进而得到当前所在的十分钟的时间标识)。以字符串的形式与用户散列值进行拼接得到唯一表示此次收款交易的信息。使用Google.zxing将其转化为二维码形式,并在视图中显示出来。
    Gather.java
    String hash_userid = new md5().hashCode(userid.replaceAll("\n|\r", "")).substring(0, 5);//获取当前时间long t=System.currentTimeMillis()/(2*60*1000);//以十分钟为单位划分时间String tString = Long.toString(t);String text = hash_userid + tString;//二维码的内容text = text.replaceAll("\r|\n", "");int width = 400;int height = 400;String format = "png";Hashtable hints= new Hashtable();hints.put(EncodeHintType.CHARACTER_SET, "utf-8");BitMatrix bitMatrix = null;try { bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height,hints);} catch (WriterException e) { // TODO Auto-generated catch block e.printStackTrace();}StringBuffer buf = new StringBuffer();buf.append("D:\\eclipse_x86_workspace\\payment3\\WebContent\\image\\to_");buf.append(userid);buf.append(".png");String pathname = buf.toString();System.out.println(pathname);pathname = pathname.replaceAll("\r|\n", "");//去掉可能出现的回车和换行System.out.println("换行第一次出现的地方:"+pathname.indexOf("\n"));File outputFile = new File(pathname);MatrixToImageWriter.writeToFile(bitMatrix, format, outputFile); String result = pathname.substring(45);System.out.println(result);
    6.2 付款付款时先扫描二维码,将扫描的图片传回服务器后进行读取。获取二维码中字符串,其前5位为用户HASH标识,之后部分为二维码生成的时间表示。先匹配时间,若当前时间与二维码中时间标识不同(相隔十分钟以上),则输出二维码已过期,停止交易;二维码未过期,再去数据库中匹配用户标识,即select所有用户,分别对其用户名进行MD5加密,取前五位(由于样本数量较少,考虑到二维码识别难度,暂取五位),若与二维码中用户标识相同,则找到收款人,进行交易,给收款人加上交易金额,给付款人减去交易金额,并将交易活动记录入数据库。
    //判断二维码是否过期long t=System.currentTimeMillis()/(10*60*1000);//以十分钟为单位划分时间String tNow = Long.toString(t);if (!tNow.equals(tString)) { out.println("out");}//开始计算收款人的useridtry{ accepter = DAOFactory.getUserDAOInstance().findAccepter(accepter);}catch(Exception e){ e.printStackTrace();}ph.setTime(new Timestamp(System.currentTimeMillis()));try{ //付款人减去金额 DAOFactory.getUserDAOInstance().pay(ul1, money);}catch(Exception e){ e.printStackTrace();}try{ //收款人加上金额 DAOFactory.getUserDAOInstance().accept(ul2, money);}catch(Exception e){ e.printStackTrace();}try{ //记录交易信息 DAOFactory.getPayhistoryDAOInstance().addHistory(ph);}catch(Exception e){ e.printStackTrace();}//付款人减去交易金额public boolean pay(user ul,double money) throws Exception { boolean flag = false; String sql = "update user set balance = balance - ? where userid = ? "; this.ps = this.conn.prepareStatement(sql); this.ps.setDouble(1, money); this.ps.setString(2, ul.getUsername()); System.out.println("ul.getBalance() - money:" + (ul.getBalance() - money)); System.out.println("ul.getUsername():" + ul.getUsername()); System.out.println(sql); this.ps.executeUpdate(); this.ps.close(); return flag;}//收款人加上交易金额public boolean accept(user ul, double money) throws Exception { boolean flag = false; String sql = "update user set balance = balance + ? where userid = ? "; this.ps = this.conn.prepareStatement(sql); this.ps.setDouble(1, money); this.ps.setString(2, ul.getUsername()); System.out.println(sql); this.ps.executeUpdate(); this.ps.close(); return flag;}public boolean addHistory(payhistory ph) throws Exception { System.out.println("into impl"); boolean flag = false; String sql1 = "insert into payhistory(payer,accepter,money,time) values(?,?,?,?)"; this.ps = this.conn.prepareStatement(sql1); this.ps.setString(1, ph.getPayer()); this.ps.setString(2, ph.getAccepter()); this.ps.setInt(3, ph.getMoney()); this.ps.setTimestamp(4, ph.getTime()); System.out.println(sql1); if(this.ps.executeUpdate()>0){ flag = true; } this.ps.close(); return flag;}
    6.3 余额查询先在DAO中定义活动的接口,然后在Impl中具体实现与表的交互,Proxy提供数据库代理,Factory提供活动入口,查询user表中相关元组即可。
    UserDAOImpl.java
    public double searchBalance(user ul) throws Exception { double balance = 0; String sql = "select * from user where userid = ? "; this.ps = this.conn.prepareStatement(sql); String userid = ul.getUsername(); //System.out.println("ul.getUsername():" + ul.getUsername()); this.ps.setString(1, ul.getUsername().replaceAll("\n|\r", "")); ResultSet rs = this.ps.executeQuery(); while(rs.next()){ System.out.println("i am here"); balance = rs.getDouble("balance"); } this.ps.close(); return balance;}
    6.4 查询历史记录用户登录之后,使用用户名遍历payhistory表即可。使用JSP打印出历史记录的表格(由于ajax的局部刷新的视觉效果不好,所以显示到另一页面,页面之间使用jQuery-params传值)。
    <% request.setCharacterEncoding("utf-8");%><% try { String keyWord = request.getParameter("kw"); //String keyWord = "admin"; System.out.println("keyword:" + keyWord); if (keyWord == null) { keyWord = ""; } List<payhistory> all = DAOFactory.getPayhistoryDAOInstance().findAll(keyWord); Iterator<payhistory> iter = all.iterator();%><center> <table border = "-2"class="table" style = "color:white;"> <tr> <td>payer</td> <td>accepter</td> <td>money</td> <td>time</td> </tr> <% while (iter.hasNext()) { payhistory ph = iter.next(); %> <tr> <td><%=ph.getPayer()%></td> <td><%=ph.getAccepter()%></td> <td><%=ph.getMoney()%></td> <td><%=ph.getTime()%></td> </tr> <% } %> </table></center><% } catch (Exception e) { e.printStackTrace(); }%>
    七、测试数据和结果首先,将项目使用Tomcat服务器在本地跑起来,打开WiFi,使用移动设备连入,则设备与服务器处于同一局域网中。
    在终端使用ipconfig指令获取WiFi局域网的IP地址,例如172.60.2.1,则在连入设备中输入https://172.60.2.1:8080/payment3 即可进入项目界面。
    注册一个名为admin用户,默认新注册用户账户金额都为10000元

    查看数据库,确实存在此用户

    使用admin账号登录

    图7
    收款,生成收款二维码

    注册另一账户,root,打开root账号的付款界面(选择文件就是调用摄像头)

    拍摄二维码

    输入金额,确定支付

    八、心得体会这个项目整体做了两个星期左右,主攻了大约一个星期,我负责后端,和二维码生成与读取以及服务器的SSL加密配置。
    项目开始时需要选择平台,原本打算使用Android写一个APP,不过由于笔记本电脑无法运行Android studio,又考虑到自己以前还是做过一些javaweb项目的,所以选择使用webAPP的方式呈现。
    使用bootstrap框架可以很好地支持移动端的响应式布局,使用ajax进行前后端之间的传值,用DAO设计模式以避开后端代码之间的耦合度太高问题,使用servlet处理请求,轻车熟路,这一部分做地很爽。
    二维码生成与破解是调用别人的接口来实现的。开始时选择的是一个日本公司的接口,只有两个jar包,而且方法也不算复杂,甚得我心,但是实现效果是在不够理想,只要光线稍微变化一些就识别不出来,屏幕上有一些暗影也不行。后来改成了Google的zxing,虽然效果也不算太好,同一二维码只有从特定的角度拍摄才能识别出来,但是至少不太复杂的二维码是没有问题的(后来在stackflow里看到有人使用hints,可以提高二维码的识别成功率,试用了一下,几乎没什么区别)。
    开始认为二维码算是一种加密算法,但是随着项目的推进和原型的成型,意识到二维码只是一种可逆的变化,加密程度太低。后来想到调用哈希算法取用户名的散列值,这样只有服务器端可以遍历数据表,确定二维码对应的收款人,而别人即使得到了二维码也没什么用。由于MD5为128位,SHA1位160位,为了处理二维码方便起见,选择了MD5算法。
    MD5算法调用java的security包内的方法稍加修改即可,这部分实现起来还是比较容易的,时间戳可以调用currentTimeMiles方法可以获取自1970年1月1日以来的毫秒数,将其除以十分钟(10*60*1000),即可得到当前所在十分钟时间区间的标识(即在十分钟内付款为有效)以此作为判断二维码是否过期的标准。
    3 评论 3 下载 2019-03-18 08:40:14 下载需要12点积分
  • 基于Python的Django框架实现的中式快餐厅管理信息系统网站

    1 初步调研随着餐饮业的连锁和国外餐饮巨头的进入,餐饮业的竞争将越来越激烈:要想在竞争中处于不败之地,必须在管理、服务等方面提高服务管理意识。面对当前餐饮业普遍的产业化程度低,管理手段、管理技术落后等问题,使用计算机管理在很大程度上可以帮助餐饮企业克服这些困难。计算机管理系统可以提高餐饮企业的管理水平,节省大量人力、物力和财力,使经营管理更加科学有序、经营物流清晰,经营状况详实、准确。
    1.1 研究现状我国餐饮业的餐饮信息管理系统的开发,规模大小各不相同,开发方法、模式、平台也不尽相同。有的是购买的系统,有的是自己开发,有的还进行了多次开发,因为开发人员和方法的原因,系统维护和升级都比较困难。信息共享性差,数据冗余大,维护困难。
    随着科学技术的不断发展,计算机科学日趋成熟,信息处理能力也日渐强大,在人类社会日常生活中也日益广泛,逐步渗透到各个领域。为了解决服务行业的高速发展和管理所产生的各种问题,各种各样的信息化管理软件日益涌现,给不同行业的信息管理带来了不可估量的经济价值。结合餐饮业自身的特点及业务流程,当下主流系统的问题分析如下:
    解决方案不完整:部分系统只有收银模块、点菜模块,然而点菜模块并没有和厨房管理仓库管理联系起来,有时会在点菜过程中要求库存不足或者没有的菜,大大影响顾客对企业的影响,人员流失在所难免。
    业务管理不够人性化:部分系统并不能即时的了解库存,进货,从而造成库存不足,不能及时满足客户要求,同时也不能及时实现客人点单,结账等情况,浪费客户时间,从而影响客户对企业的信誉度,也不能提供多种结账方式,不能给客户带来便利,这些不足使得整个企业需要花费更多的时间和精力来填补,从而大大影响了企业的工作效率。
    系统交互能力弱:部分系统的交互界面易用性差,操作不够简单,使得工作人员难以上手,必须花费一定的时间去了解和熟悉系统,从而员工的工作效率低下,不能及时满足客户需求。
    系统决策能力差:部分系统并不能对客户用餐数据进行分析,不能给决策者提供可靠的数据支持,这也直接影响了企业的前景与发展。
    酒店管理软件稳定性差:国内的酒店管理软件源自于国外,但是并没有剔除掉原有软件的弊端,而是全部接受,并且还没有随着国外软件的更新而改进,也没有在国内大环境下提出新的适合中国人的餐饮管理软件,原有的管理软件仍然是模仿手工管理的过程,但是没有考虑大数据对传统行业的影响,数据分析,用户的偏好分析等都没有提出新的有效的解决方案。
    2 企业目标餐饮企业管理是指餐饮企业管理者在了解市场的前提下,通过执行计划、组织、指挥、控制、协调等职能,使企业形成最大营业能力,保证实现经济效益和社会效益的过程。因此,我们通过餐饮业管理信息系统对餐厅内的一系列组织结构进行划分,并做出规划,通过系统的分析和调配,对市场进行分析,再加上对以往数据的分析,形成最优的配比,以实现在正常运作下,使花费的费用最少的情况下,达到的效率最高、收益最大化。
    3 技术方案拟采用Django+Mysql+Nginx+Windows方案。Django是基于Python定制的Web框架,采用MTV的框架模式,即模型M,模板T和视图V。框架的对象关系映射ORM可使用Python类形式定义数据模型,ORM将模型与关系数据库连接起来,得到一个非常容易使用的数据库API,同时也可以在Django中使用原始的SQL语句。使用Django的主要目的是简便、快速地开发数据库驱动的网站。Django将被部署在较为轻量的Nginx服务器上,Nginx配置简洁,支持高并发连接,同时又有很好的CPU使用效率。搭配Mysql数据库,四者构成完全开源的开发平台,文档完善,且拥有庞大的开发者社区。
    4 系统规划4.1 餐厅组织结构
    4.2 企业过程
    4.3 U/C矩阵基于企业过程生成数据类

    5 系统的界限
    5.1 有关组织的信息分析5.1.1有关人员方面的信息(人员及构成)餐厅内部的各职能部门由总经理全面领导,总经理将招聘准则交给人事部门,又由人事部门负责招聘,对招聘进来的人员进行管理分配,将符合各部门要求的职员分配给各部门,所有员工均有人事部门统一进行协调排班。前台由服务人员,收银人员,配送人员组成,服务人员负责服务顾客,传递订单的职能;收银人员负责收款,传递收费报表;配送人员负责成品的递送。厨房由配菜员,厨房经理,厨师组成,厨房经理负责同方的统一调度,配菜员负责将订单信息转化为配菜信息,并通过配菜信息交给仓库进行拣选,厨师负责加工产品。仓库由库存管理员,拣选员,清点员组成,仓库管理员负责对仓库的信息统一进行管理,拣选员负责将厨房发来的配菜单惊醒整理并拣选菜品,清点员负责将新到的货品对照进货单进行清点。采购部门由采购员组成,采购员负责进行缺货物料的采购。人事部门由人事管理员与绩效考核员组成,人事管理员负责招聘、管理、分配餐厅内的人员,效绩考核员负责根据考核单进行工资评定。财务部门由财务会计与工资发放员组成,财务会计负责汇各类财务单工资发放员负责工资的发放。
    5.1.2 有关工作方面和工作环境方面的信息工作方面:前台进行与客户的主要交互,因此前台人员应符合餐厅的服务理念,使顾客尽量能够满足我们的服务;厨房进行生产加工,这里的员工应该具备较强的技能,使每道菜都有其相应的价值;库存与采购主要与物料进行接触,应保证物料的质量与数量,这里的人员应具备较强的责任心与观察力,使库存不出任何差错;人事应具有较强的管理能力,使餐厅整个人员流动处于平衡状态,使工作有条不紊的进行;财务应具备较强的统计能力,使餐厅的收支准确无误。
    工作环境方面的信息:餐厅内部前台的环境是整个餐厅的核心,也是顾客进行消费的场所,这里的工作环境没有很大的变动,但一般都是琐碎的工作;厨房与库存实际上是处于一体的,厨房与库存不分家;采购是厨房的外接,主要环境是市场与库存;人事与财务都是管理层,人员的工作一般都是业务的处理,都有相应的办公室配备。
    5.2 业务功能调查
    5.3 业务流程调查

    订单信息:顾客点单产生的信息汇总
    配送状态:外卖小哥通过第三方平台传至前台的实时配送情况
    账单信息:收银台通过汇总报给财务的费用报表
    缺货告知:前台通过可生产菜品余量与以生产数量对比,当数量不足告知顾客不可选的菜品
    菜品明细:前台根据订单信息产生的菜品所需原料的明细单
    加工进度:厨房根据每个工位上菜品所处的未加工/在加工/已完成状态告知给前台
    物料单:厨房生产所需原料的明细单
    可生产菜品余量:仓库根据每天的库存余量计算出对应可生产菜品的数量



    已取消菜品:顾客因需求变动取消订单中的菜品
    取消菜品信息:顾客取消的菜品的明细单
    取消订单信息:顾客取消订单的明细
    退款单:顾客因故取消订单产生的费用明细



    预备菜品:厨房根据订单信息产生的菜品而做的物料准备工作
    菜品明细:前台通过订单产生的菜品所需物料明细单
    取料单:厨房所需取得的物料的明细
    任务分配单:厨房根据具体订单与工位状态产生的生产计划
    工位信息:工位所处的状态
    出菜信息:生产加工完成的菜品的信息



    缺货信息单:仓库根据库存监控得到库存不足的物料的明细单
    菜品需求预测:前台根据以往数据产生的需求旺盛的菜品的种类明细
    采购账单:采购所需费用的明细单
    物料商品订单:采购部根据缺货信息单制定的物料明细单
    费用单:采购所需的费用
    到货验收单:入库检查时收到的单据



    招聘准则:餐厅经理通过企业文化制定的员工要求
    职工信息表:招收进入餐厅的职工信息
    员工工资报表:员工工资的具体费用单据
    员工分配表:人事管理部门通过员工的具体信息产生的分工表
    服务反馈信息:通过前台收集的反馈单产生的反馈信息



    结算费用报表:收银员汇总的顾客消费费用的表单
    采购费用报表:采购所需费用的具体明细单
    报销费用:财务通过采购费用报表产生的报销金额
    钱款:顾客消费产生的费用
    工资标准:人事部通过不同工种的具体要求产生的薪资标准
    工资:员工收到的薪资
    财务汇总单:财务部门通过各类费用报表产生的收支明细汇总

    5.4 数据汇总5.4.1 ER模型
    5.4.2 数据项
    5.4.3 U/C矩阵
    5.5 数据流程图环境图

    零层图

    前台服务二级DFD

    厨房生产加工二级DFD

    库存采购二级DFD

    人事二级DFD

    财务二级DFD

    5.6 数据字典5.6.1 数据结构
    5.6.2 数据流
    5.6.3 数据存储
    5.6.4 外部实体
    5.6.5 逻辑处理
    6 数学模型6.1 厨房生产模型本系统采用多工位-多菜品(即一个工位可以独立加工多种菜品,一种菜品可以由多个工位加工)的生产模式。工位-菜品关系附表。
    对于所有订单菜品,定义各工位正在加工的、及其后一个待加工菜品为已分配菜品,其余的(如果存在)为未分配菜品,本模型在先到先服务的菜品加工顺序下以最小化每个订单完成时间为目标来决策未分配菜品的加工工位。
    每当一个订单到来既进行一次决策,若工位当前空闲或仅有一个正在加工菜品,则决策所得该工位的前2或1个可加工菜品直接分配给该工位作为已分配菜品,否则为未分配菜品,待下一订单到达时重新决策,每个工位按当前决策结果顺序加工。
    目标函数如下:

    其中, Fj为由j订单的菜品i实际完成时间fi,j组成的列向量,Ej为订单j的菜品i预期完成时间ei,j组成的列向量,a为订单超时惩罚系数,fi,j与决策变量即j订单i菜品加工工位xi,j存在确定函数关系:

    即根据工位xi,j及加工顺序qi,j(先到先服务,即取决于 )依次递推可得j订单的菜品i实际完成时间,而

    其中tj为订单j下单时间,ti,j 为菜品加工所需时间。
    该模型使用遗传算法求解,变量表述如下:

    其中,ai为菜品编号,bj为订单编号,xi,j为工位编号,qi,j为工位内加工顺序,形如:

    xk列向量即为个体编码,取种群数量100,交叉概率0.3,变异概率0.2,迭代次数100,以如下订单菜品信息为例进行求解(暂未考虑不同工位对同菜品加工时间不同):

    优化结果[1, 2, 3, 4, 1, 3, 4, 3, 4, 2, 3, 1, 3, 2, 1, 2, 2, 1, 4],相较随机分配可提升约25%的总体工作效率,且在任务数量不多时可大幅降低订单超时率,本例订单超时率较随机分配降低约30%。
    7.系统设计7.1 功能结构图设计7.1.1 层次模块结构图
    7.1.2 H图
    7.2 系统流程图7.2.1 系统流程-顶层
    7.2.2 系统流程-前台
    7.2.3 系统流程-厨房
    7.2.4 系统流程-库存采购
    7.2.5 系统流程-人事
    7.2.6 系统流程-财务
    7.3 程序设计7.3.1 确认订单程序
    7.3.2 厨房任务分配流程
    8 程序截图首页
    3 评论 93 下载 2018-11-06 11:52:45 下载需要8点积分
  • 基于JSP的图书馆管理系统设计与实现

    摘 要随着科学技术的进步,计算机行业的迅速发展,大大提高人们的工作效率。计算机信息处理系统的引进已彻底改变了许多系统的经营管理 。
    图书管理系统是学校管理机制中的重要组成部分,通过对图书管理系统的运行管理机制进行调查研究,开发了此图书系统。本系统中解决了学校图书管理事务中的常用基本问题以及相关统计工作。本系统中包含6个功能模块:系统设置,读者管理,图书管理,图书借还,系统查询和更改口令。
    本系统使有jsp进行网页界面的设计,使用MVC设计模式,采用了开源框架Struts,它采用了当今软件设计的最新技术,具有开发效率高、设计灵活、生成的软件界面友好美观等特点。本系统中通过JDBC驱动和数据库进行无缝连接,后端的数据库是mysql,也是一个开源的数据库系统,该数据库具有较高的完整性,一致性和安全性。
    关键词:图书管理;信息管理;jsp;struts
    AbstractWith the progress of science and technology, the astonishing rapid development of the computer industry has been improving people’s working efficiency greatly.The introduction of computerized information system has sharply changed the management in many systems in many fields.
    The management system of the library takes an important role in the administration of school organization. I desigen the system after the thorough investigations about the library management system’s mechanism. This system contains with reader informantion management model, book information management model, books borrowing and returning including system information query and password setting.
    The system is contrived with Java Server Pages Techonolege as well as Struts,the software design mode of MVC with open source framework techonolege, which makes this system have the advantages of efficiently designed with beauteous and friendly interface . This system use jdbc driver to connect the mysql database server,which is also an open source database system for its users. The batabase was desigend with highly integrity, security, and consistency.
    Key words: book management, management of information ,jsp,struts
    1.绪论1.1 毕业设计主要任务
    实现图书馆对所藏图书的按类别、书名等多方面的查询,最大的方便读者和图书馆工作人员对所需图书的查询
    建立图书馆外借读者数据库,方便工作人员对读者进行有效管理
    建立图书馆工作人员数据库,限定每个工作人员对软件操作的权限,最大限度的保护数据库
    实现图书馆对新书入库,旧书注销的简单处理,并且建立书籍档案,方便进货
    实现图书馆

    1.2 目前图书管理系统存在的问题1.2.1 检索速度慢、效率低因为图书馆的藏书种类多、数量多,将藏书准确地分门别类,快速检索,手工进行非常困难往往是终于查到了二伟的信息,馆中没有此书或已被别人借走。图书馆的规模越大,这个问题越突出。
    1.2.2 借书、还书工作量大借书、还书频率越大,说明图书馆的作用越大,然而随之而来的大量的借书、还书登记、实存图书的更新以及借出图书超期、遗失等的处理,其工作量之大,往往是人工操作所难以胜任的。而且经常会出现这样那样的差错。
    1.2.3 图书统计工作难、藏书更新不能及时完成。图书馆的图书应根据科学技术的发展和教学工作的需要及时添加和更新,然而由于藏书数量及图书种类越来越多,加上自然损耗,人为破坏,使图书的统计工作难以及时完成,藏书的更新也就很难有针对性地进行,藏书的知识结构得不到良好地控制。
    我校也是一所发展中的高校,近儿年的发展速度很快,图书馆的规模和藏书数量也不断的扩大,为了解决海量图书的管理问题,改变传统的管理方式也是迫在眉睫了。
    1.3 课题意义随着计算机的广泛应用,其逐步成为现代化的标志。图书馆或者一些企业内部,甚至是书店,在正常运行过程中总是面对大量的读者信息,书籍信息以及两者相互作用产生的借书信息、还书信息。因此需要对读者资源、书籍资源、借书信息、还书信息进行管理,及时了解各个环节中信息的变更,要对因此而产生的单据进行及时的处理,为了提高图书馆或者企业内部对图书存销的自动化的管理,能够更快速的满足读者的要求,提高各种工作的效率,现对其设计相应的系统,以达到上述的目的[1]。
    图书管理系统的主要功能是实现图书馆图书借阅和归还的管理的自动化。围绕这一主要功能,本系统涉及到以下核心功能:借阅管理,归还管理。除了这些核心功能外,还包括一些基本和辅助功能,它们是:用户管理、图书馆参数管理、图书管理、统计查询。
    1.4 论文的工作和安排本次设计的目标是,开发一个图书馆借阅管理系统。借助该系统,管理员通过快捷可靠的数据库管理,方便的管理图书馆的信息资料,规范化的管理读者用户,设定不同用户权限,并能通过互联网向读者提供更为方便的在线查询服务,方便读者的使用,最终达到提高图书馆资源利用效率的目的。
    论文设计和实现了图书借阅管理系统系统,可以根据用户的不同权限,对图书馆的的各种信息进行添加、删除、修改或查询操作。论文分为五个部分:

    第一章即本章绪论,简述图书馆借阅管理系统这个课题的背景情况以及开发本系统的意义
    第二章为需求分析,本章中明确了系统需要实现的功能,分析了系统的用例,并介绍根据系统的需求选择的开发工具和技术的概况
    第三章是总体设计,详细描述了本系统中数据库的设计情况,并给出了系统总体界面的设计方案
    第四章为程序设计与编码各主要功能模块的实现方法和部分关键代码,同时提供了个主要界面运行的参考图片,以更直观了解系统的实现情况
    第五章是软件测试,测试系统功能实现并对测试结果进行记录分析
    第六章为结束语,为此次毕业设计做一个总结,总结所获得的经验和体会

    2.图书借阅管理需求分析2.1 可行性分析采用现代化统一的计算机信息网站系统,能够有效优化图书馆管理系统,使其高效的发挥最大作用,能够迅捷的为读者提供相应的服务。开发本系统的可行性研究如下:
    2.1.1 技术可行性技术上的可行性分析主要分析技术条件能否顺利完成开发工作,软、硬件能否满足需要。本系统采用JSP开发出友好美观的人机界面,便于用户理解、操作。数据库管理系统采用MySQL,它能够处理大量数据,同时保持数据的完整性、安全性。因此本系统的开发平台已成熟可行。硬件方面,在科技飞速发展的今天,硬件更新速度越来越快,容量越来越大,可靠性越来越高,价格越来越便宜,因此硬件平台也能够满足本系统所需[2]。
    2.1.2 经济可行性鉴于计算机技术发展异常迅猛,在硬件软件配置以及开发技术均以可行的情况下开发这样一个管理系统成本不会很高,但其可以大大提高图书馆的工作效率,也是图书馆管理发展的必然趋势,其必将有比较宽阔的市场,因此改性统在经济可行性上时可行的[2]。
    2.2 图书借阅管理系统需求概述2.2.1 系统目标该系统主要建立一个基于B/S模式的图书馆借阅管理系统,面对当起很多小型图书管理仍是人工管理带来的检索速度慢,效率低,借阅归还图书量大,图书统计工作量大,藏书不能完成及时更新的问题,该系统可以对跟系统的三个用户类型的使用实现:

    对于读者在本系统的应用下可实现按照各种方式(如:书名,编号,作者)查询图书馆的藏书请客,方便的借阅图书,续借图书,归还图书,能够查询自己的借阅图书情况
    对于图书馆工作人员能够实现方便的对图书进行查询,方便的进行读者借阅情况查询,方便的进行借书还书处理等,便捷的对图书信息进行添加、修改、删除,分类管理等操作,对读者信息进行相关添加,修改,分类管理等操作
    对于系统管理员可以对图书馆信息进行修改更新操作,对系统用户进行添加、修改、删除、权限设置等操作,对图书馆的办证参数进行修改维护等操作功能

    2.2.2 用户类和用户特性图书借阅管理系统是一个基于B/S模式的对图书馆进行高效率管理的应用系统,它的用户主要是读者和图书管理员,学生通过该系统进行图书查询进而对自己需要的图书进行借阅及自己的借阅情况进行查询,图书管理员则通过本系统实现对图书及读者的高效管理,除此之外,还需要一个系统管理员对不同的用户进行权限的设置等操作[2]。
    三类用户的具体描述如下表所示:



    用户类
    描述




    读者
    读者是该系统的重要的使用角色,他们通过该系统查询自己需要的图书信息,并像图书管理员提出借阅图书的申请进而借阅自己所需的图书,还可以通过对自己借阅情况进行查询。


    图书管理员
    图书管理员是该系统的另一个重要使用者,图书管理员通过该系统进行图书的增加,修改,删除,分类管理等操作,实现对读者借阅归还续接图书的方便操作,实现对系统中图书,读者,读者借阅情况的查询,信息更改维护等操作,管理读者类型,对不同类型读者可借阅的图书数量进行设置等图书馆的基本操作。


    系统员
    系统管理员主要是图书管理系统中用户的管理,实现用户添加修改删除以及用户权限设置等操作,实现对图书馆基本信息的修改维护等操作,还包括对图书馆书架的设置操作,以及校外读者办证所需费用、证件有效期等参数的设置。



    2.3 图书借阅管理系统需求模型2.3.1 功能描述图书借阅管理系统的主要任务是实现读者迅速检索查询,方便借阅归还图书,图书管理员高效的完成系统的各项基本操作,系统管理员是管理用户设置权限等操作[3],从图2.1可以看出图书借阅管理系统要完成一下功能:

    登录:读者、图书管理员,系统管理员进入该系统必须登录,身份验证正确了才可以进入该系统,以不同身份进入该系统所对应的系统使用权限是不同的
    系统设置功能:系统管理员可以设置图书馆相关的参数信息
    用户管理功能:对系统用户进行添加,修改,删除,权限设置等操作
    查询功能:对图书馆的馆藏图书,借阅历史,读者用户等信息进行查询
    其他功能:系统管理员可以修改自己的密码,并且拥有其他用户所拥有的所有功能

    下面的系统用例图描述了整个系统用户之间的动作联系及功能模块的概述[4]。

    2.3.2 图书管理员详细功能描述
    读者管理功能:对读者的类型和读者档案进行管理,包括添加,修改,删除读者类型和读者用户的相关信息,管理不同类型读者借阅图书的数量
    图书管理功能:包括对图书类型和具体图书信息的管理,可以增加,修改,删除图书,丰富具体图书的信息,对不同图书进行分类操作
    图书借阅功能:可以完成对读者借阅,续接和还书的操作
    系统查询功能:查询图书相关资料,借阅历史和借阅到期题型
    修改密码功能:可以修改自己的登录密码

    2.3.3 读者详细功能描述
    修改登陆密码:修改自己的登录密码
    查询功能:对图书馆图书信息进行查询,对自己当前借阅书籍进行查询,对图书规划到期题型进行查看

    2.3.4 主要用例的用例描述图书借阅借阅管理系统涉及到的用例包括:图书借阅,图书归还,读书查询,读者信息管理,图书信息管理,用户管理等,现就系统的主要用例图书借阅,图书归还,图书查询进行详细分析。
    用例“图书借阅”



    用例名称
    图书借阅




    标识符
    UC-1


    参与者
    读者,图书管理员


    描述
    读书可以通过查询等方式获得自己想借阅的图书的名称,编号,等其他可唯一识别的信息,向图书管理员提出借阅请求,管理员在系统中记录相应信息,将图书交给读者,借阅成功。


    前置条件
    1. 登录;2. 进入图书借阅的页面


    后置条件
    1. 更新图书借阅列表;


    主干过程
    1.0 借阅图书 1. 读者请求借阅新地图书,并提供自己的编号 2. 系统显示读者借阅情况的表单 3. 读者提供想借阅的图书的标号 4. 系统存储读者和借阅的图书,并将之存储到数据库中 5. 系统更新借阅列表


    分支过程
    1.1 选择重置(第3步后分支出来) 1. 读者选择重置 2. 系统刷新该页面


    异常
    1.0.E.1 读者借阅已满(第2步) 1.读者借阅的数目已经到达自己借阅的上线 2. 系统将错误信息显示在借阅页面 3. 系统重新启动该用例


    被包含用例



    被扩展用例



    优先级




    用例“图书归还”



    用例名称
    图书归还




    标识符
    UC-1


    参与者
    读者,图书管理员


    描述
    读者将自己借阅的图书归还图书馆。


    前置条件
    1. 登录;2. 进入图书归还页面


    后置条件
    1. 更新图书归还列表;


    主干过程
    1.0 图书归还 1. 读者请求归还借阅的图书并提供自己的编号 2. 系统显示该读者的借阅信息表 3. 使用者填将要归还的图书交给管理员 4. 管理员输入图书编号,系统存储归还信息,并将之存储到数据库中 5. 系统更图书归还列表


    分支过程
    1.1 选择重置(第3步后分支出来) 1. 读者选择重置 2. 系统刷新该页面


    异常
    1.0.E.1 读者借阅超时(第4步) 1.该书超出了应该归还的时间范围 2. 系统将罚款信息显示在归还页面 3. 需要缴纳罚金


    被包含用例



    被扩展用例



    优先级




    用例“图书查询”



    用例名称
    图书查询




    标识符
    UC-3


    参与者
    读者,图书管理员


    描述
    读者通过图书的标号,名称等信息对相应的图书进行查询。


    前置条件
    1. 登录; 2. 转到图书查询页面


    后置条件
    1. 查询页面显示相应的图书的信息


    主干过程
    图书查询 1. 读者输入想要查询的图书信息 2. 系统显示相应的图书信息 3. 读者点击读书名称,跳转到图书详细信息链接页面


    分支过程
    输入信息时(第2步后) 1. 系统显示:请选择查询依据 2. 用户进行相应选择 重新查询(第2步后) 1. 系统已经显示了相应图书信息 2. 读者想查询其他图书


    异常
    5.0.E.1 查询的图书不存在(第2步后) 1. 读者输入的图书信息不能在数据库中查询到 2. 系统显示暂时无该图书信息 3. 重新启动该用例


    被包含用例



    被扩展用例



    优先级




    3.总体设计3.1 数据库设计3.1.1 数据库设计概述数据库是整个系统的基石,数据库的设计优劣直接影响到整个系统的设计成败,本节对数据库的设计进行专门阐述[5]。
    数据库是数据管理的最新技术。十多年来数据库管理系统已从专用的应用程序发展成为通用的系统软件。由于数据库具有数据结构化,最低冗余度,较高的程序与数据独立性,易于扩充,易于编制应用程序等优点,较大的信息系统都是建立在数据库设计之上的。因此不仅大型计算机及中小型计算机,甚至微型机都配有数据库管理系统[6]。
    数据库系统的出现使信息系统从以加工数据的程序为中心转向围绕共享的数据库为中心的新阶段。这样既便于数据的集中管理,又有利于应用程序的研制和维护,提高了数据的利用性和相容性,提高了决策的可靠性。目前,数据库已经成为现代信息系统不可分割的重要组成部分。数据库技术也是计算机领域中发展最快的技术之一。
    数据库设计是把现实世界的实体模型与需求转换成数据库的模型的过程,它是建立数据库应用系统的核心问题。数据库及其应用的性能都建立在良好的数据库设计的基础之上,数据库的数据是一切操作的基础,如果数据库设计不好,那么其它一切用于提高数据库性能的方法收效都是有限的。数据库设计的关键是如何使设计的数据库能合理地存储用户的数据,方便用户进行数据处理[6]。
    设计数据库必须遵循一定的规则,在关系型数据库中,这种规则就是范式,范式是符合某一种级别的关系模式的集合。一般人们设计数据库遵循第三范式。即:数据库表中不包含已在其他表中包含的非主关键字信息。采用范式减少了数据冗余,节约了存储空间,同时加快了增、删、改的速度[6]。
    整个系统所包括的信息有图书信息、读者信息、留言信息、图书借阅信息、图书归还信息、系统用户信息、读者类型信息。可将这些信息抽象为下列系统所需要的数据项和数据结构:

    图书信息(编号,图书名称,图书类型,作者,译者,ISBN号,价格,出版社,所在书架,入库时间,操作员)
    图书类型(编号,名称,可借阅天数)
    读者信息(编号,姓名,性别,条形码,读者类型,出生年月,有效证件,证件号码,登记日期,电话,邮箱,操作员)
    读者类型(名称,可借阅图书本数)
    图书借阅信息(图书编号,读者ID,借出时间,应还时间,是否归还,操作员)
    图书归还信息(图书编号,读者ID,归还时间,操作员)
    用户(编号,用户名称,密码)
    图书馆信息(编号,名称,馆长,电话,地址,邮箱,创建日期,简介)
    图书馆参数信息(编号,办证费用,有效期限)

    在这里使用E-R图描述了图书借阅管理系统的数据模型。图3.1图书借阅管理系统E-R图描述了该系统所涉及到的实体以及他们之间的关系。具体结构如下图所示:

    3.1.2 图书信息表结构设计图书信息表主要用于存储图书馆中所藏图书的相关信息,其中的相关信息是在图书入库时由操作员进行添加完善,此表主要用于读者和图书管理员对馆中图书的查询,系统用户根据图书的某个属性进行查询,便可得知图书的其他相关信息,其中图书所在书架属性是便于读者借阅时对图书的寻找,图书价格是在读者不慎将图书遗失时对遗失图书进行赔偿的依据。表的具体结果如下:
    图书信息表tb_bookinfo



    字段名称
    数据类型
    字段长度
    是否为空
    说明




    barcode
    varchar
    30
    No
    Key


    bookname
    varchar
    70
    No



    author
    varchar
    30
    Yes
    作者


    translator
    varchar
    30
    Yes
    译者


    ISBN
    varchar
    20
    No



    price
    float
    8,2
    No
    图书价格


    bookcase
    varchar
    10
    No
    图书所在书架


    press
    varchar
    70
    No
    出版社


    intime
    date

    No
    图书入库时间


    operator
    varchar
    30
    No
    操作员


    page
    int
    10
    Yes
    图书页码



    3.1.3 图书类型信息表结构设计该表的设计主要是方便对图书的分类,和对图书的查询,在实际应用中图书管理员就是根据图书类型的不同将之分列在不同的书架,以方便读者的借阅寻找,其中可借阅天数项设置了不同类型图书的借阅期限,可根据图书的具体情况进行不同的维护管理,表的具体结构设计如下:
    图书类型信息表tb_booktype



    字段名称
    数据类型
    字段长度
    是否为空
    说明




    ID
    int
    10
    No
    Key


    bookname
    varchar
    30
    No



    days
    int
    10
    No
    可借阅天数



    3.1.4 读者信息表结构设计读者信息表的设计是为了图书馆管理员对读者进行管理,其中读者ID,不同类型证件的号码都是唯一的,是读者在借阅图书时需要输入对读者身份进行识别的信息,读者邮件电话等信息室为了与读者进行联系,读者类型信息决定了读者一次性可借阅的图书的数量,注册时间可用于查询计算读者身份有效的期限,操作员是为了便于对信息才操作的查询。表的具体结构设计如下:
    读者信息表tb_reader



    字段名称
    数据类型
    字段长度
    是否为空
    说明




    Id
    int
    10
    No
    Key


    name
    varchar
    20
    No



    sex
    varchar
    4
    No



    barcode
    varchar
    30
    No



    readertype
    varchar
    11
    No
    读者类型


    tel
    varchar
    20
    Yes
    电话


    e-mail
    varchar
    100
    Yes



    paperType
    varchar
    10
    No
    证件类型


    PaperNO.
    Varchar
    20
    No
    证件号码


    birthday
    date

    Yes



    intime
    date

    No
    登记时间


    operator
    varchar
    30
    No
    操作员



    3.1.5 读者类型信息表结构设计此表的设计是为了对不同身份的读者进行分类方便读者的管理,其中可借阅图书数量的属性设定,是根据读者需求的不同对起权限进行的设置,用于规定不同类型读者一次可借阅的图书数量,表的具体结构设计如下:
    读者类型信息表tb_readertype



    字段名称
    数据类型
    字段长度
    是否为空
    说明




    ID
    int
    10
    No
    Key


    readername
    varchar
    50
    No



    number
    int
    4
    No
    可借图书本数



    3.1.6 图书借阅信息表结构设计该表的设计是用于对读者借阅图书进行管理,表中图书ID属性是对借阅图书的唯一性识别标识,读者ID号记录借阅的相应读者,结出时间记录了相应的归还时间,以及归还时是否超时,操作员是对借阅进行操作的人员的记录方便日后的查询,是否归还标识可查询当起读书是否被归还,表的具体结构设计如下:
    图书借阅信息表 tb_borrow



    字段名称
    数据类型
    字段长度
    是否为空
    说明




    ID
    int
    10
    No
    Key


    readerID
    varchar
    10
    No



    bookID
    int
    10
    No



    borrowTime
    date

    No
    结出时间


    backTime
    date

    No
    应归还时间


    operator
    varchar
    30
    No
    操作员


    ifback
    tinyint
    1
    No
    是否归还



    3.1.7 图书归还信息表结构设计与图书借阅信息表形成对照的是图书归还信息表,该表的设计除了像上表一样把借阅的图书与相应的借阅者进行对应的联系以外还记录了读者应归还图书的时间,以此判断读者的借阅是否超时,表的具体结构设计如下:
    图书归还信息表tb_giveback



    字段名称
    数据类型
    字段长度
    是否为空
    说明




    ID
    int
    10
    No
    Key


    readerID
    varchar
    11
    No



    bookID
    int
    11
    No



    backTime
    date

    No
    归还时间


    operator
    varchar
    30
    No
    操作员



    3.1.8 用户信息表结构设计该表的设计用于记录图书管理系统用户的信息,方便对用户的管理,表中包括用户ID 和用户的登录密码,表的具体结构设计如下:
    系统用户信息表tb_user



    字段名称
    数据类型
    字段长度
    是否为空
    说明




    ID
    int
    10
    No
    Key


    name
    varchar
    30
    No



    password
    varchar
    30
    No



    3.1.9 图书馆信息表结构设计该表包含了图书馆的名称,地址,联系方式,建馆时间,简介等信息,是对图书馆基本属性信息的描述,方便外界读者对图书馆的了解,表的具体结构设计如下:
    图书馆信息表 tb_library



    字段名称
    数据类型
    字段长度
    是否为空
    说明




    ID
    int
    10
    No
    Key


    libraryname
    varchar
    50
    No



    curator
    varchar
    10
    No



    tel
    varchar
    20
    Yes
    结出时间


    address
    varchar
    100
    No
    应归还时间


    e-mail
    varchar
    100
    No



    url
    varchar
    100
    No
    图书馆网站


    createDate
    varchar

    No
    创馆时间


    introduce
    text

    Yes
    图书馆简介



    3.1.10 办证参数信息表结构设计该表是为校外人员设计的,对于需要到图书馆进行借阅的读者可办理临时的借阅证用于对图书的借阅凭证,表中包含了办证所需费用以及证件的有效期限,表的具体结果设计如下:
    图书证参数信息表tb_parameter



    字段名称
    数据类型
    字段长度
    是否为空
    说明




    ID
    int
    10
    No
    Key


    Cost
    int
    10
    No
    办证费用


    validity
    int
    10
    No
    有效时间



    3.2 系统总体结构设计该系统在Windows98/2000/XP环境下,主要采用JSP开发工具,MySQL数据库来设计,开发过程与成果应符合GB/T 11457-1995软件工程术语,GB/T 8567-1988计算机软件产品开发文件编制指南等[7]。
    3.2.1 图书管理系统总体结构图绘制系统结构图的过程,实际上就是对系统功能模块进行分解设计的过程,即合理地将数据流程图转变为所需要的系统结构图[8]。
    系统结构图将会使读者和用户能直观的了解系统的结构模式,理解系统的各个功能的结构,能很好地方便用户使用和理解整个系统。
    本系统的结构图如下:

    根据需求分析的结果,按照“低耦合、高内聚”的原则,本系统将划分为以下主要功能模块:系统管理员功能模块,读者管理功能模块,图书管理功能模块,图书借还功能模块;系统查询功能模块[8]。
    3.2.2 系统管理员模块功能该模块主要包括图书馆信息设置,用户管理,参数设置,书架设置。

    图书馆信息设置:该功能选项用于系统管理员对图书馆名称,地址,联系方式,简介等信息的管理更新,以便于读者和外界人士对图书馆的了解。该功能是对td_library表进行维护修改等操作,修改后的信息将被保存在该表中
    用户设置:该功能子模块主要是系统管理员对系统用户的管理,通过此子模块的功能实现可以对用户进行添加、修改、删除、权限设置等操作,该子模块能将图书馆的不同工作细化到不同的相关人员,极大地提高了图书馆的工作效率。该操作是对tb_users表进行操作,在对用户进行了相关的操作后把操作后的最新信息存放在该表中
    图书馆参数设置:通过该子模块设置在图书馆办理临时读者证的费用及证件有效期限。该操作是对于tb_parameter表进行,并把操作后的最新数据存放在该表中

    3.2.3 读者管理模块功能该模块主要包含读者类型管理和读者信息管理两个子模块:

    读者类型管理:该子模块是对图书馆系统用户读者的类型进行维护,修改等操作,在此模块中主要设置不同类型读者一次性可借阅的图书的数量,该操作是对于tb_resderType表进行,并将操作结果保存在该表中
    读者信息管理:该子模块是对读者的基本信息进行管理,可以对读者的基本信息进行添加,修改,删除操作,这下操作均是对tb_resder表进行的,并将操作后的结果保存在该表中

    3.2.4 图书管理模块功能图书管理功能模块可分为图书类型管理和图书信息管理两个子模块,其各自的实现分别如下面表中所示:
    图书类型管理描述




    图书类型管理




    功能描述
    对图书进行类型设置分类,并对不同类型图书可被借阅的天数进行设置


    访问的数据库表
    图书类型表:tb_bookType


    进行的操作
    添加、修改、删除图书类型,对不同类型图书可被借阅的天数进行设置


    产生的结果
    对图书类型进行管理,对不同类型图书参数进行设置


    结果存储位置或输出
    结果存储在图书类型表(tb_bookType)中,结果在图书类型查询页面输出



    图书信息管理描述




    图书信息管理




    功能描述
    对图书进行基本操作和信息管理


    访问的数据库表
    图书类型表:tb_bookType


    进行的操作
    添加、修改、删除图书,对图书的编号、所在书架、价格、出版社等基本信息进行管理


    产生的结果
    对图书基本操作管理,对不同图书参数进行各自信息的设置管理


    结果存储位置或输出
    结果存储在图书类型表(tb_book)中,结果在图书查询页面输出



    3.2.5 图书借还模块功能该功能模块主要实现对读者借阅、续接、归还图书的操作,其中子模块各自的描述如下各表所列:
    图书借阅描述




    图书借阅管理




    功能描述
    对读者借阅图书进行基本操作和信息管理


    访问的数据库表
    图书信息表: tb_bookinfo 读者信息表:tb_reader 读者类型信息表:tb_resderType


    进行的操作
    对读者借阅图书进行管理


    产生的结果
    读者借阅成功,系统对借阅信息进行记录


    结果存储位置或输出
    结果存储在图书借阅表(tb_borrow)中,结果在图书借阅查询页面输出



    图书续借描述




    图书续接管理




    功能描述
    对读者借阅图书进行提续接操作


    访问的数据库表
    图书借阅表: tb_borrow


    进行的操作
    对借阅的图书进行续接


    产生的结果
    读者归还日期延后一个月


    结果存储位置或输出
    结果存储在图书借阅表(tb_borrow)中



    图书归还描述




    图书归还管理




    功能描述
    对读者归还图书进行基本操作和信息管理


    访问的数据库表
    图书借阅信息表: tb_borrow 读者类型信息表:tb_resderType


    进行的操作
    对读者借阅图书进行管理


    产生的结果
    读者借阅成功,系统对借阅信息进行记录


    结果存储位置或输出
    结果存储在图书归还表(tb_giveback)中



    3.2.6 系统查询模块功能该模块包括对图书馆藏书进行查询,对读者借阅情况进行查询,以及对借阅到期和超期的读者进行提醒的信息,其中三个子模块的各自实习如下所示:
    图书查询描述




    图书查询




    功能描述
    系统用户对馆藏图书信息进行查询操作


    访问的数据库表
    图书信息表: tb_book


    进行的操作
    用户通过图书的编号,作者,出版社等信息对图书进行相关查询


    产生的结果
    读者查询到相应的图书或系统提醒查询的图书不存在


    结果存储位置或输出
    结果在图书查询页面输出



    图书借阅查询描述




    图书借阅查询




    功能描述
    系统用户对读者借阅图书信息进行查询操作


    访问的数据库表
    图书借阅表: tb_borrow


    进行的操作
    用户通过图书的编号,读者编号等信息对摸个读者或某本图书的借阅情况进行相关查询


    产生的结果
    查询到相应的读者或图书得借阅情况


    结果存储位置或输出
    结果在图书查询页面输出



    图书借阅到期提醒描述




    图书借阅到期提醒管理




    功能描述
    对读者借阅的到期图书进行提醒


    访问的数据库表
    图书借阅表: tb_borrow 图书归还表:tb_giveback 读者信息表:tb_reader 读者类型信息表:tb_resderType


    进行的操作
    对借阅到期和超期的读者进行提醒


    产生的结果
    向借阅到期和借阅超期的读者发送邮件等提醒信息


    结果存储位置或输出
    结果存储在图书借阅到期提醒表



    4.程序设计与编码4.1 开发平台与工具4.1.1 J2EE平台J2EE ,即是Java2平台企业版(Java 2 Platform Enterprise Edition),是原Sun公司(现已被甲骨文公司收购)为企业级应用推出的标准平台。它简化了企业解决方案的开发、部署和管理相关复杂问题的体系结构,J2EE技术的基础就是核心Java平台或Java 2平台的标准版,J2EE不仅巩固了标准版中的许多优点,例如”编写一次、随处运行”的特性、方便存取数据库的JDBC API、CORBA技术以及能够在Internet应用中保护数据的安全模式等等,同时还提供了对 EJB(Enterprise JavaBeans)、Java Servlets API、JSP(Java Server Pages)以及XML技术的全面支持。其最终目的就是成为一个能够使企业开发者大幅缩短投放市场时间的体系结构。J2EE体系结构提供中间层集成框架用来满足无需太多费用而又需要高可用性、高可靠性以及可扩展性的应用的需求。通过提供统一的开发平台,J2EE降低了开发多层应用的费用和复杂性,同时提供对现有应用程序集成强有力支持,完全支持Enterprise JavaBeans,有良好的向导支持打包和部署应用,添加目录支持,增强了安全机制,提高了性能[9]。
    在开发图书馆借阅管理系统的过程中,应用Myeclipse6.0.1,它可以在数据库和J2EE的开发、发布,以及应用程序服务器的整合方面极大的提高工作效率。Myeclipse是功能丰富的J2EE集成开发环境,包括了完备的编码、调试、测试和发布功能,完整支持HTML, Struts, JSF, CSS, Javascript, SQL[10]。
    4.1.2 WEB服务器和数据库在系统的开发过程中使用的Web应用服务器是Tomcat,是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、SUN和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现。Tomcat是一个小型的轻量级应用服务器,它运行时占用的系统资源小、扩展性好、支持负载平衡和邮件服务等开发应用系统常用的功能,因此在中小型系统和并发访问用户不是很多的时候,经常被使用[11]。
    使用MySQL作为数据库开发工具。MySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司。在2008年1月16号被Sun公司收购。目前MySQL被广泛地应用在Internet上的中小型网站中。由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了MySQL作为网站数据库[11]。
    为了开发的便捷快速,使用struts第三方插件。Struts是一个全新的MVC框架,实在WebWork基础上发展起来的[12]。
    开发系统用的系统工具如表4.1所示:



    工具名称
    用途




    JDK 1.6.0_11
    Java 开发工具包


    MyEclipse
    J2EE集成开发环境


    MySQL 5.0
    小型关系数据库管理系统


    SQLYog 6.1
    MySQL图形化数据库管理工具


    Tomcat 6.0
    Web应用服务器


    Struts 1.0
    第三方插件,可扩展的Java EE Web框架



    4.2 程序设计4.2.1 程序设计概述在设计的Web层应用了著名的MVC模式,V有JSP来实现,为了业务逻辑和表示的分离.它是基于Web应用系统,它的客户端使用Broswer,然后是Web层的应用,业务逻辑层(有EJB实现),资源管理层。客户请求浏览页面,一般Web层的View有JSP组成,并且使用了大量Taglib。把每个请求映射到某个HTMLAction类来响应它。HTML Action类是一个标准的类,执行选择的HTML Action。使用MVC模式减少了代码的复制,即减少了代码的维护,由于模型返回的格式不带任何显示格式,因而模型可以直接应用于接口的使用,还因为MVC模型把不同的模型和不同的视图组合在一起完成不同的请求,因此,控制层可以说包含了用户请求权限的概念[13]。
    在设计中还因应用了Struts框架,Struts跟Tomcat、Turbine等诸多Apache项目一样,是开源软件,这是它的一大优点。使开发者能更深入的了解其内部实现机制[11]。
    除此之外,Struts的优点主要集中体现在Taglib和页面导航。Taglib是Struts的标记库,灵活动用,能大大提高开发效率。页面导航使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处[11]。
    4.2.2 数据库与Web服务器的连接数据库连接时采用连接池技术链接MySQL,具体代码实现如下:
    public ConnDB(){ try { InputStream in=getClass().getResourceAsStream(propFileName); prop.load(in); //通过输入流对象加载Properties文件 dbClassName = prop.getProperty("DB_CLASS_NAME"); //获取数据库驱动 dbUrl = prop.getProperty("DB_URL", "jdbc:mysql://127.0.0.1:3306/db_librarySys?user=root&password=123&useUnicode=true"); } catch (Exception e) { e.printStackTrace(); //输出异常信息 } } public static Connection getConnection() { Connection conn = null; try { Class.forName(dbClassName).newInstance(); conn = DriverManager.getConnection(dbUrl); } catch (Exception ee) { ee.printStackTrace(); } if (conn == null) { System.err.println( "警告: DbConnectionManager.getConnection() 获得数据库链接失败.\r\n\r\n链接类型:" + dbClassName + "\r\n链接位置:" + dbUrl); } return conn; } /* * 功能:执行查询语句 */ public ResultSet executeQuery(String sql) { try { conn = getConnection(); stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); rs = stmt.executeQuery(sql); } catch (SQLException ex) { System.err.println(ex.getMessage()); } return rs; } /* * 功能:执行更新操作 */ public int executeUpdate(String sql) { int result = 0; try { conn = getConnection(); //调用getConnection()方法构造Connection对象的一个实例conn stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); result = stmt.executeUpdate(sql); //执行更新操作 } catch (SQLException ex) { result = 0; } return result; } /* * 功能:关闭数据库的连接 */ public void close() { try { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } catch (Exception e) { e.printStackTrace(System.err); } }}
    4.2.3 登录模块程序设计本模块主要是用户通过图书管理系统的首页登录进入该系统。用户输入正确的用户名和密码,系统会根据用户的身份进行相应权限划分;如果登录信息有错误,则系统提示登入错误的信息,并且禁止系统用户进行任何操作。图书借阅管理系统的登录主页面如图4.1所示。

    用户在登录页面写好用户名和密码,选择登录,登录成功则跳转到系统的首页,否则提示错误信息[14]。在服务器端进行用户身份验证的程序流程图如图4.2程序流程图所示。

    4.2.4 系统管理员功能模块的实现本模块中最主要的是管理系统用户,设置图书馆信息等操作,其中管理系统用户包括对他们进行添加,修改,删除及权限划分操作。
    其中系统管理员读系统用户进行管理的操作页面如下图所示:

    其中对系统用户权限的设置是该操作的重要部分也是系统提高效率的关键所在,起具体实现代码为:
    private ActionForward managerModify(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { ManagerForm managerForm = (ManagerForm) form; managerForm.setId(managerForm.getId()); //获取并设置管理员ID号 managerForm.setName(managerForm.getName()); //获取并设置管理员名称 managerForm.setPwd(managerForm.getPwd()); //获取并设置管理员密码 managerForm.setSysset(managerForm.getSysset()); //获取并设置系统设置权限 managerForm.setReaderset(managerForm.getReaderset()); //获取并设置读者管理权限 managerForm.setBookset(managerForm.getBookset()); //获取并设置图书管理权限 managerForm.setBorrowback(managerForm.getBorrowback()); //获取并设置图书借还权限 managerForm.setSysquery(managerForm.getSysquery()); //获取并设置系统查询权限 int ret = managerDAO.update(managerForm); //调用设置管理员权限的方法 if (ret == 0) { request.setAttribute("error", "设置管理员权限失败!");//保存错误提示信息到error参数中 return mapping.findForward("error"); //转到错误提示页面 } else { return mapping.findForward("managerModify"); //转到权限设置成功页面 } }
    4.2.5 读者管理功能模块的实现读者管理主要实现对读者的类型管理和信息管理两个功能子模块,其中读者类型管理中需要设置不同类型读者一次性可借阅的图书数量,读者信息管理则主要管理维护读者的基本信息,其各自操作界面如下所示:
    读者类型管理功能界面

    读者信息管理功能界面

    该管理功能在设置读者信息时需要输入读者姓名,性别,条形码,选择读者类别,有效证件,证件号码,电话,e-mail等信息。其中的姓名,性别,条形码,证件号码是必填选项。
    4.2.6 查询功能模块的实现查询功能模块包括图书查询,读者借阅查询和借阅到期提醒三个子功能模块。
    图书查询可根据图书的条形码,书名,作者,出版社等不同信息进行查询,其操作界面图下图所示:

    实现该功能中根据读者不同需求的按条件查询实现语句如下:
    public Collection query(String strif){BookForm bookForm=null;Collection bookColl=new ArrayList();String sql="";if(strif!="all" && strif!=null && strif!=""){ sql="select * from (select b.*,c.name as bookcaseName,p.pubname as publishing,t.typename from tb_bookinfo b left join tb_bookcase c on b.bookcase=c.id join tb_publishing p on b.ISBN=p.ISBN join tb_booktype t on b.typeid=t.id where b.del=0) as book where book."+strif+"'";}else{ sql="select b.*,c.name as bookcaseName,p.pubname as publishing,t.typename from tb_bookinfo b left join tb_bookcase c on b.bookcase=c.id join tb_publishing p on b.ISBN=p.ISBN join tb_booktype t on b.typeid=t.id where b.del=0";}System.out.println("图书查询时的SQL:"+sql);ResultSet rs=conn.executeQuery(sql);try { while (rs.next()) { bookForm=new BookForm(); bookForm.setBarcode(rs.getString(1)); bookForm.setBookName(rs.getString(2)); bookForm.setTypeId(rs.getInt(3)); bookForm.setAuthor(rs.getString(4)); bookForm.setTranslator(rs.getString(5)); bookForm.setIsbn(rs.getString(6)); bookForm.setPrice(Float.valueOf(rs.getString(7))); //此处必须进行类型转换 bookForm.setPage(rs.getInt(8)); bookForm.setBookcaseid(rs.getInt(9)); bookForm.setInTime(rs.getString(10)); bookForm.setOperator(rs.getString(11)); bookForm.setDel(rs.getInt(12)); bookForm.setId(Integer.valueOf(rs.getString(13))); bookForm.setBookcaseName(rs.getString(14)); bookForm.setPublishing(rs.getString(15)); bookForm.setTypeName(rs.getString(16)); bookColl.add(bookForm); }} catch (SQLException ex) { ex.printStackTrace();}conn.close();return bookColl;}
    借阅查询子模块是对图书当前状态和读者当前的借阅情况进行查询,具有此权限的用户登录并进入该操作界面后选中相应的查询条件,并输入相应的查询信息,系统即可在页面显示被查询的图书的状态,或相应读者的当起借阅情况,此外,还可以输入相应时间段内的所有借阅清单,或选择某个读者查询他在某个时间段内的借阅情况,查询某个时间段内的此子功能操作界面为:

    系统中同时选中日期和限制条件进行查询时,程序是在条件查询的基础上选中符合时间条件限制的内容,其实现代码为:
    if (flag.length == 2) { if (request.getParameter("f") != null) { str = request.getParameter("f") + " like '%" + request.getParameter("key") + "%'"; } System.out.println("日期和条件"); String sdate = request.getParameter("sdate"); String edate = request.getParameter("edate"); String str1 = null; if (sdate != null && edate != null) { str1 = "borrowTime between '" + sdate + "' and '" + edate + "'"; } str = str + " and borr." + str1; System.out.println("条件和日期:" + str);}
    借阅到期提醒子模块是将系统当前时间与应归还的时间进行比较,如果系统当前时间以超过图书应归还时间,相应的读者借阅信息便会被显示在借阅到期提醒界面,其界面为:

    4.2.7 图书管理功能模块的实现与读者管理模块类似,图书管理模块也分为图书类型管理和图书档案管理两个子模块,其中图书类型管理功能处理将图书分类提高管理效率外还设置了不同类型图书可借阅的天数,对不同类型图书进行区别管理,图书档案管理是管理维护图书馆藏书的基本信息。这两个子模块的操作界面为:
    图书类型管理界面

    图书档案管理界面

    图书档案中包含图书的条形码,图书名称,图书类型,作者,译者,价格,出版社,所在书架等图书基本信息,其中作者,译者,页码是备选信息,可以不填。
    4.2.8 图书借还功能模块的实现该功能模块可分为图书借阅,图书归还,图书续借三个子模块.
    图书借阅该子模块实现系统的借阅功能,读者向图书管理员提供自己的编号会显示出读者当起的借阅情况,再提供要借阅的图书标号,图书管理员将信息记录在系统中,借阅成功,其操作界面如下图:

    如果在借阅时所要借阅的图书不存在或者读者借阅已达借阅图书的上线,则读者不能接续借阅图书,系统将给出相应提示,此功能的实现代码为:
    private ActionForward bookborrow(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response){ //查询读者信息 //此处一定不能使用该语句进行转换 readerForm.setBarcode(request.getParameter("barcode")); ReaderForm reader = (ReaderForm) readerDAO.queryM(readerForm); request.setAttribute("readerinfo", reader); //查询读者的借阅信息request.setAttribute("borrowinfo",borrowDAO.borrowinfo(request.getParameter("barcode"))); //完成借阅 String f = request.getParameter("f"); String key = request.getParameter("inputkey"); if (key != null && !key.equals("")) { String operator = request.getParameter("operator"); BookForm bookForm=bookDAO.queryB(f, key); if (bookForm!=null){ int ret = borrowDAO.insertBorrow(reader, bookDAO.queryB(f, key), operator); if (ret == 1) { request.setAttribute("bar", request.getParameter("barcode")); return mapping.findForward("bookborrowok"); } else { request.setAttribute("error", "添加借阅信息失败!"); return mapping.findForward("error"); } }else{ request.setAttribute("error", "没有该图书!"); return mapping.findForward("error"); } } return mapping.findForward("bookborrow");}
    图书归还该子模块实现系统的图书归还功能,读者向图书管理员提供自己的编号会显示出读者当起的借阅情况,再提供要归还的图书标号,图书管理员将信息记录在系统中,归还成功,其操作界面如下图:

    5.软件测试5.1 软件测试的方法与步骤该系统在本地服务器上进行运行和调试,鉴于对系统的内部结构和处理算法的完全了解以及对系统功能的全面掌握对系统进行白盒测试和黑盒测试。
    在开发软件系统的过程中,需要面对错综复杂的问题,因此,在软件生存周期的每个阶段都不可避免地会产生错误。测试目的在于:发现错误而执行一个程序的过程,测试重要发现一个发现其中尚未发现的错误。
    本系统的测试阶段信息流程下图所示[15]。

    为了设计出有效地测试方案按照下面准则进行测试:所有测试都应追溯到用户需求;在完成了需求模型就要着手制定测试计划,在编码之前最所有测试工作进行计划和设计;运用Pareto原理着重对占出现错误80%的容易出错的20%的模块进行测试,从小规模开始逐步进行大规模测试,通常先重点测试单个程序模块再转向集成的模块簇;精心设计测试方案,尽可能充分覆盖程序逻辑使之达到要求的可靠性[15]。
    按照软件工程的观点,软件测试(主要是指多模块程序的测试)共包括4个层次。

    单元测试。单元测试的用例从单元详细设计中导出。在单元测试中可以采用功能性测试和结构性测试两种
    集成测试和确认测试。这一阶段的任务,是通过了单元测试的模块逐步组装起来,通过测试与纠错,最终得到一个满足需求的目标软件
    验证测试。在这个测试步骤中所发现的往往是需求规格说明的错误。一般来说,系统测试是功能性测试,不是结构性测试[15]

    在整个测试中,采用了白盒测试和黑盒测试相结合的方法。
    5.2 测试用例设计与测试用例的运行过程及测试结果分析5.2.1模块测试登录模块测试


    用例
    测试数据
    预期结果




    UC1:输入正确的用户名和密码
    用户名:admin密码:admin
    系统跳转到登陆成功页面


    UC2:输入空用户名
    用户名:
    请输入用户名


    UC3:输入用户名和空密码
    用户名:admin 密码:
    请输入密码


    UC4:输入用户名和错误的密码
    用户名:admin 密码:321ff
    您输入的用户名或密码错误



    当用户输入的用户名或密码错误是系统会跳转到出错页面并提示“您输入的用户名或密码错误”,用户点击确定,系统会重新返回登陆页面,其中错误信息提示页面如图5.1所示:

    更改密码模块测试用户登录系统后可对自己的登录密码进行更改,更改过程要求用户提供原始密码,输入新密码,重新输入新密码进行确认,如果用户输入的原始密码错误,或两次输入的新密码不一致将无法执行密码更新操作,系统会给出相应的提示,起显示页面为:

    5.2.2集成测试把经过单元测试的模块放在一起形成一个子系统并对它进行测试用于检验模块相互间的协调和通信,这里主要对图书管理员功能系统进行了测试,经过检验其功能均得以顺利实现,下图为管理员操作的读者借阅模块成功运行界面:

    把经过测试的子系统装配成一个完整的系统进行测试,经过黑盒测试于白盒测试相结合的方式,对整个系统的各个功能模块进行了测试,并调试改正其中的设计和编码错误,经过这个环节的操作整个系统的功能基本实现成功运行。
    5.2.3 验收测试在进行了以上的测试工作后,将整个软件系统作为单一的实体进行测试,测试内容与系统测试基本类似,但它是在用户积极参与下进行的,此测试过程主要使用实际数据,进行测试,验证测试的目的是验证系统确实能够满足用户的需求,经过这个环节的实际数据测试,系统的各个功能实现都达到了系统需求设计的要求。
    5.3 评价测试过程严格按照测试的流程,经过单元测试、子系统测试和系统测试。通过单元测试,查找出了系统各模块内部的错误;通过子系统测试,发现了模块间相互协调和通信上的错误;通过系统的集成测试,发现了软件设计过程中存在的错误。通过改正错误的设计和实现部分,保证了图书借阅管理系统可以完成需求分析中制定的需求[16]。
    从上面的测试中可以看出,此系统可以完成用户登录、系统设置、图书管理、读者管理管理、借阅管理和系统查询等功能。读者在本系统的应用下可实现按照各种方式(如:书名,编号,作者)查询图书馆的藏书请客,方便的借阅图书,续借图书,归还图书,能够查询自己的借阅图书情况。图书馆工作人员能够实现方便的对图书进行查询,方便的进行读者借阅情况查询,方便的进行借书还书处理等,便捷的对图书信息进行添加、修改、删除,分类管理等操作,对读者信息进行相关添加,修改,分类管理等操作。系统管理员可以对图书馆信息进行修改更新操作,对系统用户进行添加、修改、删除、权限设置等操作,对图书馆的办证参数进行修改维护等操作功能。测试阶段的工作一方面发现了系统的各种错误,另外一方面也验证了修改后的系统能够实现提高图书馆工作效率的预期目的。
    6.结束语6.1 工作成果在MyEclipse开发环境下,以J2EE为平台,运用JSP网络编程语言和Struts框架和MySQL数据库完成了B/S模式的图书馆借阅管理系统。系统基本上实现了预期的各项功能,达到了任务书中的主要设计内容的各项任务,整个系统也在经过测试和不断地改正之后能够顺利运行。基本上实现了开题报告中的需求设计在程序编写,该系统能够实现:

    读者在本系统的应用下可实现按照各种方式(如:书名,编号,作者)查询图书馆的藏书请客,方便的借阅图书,续借图书,归还图书,能够查询自己的借阅图书情况
    图书馆工作人员能够实现方便的对图书进行查询,方便的进行读者借阅情况查询,方便的进行借书还书处理等,便捷的对图书信息进行添加、修改、删除,分类管理等操作,对读者信息进行相关添加,修改,分类管理等操作
    系统管理员可以对图书馆信息进行修改更新操作,对系统用户进行添加、修改、删除、权限设置等操作,对图书馆的办证参数进行修改维护等操作功能

    6.2 改进意见该系统在使用第三方插件Strusts时采用的是1.0版本的,若使用更新的2.0版本会更大的改进系统的开发便捷性和可维护性,系统在数据库与Web服务器的连接时采用的是连接池技术,若在数据库连接时使用现在流行的第三方插件Hibernate3.0,会使系统有更强的数据库映射关系,进而极大简化开发过程,还有就是系统在一些信息设置的细节上还存在不足,可以对系统的相关字段进行格式设置和异常处理,使数据更加规范化[11]。
    其次,本系统只对传统书籍进行了最基本的管理,随着计算机技术的飞速发展,应将各个图书馆的图书进行联网交流,使读者可以远程查询图书馆的藏书等信息,还应开发对电子书的管理,形成网上图书资源共享平台,使读者可以在线阅读电子书资料,并设置用户权限,使管理员可以上传图书资料信息,高级用户可以下载网上电子书资源,从而实现信息资源最大化被共享。
    0 评论 1 下载 2019-10-10 17:12:38 下载需要20点积分
  • 基于PHP的网上购物系统设计与实现

    摘 要随着Internet技术的发展,人们的日常生活已经离不开网络。未来社会人们的生活和工作将越来越依赖于Internet技术的发展,也将越来越数字化、网络化、电子化、虚拟化。电子商务也随着网络的发展日益和人们的生活贴近。Internet的发展历程以及目前的应用状况和发展趋势,可以充分地相信网络技术将极大的改变我们的生活和工作方式,甚至社会的价值观也会发生某种变化。本设计尝试用PHP在网络上架构一个动态的网上商品购物网站,以使每一位顾客不用出门在家里就能够通过上网来轻松购物。
    本文详细介绍了基于PHP的网上购物系统的系统结构设计、实现方法和操作流程,并介绍了系统各个模块的主要功能和数据库设计及功能。该系统采用B/S结构,采用PHP技术进行动态窗体页面的设计。后台数据库选用MySQL 数据库。系统设计并实现了会员注册及登录模块,会员基本信息模块,会员购物模块,产品搜索模块,管理员商品管理模块,用户管理模块,订单管理模块,信息管理模块等一系列功能模块。最后,对网上购物系统进行了系统测试,各个模块功能运行良好。
    关键字:Internet,PHP,B/S,网上购物系统
    AbstractAlong with the development of internet technology, daily life can not go on without the network. The life and work of the social people of future will depend on the development of digital technology more and more , digitization, networking, electronization, virtual more and more. E-commerce presses close to people’s life day by day along with the development of network too.Developing course and present application state and development trend of Internet can believe network technology will change life and working way of us greatly, and even change the values of the society to some extent.This paper tries to build up a dynamic e-commerce website in the network with PHP, so that each customer needn’t go out and can do some shopping easily through internet at home 。
    This paper describes system structure design, implementation method and operation process based on PHP, and introduces main functions of various modules about the system and database design. The system uses B/S structure, and conducts design of dynamic form page by PHP technology. Background database selects MySQL database. System design realizes a series of function modules such as user registration and landing module, user basic information module, shopping module, searching goods module, the management of goods ,the management of user,the management of orders ,the management of news and so on. Finally, the paper tests Shopping Inline System, and the result finds that kinds of modules operate well.
    Keyword: Internet, PHP, B/S, e-Shopping
    1 绪论1.1 开发背景及意义电子商务是伴随着信息经济的脚步,在20世纪90年代兴起于美国、欧洲等发达国家的一个新概念。目前,国际上对电子商务尚无统一的定义。一般来说,狭义的概念是指在开放的国际互联网及其它网络的环境下,通过服务器的运用,实现消费者的网上购物、企业间商业交易的一种新型交易运营模式。即电子商务=Web(服务器)+IT(信息技术)+企业业务。
    电子商务的类型:从其交易对象来看,电子商务的应用包括企业与企业之间的电子商务 (B2B)、企业与消费者之间的电子商务(B2C)、企业与政府之间的电子商务 (B2G)、政府与消费者之间的电子商务(G2C)、企业内部的电子商务。
    电子商务的本质特点:电子商务的重点在于商务、电子商务的核心竞争力在于信息平台、电子商务的使命在于利用互联网技术对传统资源的整合。
    电子商务实现贸易的全球化、直接化、网络化,发展电子商务是不可阻挡的趋势,而我国的电子商务尚不完善。要实现全过程的电子商务,就要加快网络基础设施建设和网络互联,实现金融电子化及海关、税务、行政监管部门电子化,市场环境网上支付,建立安全体系认证结构,健全相关法律法规等等。
    1.2 国内外电子商务现状以下是根据CNNIC(中国互联网络信息中心)公布的中国B2C电子商务发展报告来进一步分析目前的网上购物的现状。(主要引用其中的分析图表)

    从上面的图可以看出网上购物选择节约时间和操作方便的分别占46.7%和44.2%,这说明随着生活节奏的加快,人们越来越希望拥有简单快捷的购物方式。

    从上面的图中可以看出人们总希望直接可以拿到物品,而不需要耽搁自己的时间,如果是送货上门,也可以当面检查所购的物品,这也表现出人们对厂商信誉的担忧。

    从上面的图中可以看出目前两个最严重的问题是安全性和产品服务。
    1.3 本文研究的内容本文详细介绍了基于PHP的网上购物系统的系统结构设计、实现方法和操作流程,并介绍了系统各个模块的主要功能和数据库设计及功能。该系统采用B/S结构,采用PHP技术进行动态窗体页面的设计。后台数据库选用MySQL 数据库。系统设计并实现了会员注册及登录模块,会员基本信息模块,会员购物模块,产品搜索模块,管理员商品管理模块,用户管理模块,订单管理模块等一系列功能模块。最后,对网上购物系统进行了系统测试,各个模块功能运行良好。
    1.4 开发可行性分析1.4.1 管理上的可行性把企业业务延伸到Internet上,建立电子商务网站,对运营商业企业来说,是企业对外展示信息,从事商务活动的窗口和界面。因此,高中层管理人员不会对此有很大的抵触情绪,主管领导也能够相应的支持。
    1.4.2 技术上的可行性根据系统目标需求分析得结果来看,不需要通过购买专业软件,仅采用phpStudyAdmin为开发环境,Apachec为服务器,选择PHP语言就可以解决相关的问题,从而保证系统功能的实现。
    1.4.3 经济上的可行性商业企业在运营过程中 ,经常会遇到产品的宣传受到限制,采购商或顾客只能通过上门咨询、电话沟通等方式进行各种信息的获取,受一定的时间与物理空间的局限并且成本较高。而本系统可以帮助企业正确认识电子商务技术在企业中的重要地位,以少量的时间和资金建立企业信息门户网站并架设一定范围的商务网络,以此来是企业与顾客间的经济活动变得更灵活、更主动。
    1.4.4 执行可行性本系统采用IE浏览界面,是大家熟悉的,对于用户只需要具有一般的计算机知识的人员都可以轻松上手。而且整个系统采用最友好的交互界面,简洁明了,不需要对数据库非常了解。因此,该系统的操作是可行的。
    2 系统需求分析2.1 目标和任务网上购物基于B/S模式, 通过对一些典型电子商务网站的考察、分析,并结合企业要求, 开发一套拥有前后台的信息化管理系统,需满足以下要求:

    统一友好的操作界面,保证系统的易用性
    商品分类详尽,可按不同类别查看商品信息
    为客户提供通过一个购物车模型就能够购买多个商品项的机制
    提供简单的安全模型,让客户必须先进行登录,才允许购买购物车的内容
    设计网站后台操作平台,管理网站的各项基本数据
    对不同的管理者设置不同的权限

    系统的主要任务有:

    处理对象:主要涉及的数据有:商品、顾客(会员)、顾客组、管理员(用户)、管理员组、订单、邮寄方式等
    处理功能要求:本系统完成商品、顾客(会员)、管理员(用户)、订单等之间的功能联系,形成一个有效的循环系统。具体包括以下几点:1,顾客注册为会员;2,管理员发布商品;3,订单管理;4,顾客组管理;5,管理员权限的管理等

    2.2 系统功能分析2.2.1 功能性需求概述在线购物系统是商家和购买者直接接触的桥梁,商家通过管理在线购物系统,向购买者发布、展示产品,而购买者也通过网站和商家交流、订购产品,从而达到现实交易的目的。
    在这个交易过程前,商家需要将产品信息录入,并且在前台显示出来,这其实就是一个信息发布系统,顾客在看到产品后,可能会有许多的问题,也就是需要针对产品留言,然后企业做出相应的回答,这个留言也属于信息发布的一部分。
    在交易过程中,顾客一般是不允许匿名购买的,顾客需要留下现实的个人信息才能收到现实中的产品,相信作为顾客,也很愿意方便线下联系。接着是在线模拟交易过程,顾客完成所有的选取后,就可以付账了,这里需要和支付网关连接。付账之后就是企业方通过后台的程序发现有新交易并进行线下处理。
    在交易完成后,企业方需要对近期销售情况进行统计,如会员资料的查询、修订等。
    通过对电子交易流程的划分,在线购物系统的系统功能主要由3部分组成:信息发布系统、会员管理系统和电子交易系统。电子商务的本质更趋向于电子交易,也就是前台和客户打交道的页面。
    通过细化系统功能,很明显电子交易部分是重点,电子交易页面需要完成哪些功能呢?
    逛在线购物系统和逛超市相似,进入超市时,顾客习惯拿购物筐或者购物车,再开始逛。逛超市时会不断查看想买的东西,直到确定买的那个产品的位置,在确定的过程中,会不断将其他物品放到购物车中,然后再将不适合的东西拿出,一直到结账。在选取物品时会发现,超市总是把相关的产品放在一个位置,以方便消费者,同时消费者也会拿出两个相同类型的东西进行比较。
    通过对超市购物的分析,了解了应该如何去模拟一个现实的交易过程。首先,需要一个产品的展示,方便顾客查询,还要有产品比较的数据,更有助于消费者比较,选择自己满意的产品;然后,要有一个购物车,方便顾客查看自己选中的产品,也可以把需要购买的产品放入购物车或者从购物车中拿出不需要的产品;最后是结账,和超市结账有很大区别,电子商务不允许匿名买卖。付账和收到产品之间有一个相对较长的时间,而且企业和顾客也不是面对面的,企业需要收集有效的信息,才能把产品送到顾客手中,所以结账时要确定用户是否登录,以收集用户的资料。
    通过以上分析可知,本系统分成两个模块:前台浏览模块和后台管理模块。
    前台浏览模块可再分为两个模块:产品浏览模块和购物模块,涉及产品首页浏览、推荐产品浏览、产品列表,以及查看产品详细内容、查看评论等功能。购物模块主要充当购物车作用,包括选取产品、对比产品、会员注册、登录及网上支付等功能。
    后台管理模块可分为3个模块:会员管理模块、产品管理模块和订单管理模块。后台管理模块主要涉及产品分类目录管理,以及产品内容的管理。会员管理模块主要是查看和修改,包括管理会员的基本资料以及购买的产品等详细信息。订单管理模块主要涉及对顾客订购的产品管理,按照订单的状态大致分为待处理的订单和已经处理的订单。

    2.2.2 系统流程分析在后台管理模块中,管理员需要先添加产品栏目分类,再进入产品列表页面,选择指定的产品栏目进行产品添加操作。在会员提交订单之后,管理员可以通过订单管理模块查看订单,并根据实际情况更改订单状态,管理员也可以通过会员管理模块查看会员信息。前台界面则是会员选取需要购买的商品,并提交订单。

    2.2.3 系统目录结构系统目录结构的规划非常重要,这样可以更加方便管理程序,体现出清晰的思路。通过对系统结构的分析,可以按照功能模块来划分系统目录结构。

    由图可以看出,系统文件保存在dzsw目录中,其下有13个子目录:admin目录主要保存后台管理的程序:data主要保存一些log信息,方便以后的查看:htmlarea目录保存文本编辑代码:includes目录保存公共模块中的代码,如MySQL连接之类的封装类等;install目录保存安装程序,方便把系统移植到其他的机器上,也方便初始化网站;js目录包括程序中需要使用的JavaScript程序;languages目录主要是为了界面的多国语言需要设计的,根据不同语言的需要调用不同的文件;modules目录保存连接支付网关的程序;myaccount目录保存关于本站的一些信息;styles目录保存网站的样式文件;templates目录保存模板文件;upload目录保存所有的上传文件,这个文件夹需要特别关照,在发布网站后,这个目录中的任何东西都是不能执行的,否则将产生隐患。
    2.3 数据库分析2.3.1 数据库需求分析数据库需求分析是所有数据库系统设计的最重要一步,在这个步骤里需要对系统的所有数据存储进行分析和整理,以便得出具有稳定性和扩展性的存储结构,这也是数据建模的过程。
    通过分析,不难得出主要有4个重要的实体对象,即产品分类存储表、产品内容存储表、订单存储表及会员存储表。 这4个表是在线购物系统的核心,所有的产品必须归属于某个类别,而这些产品分类的类别是不固定的,所以就需要一个分类存储表来存储产品的分类栏目。
    2.3.2 数据库概念结构设计根据以上对数据库的分析,就可以设计出能够满足用户需求的各种实体,以及它们之间的关系,为后面的逻辑结构设计打下基础。这些实体包含各种具体信息,通过相互之间的作用形成数据的流动。
    下面是在线购物系统的E-R模型图。

    2.4 系统开发环境2.4.1 硬件平台系统所需的硬件平台:PⅡ以上的CPU,512M以上内存,硬盘80G以上,windows xp操作系统。
    2.4.2 服务器平台
    WWW服务器:Apache
    数据库软件:MYSQL

    2.4.3 开发工具开发工具使用:phpStudyAdmin
    2.4.4 技术构架系统采用B/S技术架构。
    2.6 数据字典2.6.1 数据元素
    名字:会员名称描述:顾客用来登陆网站的唯一标识数据类型:字符长度:96
    名字:产品ID描述:用来表示产品的唯一标识数据类型:整型长度:10
    名字:订单ID描述:用来表示顾客订单的唯一标识数据类型:整型长度:8
    名字:管理员ID描述:用来表示管理员的唯一标识数据类型:整型长度:4
    名字:邮寄方式ID描述:用来表示邮递的唯一标识数据类型:整型长度:8
    名字:顾客组ID描述:用来表示打折顾客组的唯一标识数据类型:整型长度:6

    2.6.2 数据存储
    名字:顾客信息描述:注册为会员的个人信息组成:自动编号ID,用户名(Email),密码,组名,消费金额,注册日期。
    名字:顾客组信息描述:存储顾客的打折优惠组成:自动编号,名称,折扣。
    名字:产品信息描述:发布的产品的信息描述组成:自动编号ID,产品名称,产品单位,产品价格,产品描述。
    名字:订单信息描述:会员发出订单的信息组成:自动编号ID,用户联系方式,订单内容,邮寄方式。
    名字:管理员信息描述:系统管理的信息组成:管理员ID,管理员名称,管理员类别,管理员密码。
    名字:邮寄方式信息描述:送货方式信息组成:方式编号ID,名称,费用。

    3 系统概要设计3.1 系统结构设计系统结构设计是结构化系统分析与结构化程序设计之间的接口。结构化系统设计运用了一套标准的设计准则工具,采用模块化方法进行新系统层次关系和模块分解设计,结构化系统设计的核心是模块分解设计,其基本思想是以系统的逻辑功能设计和数据流关系为基础,根据数据流程图和数据字典,借助于一套标准的设计准则和图表工具,通过“自上而下”的逐层分解,把系统划分为多个大小适当、功能明确、具有一定独立性、并易于实现的模块,从而把复杂系统设计转化为多个简单模块的设计。
    3.1.1 系统体系结构目前,Web项目较为流行的开发模式是三层逻辑体系结构,本系统的开发按照Windows DNA (Windows Distributed Internet Application,分布式互联网应用结构),采用基于XML的三层B/S体系结构。Windows DNA提供了一种开发三层结构Web应用程序的通用方法是一个电子商务开发的良好环境。
    MVC的设计思想简介,MVC的设计思想将平台划分为表现层、业务层、数据访问层、数据库层。
    表现层(Presentation Tier)对应于MVC的V(View),负责系统的表示逻辑,主要是每个.php 页面。
    业务层(Business Tier)体现系统的业务逻辑。业务层起到了Business Delegate的作用,屏蔽了表示层,有利于重用业务模型。
    数据访问/集成层(Data Access/Integration Tier)负责进行数据访问及系统间交互操作。数据访问组件负责与关系型数据库打交道,进行具体的增删改查(CRUD)操作。系统集成代理/适配器组件负责与软件产品和外部系统打交道,交换数据和消息。数据访问/集成层组件意识不到业务层的具体逻辑,通过约定的接口让业务层来调用。
    MVC三层逻辑体系结构如图3-1所示。

    3.1.2 系统总体功能结构根据系统分析的结果数据流程图所描述的系统的逻辑模型,把数据流程图上各个处理模块进一步分解,确定系统的层次结构关系,把逻辑模型变为物理模型。
    在管理信息系统的设计过程中,系统划分的一般原则如下:

    子系统要具有独立性,即应把相对独立的事务处理过程作为一个子系统。这样的子系统具有较高的内聚性,与其它的藕合较弱,便于软件开发、使用及日后系统维护
    子系统的划分结果应使数据冗余度较小,应避免部分数据在多个子系统中出现,尤其是修改,以保证系统的安全性、可靠性和数据的一致性
    子系统的划分应能满足目前和日后管理上的需要,功能应齐全,操作要方便且为今后发展留有接口
    子系统的划分应以该单位的管理职能为依据,应尽量避免过分依赖于组织机构,以防止机构变更后为系统带来不必要的麻烦

    从公司的组织结构上出发,把整个管理信息系统划分成多个子系统。每个子系统的功能相对独立,但是子系统之间有必要的数据联系。
    对电子购物商城系统的数据流图采用变换中心法和事务中心法进行分析,对其逐步进行功能分解,直到分解成为含义明确、功能单一的单元功能模块,从而得到系统的功能模块结构图,即系统的功能图。如图3-2,反映了电子购物商城的系统功能模块的划分。

    1、前台模块详细功能描述其中,用户信息管理以及订单和购物车是禁止匿名用户访问的内容。

    商品信息模块:商品浏览(首页显示部分普通商品列表)、特价商品浏览(首页显示特价商品列表)、商品分类浏览、商品详细信息
    购物车模块:添加商品到购物车、购物车信息修改、结账
    用户信息管理模块:注册新用户、登录、用户修改密码、用户个人资料管理
    订单模块:查询个人订单列表、查询某笔订单的详细信息、取消订单

    2、后台模块详细功能描述
    管理员信息管理:管理员登录、添加新管理员、删除管理员、修改密码
    商品信息管理:添加新商品、修改商品信息、删除商品
    订单管理:管理订单是否确认、是否付款、是否发货、是否归档,并且对相应信息进行查询

    3.1.3 系统总体物理结构电子购物各个部门在不同的地点办公,网络拓扑结构以交换机为基础,各部门通过主交换机连接到公司主服务器,电子购物有不同办公地点。根据这个特点,系统利用微机局域网作为系统的基本物理结构。为了提高系统的可靠性和可扩展性,网络采用以网络集线器为基础,以双绞线为传输介质的星型结构。在每个业务发生点以及每个管理员分别配制微型计算机作为系统结点工作站,系统功能的实现,子系统间的数据共享与交互通过网络服务器完成。电子购物的系统网络拓扑图如图3.3所示。

    系统具体物理配置如下:
    利用公司已经架设好的企业局域网,主服务器采用:服务器、交换机、网络集线器,传输介质采用10M屏蔽双绞线为介质的星型网络拓扑结构,服务器作为系统功能实现和数据共享中心,应具有较好的性能和可靠性。在此基础上再配上一台提供web服务的服务器和一台MYSQL数据库服务器即可实现对本系统的全部物理支持。
    系统具体硬件配置如下:

    WWW服务器:INTER P4 2.4 512M DDR ROM 80GB 硬盘
    数据库服务器:INTER P4 2.4 512M DDR ROM 80GB 硬盘
    客户机:目前流行的PC兼容机
    网络连接设备:路由器、交换机、打印机、扫描仪等

    系统具体软件配置如下:

    操作系统:Microsoft公司Windown2000Server,网络协议采用TCP/IP协议
    WWW服务器:Apache
    数据库软件:MYSQL

    3.2 数据库结构设计3.2.1 数据库概念结构设计根据需求分析中的结果,数据库的关系模型设计如下:

    会员(顾客ID,顾客名称,顾客组,消费金额,注册日期,联系方式)
    产品(产品编号,产品名称,售价,数量,图片,备注)
    管理员(管理员编号,密码,管理员组)
    订单(编号,顾客名称,内容,备注)
    顾客组(ID,类别,名称,折扣)
    管理员组(ID,类别,名称,权限)
    邮寄方式(ID ,名称,费用计算)

    3.2.2 数据库逻辑设计经过需求分析,概念结构设计,了解了系统的存储结构需求后,可以得出8个表结构,即顾客组设置表、顾客表、产品评论表、产品列表、订单表和邮递方式表、管理员表、管理员组表。
    顾客组设置表是为了存储顾客的打折优惠,这里记录的事组的打折信息。表结构如表3-1所示。
    顾客组设置表(usergroups)结构



    序 号
    字 段
    描 述
    类型和长度
    主 键
    可 空
    默认值




    1
    Groupid
    自动编号
    Smallint(6)





    2
    Classes
    类型
    Varchar(30)





    3
    Grouptitle
    组名称
    Varchar(30)





    4
    groupdiscount
    折扣
    float


    0



    顾客信息表主要是记录顾客的详细信息,其中groupid是指定顾客组的编号,用户的名称采用Email,记录用户的登录时间可以方便的查看最后的登录时间,这样有助于对客户的跟踪服务。表结构如表3-2所示。
    顾客信息表(customers)结构



    序 号
    字 段
    描 述
    类型和长度
    主 键
    可 空
    默认值




    1
    Customers_id
    自动编号
    Smallint(6)





    2
    Email
    用户名称
    Varchar(30)





    3
    Grouid
    组名称
    Int(10)





    4
    Regdate
    注册时间
    Int(10)


    0


    5
    Lastvisit
    最后登录时间
    Int(10)


    0


    6
    Money
    消费总金额
    Decimal(15.2)


    0


    7
    QQ
    QQ联系方式
    Varchar(30)





    8
    msn
    msn联系方式
    Varchar(30)






    产品评论表主要是针对产品的评论信息,其中products_id就是产品的编号,date_add就是记录产品的添加时间,viewed是表示这条评论被浏览的次数。表结构如表3-3所示。
    产品分类表(classes)结构



    序 号
    字 段
    描 述
    类型和长度
    主 键
    可 空
    默认值




    1
    rid
    自动编号
    Mediumint(8)





    2
    Email
    用户名称
    Varchar(30)





    3
    Products_id
    产品 id
    Int(10)





    4
    review
    评论内容
    text


    0


    5
    Date_added
    添加时间
    Int(10)


    0


    6
    viewed
    被浏览次数
    Mediumint(8)


    0



    产品的信息列表记录的是产品的基础信息,包括产品的价格、重量、名称、所属分类、详细描述等字段。表结构如表3-4所示。
    产品表(products)结构



    序 号
    字 段
    描 述
    类型和长度
    主 键
    可 空
    默认值




    1
    Products_id
    自动编号
    Mediumint(8)





    2
    Classes_id
    分类编号
    Mediumint(8)





    3
    name
    产品名称
    Varchar(64)





    4
    model
    产品单位
    Varchar(64)





    5
    image
    产品展示图片链接
    Varchar(64)





    6
    price
    产品价格
    Decimal(15.2)


    0


    7
    weight
    产品重量
    Decimal(5.2)


    0


    8
    description
    产品描述
    Text





    9
    manufacturer
    生产厂商
    Varchar(64)






    订单表主要记录的就是用户订单的详细信息,包括购买人、购买人的联系方式、产品的价格、邮寄方式等信息。由于每次用户可能会定购多种产品,所以订单将分成两个表来记录,一张用来记录联系信息,一张表用来记录联系信息和产品之间的关联。表结构如表3-5和表3-6所示。
    订单表联系信息(orders)结构



    序 号
    字 段
    描 述
    类型和长度
    主 键
    可 空
    默认值




    1
    Order_id
    自动编号
    Mediumint(8)





    2
    D_name
    用户联系姓名
    Varchar(100)





    3
    cid
    会员id
    Int(10)





    4
    D_street_address
    会员地址
    Varchar(100)





    5
    D_tel_mobile
    会员联系方式
    Varchar(100)





    6
    Orders_status
    订单状态
    Varchar(100)





    7
    Shipping_method
    邮递方式
    Int(10)






    订单产品信息关联表(orders_products)结构



    序 号
    字 段
    描 述
    类型和长度
    主 键
    可 空
    默认值




    1
    opid
    自动编号
    Mediumint(8)





    2
    Orderd_id
    于orders表关联id
    Int(10)





    3
    Products_id
    产品关联id
    Int(10)





    4
    price
    产品价格
    Decimal(15.2)


    0


    5
    Final_price
    最终价格
    Decimal(15.2)


    0



    邮寄方式表主要是为计算邮寄费用产生的,不同的邮寄方式会带来不同的邮寄费用。表结构如表3-7所示。
    邮寄方式表(shipping)结构



    序 号
    字 段
    描 述
    类型和长度
    主 键
    可 空
    默认值




    1
    id
    自动编号
    Mediumint(8)





    2
    Shippingname
    费用名称
    varchar(200)





    3
    Fee
    费用计算公式
    Varchar(200)






    管理组设置表是为了存储管理员的不同管理权限。表结构如表3-8所示。
    管理组设置表(Admingroups)结构



    序 号
    字 段
    描 述
    类型和长度
    主 键
    可 空
    默认值




    1
    AdminGroupid
    自动编号
    Smallint(6)





    2
    Classes
    类型
    Varchar(30)





    3
    Grouptitle
    组名称
    Varchar(30)





    4
    Allow_class_see
    查看会员组
    float


    0


    5
    Allow_class_add
    添加会员组
    Int(10)


    0


    6
    Allow_class_delete
    删除会员组
    Int(10)


    0


    7
    Allow_product_see
    查看商品
    Int(10)


    0


    8
    Allow_product_edit
    编辑商品
    Int(10)


    0


    9
    Allow_product_add
    上传商品
    Int(10)


    0


    10
    Allow_product_delete
    删除商品
    Int(10)


    0



    管理员信息表主要是记录管理员的信息。表结构如表3-9所示。
    管理员信息表(customers)结构



    序 号
    字 段
    描 述
    类型和长度
    主 键
    可 空
    默认值




    1
    Admin_id
    自动编号
    Smallint(6)





    2
    name
    名称
    Varchar(30)





    3
    password
    密码
    Varchar(30)





    4
    admingroupsid
    管理组
    Varchar(30)





    5
    createdate
    创建时间
    Int(10)





    6
    lastvisit
    最后登录时间
    Int(10)






    4 系统详细设计4.1 系统设计在系统总体设计阶段已经提到过本系统采用MVC体系架构,但MVC架构具体是怎么实现的呢?下面我将介绍系统的具体实现功能。
    4.2 公共模块设计结构合理的系统都是经过改良的,将共同的东西取出来放置到相同的地方供引用和调用时设计系统必须要做的工作。
    4.2.1 数据库公共模块PHP中将创建数据库连接connection 独立出来做成公用的文件是最常用的做法,我将其命名为config.php,放置在include目录下。这个目录用来存储供整个系统公用的目录。当页面需要使用数据库连接时,只需要通过PHP的<? Require ‘include/db_mysql.php’;?>引用公用文件即可,这样不但避免了每个页面都编写数据连接,而且也能避免当数据连接发生变化时去修改每一个页面的麻烦。Db_mysql.php中使用了两种方式来获取与数据库连接:一种是获取已有的连接mysql_pconnect($dbuser,$dbpw),这样无须重复的建立连接,节约了资源:另外一种方式是mysql_connect($dbhost,$dbuser,$dbpw),这种方式是获取一个新的连接。在获取连接资源时,通常会传递3个参数,这里分别是$dbhost,$dbuser,$dbpw,代表的是带有端口号的主机地址,登录用户名和密码。
    Config.php中的定义代码如下所示:
    Define(‘DB_SERVER’,’localhost’);//数据库服务器Define(‘DB_SERVER_USERNAME’,’root’);//数据库用户名Define(‘DB_SERVER_PASSWORD’,’’);//数据库密码Define(‘DB_DATABASE’,’shoopdb’);//数据库名
    4.2.2 common.php和golbal.php单元Common.php是公共函数的文件,将公共函数独立出来可以大大节约编程时间及编程量,也为后期维护带来很大方便。
    Global文件是对全局变量的处理。
    4.3 产品模块设计4.3.1 产品类型设计产品一般有大类和小类之分,多级栏目使用树结构来展示。可以单击编辑和删除来修改。

    分类编辑修改分类名称和是否在页面显示。

    4.3.2 产品添加设计把产品作为一个类封装起来可方便对产品进行各种处理。Includes中的cla.products_p.php和cla.products.php文件就是对产品的封装。
    首先,添加产品的基本信息。

    添加完产品的基本信息后单击提交按钮,系统会向服务器端提交产品的基本信息,之后就会自动转向详细信息添加页面;如果添加产品基本信息不成功,将转向错误显示页面。
    完成提交后,程序会自动转向产品详细信息添加页面。该页面分为5个子页面。

    如添加错误可以修改。

    商品图片添加页面。

    4.3.3 产品信息查询查询页面可以通过商品名称、状态、基本信息、详细说明来查找产品信息。


    4.4 前台页面模块设计这里主要涉及产品的前台展示和购物车的编码制作等。
    4.4.1 首页设计作为在线购物系统,首要的任务是展示产品。除了展示产品,还可以加入其他元素来丰富页面。为了在有限的首页空间展示最吸引客户的信息,可把特价产品和新到产品的前5名展示在首页。

    在设置前台时,会把这些信息缓存起来,以方便再次调用此页面时不需要再次读取数据库,这样可以提高读取效率,也可以减轻服务器端的压力。Fun.common.php中的cacheexists($filename,$pam=‘’)函数就是用来验证是否在硬盘中有缓存,如果没有,将生成缓存文件。Cacheeesxists($filename,$pam=‘’)的实现代码如下所示:
    Function cacheexists($filename,$lpam=’’){ If($pam==’’){ $pam=$filename; } If(!file_exists(DIR_SHOOPD.”data/cache/cache_”.$filename.”.php”)){ Updataecache($pam); } Return DIR_SHOOPD.”data/cache/cache_”.$filename.”.php”;}
    4.4.2 产品详细信息用户在首页上看到感兴趣的产品后,对商品做进一步的了解。

    单击“您对此商品有话要说,您可以点击这里发表评论。”后就进入评论页面。可以看到URL http://127.0.0.1/dzsw/writerviems.php?products_id=23 ,这里是把商品的编号传递到评论页面,找到评论商品的ID。

    评论提交后,首先判断消费者是否已经登录,如果用户已经登录,需要把评论信息和会员昵称关联起来。需对Email进行验证,使用的是正则表达式。
    在添加评论之后返回商品展示页面,就可以看到针对商品的评论了。

    4.4.3 购物车设计购物车的实现流程:购物清单(购物车)->收货/送货人地址->选择送货方式->选择付款方式->确认并提交订单。
    购物车模块有两个链接,进入购物车和点击结账。“进入购物车”主要是显示已经放入购物车的详细信息,而“点击结账”的页面就是结账页面。

    4.4.4 结账处理单击购物车中的“结账”链接就可以进入结账页面。
    4.4.5 会员注册和登录页面设计注册会员需要填入会员的基本信息,这里的注册名是消费者的Email地址,用这个作为用户登录名的好处是可以强制性的让用户输入一个Email,而且Email地址是不会重复的。获取Email地址后,就可以通过这个Email地址给消费者发送订单处理等信息。在注册会员之后还需要让用户填入详细信息。

    将会员的详细信息和基本信息分开的好处是,用户在填入某信息出错时,只需要重复填入少量资料,避免了用户的麻烦。
    输入收货人地址后就是选择发送方式。

    在中国,一般提供了3种送货方式,即中国邮政的EMS、国内快递和普通快递。这3种方式的送货费用不同,计算方法为:产品的总重量*每公斤运送价格+其他固定费用。

    4.4.6 会员账户管理顾客在购买产品后,需要对自己的产品进行跟踪,需要知道自己购买产品的状态。

    4.5 订单管理模块设计订单分类,按照订单的状态分为:新订单、已审核订单、等待付款订单、部分付款订单、全部付款订单、已确认付款订单、取消订单等。

    4.6 会员管理模块设计会员管理模块是电子商务的最后一个模块。会员添加在前台已经完成,后台只需要一个浏览模块。

    还有一个会员组的选项,对于在线购物来说,打折时很有必要的,而打折方式是按照不同的会员组来设定的。

    5 系统测试5.1 系统测试5.1.1 测试的目的软件测试的目标和定义:

    测试是为了发现程序中的错误而执行程序的过程
    好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案
    成功的测试是发现了至今为止尚未发现的错误的测试

    在对本网络书店销售管理系统测试时,也正是基于上述观点来进行的,测试的目的不是证明系统是完美的,而是发现问题,更好的解决问题,使系统不断完善,满足客户的需求。
    5.1.2 测试的准则为了能设计出行之有效的测试方案,必须深入理解并正确运用指导软件测试的基本准则。下面列举主要的测试准则:

    所有的测试都应该追溯到用户需求应该在开始测试之前就制定出测试计划
    把Pareto原理应用到软件测试中。Pareto原理说明,测试发现的错误中80%很可能是由程序中的20%模块造成的
    应该从“小模块”测试开始,并逐步进行“大模块”测试
    穷举测试是不可能的
    为了达到最佳的测试效果,应该由独立的第三方从事测试工作

    5.1.3 测试的方法测试任何产品都有两种方法:如果已经知道了产品应该具有的功能,可以通过测试来检验是否每个功能正常使用;如果知道了产品的内部工作过程,可以通过测试来检测产品内部动作是否按照说明书的规定正常工作。前一种称为黒盒测试又称功能测试,后一种方法称为白盒测试又称结构测试。
    在测试本系统时,采用的是黑盒测试来设计测试用例,而且在测试过程中,由于条件原因,不能完全按照测试规则由第三方来测试,测试过程和方案设计由作者完成。
    5.2 单元测试实例5.2.1 测试一在管理员登陆时,用户名或密码有一项为空或者填写错误,系统是否出现预先设定的操作提示。

    预期效果:输入错误及时报错
    具体操作:用户名、密码、任意一项为空或者填写有误
    结果:都出现相应的错误原因的信息提示
    结论:要求管理员必须填写正确的用户名和密码,才能进入管理页面,测试成功

    5.2.2 测试二发布产品或修改本站的公告﹑返回前台,看其是否更新成功。

    预期效果:发布和修改过后能及时更新内容
    具体操作:通过管理页面发布产品功能发布产品,修改公告功能修改公告的内容,看其是否发布修改成功
    结果:显示发布的新产品,公告内容更新为修改后的信息
    结论:发布产品,修改公告功能正常,测试成功

    5.2.3 测试三顾客浏览商品放入购物车后结账,如不登录能否提交订单。

    预期效果:该用户不能提交订单
    具体操作:前台顾客不登录提交订单
    结果:该订单无法提交,转入登录页面
    结论:购物车功能完善,测试成功。

    5.2.4 测试四顾客注册为新会员,注册号重复,密码没有6位。

    预期效果:注册失败,提示错误
    具体操作:注册号重复,密码设为5位
    结果:提示注册号已存在,密码至少6位
    结论:顾客注册功能正常,测试成功。

    5.2.5 测试五发货失败,取消订单。

    预期效果:顾客账户页面订单取消,已付款退回
    具体操作:在后台订单管理页面取消一已付款订单
    结果:前台会员账户页面显示订单取消,余额增加
    结论:订单功能正常,测试成功

    5.3 综合测试在以上测试的基础上,对系统功能进行了整体测试,依次检验系统功能是否符合系统开发的目标。经过使用大量的数据多次进行系统测试,发现系统存在的问题并及时改进,最终实现了网上购物系统的开发目标。
    5.4 系统的维护主要包括四个方面
    程序的维护:修改部分或全部程序,这种维护往往是在条件发生变化或原系统的效率低的情况下进行的
    数据文件的维护:按照用户的要求对数据文件进行不定期的修改
    代码的维护:随着系统的发展和变化,可能会出现旧代码不能适应新要求的问题,因此,有必要变更代码,予以维护
    硬件的维护:对系统所使用的设备进行维护

    6 总结本文讲述了在线购物系统的系统分析和设计,介绍了后台的商品发布、订单管理、会员管理以及前台的购物管理。
    在线购物系统只是所有在线购物系统的雏形,后台的商品发布、订单管理、会员管理和前台的购物管理是所有在线购物共有的特征。根据本实例的最初设计思想,对方案如下改进意见:
    完善系统功能除了给用户浏览商品外,提供给用户一个接口,用户对产品提出自己的建议,比如设计方面,包装方面,企业可以在网上搞一些活动,比如意见征集,这样提高用户参与的积极性,同时企业可以从用户的意见以及反馈信息中,找到使企业可持续发展的途径。只要是服务性的行业最根本的还是要坚持以客户为中心的原则。
    完善业务流程根据实际情况,使业务流程规范化。做到充分利用企业的资源,市场的资源,人力资源。使工作业务流程能够更合理,更有序的进行。
    完善人员培训机制对员工进行定期的培训,让员工了解市场,了解企业发展状况,了解客户需求。对员工进行一定的理论方面的培训。加强信息观念,这样提高了员工的素质,更加有利于员工参与工作,并胜任工作。在全球都提倡信息化的今天,面对我国的实际情况,所有人都应当提高自己的信息素养,只有这样我们才能很好的和世界贸易接轨,我国的电子商务才能有较快的发展,我国的经济发展才会有保证。
    通过开发这个项目,巩固了以前所学的理论知识,提高了自己理论联系实际的能力,为今后进一步学习新技术打下一个很好的基础,为走上社会实际工作岗位做好了充足的准备,为今后的职业发展打下良好的基础。面对以后各项挑战,我有信心做得更好!
    当然,由于时间和技术上的原因,该系统还是存在一些问题和不足的地方,比如在数据容量方面,由于没有经过大量数据的测试,数据库能承受多大负荷还不能确定,在美工方面,由于缺少美工经验,所以很多页面看起来可能会不那么漂亮美观,在一些细小的处理上可能还缺少进一步的考虑。
    0 评论 1 下载 2019-10-10 16:59:37 下载需要15点积分
  • 基于Android Studio实现的2048游戏

    1 需求分析1.1 背景与意义1.1.1 手机应用市场发展现状随着4G越来越普及以及手机应用的日益丰富还有智能水平的不断提高,从便携性和随身性这两方面来考虑,电脑所带来的体验已经不能跟手机相提并论了,它已经完美的超越了电脑。
    现如今Android、苹果等各智能手机已经基本占领整个手机市场,从而使得更多应用的出现,而手机游戏应用在其中占领主要位置。
    随着Android智能手机的普及以及游戏种类的多元化,使得Android手机游戏用户规模保持着稳步增长之势。
    1.1.2 国内外现状目前国内外的Android开发还是主要以应用开发为主,主要分成三类:企业应用、通用应用及游戏应用。企业应用的开发主要是一些大公司为了自己的品牌而开发的;通用应用主要是一些创业型公司或者独立开发者为了自己盈利开发的应用;游戏应用目前和通用应用相同。
    2048小游戏是一款最近风靡全球的手机游戏,简单的游戏模式和趣味的玩法,几乎游戏下载排行榜的前20名都可以看到“它的身影”。
    1.1.3 此游戏的意义现如今,手机游戏已在我们的生活中占据一席之地,并在一步步的壮大。可以说,随着它的迅猛发展,现今的手机游戏已经不单单是一种缓解压力的工具,而是形成了一种文化现象。随着游戏软件在市场的一步步壮大,与其有关的文化也随之传播。
    2048游戏的制作属于电子游戏中益智类小游戏,它做到了娱乐性、趣味性、教育性相统一。益智类的游戏即是需要去开动大脑思考从而获得游戏的胜利。简单的益智类游戏可以使玩家在娱乐中不断地开发大脑。这样一来就实现了在娱乐中学习。
    1.2 系统需求分析1.2.1 系统功能需求分析系统主要实现以下的几个功能:呈现游戏界面、重新开始游戏、当前分数和最高分数、游戏帮助等功能。
    重新开始游戏是当玩家无法满足当前进度时点击此按钮就会重新开始游戏,如果玩家处于不同关卡时提示重新开始游戏还是停留在此关卡。游戏帮助是当新手玩此游戏时无法知道游戏玩法时给予相应的提示。呈现游戏界面是游戏开始时主界面在游戏区域会生成4x4的矩阵同时在矩阵里面随机生成两个2或4的游戏卡片。当前分数和最高分数是显示此局玩家所获得的分数和历史上最高的分数,如果当前的分数超过最高的分数,那么最高分数显示当前的分数。如下图所示:

    1.2.2 游戏的基本规则在开始游戏后玩家通过滑动屏幕来操控卡片的移动方向,当卡片滑动中如果有两张卡片相同且他们中间也没有其他卡片时,在滑动的过程中这两张卡片会合并,显示为这两张卡片之和。在滑动过程中有三张卡片相同时只会合并向滑动方向两张卡片。在滑动中如果有两张卡片一样同时又有一张卡片的值跟这两张卡片相加的值时,滑动只会使那两张相同的卡片合并而不会接着让合并后的卡片和另一张卡片合并。
    2 系统分析与设计2.1 系统流程设计游戏进入开始页面,能够进入游戏的主界面并开始普通开局,从主界面能够重新开始游戏、查看帮助和进入关卡选择界面。当玩家点击重新开始按钮会弹出相应的对话框让玩家选择,如果玩家选择“是”时则重新开始游戏,如果选择“否”则返回游戏界面不做任何处理。在开始界面按返回按钮时则会退出游戏。
    游戏流程如下图所示:

    2.2 系统模块设计从总体出发,将该系统划分为三大模块:“菜单设计”、“界面设计”和“算法设计”。
    2.2.1 菜单设计菜单的实现是在游戏界面,可进一步划分为三个模块,分别是:“重新开始”、“退出游戏”、“游戏帮助”,如图所示:

    2.2.2 界面设计


    开始界面
    游戏界面









    2.2.3 算法设计当有两张卡片相同时,向它们可以碰撞的方向滑屏,卡片会移动到最底边并生成其两倍数字的卡片,并且生成一个“2”或者“4”的卡片。如图所示:



    生成2
    生成4









    当有两张卡片相同时,且在它们相同的方向有张跟他们之和的卡片,向它们可以碰撞的方向滑屏,相同的卡片会移动到无法移动的位置并生成其两倍数字的卡片,但合成的方向不会跟那两张数字的卡片合并,并且生成一个“2”或者“4”的卡片。如图所示:



    生成2
    生成4









    当界面上没有空位并且两两相邻的卡片不相同时游戏结束。如图所示:

    2.3 本章小结本章主要对游戏所实现的功能进行需求分析,分析了图形的特点和实现的可行性。对系统的性能进行了详细的分析。对系统的流程,系统所需的图形文件,系统的总体架构和系统用例进行了设计。通过本章的分析、设计能更加具体的了解系统功能,对系统所要实现的功能和图形文件有了更深的认识。为下一章系统功能的具体实现提供了可靠的参考依据。
    3 系统实现3.1 开始界面的实现游戏的主界面是按钮,只是为了实现界面的跳转,当玩家点击开始游戏就会调用loginActivity.java,此函数让页面跳转到游戏界面开始游戏,代码及图片如下所示:
    public class loginActivity extends MainActivity { protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.login); }}

    3.2 游戏界面的实现游戏界面主要是在activity_main.xml中当前分数、最高分数、重新开始按钮、退出游戏按钮、游戏帮助按钮、帮助按钮,当跳转到游戏界面时就会调用并执行MainActivity.java函数来展示游戏界面,代码及图片如下所示:
    protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);}

    3.3 游戏滑动卡片移动的实现当玩家滑动屏幕时,主要通过GameView函数来监听玩家手指滑动的位置,先通过获取开始坐标和结束坐标,然后通过比较结束坐标跟开始坐标的差值来判断玩家是怎么滑动屏幕的。判断出玩家的滑动轨迹后,通过调用swipeLeft、swipeRight、swipeUp、swipeDown方法来实现卡片的移动,代码及图片如下所示:
    private void initGameView(){ setColumnCount(4); //将面板设置成4列 setBackgroundColor(0xffbbada0); System.out.println("initGameView"); setOnTouchListener(new View.OnTouchListener() { /* * startX:手机刚开始在屏幕上的X坐标 * startY:手机刚开始在屏幕上的Y坐标 * offsetX,offsetY,分别是手指在屏幕上的X,Y上的偏移量 */ private float startX,startY,offsetX,offsetY; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: startX = event.getX(); startY = event.getY(); break; case MotionEvent.ACTION_UP: offsetX = event.getX() - startX; offsetY = event.getY() - startY; if(Math.abs(offsetX) > Math.abs(offsetY)){ if(offsetX < -5){ swipeLeft(); System.out.println("Left"); }else if(offsetX > 5){ swipeRight(); System.out.println("Right"); } } else{ if(offsetY < -5){ swipeUp(); System.out.println("Up"); }else if(offsetY > 5){ swipeDown(); System.out.println("Down"); } } break; } return true; } });}//向左滑动public void swipeLeft(){ boolean meger = false; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { for (int x1 = x+1; x1 < 4; x1++) { if(cardsMap[x1][y].getNum()>0){ if(cardsMap[x][y].getNum()<=0){ /* * 将下标为(x,y)所在位置的卡片上的数字 * 设置为,坐标为(x1,y)所在位置的卡片上的值; * 第二步,将坐标(x1,y)所在位置的卡片上的数字 * 设置为0 * (即:变成空卡片) */ cardsMap[x][y].setNum( cardsMap[x1][y].getNum()); cardsMap[x1][y].setNum(0); x--; meger =true; break; }else if(cardsMap[x][y].equals(cardsMap[x1][y])){ cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2); cardsMap[x1][y].setNum(0); MainActivity.getMainActivity(). addScore(cardsMap[x][y].getNum()); meger = true; } break; } } } } if(meger){ addRandomNum(); checkComplete(); }}//向右滑动public void swipeRight(){ boolean meger = false; for (int y = 0; y < 4; y++) { for (int x = 3; x >=0; x--) { for (int x1 = x-1; x1 >= 0; x1--) { if(cardsMap[x1][y].getNum()>0){ if(cardsMap[x][y].getNum()<=0){ /* * 将下标为(x,y)所在位置的卡片上的数字 * 设置为,坐标为(x1,y)所在位置的卡片上的值; * 第二步,将坐标(x1,y)所在位置的卡片上的数字 * 设置为0 * (即:变成空卡片) */ cardsMap[x][y].setNum( cardsMap[x1][y].getNum()); cardsMap[x1][y].setNum(0); x++; meger =true; break; }else if(cardsMap[x][y].equals(cardsMap[x1][y])){ cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2); cardsMap[x1][y].setNum(0); MainActivity.getMainActivity(). addScore(cardsMap[x][y].getNum()); meger =true; }break; } } } } if(meger){ addRandomNum(); checkComplete(); }}//向上滑动public void swipeUp(){ boolean meger = false; for (int x= 0; x< 4; x++) { for (int y = 0; y < 4; y++) { for (int y1 = y+1; y1 < 4; y1++) { if(cardsMap[x][y1].getNum()>0){ if(cardsMap[x][y].getNum()<=0){ /* * 将下标为(x,y)所在位置的卡片上的数字 * 设置为,坐标为(x1,y)所在位置的卡片上的值; * 第二步,将坐标(x1,y)所在位置的卡片上的数字 * 设置为0 * (即:变成空卡片) */ cardsMap[x][y].setNum( cardsMap[x][y1].getNum()); cardsMap[x][y1].setNum(0); y--; meger =true; break; }else if(cardsMap[x][y].equals(cardsMap[x][y1])){ cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2); cardsMap[x][y1].setNum(0); MainActivity.getMainActivity(). addScore(cardsMap[x][y].getNum()); meger =true; } break; } } } } if(meger){ addRandomNum(); checkComplete(); }}//向下滑动public void swipeDown(){ boolean meger = false; for (int x = 0; x< 4; x++) { for (int y = 3; y>= 0;y--) { for (int y1 = y-1; y1 >=0; y1--) { if(cardsMap[x][y1].getNum()>0){ if(cardsMap[x][y].getNum()<=0){ /* * 将下标为(x,y)所在位置的卡片上的数字 * 设置为,坐标为(x1,y)所在位置的卡片上的值; * 第二步,将坐标(x1,y)所在位置的卡片上的数字 * 设置为0 * (即:变成空卡片) */ cardsMap[x][y].setNum( cardsMap[x][y1].getNum()); cardsMap[x][y1].setNum(0); y++; meger =true; break; }else if(cardsMap[x][y].equals(cardsMap[x][y1])){ cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2); cardsMap[x][y1].setNum(0); MainActivity.getMainActivity(). addScore(cardsMap[x][y].getNum()); meger =true; } break; } } } } if(meger){ addRandomNum(); checkComplete(); }}



    效果1
    效果2









    3.4 重新开始游戏功能的实现当玩家点击游戏界面的重新开始游戏时,会弹出给玩家选择的对话框,让玩家选择“是”时游戏会重新开始,代码及图片如下所示:
    public void onClick(View view){ AlertDialog.Builder dialog3 = new AlertDialog.Builder(this); dialog3.setTitle("提示:"); dialog3.setMessage("你确定重新开始吗?"); dialog3.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog3.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog3.show(); }

    3.5 退出游戏功能的实现当玩家中途有事想退出游戏时会弹出给玩家选择的对话框,让玩家选择“是”时游戏会退出,代码及图片如下所示:
    public void onClick(View view){ AlertDialog.Builder dialog = new AlertDialog.Builder(this); dialog.setTitle("提示:"); dialog.setMessage("你确定要离开吗?"); dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { System.exit(0); } }); dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog.show(); }

    3.6 游戏帮助功能的实现当新玩家进入到游戏且不知道此游戏玩法时,玩家可以点击游戏帮助按钮来了解游戏玩法,点击按钮时游戏会弹出对话框显示游戏玩法,代码及图片如下所示:
    public void onClick(View view){ AlertDialog.Builder dialog2 = new AlertDialog.Builder(this); dialog2.setTitle("hey,guy!"); dialog2.setMessage("这么简单的游戏你确定需要帮助?"); dialog2.setNegativeButton("继续玩~", new DialogInterface.OnClickListener({ @Override public void onClick(DialogInterface dialog, int which) { } }); dialog2.show();}

    3.7 本章小结本章主要阐述本游戏相关功能的实现,详细的讲述了主界面的实现和各按钮功能的实现。
    4 测试本章主要对系统的功能进行测试,此次测试只是进行简单的调试,来确定游戏的各项功能是否能够正常运行。
    4.1 游戏流程测试该测试主要验证游戏能否实现场景的切换,当界面在开始界面时只显示按钮画面,当玩家点击此界面的开始按钮时跳转到游戏界面,如图所示:



    效果1
    效果2









    4.2 游戏模式该测试主要是测试游戏能否正常运行,当玩家滑动屏幕时能否正常的移动和当卡片相同时是否能够相加,还有就是测试游戏是否能正常结束。



    效果1
    效果2









    4.3 本章小结本章是对游戏系统进行简单的测试,通过测试可以看出此游戏可以正常的工作,同时一些功能也能够实现。
    5 总结本次课程设计的内容大部分都是参照课堂所讲以及一些网站给出的各种建议写的,在写的过程中遇到了很多问题,学到了很多东西。期间大概是因为基础不够好,只是找错误就花了很长时间。不过正因为这些错误,才能学到更多的知识,才能把知识点掌握的更牢靠,对于一些没有实现的功能,之后我一定会多花费些时间研究出来。我的课程设计优化的空间还相当大,希望老师能给出指导!
    6 评论 249 下载 2018-12-20 18:49:18 下载需要8点积分
  • 基于QT实现的基础图形绘图系统

    摘 要PaintWorks实现了图形数据的输入、编辑、填充、裁剪、变换、显示与保存功能。可绘制图形包括直线、圆、椭圆、多边形、曲线和3D六面体。交互界面简洁美观,操作实用方便。
    本绘图系统采用了面向对象设计,以C++11为基础,交互使用了Qt,基础图形的绘制使用了OpenGL,直线绘制使用了Bresenham算法,圆的绘制使用了中点圆生成算法,椭圆绘制用了中点椭圆生成算法,曲线绘制使用了3次Bézier曲线,多边形填充使用了多边形扫描填充算法,线段裁剪使用了梁友栋-Barsky算法,多边形裁剪使用了逐边裁剪算法。
    1 软件概述1.1 软件用途本软件主要用于基础图形绘制与保存,绘制完成之后可以对图形进行进行编辑、填充、裁剪等操作。
    1.2 特点本软件操作与显示简洁自然,简单方便。
    图形越新,所在图层越高;当用户选中某一图形时会自动切换到该图形对应的绘制模式并将该图形移动到最高图层。
    本软件的所有操作均可通过点击鼠标完成,其中,PaintWorks为使用频繁的操作与较为精细的操作提供了快捷键。
    2 软件安装为了免去用户安装的烦恼,PaintWorks给出了绿色免安装版,解压之后直接点击安装包中的PaintWorks.exe便可运行。(注:经过测试,不解压就运行可能会导致未知错误)
    3 使用指南3.1 图形绘制3.1.1 画笔颜色选取点击上方工具栏中的颜色选取工具(或按快捷键Ctrl+P),即可打开颜色选取对话框选取画笔颜色,之后线条颜色和填充色均为所选取的颜色。

    若不选取颜色,则默认线条颜色为黑色,填充色为绿色。
    3.1.2 2D图形PaintWorks可以绘制直线、圆、椭圆、多边形、曲线等二维图形,并可以对圆和多边形进行填充。绘制前首先点击菜单栏中的“新建画布”(或按快捷键Ctrl+N)新建画布。

    直线绘制:点击工具栏中的 按钮(或按快键键Alt+L),即可切换到直线绘制模式(软件启动默认绘制模式为直线)。点下鼠标左键并拖动,松开鼠标左键便可完成绘制,点下和松开的位置分别为直线的两端点。

    圆绘制:点击工具栏中的 按钮(或按快捷键Alt+C),即可切换到圆绘制模式。点下鼠标左键并拖动,松开鼠标左键便可完成绘制,点下鼠标左键的点为圆心,拖动的距离为圆的半径。点击工具栏中的 工具(或按快捷键Ctrl+F),即可完成对圆的填充。


    椭圆绘制:点击工具栏中的 按钮(或按快捷键Alt+E),即可切换到椭圆绘制模式。点下鼠标左键并拖动,松开鼠标左键便可完成绘制,拖动的横向偏移量为椭圆的横轴长度,纵向偏移量为椭圆的纵轴长度,拖动位移的中点为椭圆中心。

    多边形绘制:点击工具栏中的 按钮(或按快捷键Alt+P),即可切换到多边形绘制模式。单击鼠标左键绘制多边形第一个顶点,之后多次单击绘制多边形其他顶点,若要完成绘制只需单击第一个顶点,如图7. 选择填充色为绿色然后点击工具栏中的 工具(或按快捷键Ctrl+F)。


    曲线绘制:点击工具栏中的 按钮(或按快捷键Alt+V),即可切换到曲线绘制模式。先后单击4次鼠标左键绘制曲线的4个控制点,便可完成曲线的绘制。

    3.1.3 3D图形PaintWorks可以绘制3D六面体。点击点击菜单栏中的“新建3D画布”(或按快捷键Ctrl+T)新建3D画布标签页。

    此时新3D标签页中已经绘制完成一个3D六面体,如图11. 按键盘上的左右方向键可以控制这个六面体旋转。


    3.2 图形选中与编辑3.2.1 图形选中刚绘制完成的图形默认已经被选中,其关键点用蓝色圆点标记(如3.1.2中各图所示)。若要选中其他图形,只需点击想要选中的图形,该图形就会被选中且浮动到最高图层。

    3.2.2 图形编辑点击并拖动已选中图形的蓝色标记点,即可对图形形状进行编辑,操作与图形绘制时类似。

    直线标记点:两端点
    圆标记点:矩形四个端点
    椭圆标记点:矩形四个端点
    多边形标记点:各个顶点
    曲线标记点:四个控制点

    3.3 图形变换3.3.1 平移在选中情况下,图形中心有一个带十字的中心标记点。点击并拖动这个中心标记点,即可拖动这个图形。

    3.3.2 旋转在选中情况下,图形中心标记点有一条蓝色的直线延长出来的一个蓝色标记点,称为旋转标记点,旋转标记点与中心标记点的连线称为handle,如图14,中心标记点上方的蓝色圆点即为旋转标记点。点击并拖动这个旋转标记点,即可旋转该图形。


    直线旋转:以直线中点旋转
    圆的旋转:以圆心旋转,但由于圆是中心对称图形,所以旋转中视觉上没有明显效果
    椭圆旋转:以中心旋转,但由于椭圆旋转之后可以会出现变形,所以椭圆只能进行90度旋转,即只有在handle水平或垂直时做90度的旋转
    多边形旋转、曲线旋转:均绕中心标记点旋转

    3.3.3 缩放用户对当前选中的图形进行放大或缩小,放缩的中心为该图形的中心标记点。点击工具栏的放大与缩小按钮分别可以进行放大与缩小(快捷键为Ctrl + + 和Ctrl + -),如下图左右两侧图为曲线缩小和放大的效果。



    缩小
    原图
    放大










    3.4 图形裁剪用户可以使用工具栏中的 工具对当前选中的图形进行裁剪,裁剪仅限直线或多边形。
    首先点击这个工具(或按快捷键Ctrl+C),这个工具会显示被按下,此时可以在画布中绘制出一个红色的虚线框作为裁剪窗口。

    此时可以拖动红色虚线框的四个顶点对裁剪窗口进行调整,也可以直接重新绘制一个裁剪窗口。
    确定裁剪窗口之后,再次点击 工具(或按快捷键Ctrl+C),便可完成裁剪。其中需要说明的是,裁剪之后图形会被重绘,因为当前选择的画笔颜色为绿色,所以轮廓为绿色,与填充色融为了一体(而不是轮廓消失了)。

    3.5 图形删除与保存3.5.1 删除与清空
    用户可以对当前选中的图形、画布进行删除或清空操作
    要删除当前图形,只需点击工具栏中的 (或按快捷键Delete)即可将该图形删去
    要清空当前画布,只需点击工具栏中的 (或按快捷键Ctrl+Delete)即可清空画布

    3.5.2 保存图形用户可以保存画布上的图形为BMP文件(普通画布与3D画布均可保存),点击菜单栏中的“文件”>“另存为…”,即可打开一个文件保存对话框。


    输入文件名,选择路径,便可把当前画布的图像保存成BMP格式的文件。
    3.6 出错处理经过测试,本软件鲁棒性较好,但仍难以避免一些意外发生,如果出现了错误,重启即可。
    3.7 注意事项
    在新图形绘制过程中不要点到原有图形上,否则会选中原有图形,中断新图形的绘制。即便如此,原先的绘制信息也不会丢失,将绘制模式切换回来就可以继续绘制了
    由于裁剪算法所限,在裁剪凹多边形的一些特定情况下可能会出现一些不完全正确的裁剪结果

    4 系统框架设计4.1 开发环境


    操作系统
    Windows 10家庭中文版




    编程语言
    C++ 11


    外部库
    Qt 5.4,OpenGL 2.7


    编译器
    MinGW 4.9.1 32bit


    IDE
    Qt Creator 3.3.0



    4.2 系统架构概览用Qt向用户提供交互,用OpenGL提供底层绘制,考虑到Qt与OpenGL的兼容性,使用了继承自QWidget的子类QGLWidget实现Qt环境下的OpenGL绘制:

    QMainWindow负责与用户交互,并以标签页的形式集成了QGLWidget
    QGLWidget负责绘制本标签页的内容,并集成了各类FigureControl,用于将本标签页的交互信号送给不同的图形控制类
    FigureControl负责该类型图形的交互,有LineControl、CircleControl、EllipseControl、PolygonControl等,用于分别提供不同图形的不同交互方式
    Figure负责保存该图形的数据信息,包括顶点、圆心、半径以及轮廓点、填充点等,集成了Point类,图形绘制通过调用Point的draw函数完成
    Point负责实现绘制单个普通点或标记点,并向上提供其他常用功能函数支持

    系统核心架构图

    其中GLWidget派生出一个GL3DWidget,作为3D标签页,用于3D图形的绘制;在FigureControl层有一个CutWindow类,用于绘制裁剪窗口。系统架构中的聚集关系如下图:

    Point类作为轮廓和填充的构成部分聚集在Figure类中;Figure类的数组放在FigureControl中,由FigureControl处理本Figure的相关交互;CutWindow用于管理裁剪窗口;GLWidget为2D画布的标签页,GL3DWidget继承自GLWidget,作为3D画布标签页;所有标签页聚集在QMainWindow中,由QMainWindow与用户交互并向下发送消息。
    4.3 图形管理类:FigureControl图形管理类之间的关系较为简单,主要用于存储本图形的数据,并进行与本图形相关的交互,如鼠标点击、键盘按下、图形绘制、设置聚焦、裁剪当前图形等,类继承关系如下图:

    4.4 图形类:FigureFigure为所有图形的虚基类,继承关系如下图:

    Figure类提供所有图形都应有的共同接口:

    基础绘制:绘制图形、绘制图形标记点、清空图形
    基础变换:平移、旋转、缩放
    判断某点是否在该图形上


    SimpleFigure是对所有简单图形的抽象,SimpleFigure的轮廓均直接由点构成。而Polygon的边为Line,所以不属于SimpleFigure。SimpleFigure中提供了通用的draw()、clear()、isOn()。
    Area是对所有可填充图形的抽象,用于填充点管理,提供了与填充相关的函数。
    Line、Circle、Ellipse、Curve、Polygon分别为直线、圆、椭圆、曲线、多边形。其中由于Ellipse和Polygon与OpenGL库中命名冲突,所以在实现中命名为MyEllipse和MyPolygon,但相应代码文件名仍为Ellipse和Polygon。
    2 评论 50 下载 2018-12-10 20:51:16 下载需要8点积分
  • 基于SSH网上商城的设计与实现

    摘 要本文讲述了基于SSH框架的网上商城购物系统的设计与实现。所谓的网上商城购物系统是通过网站推广互联企业的商品和技术服务,并使客户随时可以了解企业和企业的产品,为客户提供在线服务和订单处理功能。
    从长期的战略目标来说,网上商城购物网站不仅是商品和服务的推广,而是通过Internet、企业内部网和企业外部网,将买家与卖家、厂商和合作伙伴紧密结合在了一起,因而消除了时间与空间带来的障碍。
    网上商城购物提供了多种检索途径,可以从分类、新品、特价等途径进行检索,快捷准确。与传统销售方式相比,在线销售能够提供海量商品信息。网上商城购物最突出的优点是:不再限制消费者的购买时段,扩大和巩固了客户群,从而增加了商品企业的核心竞争力,节省实际开店时需要投入的成本和租用费用。
    关键词:商城,在线销售,订单处理,在线支付
    ABSTRACTThis thesis relate to the design and implementation of based on the mode of 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.
    Key words: digital products, online sale, order processing, online payment 
    第一章 绪论1.1 课题背景互联网的兴起从本质上改变了现商品交易方式。由于互联网的兴起,国内各大企业从上个世纪产生了通过网络进行销售经营商品的想法。但是由于互联网上信誉难以保证、网络的商业环境的不成熟等一系列的原因,局限了网上商城的发展速度。进入21世纪以后,随着网络技术的发展、网络制度的健全,制约网上交易的各个瓶颈问题逐一被击破,各企业也纷纷的加入到电子商务的洪潮之中。
    中国互联网协会网络营销工作委员会调查显示,随着国内产业环境和消费市场的成熟,网络购物尤其是以商品为代表的网购将在今年实现更大发展。
    1999年底,随着互联网高潮来临。中国网络购物的用户规模不断上升。2010年中国网络购物市场延续用户规模、交易规模的双增长态势。2010年中国网络购物市场交易规模接近5000亿,达4980.0亿元,占到社会消费品零售总额的3.2%;同时,网络购物用户规模达到1.48亿,在网民中的渗透率达30.8%(《2013-2017中国网络购物行业市场前瞻与投资预测分析报告》统计数据显示)。对于一些传统企业而言,通过一些传统的营销手段已经很难对现今的市场形成什么重大的改变了。如果想将企业的销售渠道完全打开,企业就必需引进新的思维和新的方法。而网络购物正好为现今的传统企业提供了一个很好的机会与平台,传统企业通过借助第三方平台和建立自有平台纷纷试水网络购物,构建合理的网络购物平台、整合渠道、完善产业布局成为传统企业未来发展重心和出路。
    网络购物这一消费方式给人们生活带来的变化,除了购物场所的改变以外,更重要的是大大改变了传统的消费行为习惯,无论是否在网上购物,上网查看产品的相关信息,已经成为购物决策环节的重要组成部分,这一环节对购物行为的实际发生起到了至关重要的指导作用。
    1.2 目的和意义与传统方式销售相比在线销售有很多的优点如:
    1.2.1 检索便捷在线销售提供了多种检索途径,可以从分类、新品、特价等途径进行检索,快捷准确。
    1.2.2 信息量大与传统销售方式相比,在线销售能够提供海量产品信息。
    1.2.3 成本低,风险小,无地域限制网络销售最突出的优点是:不再限制消费者的购买时间和地点,同时大大降低中小商家开店的成本,提高其生存。
    1.3 系统设计思想对于典型的数据库管理系统,尤其是对于像网上商城购物系统这样的数据流量特别大的网络管理系统,必须要满足使用方便、操作灵活等要求。本系统在设计时应该满足以下几个目标:

    界面简洁,数据存储准确,信息处理安全可靠
    便于顾客快捷方便地查询商品信息
    实现网上购物的功能
    系统公告公布网上商城购物系统网站内的最新信息
    顾客可以随时查看自己的订单信息
    对顾客输入的数据,系统进行严格的数据检验,尽可能排除人为的错误
    系统最大限度地实现了易维护性和易操作性
    系统运行稳定、安全可靠

    第二章 系统开发工具及技术背景2.1 系统运行平台设置本系统的运行环境设置分为硬件环境和软件环境。
    2.1.1 硬件环境


    硬件
    配置信息




    处理器(CPU)
    英特尔 Celeron(赛扬) 1005M @ 1.90GHz 双核


    主 板
    宏碁 EA40_HC


    内 存
    8 GB ( 金士顿 DDR3L 1600MHz )


    硬 盘
    希捷 ST500LT012-9WS142 ( 500 GB / 5400 转/分 )


    显 卡
    英特尔 Ivy Bridge Graphics Controller ( 2176 MB / 宏碁 )


    显示器
    友达 AUO183C ( 14 英寸 )


    光驱
    建兴 DVD A DS8A9SH DVD刻录机



    2.1.2 软件环境


    环境
    软件




    操作系统
    windows7 64bit


    开发工具
    eclipse Mars2.0


    数据库
    mysql


    服务器
    tomcat7.0 64bit



    2.2 开发工具及技术简介2.2.1 开发工具简介eclipseEclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。
    MysqlMySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件。
    MySQL是一种关系数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
    MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择 MySQL 作为网站数据库。
    由于其社区版的性能卓越,搭配 PHP 和 Apache 可组成良好的开发环境。

    高效性:使得使用者可以降低开发和管理他们的数据基础设施的时间和成本
    智能性:提供了一个全面的平台,可以在用户需要的时候向其发送观察和信息
    可信任性:使得使用者可以以很高的安全性、可靠性和可扩展性来运行他们最关键任务的应用程序

    2.2.2 技术简介本系统采用目前较流行的一种Web应用程序开源框架——SSH框架。该框架由struts、spring及hibernate集成,能帮助开发人员在短期内清晰快捷的构建Web应用程序。其中以Struts作为其整体基础架构实现MVC的分离及控制业务跳转,并以Hibernate框架对持久层提供支持,再由Spring管理struts和hibernate。
    采用该开发模型,不仅有效的实现视图、模型与控制器的彻底分离,同时还实现了持久层与业务逻辑层的分离。因此当程序前端发生变化,仅需要微微改动模型层,并且当数据库产生变化时也不会对前端产生影响,由此提高了系统的可用性,从而有利于团队成员并行工作,大大提高了开发效率。
    第三章 系统分析3.1 可行性分析3.1.1 经济可行性经济可行性是指开发软件的设计成本与其经济效益相比是否相适宜。该套系统相比传统商城节约了房租并不受时间限制,大大节约了商家的成本,也提高了商家销售渠道,使得商家利益更大化。但此系统开发成本并不高。综上所述,该系统在经济可行性上可行。
    3.1.2 技术可行性该系统在软件方面采用了目前较稳定的eclipse工具和安全性较高的SSH框架进行开发管理平台的设计并选择mysql数据库作为数据的存储。软件满足安全、稳定、可行。
    此外,在硬件方面,由于现在科技发展快,硬件的配置较高,系统的开发与运行都是是可行的。
    3.1.3 运行可能性该网上商城购物系统操作简单,能为商家大大节约其成本,也让顾客实现了随时随地购物愿望。
    3.2 需求分析3.2.1 服务需求经过对各大商品购物网站及实际商品企业销售过程的考察、分析,要求本系统具有以下功能:

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

    3.2.2 购物主流程
    3.3 功能分析3.3.1 系统前台功能需求
    商品展示模块:通过添加新品显示新品上市,销售排行展示自动显示商品销售量前的进行显示
    商品查询模块:按商品的类别查询商品的相关信息
    购物车模块:用户添加商品至购物车,查看购物车中的商品,从购物车中移除不满意的商品,清空购物车中的产品,修改所要购买的商品的数量
    收银台模块:用户满意购物车中的产品后进行结账并填写订单信息
    用户维护模块:为用户提供了用户注册、用户登录的功能
    订单查询模块:用户通过查看订单能够了解到自己的当前订单信息及历史订单记录


    3.3.2 系统后台功能需求
    商品管理模块:按类别查询商品信息,并进行维护商品的信息
    顾客管理模块:由于要保护顾客的信息,此模块仅实现查看顾客信息及删除错误顾客信息,与前台顾客查看和维护个人信息区别开
    一级分类管理模块:用于管理维护一级分类
    二级分类管理模块:用于管理维护二级分类
    订单管理模块:管理员查询订单详情并修改订单信息及完成订单受理


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

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

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

    用户信息,包括用户ID,用户名等数据项
    管理员信息,包括管理员ID,密码等数据项
    商品信息,包括商品ID,产品名称、单价、特价等数据项
    商品一级类别信息,包括电子ID,类别名称等数据项
    商品二级类别信息,包括电子ID,类别名称等数据项
    订单信息,包括订单ID,用户编号,订货地址等数据项
    订单明细信息,包括订单ID,商品ID,订货时间等数据项

    4.2 数据库的详细设计4.2.1 数据库E-R图
    4.2.2 数据库表根据此商品在线销售系统的实际情况,本系统的数据库命名为db_shoping,db_shoping数据库中共分为8张数据表。
    商品信息表此表用于记录网站所有商品的基本信息,是与商品相关联的商品的类别表。



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




    1
    pid
    编号
    Int
    255


    2
    pname
    商品名
    varchar
    255


    3
    market_price
    市场价
    varchar
    0


    4
    shop_price
    商城价
    varchar
    0


    6
    image
    存放商品图片
    int
    255


    7
    pdesc
    特价
    int
    255


    8
    is_hot
    普通商品
    int
    11


    9
    pdate
    上架日期
    datetime
    0


    00
    csid
    商品种类号
    varchar
    255



    商品一级类别表此表用于记录商品一级类别的基本信息,为方便用户查询商品和管理员管理商品信息而设立。



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




    1
    cd
    种类编号
    varchar
    255


    2
    cname
    种类名称
    Varchar
    255


    3
    describe
    种类描述
    Varchar
    255



    商品二级类别表此表用于记录商品二级类别的基本信息,为方便用户查询商品和管理员管理商品信息而设立。



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




    1
    csid
    二级种类编号
    varchar
    255


    2
    csname
    种类名称
    varchar
    255


    3
    cid
    一级种类名
    varchar
    255


    4
    describe
    种类描述
    varchar
    255



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



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




    1
    oid
    订单ID
    varchar
    255


    2
    total
    总金额统计
    double
    0


    3
    ordertime
    订单生成日期
    datetime
    0


    4
    state
    订单状态
    int
    11


    5
    name
    姓名
    varchar
    20


    6
    phone
    联系方式
    varchar
    20


    7
    addr
    收货地址
    varchar
    50


    8
    uid
    用户ID
    varchar
    255



    订单明细信息表此表用于记录用户订单的详细信息,为用户提供详细的商品订单信息,同时也为管理员出货提供用户所订的商品的具体信息。



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




    1
    itemid
    订单明细编号
    varchar
    255


    2
    count
    商品数量
    int
    11


    3
    subtotal
    统计
    double
    0


    4
    pid
    商品id
    varchar
    255


    5
    oid
    订单id
    varchar
    255


    6
    uid
    用户id
    varchar
    255



    用户信息表此表用于记录用户的基本信息,是用户购买商品的权限基础,为用户维护和管理员管理用户提供信息。



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




    1
    uid
    用户ID
    varchar
    255


    2
    username
    用户名
    Varchar
    255


    3
    password
    用户密码
    Varchar
    255


    4
    name
    真实姓名
    Varchar
    255


    5
    email
    用户邮箱
    Varchar
    255


    6
    phone
    联系方式
    Varchar
    255


    7
    addr
    收货地址
    Varchar
    255


    8
    state
    账号状态
    Varchar
    255


    9
    code
    加密
    Varchar
    255



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



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




    1
    adminid
    管理员ID
    varchar
    255


    2
    UserName
    管理员名称
    Varchar
    255


    3
    password
    管理员密码
    Varchar
    255



    第五章 详细设计与实现本系统网站的主界面设计结构采用了上左右的结构,上部分为主功能菜单区,主要是显示网站的主功能,左侧为用户注册、登录,公告浏览,商品查询,右部分为信息显示区,销售排行榜 主要是为方便用户提供了一些最新上架的商品信息。
    5.1 系统前台基本功能设计与实现本节对系统前台主要功能设计进行详细的说明。
    由于网上购物必须保证用户的正确性、购物的安全性,需要对用户资料进行有效的管理,因此用户管理是电子商务网站的重要内容。它主要包括用户注册、登录和验证、用户注册和用户注销等功能。
    5.1.1 注册实现目标用户单击注册后需要输入密码和确认密码、用户真实姓名、住址、性别、E_mail、。这里需要用户通过E_mail注册是考虑到两点:第一,用户的E_mail是惟一的;第二,通过用户的E_mail可以很方便快捷的与用户取得联系。用户在提交注册信息后,系统会对注册页面填写的正确性进行检查。对于不符合要求的填写会给出必要的提示,并返回修改;对于符合要求的注册表单,用户提交信息后也要返回相应的欢迎信息,用户提交的正确注册信息将被存入系统的数据库中。

    实现过程所属页面名:userReg.jsp
    表单属性:name=”form1” action=”<%=path%>/userReg.action” method=”post”



    名称
    类型
    含义




    username
    Text
    输入用户名称


    password
    Password
    输入密码


    repassword
    Password
    输入确认密码


    name
    Text
    输入真实姓名


    addr
    Text
    输入住址


    phone
    Text
    输入联系方式


    e-mail
    Text
    输入E-mail地址


    同意以下协议并注册
    submit
    提交用户信息



    5.1.2 登录和验证顾客登录程序流程描述首先要进行身份验证顾客的用户名和密码,如果用户名存在,则登录成功,反之,当用户名不存在的时候,提示信息:“登录失败:用户名或密码错误或用户未激活!”,返回登录界面重新输入用户名和密码。

    实现目标就本系统的购物过程而言,在顾客在浏览商品时,不需行登录,但在使用购物车的时候,必须登录,并实现整个购物的过程。顾客登录需验证用户名及密码,然后系统决定是否有权限进行操作,如进行使用者信息修改、购物车及账单清算等。
    实现过程所属页面名:index.jsp



    名称
    类型
    含义




    userName
    Text
    输入用户名


    password
    Password
    输入密码


    注册
    button
    跳转注册页面


    登录
    button
    跳转登录页面



    5.1.3 用户注销实现目标已注册的用户只要登录本系统后便可以通过单击退出即可注销该用户,注销后可继续注册用户或者登录其他用户。

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

    实现过程所属页面名:index.jsp
    通过查询orderItem表中按统计出的商品销售数量排序。
    5.1.5 购物车模块的设计与实现购物车程序流程描述用户选购商品后添加到购物车中,在购物车中进行查看,同时对不满意的产品可以进行移除,对要购买的产品可以移除产品和清空产品。用户决定购买产品后可以去收银台进行结账。

    实现目标用户购买产品的核心功能是购物车和订单提交。购物车模块的设计包括:顾客添加商品到购物车和顾客对购物车的管理,如清空购物车和将购物车中商品从购物车中移除等。购物车要具有持续性,而且不限制用户购买商品的数量,也就是购物车可以显示很多商品。

    实现过程所属页面名: cart.jsp
    页面属性:\<a href="/shop/order_save.action" id="submit" class="submit"\>
    //将购物项添加到购物车中:执行的方法public String addCart(){ //封装一个CartIItem对象 CartItem cartItem=new CartItem(); //设置数量 cartItem.setCount(count); //根据pid进行查询商品 Product product=productService.findByPid(pid); //设置商品 cartItem.setProduct(product); //将购物项添加购物车 //购物车存在session Cart cart=getCart(); cart.addCart(cartItem); return "addCart";}//清空购物车public String clearCart(){ //获得购物车对象,调用清空的方法 Cart cart=getCart(); cart.clearCart(); return "clearCart";}//从购物车中移除购物项public String removeCart(){ //获得购物车对象 Cart cart=getCart(); cart.removeCart(pid); return "removeCart";}//我的购物车:执行的方法public String myCart(){ return "myCart";}
    5.1.6 收银台模块的设计与实现实现目标用户选择完商品后,需要确认购物车中内容,即结帐,点击下一步,此时页面跳转到结账页面。在结帐页面,需要用户填写收货地址、收货人、联系电话、付款方式,以便生成订单。当完成一次交易所需要的用户方面的信息都已齐全,只须生成订单即可进入配送过程。如果用户所填写的订单信息正确,系统会返回给用户此次交易所产生的订单号码。

    实现过程所属页面名:order.jsp
    表单属性:action=”/shop/order_payOrder.action” method=”post”



    名称
    类型
    含义




    userName
    Text
    收货人账号


    userRealname
    Text
    收货人姓名


    userTel
    Text
    收货人联系电话


    userAddress
    Text
    收货人地址


    odderSonghuodizhi
    Text
    送货住址



    5.1.7 查看订单模块的设计与实现实现目标用户填写完订单并提交成功后可以通过查看订单按钮看到自己的订单及详细信息。

    实现过程所属页面名:orderList.jsp
    5.2 系统后台管理功能设计与实现本节对系统后台功能设计进行详细的说明。

    5.2.1 基本信息管理设计与实现实现目标该功能主要针对用户信息、分类菜单、商品信息,订单信息的增删查改,这些功能的设计需要运用在基本信息的每一个页面中。在对此类基本信息进行添加、删除和更新操作的同时,操作所执行的结果需要通过sql语句返回到该系统的数据库中,从而在相应的页面上刷新并显示出新的结果集。模块的输出成功后将有成功的提示信息。
    实现过程所属页面名:home.jsp
    客户管理主要是使用userDAO中下的findById和findAll方法来删除和获取数据库中的数据。进入客户管理界面时通过findAll方法来显示所有用户的信息,点击删除时,通过findById方法获取指定的用户ID,使用sql语句进行操作。
    5.2.2 订单信息管理设计与实现实现目标该模块是针对顾客的订单明细信息管理功能进行的详细设计,主要是对顾客订单信息的查看、删除和订单受理的操作。同时管理员可以就此查看系统中各类订单的详细信息。
    实现过程订单管理模块使用了AdminOrderAction中的方法,当用户提交订单时,订单状态默认为未受理。管理员查看订单时调用了findAll显示到页面中。
    5.2.3 商品信息管理设计与实现实现目标在商品管理模块中除了基本的信息管理功能外,为了方便顾客浏览到商品的真实外貌,在添加商品模块中增加上传商品图片的功能。
    管理员在商品添加页面中输入添加的商品基本信息,我将商品分为特价和非特价商品来管理。然后进入图片上传页面,在上传文件位置上添加图片后点击提交,提交成功后有提示信息弹出。完成后查看商品信息时,管理员查看商品图片信息。
    实现过程所属页面名:product下的list.jsp
    本模块主要是对商品表进行管理,所以就是一些查询和删除操作,我在做的时候,主要讲商品分为热门和非热门商品,在管理时也是分开管理,主要通过判断is_hot来区分是否为热门商品。
    第六章 系统测试与性能分析完成需求分析、系统设计和程序编码等前期工作后,我得到了该系统的源程序。然而,在没有经过系统测试及性能分析前之前的各阶段中该系统程序都可能遗留下一定的错误和缺陷,若不及时查找出这些错误和缺陷并进行修改,这个软件产品就可能产生不稳定或者是不能正常使用,严重的还可能会导致巨大的损失。因此系统测试与性能分析是必不可少的。
    系统整体测试步骤:

    单元测试单元测试是整体测试中的第一步,通常在编码阶段进行。在源程序代码经过编译、评审、确认没有语法错误之后,便可开始进行单元测试。
    集成测试集成测试在单元测试完成之后,将所有的模块概要设计要求组装成系统时进行的测试,主要目标是发现与接口有关的问题。
    确认测试经过集成测试之后,接口错误已经发现被发现并改正了,接下便要进行确认测试。所谓确认测试就是验证所开发软件的功能性及其他特性是否符合软件需求规格说明书的要求。所以,确认测试又被称为有效性测试。
    系统测试系统测试是更大范围内进行测试,它将经过确认测试的软件作为整个基于计算机的系统的一个元素,在实际运行环境下,对系统进行的一系列集成和确认测试。

    6.1 前台首页的测试测试过程是单击页面左边的商品类别,选中某一类别后,就可以在页面右边显示该类别下的所有商品。通过对该功能的重复大量测试,该模块能够准确地实现此项功能。
    6.2 购物车模块的测试在本模块中首先对修改数量单元进行了测试,所修改的数量如果是有效数字,则修改所购商品数量成功,否则修改失败,系统自动将商品数量重置为“1”。通过随机测试了几组数据,其修改的数量和累计的金额均正确。如果客户购买了同一个商品,则就会进行该商品购买数量的累加,不会重复出现。然后针对购物车应该不限制顾客购买商品的数量这一原则进行测试,通过大量向购物车中添加商品来进行测试,测试结果为购物车中可以显示所添加的所有商品信息,测试结果取得了预期的效果。

    6.3 用户注册模块的测试在用户注册模块中涉及到了三项数据,项目分别为密码、用户真实姓名、住址、性别、联系方式、E_mail、QQ。测试这个模块准备的数据有:

    huqingkagn、huqika、kang、455689427@qq.com、15232152856、sjz、1
    ccc、ccc、ccc、aaa@shop.com、ccc、ccc、1
    ddd、ddd、ddd、aaa@shop.com、ccc、ccc、1
    bbb、bbb、bbb、aaa@shop.com、bbb、bbb、1

    首先进入注册页面,输入第一组数据,单击注册按钮系统会提示表单信息不能为空,因为表单信息要全部填写,而真实姓名没有写值。然后测试第二组数据,可以明显看出所输入的密码与确认密码是不一致的。然后测试第四组数据,其中九项均是系统正确的数据,因此测试通过。在填写用户名时,用户可以查看自己的用户名是否可以使用。
    6.4 商品管理模块的测试6.4.1 添加功能的测试对商品添加模块准备的商品名、商品描述、商品图片、市场价、商城价、商品种类,分别准备的测试数据为:数码、手机、诺基亚、3300、3000。其中类别的选择是通过下拉列表框来选择,图片单击上传图片后,找到图片的地址点击确定就可以上传,单击添加按钮,执行添加操作,数据提交后,就完成了商品的添加。之后,进行了几项测试,如漏填了几项数据、上传图片格式不正确,这些数据的操作结果都是失败。

    6.4.2 删除功能的测试以编号为4的这条记录为例,通过单击该条记录上的“删除”链接按钮,对商品信息进行删除的操作,数据提交后,ajax方式直接局部刷新,通过对该模块的浏览,该信息的确已被删除,查无此条记录,说明此模块运行无误。
    第七章 结论网上商城购物系统采用了比较流行的SSH模式,使用当前较流行的SSH框架和拥有较高安全性与稳定性的数据库Mysql来完成系统的设计与开发。系统充分考虑了用户的需求,最终达到了预期效果,并添加了一些附加功能,使系统更加人性化。操作者可以随时对所有的信息进行查询,并且每个模块都提供信息浏览的功能。
    本系统实现了商品企业通过互联网向消费者推销自己的商品和服务,在网上商城购物系统网站消费的顾客可以通过计算机网络搜索到自己需要的信息,购买自己需要的商品,在线下达订单。然后由网上商城购物系统后台来处理相关的订单信息、网站维护等信息。
    0 评论 6 下载 2019-10-08 17:48:36 下载需要20点积分
  • 基于Jsp的OA系统的设计与实现

    摘 要学习和研究办公自动化中涉及到的知识和技术是实现办公自动化系统的前提条件。通过学习研究,掌握了其中的关键技术之后,结合自身的理解,对其做出了相应的表述。同时也成功的实现了系统中涉及到的一些模块。这些实现了的功能模块,在日常办公中都能被用到。具有一定的实用价值。
    办公自动化(Office Automation,OA)的诞生离不开科技不断发展的趋势推动,虽然今天它已趋于完善。但在信息蓬勃发展的今天依旧是一项非常活跃和具备顽强生命力的技术。办公自动化在企业当中的应用具有无法取缔的重要意义。对办公自动化的学习和研究是有必要的。
    办公自动化有很多的优点:避免对资源不必要的浪费,节约成本,高效管理等,它能让管理变得规范和科学。在查阅了很多与OA系统相关的资料后,对其进行了深入的学习。在了解到办公自动化现在的发展状况后,对学习和研究它的现实意义进行了深入的分析。
    为了开发出更加完善的系统,本文以J2EE为技术基础,企业级的MVC设计模式为前提,科学的对系统进行了分析,阐述了OA系统的核心技术及其他工具的使用。在掌握Spring、SpringMVC、Mybatis等框架技术之后,运用Maven工具进行项目的管理,为办公自动化系统的开发做了充足的准备。
    关键词:办公自动化,J2EE,Maven,SSM
    AbstractLearning and studying the knowledge and technology involved in oa is the precondition to realize oa system. Through study and research, master the key technology, combined with their own understanding, make the corresponding expression. At the same time, some modules involved in the system have been successfully implemented. These realized the function module, can be used in the daily office. It has certain practical value.
    The birth of Office Automation (OA) is driven by the continuous development of science and technology, although it has been improved today. However, it is still a very active and tenacious technology in today’s information boom. The application of office automation in enterprises is of great significance. The study and research of office automation is necessary.
    Office automation has many advantages: avoid unnecessary waste of resources, save costs, efficient management, etc., it can make management become standardized and scientific. After consulting a lot of materials related to OA system, I made an in-depth study of it. After understanding the current development of office automation, the practical significance of learning and studying it is analyzed in depth.
    In order to develop a more perfect system, this paper takes J2EE as the technical basis and the enterprise-level MVC design pattern as the premise, scientifically analyzes the system, and expounds the use of OA system’s core technology and other tools. After mastering Spring, SpringMVC, Mybatis and other framework technologies, I used Maven tool to manage the project and made sufficient preparation for the development of office automation system.
    Key words: Office Automation, J2EE, Maven,SSM
    第一章 前言在技术发展和社会需求变更的推动下,办公自动化也在不断的成熟起来。随着信息爆炸时代的来临,为了挖掘、分析、传输和存储人们日常生活中所产生的各种数据以分析其潜在价值。各种技术的发展日新月异,其中通讯技术的发展尤为迅猛(5G已不在停留在概念上)。分布式数据库也得到了广泛的运用。这些技术的发展使得办公自动化有了更大的提升空间。
    公文在传统的办公模式下,多是手工传递处理,这种方式存在安全性不足、信息难以进行统计和分析等弊端,最主要的还是协同办公难以实现。跟传统的办公模式相比,办公自动化有着效率高、资源共享及时、以及节约成本等优势。
    现在的办公自动化系统,不止能为管理者的决策提供科学和正确的指导,还能提高领导的管理水平,同时推动了各个单位的信息化建设的进程。办公自动化在各个单位中都起着举足轻重的作用。
    随着技术的发展和社会的进步,办公自动化的内涵和外延也在不断的发生变化。也就是说它是一个动态的定义。为了应对现代化办公模式及其需求的不断发展,这就对办公自动化的整体系统结构和处理能力以及运作平台提出了越来越高的要求。办公自动化是信息时代发展下的必然产物。在协同办公理念深入人心的当今社会,办公自动化的使用程度将成为一个国家现代化进程的重要指标和衡量标准。
    1.1 项目背景目前国内外还存在着很多日常办公运用手工操作的企业和单位。这样将导致大量的信息不能得到及时的共享和充分的利用。而且随着时间的推移,不断累积的信息将成为企业和单位的一种负担,光是对信息的管理、分类、索引、利用就极其困难,对于企业和单位来说不仅是一种时间成本的投入,还是对人力和财力的损耗,最重要的是工作效率低下,决策者还难以从中挖取出有用的数据来用作决策的依据。长此以往,信息的不断累积对企业和单位来说将是有百害而无一利的。办公自动化的意义自然不言而喻。
    过去的办公自动化系统,在当时的技术条件限制下存在很多的缺陷,早已不能胜任现代办公的需求。集成化程度低,不能实现充分的资源共享,系统韧性差等因素成为了其致命的缺点。特别是过去的这些办公软件,大都是静态的。由于不能适应信息时代的需求,导致了它们的应用范围有很大的局限性,应用效果也很差。因此在信息化时代下的办公自动化系统需要具备更强劲的功能。在降低企业成本,充分利用企业内部资源,加快业务流程,显著提高工作效率和应对环境变化等方面都要有良好的表现。
    1.2 OA简介办公自动化简称为OA(Office Automation)是集计算机科学、通讯技术、系统科学、行为科学为一体的综合性技术。现代的办公自动化系统采用的是Internet/Intranet技术,基于工作流的概念,使得企业内部的员工能够方便快捷地共享信息,高效地协同工作;改变传统复杂、低效的手工办公方式,以实现迅速、全方位的信息采集和信息处理,为企业的管理和决策提供科学的依据。企业实现办公自动化的程度也是衡量其实现现代化管理的标准。办公自动化不仅兼顾个人办公效率的提高,更重要的是能够实现群体系统工作。凭借网络,这种交流和协调几乎可以在瞬间完成。
    1.2.1 办公自动化的国内外研究情况不管在过去还是在现在,办公自动化的核心都是公文处理。由于公文处理本身的特性限制,这对办公自动化系统在公文处理的流程控制方面提出了更高的要求。
    目前的办公自动化系统在企业中得到了广泛的运用,它的工作流管理自然也就延伸到日常办公,和事务处理流程中去了,比如会议的管理、财务报销审批、休假审批等等。
    办公自动化系统通过对工作流的管理,使得公文在流转、审批、发布等方面极大的提高了其效率。实现了办公管理的规范化和信息管理的规范化,极大的降低了企业的运行成本。
    现在国内主流的OA系统有泛微、蓝凌等,其主要功能模块见图1.1和图1.2:



    国外OA系统的代表有EGroupware,其主要功能模块如图2.3所示:

    对比分析上图可以看出,这些OA系统中都有流程管理这个模块。要实现对这个模块的管理,还需要有相应的软件系统作为支撑。即工作流管理系统(WFMS),工作流管理系统的主要作用是:调用和管理业务过程中的各种活动的先后顺序和资源,以此达到自动化办公的目的。
    1.2.2 本文的主要内容及章节安排本文对办公自动化进行了分析和研究、并且还将JBPM(Java Business Process Management)和SSM框架技等技术应用在了办公自动化领域中,通过Maven这样的项目管理利器来对项目进行管理,从一定程度上保证了系统整体架构的稳定性和具体实现代码的鲁棒性,致力于实现系统各个模块之间的“高内聚、低耦合”度,使得系统各个模块的复用程度、系统功能的扩展性和可维护性都得以提高;通过使用管理工具Maven还可以轻松的实现对系统中各个模块的管理。
    本文的章节安排和主要的研究内容所下所述:

    第一章节:前言主要概述了本文的研究背景和这个课题在国内外的研究情况,并且还通过对项目背景的简述,说明了对办公自动化进行研究的意义。
    第二章节:主要是相应架构技术和开发环境的概述,首先介绍了所要用到的相关技术的理论知识,然后对Spring、SpringMVC、Mybatis等框架的运行机制进行分析,它们是构建OA系统的关键技术。
    第三章节:这一章节对系统开发进行了必要的分析,为系统设计环节提供了相应的理论基础。
    第四章节:系统设计是实现系统开发的主要环节和前提条件,对办公自动化系统的主要模块进行了详细的分析和设计,为后续的具体实现奠定基础。
    第五章节:对系统的具体实现也作了简要描述叙述的同时,还对开发环境的搭建,框架的整合进行了简要的说明,在系统实现章节附录了相应模块的核心代码。
    第六章节:总结全文,同时对系统的进一步提升和完善提出改进意见。

    第二章 系统架构技术的研究及简单的环境搭建概述2.1 Web应用体系结构技术总是在不断发展和进步的,企业级应用程序的架构也不例外,在多年的发展演进过程中,它的设计思想也产生了巨大的变化。分析它的发展历史,可以发现:在大型机和个人计算机盛行的时期,很多的应用程序都是运用的两级体系结构,在这种结构中,服务端的主要职责是数据的存储和检索,而绝大多数的业务逻辑还交由客户端来进行处理。随着应用程序中需求的增多,其中包含的业务逻辑变得越来越复杂的时候,客户端就显得不堪重负啦,为了减轻客户端的压力而将系统中的业务逻辑剥离出来,形成单独的一部分,就这样衍生出了三层体系结构。
    三层体系结构的划分如图2.1所示。


    表现层:可以理解为jsp、html等页面。
    业务逻辑层:主要任务是对程序中与业务流程进行处理,为前端页面提供相应的业务服务。
    数据持久层:主要是对数据进行存储。

    运用这样的三层结构,可以实现让每一层在功能实现上有一个清晰的界限,这样三层之间是相互分离的,但它们之间存在彼此进行通信和交互的接口。
    软件开发采用这种三层体系结构,可以让软件系统在可扩展性、可复用性、和安全性上得到很到的提升,还也有助于系统易管理性的提高。
    2.2 B/S架构介绍B/S架构是一种对C/S架构进行改进后的架构,它不需要安装任何专门的软件,对操作系统也没有任何限制,由于只需要客户端上具备浏览器就行,这种架构实现了客户端的统一和平台无关性。在这种模式下,系统功能的核心实现集中在了服务器上,这样可以简化系统的开发、维护和使用。
    使用架构,可以使得软件维护和升级方式变得简单,由于浏览器就是它的客户端,所以根本不需要做任何的维护,只需要对服务器进行管理即可。用户量的增多也不会对它的升级维持产生影响。甚至还可以实现远程维护、升级和共享。管理人员只需要管理服务器就行了,软件的维护成本较低。
    也正是因为B/S架构的特性,所以客户机越来越“廋”,但服务器却因此变得越来越“胖”,在这种架构之下,服务器运行数据的负荷较重,为避免发生服务器“崩溃”,造成无法弥补的损失。使用这种架构往往需要配备数据库存储服务器来以防万一。
    2.3 j2EE简介和JDK的安装配置Java编程主要有三个方向:Java SE(Java Platform , Standard Edition),它是Java中的基础部分,也称J2SE,主要用于桌面开发,同时它也是Java EE(Java Platform , Enterprise Edition)的基础。Java EE也称为J2EE主要应用于Web开发。最后一个是Java ME(Java Platform , Micro Edition)也称J2ME,主要应用于移动端的开发。
    J2EE这种技术架构,它有很多组件,主要用来简化和规范系统的开发和部署,从而可以提高代码的移植性、安全性和复用性。因为它是Java技术中的一部分,所以Java语言所具备的特点它也都具备,面向对象、高性能、跨平台(操作系统)的。而且“一次编译,到处运行”。
    俗话说:“工欲善其事,必先利其器”,如果想要通过使用J2EE架构进行系统开发,首先需要进行JDK(Java Development Kit)的安装及其配置。具体的安装配置如下:
    下载JDK的安装包:虽然JDK是sun公司开发的产品,但由于sun公司已经被Oracle公司收购,在下载安装包的时候需要到Oracle官网上去根据自己的操作系统进行下载。具体的下载过程就不再赘述,接下来说一下JDK的环境变量的配置方式。
    我的电脑->系统属性->高级系统设置->环境变量->新建



    变量名
    变量值




    JAVA_HOME
    D:\DEV\jdk1.8(具体配置视安装目录而定)


    CLASSPATH
    .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; (固定写法)



    最后在path路径中添加变量值:%JAVA_HOME%\bin和%JAVA_HOME%\jre\bin即可。
    测试:运用组合键“win+r”输入CMD命令进入控制台,然后在控制台输入java–version、java、javac等命令进行测试。
    得到图2.2、图2.3和图2.4所示则表示JDK安装配置成功。



    2.4 Jsp简介Jsp(Java Server Page)是一种动态网页的综合性技术。它的产生是由于程序员在开发的过程中发现,Servlet用来做界面非常的不方便。于是就想到了用一种新的技术来做界面,就这样Jsp技术就出现了。Jsp技术可以用下面这个公式来进行表示:公式:Jsp=html+java片段+Jstl+Javascript+css。其实Jsp的本质还是Servlet,Jsp和html最大的区别仅是多了一些Java片段而已,所以写Jsp就和写html差不多。
    相比html来说:html只能为用户提供静态数据,而jsp技术允许在页面中嵌套Java代码,能够为用户提供动态数据。
    相比Servlet来说:Servlet要对数据进行排版难度较大, Jsp不止是可以通过Java产生动态数据,它还综合了JavaScript和css技术,所以能够很轻易的对数据进行排版。
    Jsp的运行原理如图2.5所示:

    说明:Jsp页面报错实际上是报的Servlet即xxx_jsp.java中的错误,在查找错误的时候应当找到与该Jsp对应的Servlet中去查找相应的错误。
    2.5 MVC简介MVC是一种设计模式,所谓设计模式就是开发人员在长期的开发过程中提炼和总结出来的一套优秀的应对一般问题的解决方案。
    MVC当中的M代表model,可以理解为JavaBean,V即视图,是系统与用户进行交互的窗口,可以理解为Jsp页面或其他的前端页面。其中C是Controller控制器,主要用于处理业务逻辑。采用MVC这样的三层模式,可以有效的将视图、业务逻辑和数据持久层分离开来,它们之间相互分离,仅通过业务逻辑来进行调用。
    例如这样一个简单的需求,前端Jsp页面的用户通过输入用户名和密码发起一个登陆请求,请求将传达到控制器,控制器通过对数据库的调用来进行数据比对,如果在数据库中不存在那么一个用户,那么控制器将返回一个失败信息给前端页面。
    这种设计模式极大程度上的增加了程序的健壮性,可维护性和易于扩展。
    J2EE中几种重要的开发模式:
    Model1模式: Jsp文件是Model1模式的基础,它是由一些独立的Jsp文件,和一些Java Class组成的(不是必须的),这些Jsp文件通过从Http 请求中获得所需要的数据,并进行业务逻辑的处理,处理的结果通过服务器响应返回前端界面。
    Modell模式有开发简单、开发速度快,适合开发小项目等优点。缺点是,表现层和业务逻辑层混在一起,首先这样显得很乱,代码的可读性差,后期维护工作难以进行,同时也不利于多个人进行协同开发。Model1模式原理如图2.6所示:

    分层模式即Model1.x模式(MV模式,分层),是在Model1模式的基础上演变而来,将业务逻辑和表现层分离开来,但是业务逻辑和数据模型模型依旧放在一起也不利于系统的维护和扩展,其原理如图2.7所示:

    MVC模式要求在开发的过程当中,把数据的输入、输出和显示分进行分离。
    MVC模式的原理,如图2.8所示:

    2.6 Spring简介首先说一下Spring是什么?
    Spring是一个为了解决软件开发复杂性而被开发出来的,优秀而且开源的容器框架,来看一下如图2.9所示的Spring层次原理图。

    从图中可以看出Spring是一个横跨三层(Web层、业务层、数据持久层)的框架,之所以把它称之为容器框架,是因为它的核心主要是用于配置bean,并且维护bean与bean之间的关系。这里说到的bean是Spring框架中一个非常重要的概念,它可以是Java中的任何一种对象,Spring的核心配置文件包含并管理了应用中对象的配置和生命周期,从这个层面上来说,可以将其看成是一种容器。
    Spring中提出了控制反转技术(IoC),和面向切面编程(AOP)的思想等促进了应用软件模块之间的松耦合度。能够有效的提升软件的稳定性和可测试性。
    Spring命名的由来,起初在Rod Johnson的Expert One-on-One Java EE Design and Development(专家一对一J2EE设计与开发)一书中Spring被称为“Interface21”(当时它使用com.interface21这个包名)。对于使用过EJB来开发过J2EE的人,一定知道这门技术在开始学习和应用的时候非常的艰苦。Spring出现后采用简单的JavaBean代替了EJB,并且还提供了更多的企业应用功能。Spring代表了传统J2EE“冬天”之后的一个新的开始,而且为了激励开发者社区,然后就有人提出了用“春天”这样一个简洁优雅的词来命名。
    Spring框架由七个明确定义的模块组成,详见图2.10。

    Spring框架的组成模块之间是相互独立的,在实际开发的过程中,可以根据自己的需求选用其一部分子框架即可,然后应用其他的框架方案加以代替。例如:它所提供的ORM(对象关系模型)框架,就可以采用Mybatis框架来进行代替。如果采用了其他的框架来进行替代的话,就涉及到框架的整合。在它的核心配置文件中,应当合理的进行配置,如图2.11所示:

    框架多是通过Java的反射机制来实现的,至于其内部的实现细节在此不做叙述,在此只对其运行原理进行说明,Spring的运行原理如下图2.12所示:

    Spring开发提倡接口编程,配合di(Dependency Injection)技术可以更好的达到程序间的解耦,使用框架的时候需要到其官网去下载jar包,然后导入到工程目录中去才能进行使用,对于项目工程来说,可以理解为第三方库。
    2.7 SpringMVC简介SpringMVC是Spring框架的子模块,它是类似于Struts2的一个MVC框架,在实际的开发中,接收浏览器的请求响应,对数据进行处理,然后返回页面进行显示。上手难度较Struts2简单得多,而且由于Struts2所暴露出来的安全问题,SpringMVC已经成为了大多数企业优先选择的框架。
    运用SpringMVC框架进行开发,程序员只需要把精力放在处理器Handler的编写及视图比如JSP页面的编写上即可。
    学习框架实际上学习的就是其配置文件,使用框架有很多好处,但是相应的也会存在一定的限制,开发的过程中应当遵从其相应的规范。
    在运用SpringMVC进行开发的时候,需要在它的核心配置文件中,进行相应的配置。其中主要的是对映射器、处理器、视图解析器、视图过滤器还有Handler进行配置如图2.13和图2.14所示:

    SpringMVC的试图过滤器需要到Java Web工程的Web.xml文件中去进行配置。

    编写SpringMVC中的映射器、处理器有两种方式,一种是注解的方式,还有一种是非注解的方式,在运用注解方式的时候应当注意:

    注解方式的映射器
    spring3.1之前使用org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping注解映射器。spring3.1之后使用 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping注解映射器。

    注解方式的处理器
    spring3.1之前使用org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter处理器适配器。spring3.1之后使用 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter处理器适配器。
    SpringMVC的映射器和处理器在使用的时候需要配对使用,版本需要一致,不然在项目运行的时候会报错。SpringMVC还提供了<mvc:annotation-driven/>标签来配置映射器和处理器,Handler的配置还可以通过包扫描的方式进行配置:
    <context:component-scan base-package="包含controller的包名 ">。
    2.8 Mybatis简介Mybatis可以理解为一种不完全的ORM(对象关系模型)框架,它是Apache下的顶级项目,对于Mybatis来说对JDBC的封装程度没有Hibernate深,所以它对开发人员有着更高的要求,开发者需要自己编写SQL语句。
    Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。它可以使用简单的XML或注解来配置和映射原生类型、接口和Java的POJO为数据库中的记录。
    Mybatis是数据持久层框架,Mybatis对于大型数据库的优化和适配性较强。适用于需求变化周期快,数据处理量较大的系统。Hibernate采用了更加自然的面向对象的视角来持久化Java应用中的数据,让开发者不再关注底层数据库的细节。Mybatis在这方面没有特定的文档说明,这样便于开发者发挥自身想法来对对象进行管理。
    Mybatis运行原理如图2.15所示:

    Mybatis的核心是mapper.xml文件,简单的说就是配置SQL语句。
    2.9 Maven的简介Maven是一种优秀的项目管理工具,它为构建项目提供了一套完整的生命周期框架。
    由于Maven使用了标准的目录结构和生命周期。所以在多个开发团队进行开发的情况下,它可以按照设置标准在很短的时间内,完成相关的配置工作。由于大部分项目的设置都很简单,并且可以重复使用,Maven让开发者的工作更轻松。同时它可以自动的完成:创建报表、检查、构建和测试等工作。
    系统在运用框架开发的过程中,需要到各个框架的官网上去下载jar包,运用Maven的话,只需要在其核心文件中添加依赖即可。可以方便的进行管理、节约时间、提高工作效率。
    总的来说,Maven可以帮助开发人员简化和标准化项目的建设。它主要有负责处理编译,分配文档和管理团队协作等功能。Maven可以增加项目中模块的可重用性。
    Maven项目的结构和内容在pom.xml文件中声明,pom.xml文件这个文件是整个Maven系统的基本单元。
    管理工具Maven的安装步骤如下:

    进行下载安装:到Maven的官网去下载和系统对应的文件。由于是下载好的文件是压缩包格式,只需要将它进行解压就能完成安装了。
    配置环境变量:此电脑系统属性高级系统设置环境变量
    点击新增变量,变量名为:MAVEN_HOME,变量值就是maven解压位置的路径。
    接着点击编辑Path变量,在有变量值的那一栏中追加 %MAVEN_HOME%\bin即可。
    测试:win+R->cmd->调出控制台->输入命令(mvn –version)。得到图2.16所示的结果,那么环境变量就配置完成。


    对Maven的settings.xml文件进行配置,可以实现其默认仓库的转移:
    根据Maven的安装路径找到它的配置文件(settings.xml),用记事本打开之后找到“<localRepository>”这对标签,并在这对标签中间填写上指定的路径,如图2.17所示:

    接着配置Maven,由于到它本身的中央仓库去下载jar包会非常慢,这里将其更改为阿里云的,在settings文件中找到“<mirros>”这对标。
    然后在标签当中增加阿里云maven镜像,如图2.18所示:

    至此,Maven的安装配置完成。
    2.10 本章小结本章节通过对办公自动化系统中所到使用到的相关技术进行了简要的叙述,对使用的框架的原理及配置文件进行了简要的说明,通过对理论知识学习和相关技术的研究,为办公自动化系统的开发提供了一定的理论基础,让办公自动化系统的实现成为可能,同时还做了一些必要的准备,安装JDK和Maven,并且对环境变量进行了配置。
    第三章 系统分析3.1 系统的可行性分析在准备开发一个项目的时候,对其进行可行性分析是必不可少的一个重要环节,通过对其进行可行性分析,可以为我们的决策(是否对该软件进行开发)提供科学的依据。可行性分析可以帮助我们在开发项目的过程中以最小的代价,并且尽可能的在短时间内来确定相应的问题是否能够得到解决。通过确定系统的相关约束和限制,以此来分析准备开发的系统需求和规模等是否能够具体实现,实现后能否为企业带来经济效益的最大化。总而言之,只有通过认真的对系统进行可行性分析,才能有效的避免在开发过程中的阻抗问题。
    3.1.1 技术可行性字面上的意思就是通过现有掌握的技术是否能够实现这个项目?
    本课题的技术基础是Java,结合掌握了现有的一些优秀的框架Spring(容器框架)、SpringMVC(MVC框架)、Mybatis(数据持久层框架)技术的基础上,结合项目管理工具(Maven)来对办公自动化系统进行开发。通过将这些框架进行整合来实现具体的开发,可以增加系统的稳定性、可维护性以及可扩展性以此来达到快速稳健的构建项目的目的。
    数据的存储采用了开源的MySQL数据库,虽然它是开源的,但是在安全性做得较好,数据处理的能力极强,并且它是一个最轻量级的数据库,系统要求没那么高。
    开发工具采用具有错误代码提示功能的Eclipse(一个免费的集成开发工具),它所提供的错误代码提示功能对于初学者来说是比较重要的(不怕出错,就怕不知道哪儿出错)。
    在长期的学习过程中,对于相关技术的掌握让我对办公自动化系统的开发成为可能。
    3.1.2 经济可行性从企业的出发点来看,就是某个软件开发出来之后所带来的经济效益是否
    会大于其开发成本。如果该软件所带来的经济效益能够远远大于其开发成本,那么决策者将决定对其进行资金注入。
    就个人的毕业设计而言,所采用的相关技术以及开发工具等都是免费的。所以并不存在因为经济压力而开发不下去的情况。
    3.1.3 操作可行性该办公自动化系统应用Tomcat容器进行部署,前端页面运用了JSP技术。在项目进行发布的时候,只需要通过浏览器输入对应的URL就可以实现访问和操作。该系统具有交互界面简单,操作容易,方便管理等特点。
    综上所述,本系统可以进行实际开发。
    3.2需求分析3.2.1 功能性需求分析本系统从功能的实现上主要分为日常办公、综合信息、系统管理三个模块,初始情况下只为系统设置一个用户admin,这个用户是系统的超级管理员,拥有操作这个系统的最高权限(系统管理、个人信息管理、审批管理、公告管理等)。
    3.2.2 日常办公工作流是办公自动化系统的核心所在,在最初的办公模式下,工作流的流动是基于纸张表单、人工传递的方式进行逐级流动的,最后再又管理者进行审批签字。对资源来说是一种浪费,最主要的还是工作效率不高,企业中应用办公系统,员工只用通过电脑来填写好相关的表单即可,表单会按照系统定义好的流程,自行的流动向下指定的审批者,审批者在接收到表单后,可以根据需要对其进行相应的更改,大大的提高了员工的工作效率,同时也提升了公司的核心竞争力。在这一模块中审批管理是其核心。系统需要将消息分发给对应的审批人员,最后根据审批人员的抉择来确定最后的结果。公告的发布修改删除只能是管理员才具备的权限。每次公告的更新数据都会同步到数据库中去,在其他用户登录系统的时候可以及时的接收到公告通知。
    3.2.3 综合信息企业的管理离不开对数据的处理,例如:一个新员工在正式进入公司的时候,要对其信息进行录入、备份,在其职位、薪水等发生变化的时候要对相应的信息进行更改。在员工离职的时候需要将其相应的信息进行删除。企业中信息的交流处理(业务流程)是办公系统中重要的组成部分。采用传统人工的方式进行处理,工作效率低下。大量累积的信息需要进行筛选、分类、归档。如果仅靠人工进行操作,工作量大、不易管理、在对信息进行查找的时候工作难度大,对于企业来说是一笔不小的资金投入,因此需通过系统来实现其管理的便捷性,以此提高工作效率、降低运作成本。
    3.2.4 系统管理系统管理是针对具有系统管理权限的人员对系统进行维护而开发的基础模块。
    系统管理的主要模块主要包含(用户管理、岗位管理、权限管理、部门管理)等模块。

    用户管理模块要具体实现的共能为:添加、删除、更新、用户列表等。
    系统的岗位管理模块的主要功能为:添加、删除、更新、岗位列表等。
    部门管理主要实现的主要功能为:添加、删除、更新、部门列表等。

    3.2.5 非功能性需求分析对系统的非功能性需求进行分析是必要的,虽然它与系统的实现无关。但也是要重点考虑到的一个环节,它具体包括了系统的安全性、可靠性、健壮性、可扩展性等。这些属性是衡量系统好坏的关键。
    系统开发完成之后应该具有操作简单、良好的交互性(用于提升用户使用的满意度、和良好的使用体验)、界面具有友好性(针对用户的误操作给出相应的提示信息)等特性。系统应该充分的考虑用户的操作习惯,针对这些需求对系统各项功能进行严格的测试,并进行逐步完善,以此来增加系统本身的实用性。
    3.3 本章小结本章节通过对系统的可行性进行了简要的分析,为是否开发该系统提供了科学的理论依据。通过对系统功能性需求分析的阐述,说明了系统主要的几个模块以及它们应该包含和实现哪些具体的功能。最后通过系统非功能性的需求分析,对系统还需实现哪些与系统主体功能无关的细节进行了补充和说明。
    第四章 系统设计4.1 系统的架构设计这个办公自动化系统,采用的是B/S架构、运用了MVC模式进行开发,主体包括了数据持久层,核心业务层以及应用层(即前端视图界面—-用户实现操作的交互界面),运用框架技术结合Maven管理实现对系统的构建,系统整体架构如图4.1所示:

    在此系统架构下,项目工程的文件结构如图4.2所示:

    4.2 系统模块设计系统模块的合理划分是系统成功的关键,因为OA系统模块众多,如果事先不做好模块划分,开发过程中的时间成本的投入将会提高,还可能造成做无用功的现象。对系统的各个模块进行合理的划分,能够促进系统功能的具体实现。
    系统模块大致分为系统管理、个人信息管理、审批管理、公告管理等(模块)。如图4.3所示:

    系统管理模块又分员工管理、部分管理和岗位管理,如图4-4所示:

    系统的个人信息管理模块,主要功能是对用户进行CRUD操作,如图4.5所示:

    系统的审批模块,主要由请假申请、申请查询和待审批申请组成,如图4.6所示:

    系统的公告管理模块,主要实现:管理员对公告的增、删、改操作,用户对公告可以进行的操作是查询,如图4.7所示:

    4.3 数据库设计数据库是系统的核心组成之一,主要用于对各种信息进行增删改查操作。数据库设计得是否合理,对整个系统有着深远的影响。
    4.3.1概念结构设计为了方便描述系统各模块间的联系,应设计与之对应的实体,实体中需要包含相关的实体属性。这里通过“请假”这个具体的事务流程为主线来贯穿系统中所涉及的实体。企业内部某个部门的员工(仅仅具有普通权限的系统用户)在要请假的时候,应该向具有相应权限的管理人员(具有系统管理权限的用户)发起“请假”申请,然后由管理人员对“请假”进行审批,最终将审批的结果返回给申请人。
    这个业务中所包含的实体有:用户、部门、请假、审批、权限和角色。
    (1)用户实体用于存储用户的相应信息,用户实体如图4.8所示:

    (2)部门实体包含了部门名称和描述等属性,部门实体,如图4.9所示:

    (3)系统的请假实体主要包含的信息,如图4.10所示:

    (4)审批实体主要包含了一下信息,详见图4.11:

    (5)权限这个实体存储了与权限相关的信息,如图4.12所示:

    (6)用户角色实体主要用于存储用户在企业中担任的角色,角色实体如图4.13所示:

    4.3.2 系统E-R图E-R图是描述实体之间的关系图,本系统的E-R图,如图4.14所示:

    4.3.3 表结构的详细设计表结构设计的好坏,对系统的运行性能起着决定性的因素。不合理的设计还可能导致在开发的过程中遇到很多难以解决的问题,甚至导致开发难以进行下去。所以在设计表的时候应该遵循一定的关系模式。设计的时候至少需要满足第一范式的要求(即保证表中的每个属性的值域都是不可再分的数据项),目的是为了保证数据的完整性和可靠性避免数据冗余。
    (1)用户表用保存用户的相关信息,表结构如表4.1所示:
    表4.1系统用户表(t_wl_user)



    字段名
    类型
    长度
    是否为空
    是否主键
    说明




    user_id
    int
    20


    用户ID


    depart_id
    int
    20


    部门ID


    role_id
    int
    20


    角色ID


    login_id
    varchar
    40


    登陆ID


    userName
    varchar
    25


    用户名


    userPassword
    varchar
    30


    用户密码


    sex
    char
    2


    用户性别


    phoneNumber
    varchar
    20


    手机号码


    email
    varchar
    30


    电子邮件


    description
    varchar
    90


    描述


    createTime
    dateTime



    注册时间



    (2)部门表用于存储部门的相关信息,表结构如表4.2所示:
    表4.2系统部门表(t_wl_department)



    字段名
    类型
    长度
    是否为空
    是否主键
    说明




    depart_id
    int
    20


    部门ID


    name
    varchar
    25


    部门名称


    description
    varchar
    90


    描述


    parent_id
    int
    20


    上级ID



    (3)角色表用于存储角色的相关信息,表结构如表4.3所示:
    表4.3系统角色表(t_wl_role)



    字段名
    类型
    长度
    是否为空
    是否主键
    说明




    role_id
    int
    20


    角色ID


    name
    varchar
    25


    角色名称


    description
    varchar
    90


    描述



    (4)权限表用于保存权限信息,表结构如表4.4所示:
    表4.4系统权限表(t_wl_power)



    字段名
    类型
    长度
    是否为空
    是否主键
    说明




    id
    int
    20


    ID


    name
    varchar
    25


    名称


    url
    varchar
    130


    url


    parent_id
    int
    20


    上级权限ID



    (5)公告表用于保存公告信息,表结构如表4.5所示:
    表4.5系统公告表(t_wl_notice)



    字段名
    类型
    长度
    是否为空
    是否主键
    说明




    notice_id
    int
    20


    公告ID


    user_id
    int
    20


    创建人


    content
    longtext



    公告内容


    createTime
    dateTime



    创建时间



    (6)请假表用于保存请假信息,表结构如表4.6所示:
    表4.6系统请假表(t_wl_leave)



    字段名
    类型
    长度
    是否为空
    是否主键
    说明




    leave_id
    int
    20


    请假ID


    user_id
    int
    20


    请假人


    approver_id
    int
    20


    审批人


    startTime
    dateTime



    开始时间


    endTime
    dateTime



    结束时间


    days
    int
    2


    请假天数


    reason
    varchar
    90


    请假原因


    result
    varchar
    10


    请假结果


    createTime
    dateTime



    创建时间


    status
    varchar
    10


    请假状态


    type
    varchar
    10


    请假类型



    (7)审批表用于保存请假的审批信息,表结构如表4.7所示:
    表4.7系统审批表(t_wl_leaveApprover)



    字段名
    类型
    长度
    是否为空
    是否主键
    说明




    approver_id
    int
    20


    ID


    leave_id
    int
    20


    请假ID


    user_id
    int
    20


    审批人


    username
    varchar
    25


    请假人


    status
    varchar
    10


    审批状态


    advice
    varchar
    10


    审批意见


    createTime
    dateTime



    创建时间



    (8)消息表用于保存待审批消息,表结构如表4.8所示:
    表4.8系统消息表(t_wl_message)



    字段名
    类型
    长度
    是否为空
    是否主键
    说明




    message_id
    int
    20


    消息ID


    user_id
    int
    20


    消息归属


    leave_id
    int
    20


    消息来源


    title
    varchar
    45


    消息标题


    watch
    char
    2


    是否查看



    至此,系统中各个表的表结构设计完成。
    4.4 核心业务流程设计工作流的设计是办公自动化系统的核心。针对本系统,通过“请假”这一业务来进行工作流设计,具体流程为见图4.15所示:

    4.5 本章小结通过“请假”这一业务来贯穿整个章节,对系统的架构设计、模块设计、数据库设计和核心业务流程设计进行了详细的说明,并且给出了进行过合理设计实体图、E-R图和表结构。
    第五章 系统实现完成以上过程后,现在进行办公自动化系统的开发。选择合适的开发工具和框架实现开发。严格按照框架约束和MVC模式的要求,遵循Java的命名规范,对代码进行优化、抽取和封装,最终完成一个高性能的办公自动化系统。
    5.1 开发环境搭建在安装配置了JDK和Maven的基础上,现在进行Eclipse(集成开发工具)的安装。注意事项:Eclipse的安装需要选用与之版本对应的JDK版本才能成功运行。

    在官方网站下载安装好Eclipse2018-12后运行(因为下载好的文件是压缩包格式,安装过程只需要将其解压到指定目录即可)。
    Eclipse在第一次运行的时候需要先选择它的工作空间(工作空间自行指定),如图5.1所示:



    新建一个Maven工程,如图5.2所示:

    到选择工作空间的时候把“Use default Workspace location”勾选好即可,在选择类型的时候需要选择webapp,如图5.3所示:

    选择完毕后点击下一步,最后为工程命名(myDesign),如图5.4所示:

    在命明完成后点击完成即可。

    Maven工程新建完毕之后对其配置文件(pom.xml)文件进行配置部署,添加开发所需的依赖。如图5.5和5.6所示:



    进行框架整合,先按照SSM框架的整合规范建立相应的文件结构,然后对系统中所用到框架的配置文件进行相应的配置,目的是完成框架的整合。Mybatis的配置如图5.7所示:

    Spring配置文件的部分配置如图5.8所示:

    5.2 通用功能实现由于CRUD操作是各模块数据通用的,故而将其抽取为公共代码部分,采用面向接口编程的方式,具体模块的实例需要运用到的时候对其进行实现即可。主要代码如下:
    public interface UserService { public User findUser(String username, String userpwd) ; public List<User> selectAll(); public void add(User u); public void del(int id); public User getById(int id); public void update(User u); public List<User> getByLike(String keywords);}
    5.3 登陆模块实现登陆界面采用html+js+css来具体实现,效果如图5.9所示:

    下面附录的是实现登陆主要代码:
    // 申明这是一个控制器@Controllerpublic class Usercontroller { // 注入Service @Autowired UserService service; //url映射 @RequestMapping("/login") public String login(){ return "login"; } //登陆验证 @RequestMapping("/main") public String checkLogin(@RequestParam(value = "username") String username, @RequestParam(value = "userpwd") String userpwd){ User user = service.findUser(username, userpwd); if(user!=null) { return "main"; }else { return "err"; } }
    5.4 系统模块的实现系统的主要模块有:角色管理、部门管理、用户管理三大模块,基础部分均为数据的CRUD操作,其中还包含用户列表的分页功能。页面效果如图5.10所示:

    部分核心代码如下:
    //后台核心代码@RequestMapping(value = "/user")public ModelAndView selectAll() {ModelAndView mav = new ModelAndView(); mav.addObject("userList", service.selectAll()); return mav;}
    //前端界面的关键代码:<tr> <th class="table-check"><input type="checkbox" id="chkAll"></th> <th class="table-id">ID</th><th class="table-title">姓名</th> <th class="table-type">电话</th> <th class="table-author am-hide-sm-only">性别</th> <th class="table-set">操作</th></tr></thead><tbody><c:forEach items="${userList}" var="user"> <tr> <td><input type="checkbox" name="chk"></td> <td>${user.id}</td><td>${user.name}</td> <td>${user.phonenumber}</td><td class="am-hide-sm-only"><span class="am-badge am-badge-primary">${user.sex}</span></td><td>
    5.5 本章小结本章节主要叙述了开发环境的搭建,说明了搭建开发环境时的注意事项。在环境搭环节就系统框架的整合进行了简要的说明,最后对系统的具体实现也作了简要的描述并附录了相应模块的核心代码。
    0 评论 1 下载 2019-10-08 17:11:18 下载需要20点积分
  • 基于java的改良版超级玛丽

    1. 用户需求1.1 用户希望游戏要有它的创新性,有吸引力我们的这个游戏考虑到用户的这样的希望有新鲜感的心理需求。所以我们游戏首先有很多创意。从开始构思的时候我们就想基于软件园的实际生活,做一款跟我们每天的生活都息息相关的游戏。这样就产生了《逃离寝室》这样的构思,游戏主人公会从寝室之中逃出,然后越过种种障碍,闯过许多关,最后成功上完一天的课程。像这种冒险类游戏其实有很多,像是超级玛丽、temple run,地铁跑酷等等,一个游戏的灵魂不是他的游戏方法,而是其主题的定位。可以说在创意上面,我们已经占领了先机。
    1.2 用户希望有帮助等基本功能在吸引用户之后,要满足用户的对游戏的探索能力。在编写这个游戏的后期,我们小组给程序设置了帮助功能,将会给用户讲解游戏的规则以及具体的游戏方法,进一步指导用户将这个游戏玩下去。
    1.3 用户希望有好的视觉体验我们小组,为了使用户有更好的视觉体验,在游戏的编写过程中也一直在商讨关于游戏的人物障碍物背景等等的外观,以求使用户在游戏的过程中不会产生审美疲劳。也有更好的体验。
    1.4 用户希望有更好的听觉体验为了实现这个目标我们给游戏增加了背景音乐。
    1.5 用户希望游戏过程流畅为了实现这个目标我们进行了两方面的工作。第一就是游戏的障碍物的出现比例和节奏的调整,如果障碍物太多或者太少,会使游戏太难或太简单,以至于用户丧失游戏兴趣。其次就是运用了多线程的方法,使电脑的CPU合理分配,使游戏的画面更加流畅,不会出现卡机等现象。
    2. 系统设计计划做一个类似于超级玛丽之类的冒险游戏。主人公就是我们作为游戏原型。主要的任务就是主人公会试图从寝室出来赶时间去上课,途中会遇到种种困难阻碍我们上课的道路,我们需要做得就是闯过这些障碍最终顺利到达教室。我们的具体的类的大致设计和构思为:

    游戏流程:

    3. 系统实现我们每个周的任务进度:
    第一周

    我们已经想出了大体的设计方向及游戏的某些功能及流程
    已经初步做了几个像素小人
    正在做GIF形式的小人,一像素一像素的改
    做了一些图形界面的学习设计
    待解决的问题及后续的工作安排
    怎么样将真人做成人物并融合到程序里面
    具体的算法流程等还不是非常清楚,正在学习的阶段
    后续会先开始进行简单的地图的绘制以及人物和障碍物的创建

    第二周

    已完成的工作
    音效类,游戏中相应的音效
    精灵类,游戏中存在的人物形象,人物所存在的动画效果以及所拥有的特效;以及人物所产生的相应效果,满足相关的游戏性
    金币类,实现金币与人物的交互功能,实现金币的基础算法
    新增素材:下载了一些简单的人物素材和音乐背景,准备先做一个demo,再具体改
    本周遇到的问题 对GUI用户界面的一些方法还不是很熟悉
    写精灵的过程中出现精灵不能随着操作的指令做相应的动作,系统指令无效,无法实现交互。通过查阅资料以及不断地改进尝试终于发现了监听器出现了问题,最终改变监听器的错误,得到改进,精灵可以完成用户想让其进行的各种动作
    在创建金币类的过程中,出现了程序错误,不能正常实现金币的产生,后来经过debug发现是由于金币数组越界产生的,随后改变数组的定义,得到解决

    第三周

    本周完成了map背景类,将从网上搜集的图片元素加入界面中,实现界面的设计,实现界面可以随着指令发生移动而完成相应功能; 精灵碰撞类,实现精灵与地图元素的交互功能,当精灵与元素进行碰撞之后,实现相应的动画效果
    数据文件及数据库文件还未全部进行加入。正在设计基本类
    素材:像素小人已经初步捏好。从而实现创建了精灵类
    音效已经找好并自己录制了一部分。实现了音效类
    增强了小组成员的之间的融合。经过美工的PS设计,使得我们的界面更加的好看更加的友好。同时增加了交互的功能设计,比如调节音量等。下一步准备增加更多的交互式设计,实现更多的功能选择比如调节速度调节难度等等

    第四周

    进一步优化界面,加强人机交互的功能。人物素材也进行了修改,准备动作、前进动作、跳跃动作等等都进行了讨论并由美工进行了进一步的制作和修改。基本实现了游戏算法类和动画类
    游戏的完整体系已经基本完成了,大体框架已经形成,接下来进行细节处的改动即可。加入游戏开始页面以及游戏流畅性。游戏的开始界面已经结合我们的具体的功能进行了设计,并进行了编写和实现
    在编写动画类的时候出现了动画编程中的动画闪烁和图像残缺不全等现象,后来我们从网上发现是多线程的部分方法出现了问题。为了每秒中多次更新屏幕,必须创建一个线程来实现动画的循环,这个循环要跟踪当前帧并响应周期性的屏幕更新要求。应该生成一个独立的动画线程来完成图像的显示和更新。并改变了一些其他的方法,进一步优化我们的动画效果
    在编写游戏算法类的时候,具体的算法可能还是考虑的不够清楚,常常出一些运行中的错误或者出现编写的某段代码对整个项目无效的情况。经过仔细的思考逐步解决了这些问题
    初步根据我们的系统设计,写了一个游戏的思路以及规则方法
    大体的文案已经形成。

    第五周

    进一步优化界面,加强人机交互的功能。人物素材也全部完成,包括各种行进跳跃动作。把美工所有捏的小人都增加到程序中去了。正式更新了部分的原创设计。使整个界面更加人性化有设计性
    讨论设计了游戏的开始界面及结束界面并进行开发。结合内部的具体构造进行设计,力求准确美观实现各种功能.对人物进行了进一步的修改。逐渐与原来的想法进行拟合。制作开始和结束界面的时候总是有不协调性看起来很奇怪,并且有些想法无法实现。经过不断地努力和修改逐渐解决了这些问题。开始和结束界面初步成型。再做微型调整即可

    第六周

    Javadoc进行了部分修改,因难以全部传输上去,此处仅提供大体的构架和截图,我们在其内部进行了具体的修改
    所做的项目测试工作。项目总体进度
    仍存在的问题,及待提高的方面
    还有一些在测试时发现的问题没有解决,接下来需要大家一起解决代码中的bug,共同解决游戏进行的过程中出现的种种问题,种种影响游戏顺利进行或者不流畅的画面等等问题

    第七周

    本阶段的工作主要是项目的系统收尾工作
    正在进行文档的修改和最终总结报告的书写工作
    更改了一些界面上面的设计。进行系统的最终完善
    比如设计了一些夜间场景。最终的成果的效果还没有最终确定。正在进行不断地比较和修改。开始画面希望能更加完善。还未添加帮助等功能,接下来会进一步添加,尽可能的完善。尽早的提交上我们的作品
    界面、美工、素材的美化。正在进行更改。美工正在进行对素材的梅美化。以求我们的界面更加的美观并且实用,符合我的们的设计的整体风格和思路。下附我们目前的界面,当然我们还会进行不断地改善和调整

    4. 美工素材整体游戏使用了扁平化设计理念。扁平化概念的核心意义是:去除冗余、厚重和繁杂的装饰效果。而具体表现在去掉了多余的透视、纹理、渐变以及能做出3D效果的元素,这样可以让“信息”本身重新作为核心被凸显出来。同时在设计元素上,则强调了抽象、极简和符号化。模拟现实物品的造型和质感,通过叠加高光、纹理、材质、阴影等效果对实物进行再现,也可适当程度变形和夸张,界面模拟真实物体,拟物设计会让你第一眼就认出这是个什么东西。交互方式也模拟现实生活的交互方式。简约而不简单,搭配一流的网格、色彩设计,让看久了拟物化的用户感觉焕然一新;突出内容主题,减弱各种渐变、阴影、高光等拟真视觉效果对用户视线的干扰,让用户更加专注于内容本身,简单易用。设计更容易,优秀扁平的设计只需保证良好的架构、网格和排版布局,色彩的运用和高度一致性。
    在色彩搭配方面,颜色是影响整个游戏的重要因素,不同的颜色对人的感觉有不同的影响。整体颜色采用了冷色调, 多为蓝、绿等。游戏主人公使用了与背景有鲜明对比的红、橙。建筑物使用了传统的灰色调,制作了具有使其与背景整体协调。通过对游戏的各种元素、颜色、字体、图形、空白等,使用一定的规格,使得设计良好的游戏看起来应该是和谐的。游戏设计上要保持一致性,这又是很重要的一点。一致的结构设计,可以让浏览者对游戏的形象有深刻的记忆。一致的背景界面设计,可以让浏览者迅速而又有效的进入在软件中自己所需要的部分,一致的操作设计,可以让玩家快速地了解、上手游戏。建筑风格上参考纪念碑谷,给玩家带来新鲜的感觉。



    5. 收获体会以往几周的实验报告摘要
    第一周结论分析与体会:

    每一个项目的进行都需要具体的执行方案和具体的分工合作。
    好的创意和构思往往来源于生活。
    在做一个项目之前应该先想好具体的框架及模板模块,以防真正执行起来的时候出现种种难以预料的问题。
    任何创意的背后都需要强大的技术支持和不断地学习,经验的积累。

    第二周结论分析与体会:

    学习的过程是艰苦的迂回的,所有的代码都不是能够突然写出来突然完成的。
    不能太急于求成,从小的方面一点点的进行,最终实现整个类的实施,才是比较可行的方法。学习的过程是必须的,不能急躁。
    在一些容易出错的地方比如数组超界之类的问题要一开始就多加注意。写代码的时候要有给每一个模块增加注释的习惯,这样遇到问题的时候比较好随时回来改。
    debug的时候要有耐心,一遍遍的进行调试更改,不能急躁。
    要懂得合作。合作的力量是无穷的!

    第三周结论分析与体会:

    每一个程序的实现不能只是简单地大体的做一下,必须要考虑要多种因素的影响,考虑到用户的游戏时的视觉感官体验等等。
    增强游戏的功能,提供更多的交互功能。在游戏过程中能够随时进行调节。
    每一个项目的进行都需要经过不断的调试不断的改进,前面做的某些东西要根据实际的项目发展进行改变。制定目标时不能定死。多做一些动态方法。有利于项目的进行。
    想法也要尽可能完善,尽量在初期考虑到后面的可行性。

    第四周结论分析与体会:

    必须要考虑要多种因素的影响,考虑到用户的游戏时的视觉感官体验等等。
    每一个项目的进行都需要经过不断的调试不断的改进,前面做的某些东西要根据实际的项目发展进行改变。制定目标时不能定死。多做一些动态方法。有利于项目的进行。
    有了大体的框架可能更有利于下面的进一步细节的改动,有些细节不用太过拘泥,可以形成基本框架之后再进行改动。要有整体意识。

    第五周结论分析与体会:

    每一个项目的进行都需要经过不断的调试不断的改进,前面做的某些东西要根据实际的项目发展进行改变。制定目标时不能定死。多做一些动态方法。有利于项目的进行。
    有了大体的框架可能更有利于下面的进一步细节的改动。

    第六周结论分析与体会:

    必须要考虑要多种因素的影响,考虑到用户的游戏时的视觉感官体验等等。
    游戏基本完成时其测试的安排十分重要,包括测试的规划,如何进行,部署,怎么样才能发现更多的问题并且进行解决,发现问题的时候又应该如何解决,对我们来说都是一些挑战。测试前要事先做好规划,并且测试进行的过程中发现的问题要及时记录并想办法解决。

    第七周:结论分析与体会:

    每一个游戏的完成都是艰难的,只有坚持到底,不断地学习不断地进步才能实现最后的成功。
    在今后的学习生活中还要不断培养自己的自学能力,遇到各种困难都不能退缩。逐步增强自己解决问题的能力。

    最终总体体会:
    课设的构想是美妙的,但是真正做起来却是困难的。从组队确定好主题到现在我们遇到了很多很多的困难。刚开始的时候什么都不懂,经过上学期的学习,对于GUI、多线程等等就只是听说过,一点也不懂,难以想象这样的我们有一天会做出这样一个比较完整的作品。回过头来想想走过的路真是感慨万千。经过了课程设计的锻炼,我们总结出了以下这样的几个经验或者说是体会。

    首先,对于任何事物都要有一个总体的规划。对于大体要做成什么样子,必须有一个整体的规划并且向着那个明确的目标努力,不能无组织的随便乱写。必须有了正确的明确的大方向的指引,才能不断的朝这个目标努力并且最终实现。
    其次,任何事物的完成要有扎实的基本功做基础。像刚开始的我们什么都不懂。在游戏的编写过程中我们也吃了很多苦。上课的时候认真听讲做笔记,下课之后课下也要不断地对代码进行研究,研究各种资料。我们都深切的感受到,没有深厚的技术基础做保障,所有的都是空谈。
    实践出真知。很多时候只是上课好像听懂了或者是看视频看懂了其实真正自己敲起来的时候还是觉得很困难,出现了很多的bug,也都得一点点的去改,有时候很多bug发现不了也改不出来的时候特别烦躁,不过也得耐心一点点看。可以说在这个过程中我们每个人都吃了很多苦,不过也正因为这个过程我们的能力也得到了很大的提高,从一开始的什么都不会到现在的可以完成一个完整的游戏,这对我们来说已经是巨大的飞跃和提高。在这个过程中我们极大的锻炼了自己的自学能力。
    团队的力量是无穷的。自己一个人完成一个大的任务可能是困难的,但是有了小组的合作,有了大家的齐心协力任何困难都会被解决的很好。
    我们的代码可能还比较幼稚比较简单,但是我们已经付出了很多努力,不管多难,都能努力咬牙坚持去学习去尝试去自己写,而不是简单地copy网上的或者别人的代码。正因为有了这样的毅力有了这样的决心才会有进步才会有提高。我们也知道我们的能力还不足,我们也还有很大的进步的空间。在以后的学习中,生活中,我们还会继续努力,课程设计虽然即将告一段落,但是我们的学习之路还远远没有结束,将来的路还很长。我们会永远记得这段努力完成课设的时光,并继续加油、继续努力。向着我们的未来向着我们的目标不断迈进。
    2 评论 8 下载 2019-06-24 14:10:51 下载需要15点积分
  • 基于C语言的二叉树遍历

    一、实验要求1.1 实现功能在采用链式存储结构存储的二叉树上,以bt指向根结点,p指向任一给定的结点,编程实现求出从根结点bt到给定结点p之间的路径。
    1.2 设计要求typedef struct node{ char data; //数据域 struct node *lchild , *rchild; //左右孩子指针}BinTNode, *BinTree; //树中结点类型
    首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。
    程序运行后,给出如下菜单项的内容和输入提示,使用数字0—7来选择菜单项,其它输入则不起作用:

    1.建立二叉树存储结构
    2.输出二叉树的形态
    3.求二叉树的先序遍历
    4.求二叉树的中序遍历
    5.求二叉树的后序遍历
    6.求二叉树的层次遍历
    7.求给定结点的路径
    0.退出系统

    二、实验步骤2.1 程序流程图2.1.1 主函数流程图
    2.1.2 CreateBiTree函数流程图
    2.1.3 PreOrderTraverse函数流程图
    2.1.4 InOrderTraverse函数流程图
    2.1.5 PostOrderTraverse函数流程图
    2.1.6 LevelOrderTraverse函数流程图
    2.1.7 Path函数流程图
    2.2 主函数源代码#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX 100 //队列最大长度typedef struct node{ char data; //数据域 struct node *lchild , *rchild; //左右孩子指针}BinTNode, *BinTree; //树中结点类型typedef struct { BinTree* base; int front; int rear;}Quene; //队列结构 void CreateBiTree(BinTree &bt); //建立二叉树存储结构void OutputBiTree(BinTree bt); //输出二叉树的形态void PreOrderTraverse(BinTree bt); //求二叉树的先序遍历void InOrderTraverse(BinTree bt); //求二叉树的中序遍历void PostOrderTraverse(BinTree bt); //求二叉树的后序遍历void LevelOrderTraverse(BinTree bt); //求二叉树的层次遍历void Path(BinTree T, BinTree bt, char data, char* path, int &i); //求给定结点的路径void InitQuene(Quene &q); //创建队列int LengthQuene(Quene q); //计算队列长度void EnQuene(Quene &q, BinTree e); //进队void DeQuene(Quene &q, BinTree* e); //出队void getQuene(Quene q, BinTree* e);void printSpace(int n); //打印n个空格void main(){ BinTree bt; while(1) { int choice; printf("请选择功能:\n"); printf("1.建立二叉树存储结构\t2.输出二叉树的形态\n"); printf("3.求二叉树的先序遍历\t4.求二叉树的中序遍历\n"); printf("5.求二叉树的后序遍历\t6.求二叉树的层次遍历\n"); printf("7.求给定结点的路径\t0.退出系统\n"); scanf("%d", &choice); switch(choice) { case 1: getchar(); CreateBiTree(bt); break; case 2: OutputBiTree(bt); break; case 3: PreOrderTraverse(bt); break; case 4: InOrderTraverse(bt); break; case 5: PostOrderTraverse(bt); break; case 6: LevelOrderTraverse(bt); break; case 7: { printf("请输入要查找的节点数据:"); char ch; getchar(); scanf("%c", &ch); char path[50]; //用于存储路径(倒置),最后倒置输出path BinTree T = bt; int i = 0; Path(T, bt, ch, path, i); printf("从根结点到达该结点的路径为:"); for (int j = i - 1; j >= 0; --j) { printf("%c", path[j]); } break; } case 0: return; default: printf("输入数字错误\n"); } printf("\n"); }}
    2.3 运行结果截图2.3.1 主函数运行结果
    2.3.2 CreateBiTree函数运行结果
    2.3.3 PreOrderTraverse函数运行结果
    2.3.4 InOrderTraverse函数运行结果
    2.3.5 PostOrderTraverse函数运行结果
    2.3.6 LevelOrderTraverse函数运行结构果
    2.3.7 Path函数运行结果
    三、总结与体会在这几节实验课上,让我有机会将理论课上的一些知识真正地运用起来,将课本上的伪代码实现为C语言代码。通过这些实验题目,让我感受到理论知识和实际应用还是有一些区别,在学习数据结构的过程中,光学习理论知识是不够的,更重要的是自己动手实践,这样才能更好的理解知识并学会运用。
    该实验让我更好地理解了二叉树三种遍历的递归实现和层次遍历的原理。在完成这这个程序的过程中也遇到一些困难,二叉树不会寻找搜索路径。在遇到问题时我回顾了课堂上讲的内容,并充分利用VC6.0的调试功能,最终独立解决了这些问题。
    1 评论 1 下载 2019-10-02 11:45:11 下载需要6点积分
  • 基于Face++的人脸融合及换脸系统

    1.项目介绍在本项目中,我们实现了对人脸图片数据的三种处理:人脸互换(face swap)、人脸融合(face morph)以及基于特征向量的人脸处理(eigen face)。
    1.1 人脸互换(face swap)人脸互换部分主要实现的功能是,给定任意两张人脸图片,通过一系列操作,使两个人的脸部交换,这部分需要的问题有:

    不同的人的脸部结构千差万别,同一个人也会因为角度、面部表情的不同而导致差别,即如何实现不同图片的人脸对齐
    不同人脸的肤色、光照不同,即不同图片的面部亮度不同,在换脸后如何与整体亮度统一
    不同人脸的纹理不同,比如老人的皱纹等,如何实现换脸后纹理的统一

    1.2 人脸融合(face morph)在人脸融合部分,我们需要实现给定任意两张人脸图片和融合度α,通过一系列操 作,实现两个人脸的融合。这一部分的困难在于:

    人脸结构的检测与分割。对于给定的人脸图片,人脸的结构差异很大
    人脸融合度的构建。对于给定的融合度 α,如何对两张图片的人脸取样与映射

    1.3 本征脸(eigen face)在这一部分,需要对较大的数据集(几百张,几千张人脸图片)进行处理,通过主成分分析的方法,得到一定数量的人脸主成分。这一部分的主要困难在于数据集的预处理,我们需要将不同图片中的人脸对齐,才能进行后续的处理。
    2.算法结构与处理过程2.1 人脸变换2.1.1 人脸关键点检测实现人脸变换的第一步,便是人脸关键点的检测,得到图片中的人脸的结构。在这 里,我们利用旷视face++的API来定位人脸关键的集合{V1,V2,…,Vn},其中关键点的数量可 以选择 83 或者 106。
    左:人脸关键点与凸包;右:德劳内三角集。

    2.1.2 计算凸包在获取人脸关键点集合后,我们需要计算这些关键点的凸包(convex hull)(凸包是一个计算几何(图形学)中的概念:在一个实数向量空间 V 中,对于给定集合 X,所有包含 X 的凸集的交集 S 被称为 X 的凸包。X 的凸包可以用 X 内所有点(X1,…Xn)的凸组合来构造.)在这里,我们计算凸包是为了获取这些人脸关键点组成的一个人脸区域。
    2.1.3 德劳内(Delaunay)三角划分在获得凸包以后,我们对凸包内的人脸关键点进行德劳内三角的划分。德劳内三角划分能将我们的凸包区域进行分割,并且更易于保留人脸的细节部分,并且因为获取仿射变换需要原图片和目标图片的各三个点,正好对应于原图和目标图的对应的德劳内三角。
    2.1.4 进行仿射变换在获得原图片和目标图图片的德劳内三角以后,我们需要寻找两张图对应的三角形对,对这样的每一对三角形,我们可以计算得到一个仿射函数。这个仿射函数将被用于三角形对之间的仿射变换。重复这个操作,直到所有区域都操作完毕,我们得到了人脸的位置变换。
    2.1.5 无缝融合在上述人脸仿射变换后,我们得到人脸结构和位置的变换,但我们没有对人脸区域亮度进行调整,这样会造成人脸区域和其他区域的颜色协调的问题。所以最后我们用 opencv 的无缝融合函数 seamlessClone()来实现无缝融合操作。
    2.2 人脸融合2.2.1 人脸关键点检测和 2.1.1 部分一样,我们首先需要确定给定图片的人脸的结构,所以需要检测人脸的关键点。在这里我们仍然使用旷视 face++的人脸关键点识别 API,选择 108 点检测。
    2.2.2 定义融合度要实现两张人脸的融合,我们还要定义融合度 α(0=<α<=1):

    M 是融合后的图像,I,J 是两张待融合图像。我们定义 α,使 α 趋于 0 使,越来越接近图 像 I;α 趋于 1 时,越来越接近图像 J;α 等于 0.5 时,相当于两张图像的平均。
    2.2.3 采样点加权在获得两张人脸的关键点后,我们再对两张人脸进行加权平均:

    通过这个式子,我们计算加权后的人脸关键点的位置。
    左:采样点加权后的人脸结构;右:德劳内三角划分。

    2.2.4 德劳内三角划分如同 1.1.3,我们对获取的人脸关键点进行德劳内三角划分,不同的是,我们为了获取人脸框架结构在整张图中的位置,需要手动添加图片四个角以及四边中心点作为辅助点,再进行德劳内三角划分。这样,我们就得到非常详细的人脸结构。
    2.2.5 图像融合在经过以上步骤后,我们进行人脸融合。首先,我们对源图像的人脸关键点对我们在 2.2.3 中得到的加权后的人脸关键点进行仿射变换。由对应的德劳内三角形确定的三个点,我们可以确定一个仿射变换;对所有的三角形进行这样的操作,我们就得到了仿射后的人脸图片。对两张源图进行这样的操作,我们就得到两个仿射后的人脸图片,再运用我们定义的融合度 α 进行加权平均,最终得到我们的目标图片。

    2.3 本征脸2.3.1 数据预处理此次我们用于测试的数据集有两个,一个是 NBA 现役球员,另一个是女外女明星。对于我们的人脸图片数据集,我们首先要做的是将它们的大小固定为统一的大小。然后,我们需要将每张人脸配准定位,一个方法是将每张图片的人的眼睛定位于同一水平线上,并且使每张图片的两眼中心点在相同的位置。
    2.3.2 主成分分析在预处理图片后,我们对图片的数据进行主成分分析。首先,对于每张 NxN 大小的图片,我们将其转化成一个(NxNx3)x 1 的向量。当有 M 张图片时,我们便有一个(NxNx3)x M 的矩阵。
    在计算主成分之前,我们先来对我们的图片矩阵数据求平均值向量,这是为了后面的方差和协方差准备的。在获取了平均值向量之后,我们来计算主成分。在数数学上,我们通过线性代数中的矩阵特征值分解,可以找到矩阵的特征值和相应的特征向量,我们将这些特征值按从大到小排列,越大的特征值说明数据在这个特征值对应的特征向量的方向上 的方差越大,这就是我们要找的主成分。在这里,我们可以设置参数,来选择主成分的数量。例如,我们选择前十大的特征值和对应的特征向量。
    2.3.3 获得本征脸在获得主成分之后,我们将选取的主成分矩阵,按原来图片矩阵转化为向量的逆操 作,将矩阵变成图片矩阵。
    3.代码结构3.1 人脸互换相关文件:faceswap.py

    get_points 函数。用于封装好 Face++的 API,得到图片的 83 个人脸特征点,并存储在一个列表当中,方便后续处理
    AffineTransform 函数。该函数输入源图、源图的德劳内三角、目标图的德劳内三角和给定的大小。通过计算获取仿射变换函数,并且进行仿射变换,输出变换后的图片
    DelaunayTriangles函数。用于计算我们人脸关键点的德劳内三角。我们应用openCV的Subdiv2D 函数,可以得到我们的德劳内三角
    warpTriangle 函数。通过德劳内三角的划分,我们定义这个函数,用来实现对德劳内三角的仿射变换,并且最终将左右变换后的三角形区域合并,得到我们的目标脸
    最后是主函数,调用这些定义好的函数,读取我们的图片进行处理

    3.2 人脸融合有关文件:morph.py

    detect 函数。用于封装好 Face++的 API,得到图片的 108 个人脸特征点,并存储在一个字典当中,方便后续处理
    addBorderPoints 函数。该函数功能是给处理图片准备要划分三角形的时候,把图片四个顶点和四条边的中点的坐标添加到带划分的点中,这让得劳内三角形能完整的划分 整张图片
    delaunaryTriangles 函数。由特征点的坐标生成其用来划分这些特征点的得劳内三角形
    affineTransform 函数。根据划分好的三角形,我们可以用来计算一张图的三角形到另外一张图所对应的三角形的仿射变换,该函数在 morphingTriangle 函数中使用
    morphingTriangle 函数。对两个仿射后的人脸图片,运用我们定义的融合度 α 进行加权平均,最终得到我们的目标图片


    morphing 函数。总的融合函数的接口,得到融合图片的脸部特征点的坐标,与新图片的脸部划分三角形坐标,调用 morphingTriangle 函数得到新的融合图片
    getPic 函数。用于实现 GUI 中根据 alpha 生成一张图片的功能
    get20Pics,create,sortKey,createGIF 函数。用于实现 GUI 生成一张 gif 图片的功能

    3.3 本征脸人脸相关文件:eigenface_origin.py

    readImages 函数。从指定的文件夹中读取图片文件,将其转化成 numpy 矩阵,放到一个 list 中。在此过程中,每张图片翻转后又保存了一次
    createdatamatrix 函数。将保存图片的 numpy 矩阵压平。(每张图片压平)
    createnewface 函数。产生特征脸并且用 opencv 可视化界面展示
    resetslidervalues 函数。在 opencv 可视化界面中,点击一下图片,就重置所有 bar
    总体思路:从文件夹中读取图片,变成矩阵,每张图片 flatten,用求平均向量,特征向量,再计算出 eigenface。

    3.4 GUI 部分有关文件:

    mainPage.py 主界面 GUI
    morphGUI.py 融合脸功能界面 GUI
    swapGUI.py 换脸功能界面 GUI
    eigenGUI.py 特征脸界面 GUI

    4.开发环境在本次项目中,算法几接口 API 都是由 pyhton3.5(python3.6)完成的,其中还使用了openCV 库。GUI 使用 pyqt 完成。API 使用 face++人脸关键点接口。
    5.可执行文件及使用的数据集5.1 数据集我们有 2 个数据集,其中一个 image_swap 是用于测试换脸操作的;另外一个 image_eigen 数据集是用来测试本征脸的,是 NBA 现役球员的图片。人脸融合测试图片,一定要是放在与该py文件夹中相同的文件夹,所以没有专门的数据集,可以从其他地方复制一些图片,进行测试。
    5.2 可执行文件及运行方式在 windows 下,我们有可执行文件 face#.exe。执行方式:双击打开,会看到我们 GUI 的初始界面。在界面中我们会看到三个按钮,这是我们 GUI 实现的三个功能,及人脸互换、人脸融合和本征脸。点击其中一个按钮,会进入下一层界面,具体的操作可以参考我们附加提交的操作演示视频。




    在 macOS 系统下,可以通过 python 文件名.py 命令运行我们的 python 文件。
    6.项目成果与反思6.1 项目成果6.1.1 人脸互换
    从测试结果图中,我们可以看到,我们的人脸互换效果还是非常好的:从前景图上截取的脸部,能够非常好地与背景图融合;在边缘部分,没有明显的边界;在人脸的姿势上,也根据背景的姿势得到了调整,能够与背景姿势相一致。当然我们也可以看到,在第二个结果中,由于前景脸和背景脸的脸部颜色相差太大,导致结果图中的脸部与额头等地方有明显的不一致,这是因为我们在做人脸互换的时候,只根据人脸关键点确定的凸包进行变换,而人脸关键点是没有包含额头及脖子部分的。这是我们人脸互换做的不好的地方
    6.1.2 人脸融合
    同样,对于我们人脸融合的结果,也非常好。在它融合度为 0.5 的情况下,包含了两张源图中一样多的特征,让我们能在结果图中能找到明显的属于两张源图的特征。但是同样存在一些问题,比如在上面一张结果中,我们可以看到头发部分有重影。这是因为两张源图片的头发差异部分存在白色的背景,当进行融合时,由于有两部分的特征,所以会造成重影;但是第二张结果图中,我们没有看到这个现象,这是因为两张源图的差异部分没有很白的背景颜色。
    6.1.3 本征脸
    对于我们的本征脸,我们在此解释一下左侧拖条的含义:首先我们这部分是对人脸数据集进行主成分分析,所谓的主成分就是数据中方差最大的一些方向,对应到人脸数据中,便是影响数据集中人脸的形态的最大的方向,或者说数据集中人脸变化最大的一些特征。比如,NBA 球员数据集中,球员的肤色有黑有白,这是变化非常大的特征,所以应该会有一个主成分只指向球员肤色的黑白的。而之所以右侧的结果会很模糊,正是因为我们计算出的主成分代表了人脸数据集中变化最大的特征,所以这些特征组成的图片必定是非常模糊非常不整齐的。
    6.2 项目思考与改进6.1.1 人脸互换我们的人脸互换算法依赖于人脸关键点锁定的区域,基本上限定于眉毛-两侧脸颊-下巴组成的区域,当两张源图的脸部颜色差别很大时,会出现结果图中脸部与额头差别很大的问题。所以,我们设想后续的优化是,将脸部的区域扩大到额头,乃至整个脖子,但是由于一般人脸检测的算法只限于原先的区域,如何检测这些扩展的区域,是一个较难解决的问题。
    6.1.1 人脸融合对于人脸融合中出现的结果图中脸部区域以外的重影问题,我们设想的优化是,将脸部以外的区域,全部设置成其中一张源图的背景区域。
    6.2.3 本征脸对于主成分分析得出来的若干个对人脸变化影响最大的特征,其中一些我们能够直观地看出来,例如肤色的黑白等,但有一些特征并不能很容易地得知与什么相关,需要我们进一步测试、观察与分析。
    2 评论 20 下载 2019-05-24 10:28:03 下载需要11点积分
  • 基于JAVA和SQL SERVER数据库实现的医院病房信息管理系统

    1 系统设计1.1 设计目标医院病房管理系统是一种以窗体界面为基础的多功能平台,本系统最根本的目的是让使用者与数据库能够通过系统达到交互,以此来进行医院病房的管理等相关操作。管理员可以通过该平台对医生、病人、科室、病房、病床进行增加、删除、修改、查询操作,普通用户可以通过该平台查看修改自己的个人信息、进行病人住院登记、查询病人和床位信息、根据病人的住院日期、出院日期和所住病房的收费标准进行出院结算,然后删除该病人的信息。本系统在全面提高医院的整体工作效率、为病人提供快捷的服务、为医生提供人性化的管理、减轻医院工作人员的负担等方面发挥着重要作用。
    1.2 需求分析信息要求:医生基本信息包括工作证号、密码、姓名、性别、职称、年龄、联系电话、所属科室,病人基本信息包括病历号、姓名、性别、诊断结果、病房号、病床号、主治医生工作证号、联系电话、入院日期、出院日期,科室基本信息包括科室名称、科室地址、科室电话,病房基本信息包括病房号、所属科室、收费标准,病床基本信息包括病房号、病床号、目前状态。
    处理要求:一名医生可以诊治多名病人,一名病人只能被一名医生诊治。一个病房可以住多名病人,一名病人只能住在一个病房。一个科室有多名医生,一个医生只属于一个科室。一个科室包含多个病房,一个病房只属于一个科室。一个病房拥有多张病床,一个病床只能位于一个科室。
    安全性与完整性要求:管理员和医生只有输入正确的工作证号和密码才能登录系统,如果还没有注册,先输入相关信息进行注册。对于管理员,管理主页列出了管理员所能实现的功能,包括对医生、病人、科室、病房、病床的增加、删除、修改、查询,管理员根据需要选择对应的项目。对于用户,即医生,管理主页列出了医生所能实现的功能,包括查看修改自己的个人信息、登记病人基本信息、查询病人和床位信息、根据病人的住院日期、出院日期和所住病房的收费标准进行出院结算,然后删除该病人的信息。为了保证系统的安全性,系统提供对工作证号和旧密码的验证,来修改登录密码。
    1.3 开发和运行环境选择
    开发工具:前台开发语言为Java编程语言
    后台数据库为SQL Server 2014
    运行环境:Windows 10

    2 数据库设计2.1 数据库概念设计根据需求分析,可以确定该系统中的实体、属性和联系之间的关系,并画出如下所示的E-R图。
    实体及属性如图2.1所示。

    病人实体及属性如图2.2所示。

    科室实体及属性如图2.3所示。

    病房实体及属性如图2.4所示。

    病床实体及属性如图2.5所示。

    由该项目的处理需求可知,“医生”和“病人”之间的“治疗”联系为1:n,即一名医生可以诊治多名病人,一名病人只能被一名医生诊治。“病房”和“病人”之间的“入住”联系为1:n,即一个病房可以住多名病人,一名病人只能住在一个病房。“科室”和“医生”之间的“属于”联系为1:n,即一个科室有多名医生,一个医生只属于一个科室。“科室”和“病房”之间的“包含”联系为1:n,即一个科室包含多个病房,一个病房只属于一个科室。“病房”和“病床”之间的“拥有”联系为1:n,即一个病房拥有多张病床,一个病床只能位于一个科室。系统的实体联系图,如图2.6所示。

    2.2 数据库逻辑结构设计2.2.1 关系模式根据转换规则和医院病房管理系统E-R图,可以得到医院病房管理系统的关系模式如下。
    医生(工作证号、密码、姓名、性别、职称、年龄、联系电话、所属科室)为医生实体对应的关系模式,其中工作证号是主码,科室的主码科室名称是医生的外码。
    病人(病历号、姓名、性别、诊断结果、病房号、病床号、主治医生工作证号、联系电话、入院日期、出院日期)为病人实体对应的关系模式,其中病历号是主码,医生的主码工作证号是病人的外码属性,病床的主码病房号、病床号是病人的外码属性。
    科室(科室名称、科室地址、科室电话)为科室实体对应的关系模式,其中科室名称是主码。
    病房(病房号、所属科室、收费标准)为病房实体对应的关系模式,其中病房号是主码,科室的主码科室名称是病房的外码。
    病床(病房号、病床号、目前状态)为病床实体对应的关系模式,其中病房号、病床号是主码。
    2.2.2 结构设计表医生结构设计表如表2.1所示。

    病人结构设计表如表2.2所示。

    科室结构设计表如表2.3所示。

    病房结构设计表如表2.4所示。

    病床结构设计表如表2.5所示。

    2.2.3 数据字典数据项描述如表2.3所示。

    数据结构描述如表2.4所示。

    3 医院病房管理系统详细设计3.1 系统功能医院病房管理系统主要分为用户模块和管理员模块(分为医生、病人、科室、病房、病床信息增删改查功能)。其中用户模块包括查看修改自己的个人信息、进行病人住院登记、查询病人和床位信息、根据病人的住院日期、出院日期和所住病房的收费标准进行出院结算,然后删除该病人的信息。管理员模块包括对医生、病人、科室、病房、病床进行增加、删除、修改、查询操作。
    3.2 数据库以及表的建立医院病房管理系统数据库中包含五张表,分别为医生(Doctor)、病人(Patient)、科室(Department)、病房(Ward)、病床(Bed),相关代码如下。
    CREATE TABLE Doctor (Dno CHAR(10) PRIMARY KEY, Dpassword VARCHAR(15) NOT NULL, Dname CHAR(20) NOT NULL, Dsex CHAR(2) NOT NULL, Dtitle CHAR(10) NOT NULL, Dage SMALLINT NOT NULL, Dtel CHAR(11) NOT NULL, Deptname CHAR(20) NOT NULL, FOREIGN KEY(Deptname) REFERENCES Department(Deptname) );CREATE TABLE Department (Deptname CHAR(20) PRIMARY KEY, Deptaddress CHAR(20) NOT NULL, Depttel CHAR(11) NOT NULL );CREATE TABLE Ward (Wno CHAR(9) PRIMARY KEY, Deptname CHAR(20) NOT NULL, Wcharge INT NOT NULL, FOREIGN KEY(Deptname) REFERENCES Department(Deptname) );CREATE TABLE Bed (Wno CHAR(9), Bno CHAR(9), Bstate CHAR(20) , PRIMARY KEY(Wno,Bno), FOREIGN KEY(Wno) REFERENCES Ward(Wno) );CREATE TABLE Patient (Pno CHAR(10) PRIMARY KEY, Pname CHAR(20) NOT NULL, Psex CHAR(2) NOT NULL, Pdiagnose CHAR(20) NOT NULL, Wno CHAR(9) NOT NULL, Bno CHAR(9) NOT NULL, Dno CHAR(10) NOT NULL, Ptel CHAR(11) NOT NULL, Pindate DATE NOT NULL, Poutdate DATE , FOREIGN KEY(Wno,Bno) REFERENCES Bed(Wno,Bno), FOREIGN KEY(Dno) REFERENCES Doctor(Dno) );
    3.3 连接数据库连接数据库的代码及设置和连接操作的相关代码如下。
    package linkdatabase;package linkdatabase;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class linkdatabase { static Connection connection; public linkdatabase(){ //数据库驱动 String driverName="com.microsoft.sqlserver.jdbc.SQLServerDriver"; //连接的数据库 String url="jdbc:sqlserver://localhost:1433;DatabaseName=HWMS"; String user="sa"; String password="yyl13593519418"; //加载JDBC-MySQL数据库驱动 try { Class.forName(driverName); connection = (Connection) DriverManager.getConnection(url,user,password); System.out.println("数据库连接成功"); } catch(Exception e) { e.printStackTrace(); System.out.println("数据库连接失败:"+e.getMessage()); } } public static Connection getConnection(){ new linkdatabase(); return connection; } public void setConnection(Connection connection){ this.connection = connection; } public static void closeAll(ResultSet rs,PreparedStatement ps,Connection con){ if(rs != null){ try{ rs.close(); }catch(SQLException e){ e.printStackTrace(); } } if(ps != null){ try{ ps.close(); }catch(SQLException e) { e.printStackTrace(); } } if(con != null){ try{ con.close(); }catch(SQLException e){ e.printStackTrace(); } } }}
    3.4 登录系统登录系统为进入系统的首要操作,相关代码如下。
    package Hospitallogin;import java.awt.Button;import java.awt.Color;import java.awt.Cursor;import java.awt.Font;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import javax.swing.ImageIcon;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JTextField;import Doctorfunction.Main;import Hospitaladmin.admin_frame;import Hospitalresponse.Alter;import Hospitalresponse.Register;import geng.handle.HandleLogin;import geng.model.Login;import linkdatabase.linkdatabase;public class LoginFrame extends JFrame implements ActionListener{ String sql; Login login = new Login(); HandleLogin handleLogin = new HandleLogin(); JLabel l1 = new JLabel("欢迎登陆医院病房管理系统"); JLabel l2 = new JLabel("账号:"); JLabel l3 = new JLabel("密码:"); JLabel l4 = new JLabel("账号不存在!"); JLabel l5 = new JLabel("<HTML><U>"+"注册账号"+"</U></HTML>"); JLabel l6 = new JLabel("<HTML><U>"+"修改密码"+"</U></HTML>"); JTextField t1 = new JTextField(); JTextField t2 = new JTextField(); Button b1 = new Button("登陆"); Button b2 = new Button("取消"); public LoginFrame() { // TODO Auto-generated constructor stub //设置标题 super("欢迎登陆医院病房管理系统");//创建标题为欢迎登陆医院病房管理系统的窗口 setBounds(300,100,910,500);//设置窗口在屏幕上的位置及大小 String path = "lib/login.jpeg"; ImageIcon backgroundimage=new ImageIcon(path);//使标签有图片,用此创建背景图片 JLabel jLabel = new JLabel(backgroundimage);//标签为用户提示信息 jLabel.setBounds(0, 0, this.getWidth(), this.getHeight());//标签在窗口上的位置及大小 JPanel jPanel1 = (JPanel) this.getContentPane();//初始化一个内容面板,这样才可以把内容面板设置成透明的 jPanel1下面是我们要添加的图片,上面是我们的组件 jPanel1.setOpaque(false);//使组件不会显示其中的某些像素,允许组件下面的像素显现出来,即设置透明 jPanel1.setLayout(null); this.getLayeredPane().add(jLabel,new Integer(Integer.MIN_VALUE)); setVisible(true); // 登陆界面配置 l1.setBounds(450, 70, 450, 35); l1.setFont(new Font("宋体", Font.BOLD, 30)); l2.setBounds(470, 140, 70, 25); l2.setFont(new Font("宋体",Font.BOLD,23)); l3.setBounds(470, 200, 70, 25); l3.setFont(new Font("宋体",Font.BOLD,23)); l4.setBounds(120, 200, 150, 20); l4.setFont(new Font("宋体",Font.BOLD,23)); l5.setBounds(730,140,70,25); l5.setFont(new Font("微软雅黑",Font.BOLD,15)); l5.setForeground(Color.blue); l5.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); l5.addMouseListener(new Register()); l6.setBounds(730,200,70,25); l6.setFont(new Font("微软雅黑",Font.BOLD,15)); l6.setForeground(Color.blue); l6.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); l6.addMouseListener(new Alter()); t1.setBounds(540, 140, 160, 25); t1.setFont(new Font("宋体",0,18)); t2.setBounds(540, 200, 160, 25); t2.setFont(new Font("宋体",0,18)); b1.setBounds(540, 260, 70, 30); b1.setFont(new Font("宋体",0,15)); b1.addActionListener(this); b2.setBounds(660, 260, 70, 30); b2.setFont(new Font("宋体",0,15)); b2.addActionListener(this); super.add(l1); super.add(l2); super.add(l3); super.add(l5); super.add(l6); super.add(t1); super.add(t2); super.add(b1); super.add(b2); super.setLayout(null); super.setVisible(true); //当单击窗口右上方的关闭图标时,监视器调用windowClosing方法,如果在该方法中使用System.exit(0)退出程序的运行 super.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { // TODO Auto-generated method stub super.windowClosing(e); System.exit(0); } }); super.setResizable(false); } public static void main(String[] args) { // TODO Auto-generated method stub new LoginFrame(); } @Override //事件源触发ActionEvent事件后,监视器调用接口中的此方法对发生的事件做出处理 public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub Object source = e.getSource();//返回添加事件监听的对象 Connection con = null; PreparedStatement ps = null; ResultSet rs = null; if(source == b1) { String name = t1.getText(); String pass = t2.getText(); Login login = new Login(); login.setDno(name); try { con = linkdatabase.getConnection(); if("".equals(name.trim()) || "".equals(pass.trim())) { JOptionPane.showMessageDialog(null, "请输入完整的登陆信息!","系统提示",JOptionPane.ERROR_MESSAGE); }else if(name.equals("admin") && pass.equals("123456")) { new admin_frame(); super.dispose(); }else { login.setDno(name); login.setDpassword(pass); login = handleLogin.queryVerify(login); if(login.getLoginSuccess() == true) { System.out.println("登录成功了!"); new Main(login); super.dispose(); }else { System.out.println("登录失败了!"); JOptionPane.showMessageDialog(null, "登录失败,请重新登录","系统提示",JOptionPane.WARNING_MESSAGE); } } } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); }finally { linkdatabase.closeAll(rs, ps, con); } } if(source == b2) { System.exit(0); } }}
    4 系统测试以及界面4.1 订书单位信息查询测试测试注册账号,界面如图4.1所示。

    注册账号成功,结果如图4.2所示。

    4.2 病人出院结算测试进入病人出院结算界面,点击查询与结算,得出病人出院费用,结果如图4.3所示。

    结算出院成功,结果如图4.4所示。

    5 总结在本次数据库课程设计中,我设计开发了一个小型的医院病房管理系统,实现了对病人的住院登记、出院结算、信息查询,对医生信息、病人信息、科室信息、病房信息、病床信息的增加、删除、修改、查询的功能。设计过程中曾经遇到了不少难点和问题,如:将界面和后台数据库连接起来时出错;对数据库中信息操作时有时忽略了参照完整性;病人出院结算时无法调用数据库中存储的信息;页面间参数传递实现不了;还出现了一个语法错误,对一些控件的属性及方法不熟悉等。对于上述这些难点,我花了很多时间去解决,查阅数据库教材和理论课的课件、并借来相关书籍辅助学习,注意数据库中各个所建表的主外键约束,上网搜索也让我学到很多知识,还有些问题是与同学之间的相互讨论,最终将难点一一克服。
    3 评论 155 下载 2018-11-06 15:43:53 下载需要5点积分
  • 基于C语言的串模式匹配算法

    一、实验要求1.1 实现功能从主串中第K个字符起,求出子串在主串中首次出现的位置,即模式匹配或串匹配。
    要求用三种模式匹配算法分别实现:

    朴素的模式匹配算法(BF算法)
    KMP改进算法(Next[ ])
    KMP改进算法(NextVal[ ])

    1.2 设计要求首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。
    程序运行后,给出5个菜单项的内容和输入提示:

    1.输入主串、子串和匹配起始位置
    2.朴素的模式匹配算法
    3.KMP改进算法(Next[ ])
    4.KMP改进算法(NextVal[ ])
    0.退出管理系统

    请选择0—4:

    菜单设计要求:使用数字0—4来选择菜单项,其它输入则不起作用
    输出结果要求:输出各趟匹配详细过程(其中3、4,首先输出Next[ ]或者NextVal[ ]的各元素的数值),然后输出匹配总趟数、单个字符比较次数、匹配成功时的位置序号或者匹配失败提示信息

    二、实验步骤2.1 程序流程图2.1.1 主函数流程图
    2.1.2 Input函数流程图
    2.1.3 Output函数流程图
    2.1.4 getNext_val函数流程图
    2.1.5 Index_BF函数流程图
    2.1.6 Index_Next函数流程图
    2.1.7 Index_NextVal函数流程图
    2.1.8 getNext函数流程图
    2.2 主函数源码#include <stdio.h>#include <string.h>#include <stdlib.h>void Input(char* str1, char* str2, int* pos); //输入主串、模式串、匹配位置的函数void Index_BF(char* str1, char* str2, int pos); //朴素的匹配算法void Index_Next(char* str1, char* str2, int pos); //KMP算法void Index_NextVal(char* str1, char* str2, int pos); //KMP改进算法(NextVal[])void Output(char* str); //输出主串或模式串void getNext(char *str1, int* &next); //计算next数组的值void getNext_val(char* str2, int* &nextval);void main(){ int choice; char str1[1000]; char str2[100]; int pos; while(1) { printf("请选择功能:\n"); printf("1.输入主串、子串和匹配起始位置\n"); printf("2.朴素的模式匹配算法\n"); printf("3.KMP改进算法(Next[])\n"); printf("4.KMP改进算法(NextVal[])\n"); printf("0.退出管理系统\n"); scanf("%d", &choice); switch(choice) { case 1: Input(str1, str2, &pos); break; case 2: Index_BF(str1, str2, pos); break; case 3: Index_Next(str1, str2, pos); break; case 4: Index_NextVal(str1, str2, pos); break; case 0: return; default: printf("输入数字错误\n"); } }}
    2.3 运行结果截图2.3.1 主函数运行结果
    2.3.2 Input函数运行结果
    2.3.3 Index_BF函数运行结果
    2.3.4 Index_Next函数运行结果
    2.3.5 Index_NextVal函数运行结果
    三、总结与体会在该实验中,我实现了几种模式匹配算法,并通过程序输出匹配的过程,让我对课本上的理论知识有了更深层次的理解。
    这些程序还有些不完美的地方,可能有些算法实现地比较复杂,有些地方写出来之后不具有普遍性,只针对某种特殊情况。这些不完美的地方在之后我还会尽量修改。
    1 评论 2 下载 2019-09-29 07:20:02 下载需要6点积分
  • 基于C语言的单链表客房管理系统

    一、实验内容1.1 实现功能以带表头结点的单链表为存储结构,实现如下客房管理的设计要求。
    1.2 设计要求#include<stdio.h>#include<stdlib.h>#include<string.h>//定义客房链表结点结构typedef struct HNode{ char roomN[7]; //客房名称 float Price; //标准价格 float PriceL; //入住价格(默认值=标准价格*80%) int Beds; //床位数Beds char State[5]; //入住状态(值域:"空闲"、"入住"、"预订",默认值为"空闲") struct HNode *next; //指针域}Hotel, *HLink;

    实现创建客房信息链表函数void Build(HLink &H),输入(客房名称、标准价格、床位数),同时修改入住价格、入住状态为默认值,即入住价格=标准价格*80%,入住状态为”空闲”(提示:用strcpy()字符串拷贝函数)。为了提高程序调试效率,强烈建议:用文件操作来输入客房信息(客房名称、标准价格、床位数)
    实现输出客房信息函数void Exp(HLink H),输出所有客房的客房名称、标准价格、入住价格、床位数、入住状态
    函数int Find(HLink &H, char *roomN)),查找房间名称为roomN的客房。如果找到,则返回该客房在链表中的位置序号(>=1),否则返回0。提示:用strcmp()字符串比较函数
    实现函数void updateH(HLink &H, int beds, char *state),将床位数为beds的客房入住状态改为state。提示:用strcpy()字符串拷贝函数
    函数void Add(HLink &H),将该链表中未入住的客房入住价格均加价20%
    求出入住价格最高的客房函数HLink FirstH(HLink &H),该函数内return语句返回入住价格最高的客房结点指针,返回前将该结点在链表中删除
    函数void MoveK1(HLink &H, int k),将单链表中倒数第k个结点移到第一个结点位置,注意:严禁采用先计算链表长度n再减k(即n-k)的方法
    函数void ReverseN2(HLink &H),将单链表的正中间位置结点之后的全部结点倒置的功能,注意:严禁采用先计算链表长度n再除以2(即n/2)的方法
    函数void SortPriceL(HLink &H),按照客房(入住价格,客房名称)升序排序
    函数void upBed(HLink &H,int beds),创建一个【床位数为beds的新结点】(还需输入:客房名称、标准价格等信息),使链表的形态为:【头结点】->【床位数>beds的结点】->【床位数为beds的新结点】->【床位数<=beds的结点】,要求【超过beds的结点】和【不超过beds的结点】这两段链表中的结点保持原来的前后相对顺序
    主函数main()调用以上函数,(3)若返回值>=1则输出该客房在链表中的位置序号,否则输出该客房不存在;输出(4)~(10)处理后的链表内容,其中(6)还要输出入住价格最高的客房信息

    可能用到的函数:

    从文件中读取客房数据:fscanf(文件指针,”%s %f,%d”,p->roomN,&p->Price,&p->Beds);
    输出客房数据:printf(“%s%8.1f%8.1f%6d%8s\n”,p->roomN,p->Price,p->PriceL,p->Beds,p->State);
    字符串赋值函数:char* strcpy(char *, const char *);
    字符串比较函数:int strcmp(const char *, const char *)

    二、实验步骤按以上实验内容的要求,给出实验步骤,包括程序流程图、源程序和运行结果截图等。
    2.1 函数流程图2.1.1 主函数流程图
    2.1.2 Build函数流程图
    2.1.3 Exp函数流程图
    2.1.4 Find函数流程图
    2.1.5 updateH函数流程图
    2.1.6 Add函数流程图
    2.1.7 FirstH函数流程图
    2.1.8 MoveK1函数流程图
    2.1.9 ReverseN2函数流程图
    2.1.10 SortPriceL函数流程图
    2.1.11 upBed函数流程图
    2.2 main函数源代码void main(){ HLink H; int choice; Build(H); while (1) { printf("请选择使用的功能:\n"); printf("1.输出全部客房信息\t\t\t\t2.查找客房名称\n"); printf("3.更改指定床位数的客房的入住状态\t\t4.未入住的客房加价20%%\n"); printf("5.找到价格最高的客房\t\t\t\t6.倒数第k间房移动到第一间的位置\n"); printf("7.正中间客房之后的房间全部倒置\t\t\t8.按照客房(入住价格,客房名称)升序排序\n"); printf("9.创建新客房\n"); scanf("%d", &choice); switch (choice) { case 1: Exp(H); break; case 2: { printf("请输入要查找的客房名称:"); char name[7]; scanf("%s", name); int pos = Find(H, name); printf("客房名称为%s的房间在第%d个位置:", name, pos); break; } case 3: printf("请输入要更改的客房的房间数:"); int bed; scanf("%d", &bed); printf("请输入要更改的状态\n"); char state[5]; scanf("%s", state); updateH(H, bed, state); break; case 4: Add(H); break; case 5: { HLink high = FirstH(H); break; } case 6: printf("请输入要移动的客房位置:"); int k; scanf("%d", &k); MoveK1(H, k); break; case 7: ReverseN2(H); break; case 8: SortPriceL(H); break; case 9: printf("请输入新客房房间数:"); int beds; scanf("%d", &beds); upBed(H, beds); break; default: printf("输入不合法\n"); } printf("\n\n\n"); }}
    2.3 运行结果截图2.3.1 main函数执行结果
    2.3.2 Exp函数执行结果
    2.3.3 Find函数执行结果
    2.3.4 updataH函数执行结果
    2.3.5 FirstH函数执行结果
    2.3.6 MoveK1函数执行结果
    2.3.7 ReverseN2函数执行结果
    2.3.8 sortPrice函数执行结果
    2.3.9 upBed函数执行结果
    三、总结与体会通过这些实验题目,让我感受到理论知识和实际应用还是有一些区别,在学习数据结构的过程中,光学习理论知识是不够的,更重要的是自己动手实践,这样才能更好的理解知识并学会运用。
    该实验使我对链表有了更好的理解,明白了链表几种基本操作的实现方法,知道了什么时候该用到链表这种结构。我也遇到了一些困难。比如链表操作时使用了NULL指针中的内容;模式匹配不知道如何直观输出匹配过程,不会记录匹配次数。
    1 评论 1 下载 2019-09-27 07:18:27 下载需要6点积分
显示 0 到 15 ,共 15 条
eject