分类

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

资源列表

  • 基于JSP和MySQL的农产品销售管理系统

    摘 要本文论述了基于JAVA、Web的农产品销售管理系统开发的目的及意义,目的是为了农产品资源的合理利用和物资的充分交流,有些地方富余而卖不出去,有些地方却吃不上。意义在于加快社会主义现代化建设的步伐、实现民主富强的小康社会,充分体现各地的特色。
    根据实际需求和,本人策划了(基于Web的农产品销售管理系统)本体系,本系统充分考虑了国家的农产品生产和销售管理之间的相互关系,以及互联网络的现代化应用,在互联网络中,搭建一个类似网上商城一样的网站系统,其中会用到 MyEclipse、MySQL、JSP等之类的网络工程技术,本系统分为前台销售系统和后台管理系统,前台会员系统,为会员提供:会员注册、购物车、顾客留言、商品浏览、订单管理等主要功能。后台管理系统,为管理员提供:农产品订单管理、农产品的商品管理、农产品的商品分类管理、农产品的特价商品管理、会员信息管理、系统用户管理等优质服务。
    关键词:JSP;农产品;网上商城;MySQL
    AbstractThis paper discusses the purpose and significance of the system based on JAVA, the development of agricultural products sales Web, in order to fully communicate the rational use of agricultural resources and materials, and sell surplus in some places, some places have not. The significance lies in speeding up the socialist modernization construction, realize democracy and prosperity a well-off society, fully reflect the local features.
    According to the actual demand, I designed (Web based agricultural products sales management system) of the system, the system takes full account of the relationship between national agricultural production and sales management, and modern application of the Internet, in the Internet, build a similar online mall as the website system, which use of network engineering technology MyEclipse, MySQL, JSP and so on, the system is divided into front and back office management system, sales system, the membership system, to provide members: the main function of membership registration, shopping cart, customer message, product browsing, order management etc.. The backstage management system, provide the administrator: agricultural products, agricultural products, order management, merchandise management, commodity management, classification of agricultural products agricultural products special offer merchandise management, member information management, user management and service system.
    Key words: JSP; agricultural products; online shopping mall; MySQL
    前 言从瓦特改良蒸汽机到内燃机和电力发明,从哥白尼的日心说到爱因斯坦的原子裂变,名为科学的力量,在人们社会悄然崛起,人们对未知的恐惧并不能阻拦科学的发展。
    随着时间的流逝,科学越来与壮大,最终成为人们都认同的力量,成为了主流,它的发展解放了人的劳动力和思想,让人们有了更多的时间和空间去思考,去发现,去学习,去揭秘,去知道,最终成为人类自己的知识。
    在这种情况下,互联网络掀起了新的科技革命浪潮,他改变了人们的生活习惯,思维方式,交流沟通和知识传承,它方便了人们之间的交流沟通,使空间距离不再成为阻碍,使时间屏障不再成为难题,使语言不通不再成为天险。人们通过它互相交流自己的想法和思维,通过它互相论证自己的观点,通过它来相互传达信息,最后达成共识,总为言之,互联网络以其强大的优势和独特迷人的魅力成为时代的主流,未来是互联网络的时代,当然,也是本人们的时代。
    互联网络技术发展到现在,Java Web技术已经是使用最为多,在这个体系中常常被人用来架构各种程序的技术.人们常常用它来编写代码完成程序并且应用到现实生活和网络的各个方面,它通过连接服务器访问后台进行数据交换进而完成对后台数据的交互除了处理与各种查询。
    JSP是本人们所需要的一种毕业设计技术,而本人们的毕业设计可以用和多种关系数据库中的简单实用型数据库管理系统,为Web框架应用提供了较好的实现方法. 农产品网站就是以这种方式下起色起来的,通过以产品信息展示和采购运输为主要的核心内容来达成本人们让他实现的作用,用网页的形式,以农产品交易为主意交易系统。
    基于JSP的农产品网站网上购物系统是一个很多人都做过类似的网站设计,自己用数据填写别人提前写好的框架,自己根据上帝的要求去完成相应的功能,进而成为人人都用到的需要要求的网站,这样人们就能快速的寻求到自己的宝贝需求而不用带热天的去晒日光浴和大寒天的去吹西北风,并且还有很多上帝,例如:方便盘问,可以“住”进的数据多,容易命令操纵便于增加删除改变纠错查找盘问等;对浏览者来说,统合了盘问产品信息的过程,并且随时可以加快速的找到自己渴望的产品信息。农产品网站系统相比传统的商品信息发布传播的方式具有十分明显的优点。这种显而易见的优势,使它更容易在这个追求方便、快捷的时代下,蓬勃发展和欣欣向荣。
    1 课题简介1.1 选题背景自宇宙出现盘古开天依赖,万事万物就在不断的进步更新淘汰弱者,现在到了如今人们进入了互联网上帝世纪,越来越多的事物和工作都可以在网上用数据流代替和执行,不必再像以前一样亲自出面和出门做事,也比不向本人以前一样在街头走路发传单通知消息,这些纸张的载体因其自身的缺陷而慢慢被淘汰,它们消耗高纸张要钱期刊要刊登费低昂是要提前预定浪费了了人们的时光和精气神而被逐渐淘汰。所以,在网络上走数据流来传达信息和需求进而选定需求的节约时光和精气神的方法被人们大大的接受,互联网络在很短的日子里成为全球所接受认可的主流传播方式。本次毕业设计的上帝是农民主要是为农民的农产品销售买卖提供方便之路,通过使用开发工具制作成为客户和用户都满意的系统。
    1.2 课题的意义在当前时代,民众们已经深深的感受到了Internet信息革命的狂潮的冲击。信息技术的突破使得空间距离已不再成为限制,真正实现了地球村的理想,以Internet为标榜的现代化信息网络快速扩张,它的辐射领域也从单一的信息的交流扩张到人们生活的方方面面。从这个大势中本人们得出,信息资源在互联网信息技术的巨大的传播下,一种新的、基于网络的信息沟通与交流正在逐步形成,这给你、本人、他乃至世界带来了巨大的冲击,这是机遇,也是挑战。
    本人在网上找了一下这方面的数据发现农村中的信心普及率很是低农民们都不是怎么会用手机顶多就是打打电话发发短信,平时不太会上网更不会想到通过网络手段去卖出自己的劳作成果—农产品,这无疑大大浪费了农民的劳动成果和国家资源也大大打击了人们的生产劳作的积极性,所以一个可以为农民处理难题的体系应运而生。本次毕业设计的开发,不光可以为农民们出售他们的农产品提供网上道路,省去他们精气神和时间金钱不用必须亲自去菜市场或推着三轮车去大街上去卖菜,而且还使的买菜的家庭主妇不用花费大把的时间去实体店里采购这样既省钱又省精气神。这绝对是农民心目中 的最好用最符合他们期望的系统。
    1.3 系统目标系统的目标是为上帝服务—农民,主要通过开通网上那个东西提供数据的方便之路使农民能够通过网络快速方便的与那些急需农产品却又找不到供货商的买家进行交流达成协议,进而形成供求关系长期下来是形成产业链也必是不可能,形成物资的充分流动与吸收吸引,并且省去了民众许多的time和money。
    在很多城市、镇子里面、超市里的水果蔬菜之类的农产品都昂贵非常的让人恐惧,而在农村了很多东西都烂在树上、拦在土地里、堆在家里都卖不出去,而你又需要某些东西却不知道到哪里去找,可能只能亲自或找人代去才能买到不然的话就要花大价钱被小贩当肥羊仔宰,还不一定能找到所需要的,同时还有可能受不同能量在空寂的空间流动的限制。在另一是事物的相同方面,农产品网站所提供的更加方便、更加简单的农产品的咨询查找;而拥有本系统有的公司的业绩硬顶会大幅提升有,因为它让人们更好受以及更不难受更方便不吃亏及省去资产浪费使大家能够以最少的资产做最大的事随之更持续更坚挺活的更久。
    2 可行性研究本人们实施研究,要做的是在有限的time和资源条件下确定所有问题,并且找到问题的解决的方法和可能性,进行的原因是确定所找的问题应不应该去费工夫研究,放开你的大脑去畅想有几种可能:
    2.1 技术可行性于Web的农产品销售管理的策划是靠Web服务器以及浏览器来完成的。然后应用Java Web技术,使用方便、快捷、应用性强大的、好用MyEclipse开发工具软件来设计完成整个系统,建立Web项目,用Java语言编写程序,用JSP(Java版的HTML)设计丰富多彩、美轮美奂的动态界面,本系统使用的是 MySQL数据库。在学校上学期间,老师花功夫讲过这门语言并且让本人们编写了好些相关程序以及做过好些课程设计,对本次毕业设计有一定的经验和把握,而且如果有问题,指导老师就会帮本人们讲解,所以,本人认为,此次毕设在技术上是可行的。
    2.2 经济可行性在此次毕业设计之前,本人对相关情况做过调查,并有了很好的了解和整体把握,虽然需要较高的技术和相应的制作完成人员,但任何困难是阻挡不了本人的,本人坚信党和人民坚信国家,坚信本人一定会成功,只有前期有个好开头后期就会节省大量的人力物力。农产品更容易强劲的买盘能否产生本人们开发者所不知道的各种可能的未知。这些可能的未知就像黑暗处的毒蛇一样隐藏不为人知,不知道什么时候就会跳出来咬你一口,所以在维护上要多下些功夫啊,而本系统的开发只需要技术较好的软件工程师,就能成功。与其它的系统相比,本系统可靠性相当强,只即开发出来,后期运行良好就可以了。如果它成功上架并应用,不光可以为农民们出售他们的农产品提供网上道路,省去他们精气神和时间金钱不用必须亲自去菜市场或推着三轮车去大街上去卖菜,而且还使的买菜的家庭主妇不用花费大把的时间去实体店里采购这样既省钱又省精气神,满足了人们的需要。因此在经济上可行的。
    2.3 操作可行性操作可行性是看本人是否有可能去做并做完本次毕业设计。
    随着互联网和信息技术的不断进步,各种技术层出不穷,电脑的小型化和私有化,软件工程师们的技术的成熟,使得很多系统都能够实现并且应用,独立开发与生产成为了可能,MyEclipse、Tomcat、MySQL等开发工具软件都能在网上下载,应用教程也能在网上学习,Java、Web等的jar包在网上直接下载导入开发工具之中,就能够自己编写程序,开发前曾向老师请教过相应的问题,因此对整个程序有了一个大体的了解和清晰的模块划分,将程序划分一个又一个的模块,是整个程序有了一个清晰展示,这其中每个模块都是可以完成的。
    综上所述,程序的操作性是可行的。
    2.4 法律可行性本系统的开发遵循客观法律法规和人性,不损人利己,不侵犯他人财产和权益,誓死遵守国家的荣誉和法则、一切以集体和国家利益为主,为人民造福,所以不存在危险主义,恐怖主义,帝国主义,侵权等问题,具有法律可行性。
    3 需求分析3.1 系统需要解决的主要问题目前,本系统需要了解客户的层次分类和客户具体需要哪些功能,能做到什么,达到什么程度,提供什么便利,使用本系统后又能有什么改变和益处,能为客户、人们和国家带来哪些影响,能为社会带来那些发展。
    本次系统的需求对象是农民,要完成系统的全能制作,就必须要完成对农民的实际情况和现场检查的了解意见收集看看他们需要什么都会什么能做那些能为他们做哪些,对他们亲切问候完成分析报告进而严格根据分析报告制作系统一步一步完成农民要求的功能,最后验收符合他们的要求内容的情况然后就能收到钱币了。
    3.2 系统具备的基本功能农产品销售管理体系的成功是靠两个重要部分完成的,他们真的很重要,前台用户销售系统要求基本功能都实现,如登录、注册、购买、下订单、修改密码、查订单。在此基础上如果能体现界面美观、大方、美轮美奂等,能一下子突出重点、震撼他们的内心的效果,就更好了。
    3.2.1 网站前台作为用户上网浏览能瞬间看到的功能界面,首先,功能全面、且简洁易懂好操作,让用户能够方便快捷的使用本系统,进而爱上本系统并吸引更多的用户前来,让他们也能够了解记住本系统的上帝是谁—是他们。为上帝们直接展示的功能界面主要包括商品信息按类别、名称搜索,用户注册成会员,会员留言,购物等。上帝们进入本系统首面就能看到所有的数据流,游客和任何人都可以查看询问。上帝们注册表级进入后就可以拥有权限做他们本人可一直在做的事了。
    3.2.2 网站后台作为拥有特殊权利的人群的操作界面,理应没有注册界面,为了方便拥有特殊权利的人群对系统的管理,提供了方便的模块化管理模式。后台系统模块主要分为是管理模块、会员(在前台注册的用户)的管理模块、商品的分类管理模块、商品本身是管理模块、订单(用户购买东西的凭证)的数据流等。
    3.3 数据流图数据流图(DFD):是一颗天才的发现烈日般的发明。是本人设计中表达最为清晰度的图,其中本图没有任何(应该是太多)难以理解的地方,简单一点,好懂一点、任意一点、容易并又容易一点(不懂得查资料,你就会了),它只是一个描述说明“水”(信息)的流动和处理(信息来回交流并把有返回结果的信息在交流的过程图)情况,是极好的向人们(即使不是专业的计算机相关人员)表达他们想法和理解的工具。



    图 形 符 号
    名 称
    符 号 说 明





    实体
    讲解体系除外有关数据的团体和微小,框内为之称号



    处理
    追究某种相应解释和体悟 其中,PM区的解释相应的顶号 C区的解释相应的称号



    数据存储
    讲解与剖析的相应资料的“住处”,DN部分讲解资料“住处”的标号,S部分讲解“住处”的资料的称号



    数据流
    讲解资料的流向方向,FM讲解资料流向的称号



    农产品网站系统TOP数据流图

    农产品网站系统管理员子系统数据流图

    农产品网站系统会员操作子系统数据流图

    3.4 数据字典数据字典是看有信息和有关资料的团体,数据字典的作用是在软件的分析和设计过程中提供关于数据的描述信息[1]。它让人们有了关于数据最重要直观的野望。
    3.4.1 数据存储数据存储是相应资料停歇或看管的住处。本人们常常把它堆放在文献中、资料数据库中、缓存池中、内存中包括但不限于话会话session、二级缓存池、表,下面就是一些本系统的数据表,也是本系统的相关资料“住处”的地方。




    3.4.2 数据流数据流是相应资料在通道的流动方法。本设计使用的是不同的编号来代表不同的信息流,清晰的展示了设计的信息为他人了解本系统提供了极大地方便。



    3.4.3 数据处理数据的处理往往在数据的后台不是那么容易找见,给软件工程师们造成了极大的困扰,使他们不能方便的通过查看数据的交互处理来定位问题和了解流程,这时,通过编号定位信息进而了解业务流程和解决问题就非常有必要了。


    4 总体设计4.1 概述本次毕业设计到这里就开始思考怎么完成任务的事了,这里大体部署出设计的各个阶段任务内容和完成时间,然后对各个阶段的任务内容进行分析后确定软件的各种功能模块的划分从而对系统进行论述概写,即,也就是分析判断确定本次毕业设计的模块组成结合和实现的。
    4.2 系统功能本次毕业设计提炼本人的深思熟虑和对系统完美剖析而得到的结果来看,处理体系设计规定为两个分部,是会员子体系和拥有特殊权利的人群子体系。
    4.2.1 会员子系统会员子系统主要包括会员注册(系统必须,几乎每个系统都有)、购物车(一般买到的东西可以放购物车和直接付钱,这里本系统是统一放购物车)、顾客留言(供用户发表言论的地方)、商品浏览(本系统的主要功能也是系统的首页也是商务网站永恒的信仰,太常见了)、订单管理(查询用户自身所买东西的地方)、修改注册资料。会员子系统如图4-1。

    4.2.2 拥有特殊权利的人群子体系功能划分拥有特殊权利的人群子体系可设计出如下图的图形如图4-2。

    4.3 系统功能描述4.3.1 会员子系统功能描述会员(没有特殊权限的人群)是系统中的上帝,主要可以实现没有特殊权限的人群的注册(身为一个系统中的UI中最重要的一部分没有客户的系统给谁用,这部分是应定要有的)、购物车(没有特殊权限的人群买下东西给那里放,而是这里)、顾客留言(供没有特殊权限的人群查看交流的地方这里你可以查找到的没有特殊权限的人群给本系统的评价来供你查考)、商品浏览(没有特殊权限的人群要选择产品就需要看看都有什东西)、订单管理(没有特殊权限的人群消费了就要有收据,这是凭证是老板和没有特殊权限的人群查看的依据)、修改注册资料(这个用于客户忘记密码之用)等功能。具体功能如下:

    没有特殊权限的人群注册(Lid registratie):用于给叔叔阿姨们加入而使用的,各位没有特殊权限的人群还等什么快来吧别让宝宝失望
    商品浏览(Product bladeren):没有特殊权限的人群浏览产品资料和特价产品资料
    修改注册资料(Inschrijvingsgegevens wijzigen):登录系统的没有特殊权限的人群变更与团体相反的东西的资料
    购物车(Uw winkelwagen):存储没有特殊权限的人群购买的产品资料待结算
    没有特殊权限的人群留言(Klant berichten):没有特殊权限的人群可以向拥有特殊权限的人群宣传留言资料
    单子管理(Orderbeheer):审阅和修改单子资料

    4.3.2 拥有特殊权利的人群子系统功能描述拥有特殊权限的人群对子系统Be responsible for全部体系的各种资料的更新与维护的操纵。

    订单管理(Orderbeheer):拥有特殊权限的人群对没有特殊权限的人群的订单进行审阅和去掉控制
    系统没有特殊权限的人群的控制(Systeem heeft geen speciale rechten beheersen van mensenmassa):对体系的没有特殊权限的人群的资料进行添加修改删除控制
    留言的操纵控制(Kontrolelementer for post):拥有特殊权限的人群对没有特殊权限的人群发布的留言信息实施控制
    商品类别的操纵控制(Categorie Productcontrole):拥有特殊权限的人群对商品的类别资料实施控制
    特价商品(Specijaliteti):拥有特殊权限的人群发布和控制特价产品资料
    商品的操纵控制(Control and control of commodities):拥有特殊权限的人群发布和控制产品资料
    没有特殊权限的人群的操纵控制(Mensen zonder bijzondere machtiging controle):拥有特殊权限的人群对已经注册的没有特殊权限的人群实施控制

    4.4 数据库设计此物几乎每个设计都能都能及都会用到的高效好用方便的技术,它既能存储数据又能读取数据,使本人的毕业设计不至于成为只能看或只能跳转的界面(中看不中用)正是因为有了这个技术本人们的毕业设计才能多姿多彩本人们的各种软件才能够具备实用性经济性整个社会才会进入互联网的时代,注意使用数据库设计必须要有相应的数据库语言,如本人在本次毕业设计中用到的MySQL数据库,它能很好的存储数据提取数据因而大量应用于网站架设上,也就是说打开电脑上网找找发现很多的网站都用MySQL并且没有一个网站不用数据库技术,它让数据有了“家”,进而就能“住进”更多的数据,实现了从只能算数到能实现论文查重,从只能测算弹道(物理存储设备还那么大)还相当费劲到发射火箭相当轻松,数据库技术的作用功不可没,在学校的时光老师常常讲解数据库讲理好几种包括MySQL、oracle,好几种册次包括数据结构、SQL语句,好几种实例加上应用包括上课讲的例子、课程设计,他说这个非常重要,所以那些学弟学妹们努力学习SQL语言吧。
    数据库技术有几大优点:

    数据库兼容性强
    本次毕业设计的设计那可不是以次为焦点的策划技术
    本次毕业设计的数据库是有相当严格的标准
    本次毕业设计的要求能相当的联系出来

    4.4.1 数据库概念结构设计人们往往讨厌看到复杂的东西因为那很难看懂并且还有浪费时间更可怕的事实是你花费了时间却看不懂,数据库就是这样一个东西,但看他的数据库语句你发现他很混乱看不懂就是它认识你而你不认识他,这往往导致出现解析困难的情况,所以一种直观的视图概念工具就应运而出了—ER图,它用来对物体进行抽象,再把抽象的结果用线相互关联起来这样一个清晰明了的结构图就出来了,通过它软件工程师们可以大致的了解各个对象之间的关系并对系统有了规划和认知就是一个外行人都能够了解。它有两个明显的优点:简单容易;受人喜爱哪怕这个人他不懂计算机。所以无论是做程序还是做业务最好都画上E-R图,它有助于你理解你所做的事并让你善于总结和善于发现,本人的结束大学的任务中就有ER图。
    E-R图是表达事物“奸情”的联系的东西,它有一下能量组成:

    矩形框—实体类型(Rektangulære boks-type enhed)
    菱形框—联系类型(Diamanter-kontakt type)
    椭圆形框—实体的属性(Oval box – en egenskab for en enhed)。

    各实体属性图
    大家快来看看啊,下面的都是“尸体”属性图,快开瞧一瞧啊!如下所示:
    没有特殊权限的人群图

    拥有特殊权限的人群图

    产品类图

    留字图

    产品图

    实体总E-R图

    4.4.2 表的设计本人的毕业设计数据库逻辑架构使用的是MySQL。它的作用就是为本人的毕业设计的数据提供足够的和规划好的整齐的存储空间,方便本人们实现资料的相应控制。
    本体系的资料库称号db_shop_wgsc.sql。主要包括如下几个表:
    商品类别(category)表



    字段名称
    说明
    类型
    长度
    允许空




    ID
    ID
    int
    4



    CateName
    分类名称
    char
    40



    CateDesc
    分类描述
    text
    0




    留言(leaveword)表



    字段名称
    说明
    类型
    长度
    允许空




    ID
    编号
    int
    4



    Member
    顾客姓名
    int
    4



    Admin
    拥有特殊权利的人群
    int
    4



    Title
    留言标题
    char
    60



    Content
    内容
    text
    0



    LeaveDate
    留言时间
    datetime
    0



    AnswerContent
    回复内容
    text
    0



    AnswerDate
    回复时间
    datetime
    0




    会员级别(memberlevel)表



    字段名称
    说明
    类型
    长度
    允许空




    Id
    序号
    int
    4



    LevelName
    名称
    char
    20



    Favourable
    折扣
    int
    4




    拥有特殊权利的人群(Admin)表



    字段名称
    说明
    类型
    长度
    允许空




    ID
    ID
    int
    4



    AdminType
    类型
    int
    4



    AdminName
    姓名
    char
    12



    Password
    密码
    char
    12



    LoginName
    账号
    char
    12




    商品(merchandise)表



    字段名称
    说明
    类型
    长度
    允许空




    ID
    ID
    int
    4



    Category
    类别
    int
    4



    MerName
    名称
    char
    40



    Price
    特价
    decimal
    8



    SPrice
    售价
    decimal
    8



    MerModel
    型号
    char
    40



    Picture
    图片
    varchar
    100



    MerDesc
    描述
    text
    0



    Manufacturer
    厂家
    char
    60



    LeaveFactoryDate
    出厂日期
    datetime
    0



    Special
    是否特价
    int
    4




    会员(member)表



    字段名称
    说明
    类型
    长度
    允许空




    ID
    编号
    int
    4



    Memberlevel
    级别
    int
    4



    LoginName
    账号
    char
    12



    LoginPwd
    密码
    char
    12



    MemberName
    真实姓名
    char
    20



    Phone
    电话
    char
    15



    Address
    地址
    varchar
    100



    Zip
    邮编
    char
    10



    RegDate
    注册日期
    datetime
    0



    LastDate
    最后登录日期
    datetime
    0



    LoginTimes
    登录次数
    int
    4



    Emails
    邮箱
    varchar
    100




    订单(orders)表



    字段名称
    说明
    类型
    长度
    允许空




    ID
    编号
    int
    4



    Member
    会员号
    int
    4



    Cart
    购物车号
    int
    4



    OrderNO
    购物单号
    char
    20



    OrderDate
    时间
    datetime
    0



    OrderStatus
    订单状态
    int
    4




    购物车(cartselectedmer)表



    字段名称
    说明
    类型
    长度
    允许空




    ID
    编号
    int
    4



    Cart
    购物车号
    int
    4



    Merchandise
    商品编号
    int
    4



    Number
    数量
    int
    4



    Price
    价格
    decimal
    8



    Money
    金额
    decimal
    9




    账单(cart)表



    字段名称
    说明
    类型
    长度
    允许空




    ID
    编号
    int
    4



    Member
    会员代号
    int
    4



    Money
    总额
    decimal
    9



    CartStatus
    账单状态
    int
    4




    4.5 业务流程图它常常指的是软件工程师们对业务的了解情况,这个业务时做什么,为哪些人服务,怎么流通的,为什么这里是这样流的,具体的内容是什么,这些都是程序员必须要知道的(无论是测试还是开发人员),在公司工作的软件工程师们相信大家深有体会对一个业务的了解,尤其是对新生(实习生)了解业务都有相关文档来进行描述,文档中就有业务的相关流程图,新生们通过这个图就能大体和整体了解相关业务,也就是通过这个图,他们将了解他们日后将要进行的工作和饭碗。
    下面是一些流程图的符号,本人了解业务时,常常接触它们,所以认识它们,下面本人来给大家分享一下:
    其中图1-1农产品业务流程图:


    5 详细设计与系统实施5.1 相关技术简介本次毕业设计在这一阶段就是要开始具体规划了,怎么写如何写就成为要思考的;

    first,对本系统第一部分首页,要有产品的展示,游客不管是不是会员有没有登录首先要看到这部分内容才会对本系统有了解有兴趣才会试着去注册登录进而有了后面的一系列事情,可以说它是一切的前提。当然登录注册界面也要放在首页并且占用面积不宜过大,否则会影响客户的兴趣,想想一个系统最主要的是向人们表示他们的作用和价值而不是其它一些次要的东西。如果你能做到以上几点,那你的系统的第一步就好了
    Second,用户点击进去后要了解产品怎么办?这时就需要产品的介绍了这种能让用户了解产品信息的方法了,用户通过注册登录后就浏览首页通过产品名称和图片来找到要找到产品了,那么用户不知道产品的名称只知道大概图片或只知道产品名称而不知道图片或通过查询(后便讲到)得到但不确定想要更具体的了解产品信息,这样通过单击图片和“查看详情”就得到了更具体产品详情,这样用户就因为能够查询产品详细信息(这可能就是你比同类产品多的地方)而对本系统大力支持进而让你的系统更有名并且吸引更多人来最后甚至走出市场打开国门进军国际舞台,还有为了防止因产品太多客户浏览太频繁导致人们厌倦需要做一些功能,第一增加商品搜索功能让商品更快更容易的被找到这包括模糊查找和精确查找,第二增加商品分类功能根据不同性质的商品分成不同的类别,这样用户就能根据类别更快一步查找物品。以上的功能本系统都有
    Thirty,也是最重要的一部分之一,当客户辛苦注册登录并浏览查找到所需商品时,却发现少了最重要的东西—没有购买按钮,不能购买那就尴尬了,所以本系统还要添加购买功能,当用户点击购买后跳转到购物车界面后就能看到他们所买的东西的单价、数量(默认是1可修改)和总计了,如果客户不想买的话还有返回上一级的选项供选择,点击“返回上一级”按钮,返回首页然后进行重新购买,如果客户(ˇˍˇ) 想~弄走购物车里的东西,有挑走购物车里的东西的选项按钮供挑选,按下“清空购物车”,购物车变空,如果想进行购买的话按下“下一步”就会生成订单项等到客户确认,如果客户不想买的话还有返回上一级的选项供选择,点击“返回上一级”按钮,返回首页然后进行重新购买,如果想进行购买的话点击“确认”就会生成订单并把数据发送给后台,联系拥有特殊权利的人群就可以从后台查到数据

    This volume aims to take the reader behind the details of the Access interface, focusing on the general knowledge necessary for Access power users or developers to create effective database applications. [1]
    5.1.1 B/S模式及其优势随着科学技术的发展,互联网络信息技术也随着发展,原来使用的C/S技术模式也随着Internet的逐渐扩张,慢慢向(B/S)技术模式转变。
    很久以前,互联网公司都喜欢采用C/S(client/Server)技术模式来生产产品,这种C/S(client/Server)技术模式生产下来的产品因为client分担了一部分数据处理,所以对服务器的要求就降低了,这种情况对公司的发展扩张就极为有力了,就导致很多软件工程师们从事并开发出了很多C/S(client/Server)技术模式的应用软件,这是他的优点,同时也是它的缺点,因为在这种开发模式下的软件产品,相当一部分的数据思维都在于客户端处理,那么,可能就会出现一些的缺陷:

    前台客户端系统的下载、安装、运行、测试、维护乃至最后的升级就非常的困难了。首先,下载需要一定的流量(MB),这一步让用户看着他们干瘪的钱包心痛,安装需要一定的时间,让分分钟上万、生活节奏快、视时间为生命的部分用户(社会精英)肝疼,每次打开运行又要一些时间,哎!不说了,上火啊!然后,运行出了问题的话,得!强制退出、重新启动,哦!对了,如果你的手机内存小,客户端产生的数据量大,嗯,还要清理一下垃圾(前一次运行产生的数据),又肾虚啊!最后,每一次的测试、维护乃至最后的升级都要耗费公司的人力物力财力,软件工程师们的时间和精力,夭寿啊!这是本人真是的经历,在公司工作时,客户端系统每开发出一个版本,就要赶紧开发下一个版本,是很忙的,有时候都没时间管本人们,誒,不说伤心的事情了
    一部分的业务逻辑和数据处理集中到了客户端,就会有可能导致安全隐患

    使用C/S(client/Server)技术模式成产软件产品,受几个因素影响,如电子设备的硬件差异、软件运行环境的不同(使用Android是操作系统,还是iPhone的操作系统)兼容性的问题又是一道重击,正是由于这其中的种种问题,人民开始使用(B)/(S)体系,这种模式与C/S模式最不同的也是最重要的部分,以现成的东西替换繁重的客户端,完成数据的交互。
    B/S的技术模式的使用但却换来了非常多的益友:

    数据体系在浏览器下载、安装、运行、测试、维护乃至最后的升级时,可以可能在相应的地方制作相应的设备就OK
    很多的使用都是在想用的乡音的地方进行的,这大大增加了体系的影响性

    这里补充一点,虽然B/S模式看似为本人们添加了很多的都得用处,但是由于相应设备的某些方面的局限性的限制,可能,在C/S的技术中部分相对可以设计的相应设备的性质,在B/S的技术模式下,编程受到重重阻碍,可能不能搭建设计。然而这样,B/S的技术还是当今时代many公司生产软件产品的使用技术。所以各位后来人,去学习去寻找去努力为了以后的饭碗和前途去努力的拼搏吧!!!
    5.1.2 Web—JSP技术JSP技术是本人做毕业设计使用最多的Web应用开发技术之一,本人通过它的设计脚本(底层代码)来学习它,将来你们也没用到它,所以请努力学习使用它,后面本人们才做详细讲解。
    5.1.3 MyEclipse简介MyEclipse是本人实现本次毕业设计的主要集成开发工具,类似于eclipse开发工具,但是比它更好用,它可以在工作空间中创建工程(文件夹和文件),对工程不停地添加内容,如创建并编写Java文件,完成逻辑代码,创建并编写JSP文件完成界面布置并向后台提交用户输入的数据,工程文件自带框架(各种已经写好的封装了Java对象的jar包),极大地丰福了程序的编写和MyEclipse的内容,MyEclipse开发工具天生自带Tomcat和很多插件,不必用户自己去一一架设,这为用户带来了方便,能使软件工程师们集中时间与精力,更加高效的编写、调试、测试、运行程序并成功完成任务,公司也能因此增加效益,社会、人民也能因此更加美好。
    MyEclipse 是一个十分方便的、好用的、快捷的、流行的、卓越的用于互联网未知领域的开道的Java的东西纠合,MyEclipse的功能非常强大且完好,应用范围很广,尤其是对各种开源免费的产物的拥护十分不错。本次毕业设计中用Java Servlet接受表单数据,用AJAX文档,用JSP编写优美漂亮的界面传递数据给后台(要经过Java Servlet),用Struts框架转化数据为各种action,用Hibernate映射Java对象与数据库的属性,用 JDBC数据库链接,Tomcat做服务器传递数据。上述多项功能都集成于MyEclipse。可以说有了MyEclipse几乎不需要其他java开发工具。
    5.1.4 Tomcat简介Tomcat是一个十分优秀并且十分好用的服务器,它不需要程序员自己写服务器、自己写输入流、输出流,来来回回自己传递字节或字符流,最重要的是它免费,并且开源这大大方便了程序员编程,节省了每次来回写输入流、输出流的时间,老师曾说,Tomcat是轻量级的应用服务器,对于很多小型,中型项目来说,它是首要选择,本人们创建项目,编写程序时,要经常用到它.通过它实现并达到本人们想要的效果。
    Jakarta Tomcat服务器是在SUN公司的JSWDK(Java Server Web DevelopmentKit,SUN公司推出的小型Servlet/JSP调试工具)的基础上发展起来的一个优秀的Java Web应用容器,它是Apache-Jakarta的其中个子项目。
    5.1.5 MySQL简介MySQL是一种方便的、好用的、开放源码的、便捷的、使用范围广的、可拓展性好的数据库的管理系统。它是一种小型的数据库,所以(相比其他大型数据库)就有了占用系统内存少、速度和反应快、浪费资源少、成本低等之类的优点,因为这些优势它很快占据了广大的市场(尤其是在小型、中型公司,)为了节约成本,增加效益,就选择了MySQL作为他们公司所搭建的网站的数据库。
    MySQL配合其他一些网络技术和开发工具,就能很好的架构网站或其他应用。本次毕业设计中使用的数据库也是此次介绍中的MySQL数据库。
    5.1.6 JavaScript简介JavaScript(简称JS),是一种方便的、好用的、能对对象和事件进行编辑处理的网页开发语言,它可以再HTML上使用(对新手来说,它就相当于一个Java版本的HTML),用于给HTML的网页添加动态操作。
    JavaScript是由网景公司(Netscape)开发设计的一种动态的、内置支持类、属于弱小类型的、基于原型的网页开发语言。
    是能让HTML的网页更加活泼的网页开发语言,也是当前业内网页设计中好学、方便、好用又快捷的语言。人们可以利用JavaScript轻易的做出丰富多彩的网页。
    5.1.7 JSP简介JSP(对新手来讲,就当他是一个Servlet),由出名的Sun首倡主导、联络许多家公司一起讨论并创建的一种动态技术标准。它实现了在HTML中的书写Java语言(指令、脚本,动作元素)。它通常被发送到服务器端(server),经过编译执行返回给客户端(Browser/client)的就是一个HTML,所以客户端(Browser/client)自然就能浏览。在接收到访问JSP网页的request请求时,Web服务器端(server)可以实现你很多的功能设计让你是想能够使用你所(ˇˍˇ) 想~要的性质,其中拨入的Java程序片段可以用作包括但不限于斗志斗彩的内容的添加和对数据“住”的地方的操纵等,方便实现网页的动态功能。

    经过一次性编写,使其成型,然后就可以四处的运行
    适用范围广大,可以在系统的多个平台运行。JSP从发明出来开始就是用来在各个平台溜达的,并且可以在任何环境中进行搭建、在任何环境中扩展。本人们把它和ASP相比较,JSP的优势就很明显了
    很强的可伸缩性。只要有一个相应的Jar包,本人们就可以四处运行Servlet或JSP,从一台服务器到many台服务器,Java Server Pages表现出来了强大的生命力
    功能强大并且丰富多样的开发工具的拥护。在这一点上与ASP很像,众所周知,有了许多非常功能很好并且卓越的开发工具都支持Java,其中有一部分是可以免费得到、可以独自编的并且已经可以顺利的运行在多种平台之下了
    可以支持并用于服务器端的交互。在工作空间新建一个web工程,工程中自带交互服务器端的组件,软件工程师们可以在其中书写、设计、运行、进而实现具有相应的逻辑功能的组件来供本系统的程序调用,来增加本人的毕业设计的系统的强大

    最后,JSP是本系统中很重要的、不可或缺的一部分,它构成了本人系统美轮美奂的动态页面和用户输入数据的数据提交功能。没有它就没有本系统。
    5.1.8 JDBC 简介JDBC(数据库连接)是好用的、便捷的、大大节省软件工程师门时间的语句,为人们使用相关资料提供有利的condition,这也是Java语言“编写了一次,处处都运行”的优点。JDBC为工具/数据库软件工程师们提供了一个统一的API标准,据此软件工程师们可以编写更高层次的接口工具和、类,这样软件工程师们就能够通过纯 Java API 来编写好用的、方便的数据库应用程序。
    JDBC的各项人物的关系数据库中,你可以与他,它不是一项容易的任务,换句话说,使用JDBC和API,就不必为访问关系数据库专门写一个程序了,本系统中就是使用了JDBC的高级封装方法,大大节省了本人的代码量和时间,因为有JDBC的系统可以向相应关系型数据库发送SQL以便调用。
    5.1.9 Hibernate简介Hibernate是一个便捷的好用的时尚潮流的数据库资料链接方法,是JDBC的升级版,能够更好的、更方便的连接数据库,使得软件工程师们可以随时随地的使用这个对象与关系的映射框架来操纵数据库。 这个对象与关系的映射框架可以应用在任何使用JDBC的场合中,如客户端的Java的程序, Web应用中的Servlet/JSP程序。
    hibernate比JDBC简单好用、便捷、方便、快速,它不需要输入很多的连接代码,数据库里的数据也不用循环提取。制作它的人是一个聪明、执着、有毅力、有恒心、不拍困难的人,因为它真的很优秀、研发它的过程必然充满了艰辛与磨难。
    Hibernate优点:

    对象/关系数据库映射(ORM)
    透明坚强化(Transparant sterke)
    很好很方便的事务处理(Very, very convenient transaction processing.)
    它没有占有性(It has no possession.)
    移植性会很好(Portability is good.)
    方便好用的缓存体系(Easy and easy caching system)
    简洁的HQL编程(Simple hql programming)

    Hibernate的缺点:

    不好学(Bad science.)
    虽然它把JDBC中的重复的数据进行了封装(包装成一个方法),使其调用是极其方便、快捷、好用,大大节省了软件工程师们的时间、金钱和工作量,但是它本身涉及或者是调用的东西也是极为复杂而又繁多的,这大大增加了初次学习者的负担和压力,让人们学习它的过程充满艰辛、苦难、挑战和心酸(谁又知道本人是怎么过来的,苦啊),所以使用的时候要好好注意,努力学习,不要因困难而放弃。千般苦难都阻挡不了本人们对学习的热爱,本人们向往努力向往美好明天。
    5.2 程序流程图程序流程图又称为程序框图,是本人们学习并且作项目时常用的方法。本人们学习并且作项目时常用的方法,在本次毕业设中,也是必须有的。
    下面是是本人画的没有特殊权限的人群体系的图(Below is a diagram of the membership system I draw)。

    拥有特殊权限的人群子体系程序流程图( Mensen met speciale machtigingen systeem stroomschema)

    5.3 拥有特殊权利的人群子系统的实施虽然该系统的计划,但从后面,由系统拥有特殊权利的人群的系统到系统的成员。成员需要实际上是管理的网站的一部分的您的需要,更重要的是管理的网站的,管理系统的需要。基于背景的管理系统,并于次年由于各种实际数据在数据库中,前厅部系统会更清晰的原始版本。
    后台体系是给某些特殊权势的人群使用的,十分位豆子都猜等性质。
    5.3.1 连接数据库的包含文件数据库中的数据是动态 Web 页后,可以创建很多时候重复的代码。它存储了数据库连接参数,您必须编写的文件。JDBC 封装方法的对象系统在这里,使用 Hibernate,JDBC 数据库中,以便通过连接的连接。
    文件中数据库参数代码如下:

    5.3.2 拥有特殊权利的人群登录页面如果拥有特殊权利的人群要登录的话可以通过点击进入后台的按钮进入后台界面其对应的页面是Admin/adminLogin.jsp,本页是拥有特殊权利的人群子系统管理的入口,不会是什么人都能登录的,必须是特定的相关要求的人才能进出本系统,尤其是网站的后台管理系统,如果发生数据泄露的话将会给使用人带来巨大的损失,所以本次毕业设计的后台管理系统是不设及注册功能的。此消息的危地马拉页的主要派别是取悦不是拥有特殊权利的人群身份。访问页控制台后端系统如下图。

    其相应的页面代码如下图5-3.1(De bijbehorende code van de pagina hieronder 5-3.1)

    5.3.3 会员管理模块在系统主页面中点击会员管理进入会员管理页面。
    成员的 web 页将显示系统中用户的注册表数据。关于按钮 supprimer 是完全摆脱自己的所有成员和成员。对应 Admin/URURadminMember.domr?meth = browseMember,面对显示页的计划:5-4。

    对应的代码如图5-4.1(Overeenkomstige code in figuur 5-4.1)

    在后台管理界面中挑选无特殊权利人群的详情,就会跳转到其对应的资料路径是为Admin/adminMember.do? method=viewMember&id=1,然后就是查看无特殊权利人群的详细信息页面。页面显示如图5-5所示:

    其对应的JSP代码如图5-5.1(De overeenkomstige JSP-code in figuur 5-5.1)

    在后台管理中的界面中挑中留言管理按钮,就会跳转到对应的资料路径,就会进入到查看没有特殊权利的人群的留言信息页面。页面设计如图5-6所示:

    其中对应JSP代码如图5-6.1(Die de bijbehorende JSP-code in figuur 5-6.1)

    5.3.4 产品控制模块产品控制的显示(Paj pwensipal pwodwi jesyon)
    一些特殊权利人群去挑中按钮来对产品实施相关操纵,其中大都是添加修改删除搜索管理。==相当的方法是method=browseMer,页面的设计如图5-7所示:

    修改产品资料(Modifiseer produk inligting)
    跳入相应产品的具体内容侦查相信的资料。==相当的方法是 method=loadMer&id=1,页面的设计如图5-8所示:

    其中“提交”按钮的代码设计如图5-8.1:(Die “stuur” knoppie kode is as volg:)

    5.3.5 特价商品管理模块拥有特殊权利的人群对特价商品信息进行管理。==相当的可能方法为 method=browseSMer,==相当的页面显示如图5-9所示:

    其中对应的JSP代码如图5-9.1:(JSP kode een soos in figuur 5-9.1:)

    拥有特殊权利的人群挑中查看详情查看产品的详细情况,如图5-9.2:

    其对应的JSP代码如图5-9.3:

    挑中修改商品的选择,如图5-9.4(Uchukuzi iliyobadilishwa uteuzi wa bidhaa, kama inavyoonyeshwa katika Kielelezo 5-9.4)

    相应的JSP代码,如图5-9.5(Msimbo JSP, kama inavyoonyeshwa katika Kielelezo 5-9.5)

    挑中新增特价商品就能添加商品,如图5-9.6(alichagua Ongeza mpya specials wataweza kuongeza kipengee, kama inavyoonyeshwa katika Kielelezo 5-9.6)

    对应的JSP代码如图5-9.6(Msimbo wa JSP inayoendana na Kielelezo 5-9.6)

    5.3.6 订单模块拥有特殊权利的人群对没有特殊权利的人群的订单信息进行审阅和去掉控制。
    订单控制的显示中显示全部订单信息,==相当的方法为Admin/adminOrder.do? method=browseOrder,对应的页面设计如图5-10所示:

    在单子相关操作的相关资料中挑中相关资料操纵,审查单子的详细信息,==相当的磁盘文件为Admin/adminOrder.do? method=viewOrder&id=7,对应的页面显示如图5-11所示:Ukurasa ufaao inaonekana kama inavyoonyeshwa katika Kielelezo 5-11:

    5.3.7 系统用户管理模块本次毕业设计的特殊权利人群去对相关资料实施大部分系统都会进行的操纵。
    本系统的特殊权利人群的主页面,==相当的方法是 method=browseAdmin,对应的页面设计如图5-12所示:Sanifu ya ukurasa sambamba unaonyeshwa katika Kielelezo 5-12:

    修改拥有特殊权利的人群信息页面,==相当的可能方法设计是method=loadAdmin&id=2,对应的页面显示如图5-13所示:

    填加没有特殊权利的人群信息页面,如图5-13.1。

    5.3.8 商品类别管理模块拥有特殊权利的人群对商品的类别信息加以增加删除更改查看处理其对应的可能方法是Admin/adminCate.do? method=browseCate,==想当的页面设计,图5-14:

    5.4 会员子系统5.4.1 相关的显示在这个相关资料中标记有很多事实是上帝需要的可以看到的能供人们使用和坚持的。供人们使用生产选中。==相当的方法为wgsc/mer.do? method=browseIndexMer,==相当的页面设计如图5-15所示:

    其中“登录”按钮的代码是:(”Kuingia” kitufe msimbo ni:)

    5.4.2 会员注册页面查看页面的房子,请单击登录页面注册成员按钮。相应的磁盘之后的其他规则和相应的页面的图 5-16 的脸,在这里,使用系统技术 Struts 的检查数据从没有特殊权利的人群的人:

    5.4.3 搜索商品信息页面在主页面中输入要搜索的关键字,点击搜索按钮,显示相应信息。对应的磁盘文件1.输入单词搜索页,主要单击按钮搜索来显示相应的信息。相应可能方法mer.do? method=searchMer&cateid=0,在脸上 5-17 的相应计划页的显示︰

    挑选搜索结果页面以查看详细信息的另一个,相应提交磁盘嗅到植物的详细信息对应的可能方法为mer.do? method=showMer&id=1,对应显示,图5-18的纸皮上:

    5.4.4 购物车的信息页面没有特殊权利的人群查看购物车中的商品信息。对应的可能方法为cart.do? method=browseCart,相当的可能的资料显示,图5-19:

    没有特殊权利的人群在相应的设施中挑中下一步进入提交订单页面。对应的磁盘文件为cart.do? method=checkOrder,相当的可能的资料显示如图5-20:

    挑选订单键来生产制造出成订单。对应的可能方法为cart.do? method=submitOrder,==相当的资料显示,图5-21:

    5.4.5 单子操控显示没有特殊权利的人群查看订单管理界面并对订单进行相应操纵等方法。==相当的可能方法为order.do? method=browseOrder,对应的页面显示如图5-22所示:

    5.4.6 顾客留言页面没有特殊权利的人群查看和发布留言信息。==相当的可能方法为mem.do? method=browseWord,相当的页面显示如图5-23所示:

    5.4.7 修改资料页面没有特殊权利的人群更改与团体相反的东西的资料。==相当的可能方法为mem.do? method=loadMember,相当的页面显示如图5-24所示:

    6 测试与维护6.1 测试的任务及目标6.1.1 测试的任务在本系统开发完成之后,通过相应的测试方法测出系统中的错误,以减少后期时间和成本花费。
    6.1.2 测试的目标
    是为了找到系统中的错误而做的行为
    是用来发现还没找到的question

    6.2 测试方案弄这个让人熟悉的东西是为了让本人让老师让同学让人们看看可能的question。本人们所说测试进行是不停地对系统导进本人们提前写好的东西,导出本人们的提前制定好的从而验证系统的功能,进而找到功能问题。在校老师长江的方法大概有两种,这里就不继续唠叨了,就在后面再一一介绍。
    黑盒测试,用来对编写好的类进行尝试(输入测试数据,得到结果),不管程序的内容如何,只查看程序的功能是否符合规格说明书的规范,程序是可以接收输入的资料产生测试人员预定的输出信息,而且要能够保持不破坏除这个接口以外的其他部分的信息。
    结构测试,要求程序开发人员必须深刻了解程序的内部构造和逻辑处理过程,进行这种测试方法对开发人员的能力要求比较高,他们必须了解程序内部的逻辑脚本和算法每一条每一列都要清清楚楚明明白白才能顺着顺序往下执行。
    6.2.1 模块测试也叫单元测试是将每一个可以分割的程序封层一个一个的单位,然后分别审查每一个单位的能力看有没有问题、哪里不顺畅、要坚定的这行下去。
    模块测试主要由代码审查和软件测试两部分组成[1]。
    在“基于Web的农产品销售管理系统”中经常有模块测试不通,但有可能整体确定能够运行,在下次出问题,所以模块测试非常有必要,不经过它,你几乎完不成测试,更别提随后的集成测试、验收测试。
    6.2.2 集成测试本次毕业设计中在这里卡住了,为了这个集成测试,本人苦思冥想、夜不能睡,每时每刻都在想着如何才能解决,前面的单元测试保证了每个模块都能正常运行,但一到一起运行时,不是这出问题(数据交互出错),就是那出问题(模块冲突不兼容),错误报告杂乱无章,不好找到问题,心都快碎了,后来静下心来,认真研读代码,一步一步排除错误,终于找到问题所在。
    从这件事中本人们懂得了集成测试是非常有必要的,它为本人们检查并暴露了本次毕业设计中的问题,进而通过解决这些问题使程序终于能够顺利运行了,前期做的越少后期就做的越少:

    编写的测试软件较少,开销较小
    错误位置容易判断
    测试更彻底

    6.2.3 验收测试这一步是验证软件的有效性。目的是老师证明本系统能够正常运作并达到最基本的功能要求,本次毕业设计的使用是黑盒测试,最终的概率为:

    可能与毕业设计的发现可能相符合,设计的系统是可以接受的
    界面不够美观,功能有待加强,还有提升的空间

    在这一阶段测试发现的问题,仔细想想就能发现其实和需求分析阶段的报告是有关联的。所以最好就在需求分析阶段等之类的前阶段就把问题、需求弄好。否则越往后,错误修改成本越高。
    6.2.4 平行运行本人们程序员所谓的平行运行就是同时运行。本次的毕业设计和以前相似的体系功能作copy,可以来知道本人们设计的能力如何。
    6.3 设计测试方案测试方案是本次毕业设计中最重要的一部分之一,本人设计方案时,用到的是最简单的黑盒测试,并且还是简单的一些测试组成立简单的测试方案,用了一些简单的逻辑就组成了好用的测试,本人测试了数据的可用性包括但不限于长度的限制、特殊字符的应用。编写测试用例时常常遇到数据走不通,用system.out.print方法输出语句俩查看哪里是错误真的非常可悲而又可怜,测试它为什么是这里的错误,最后发现是数据库中表之间的关联导致数据紊乱今儿是这里出现错误,但也是本人的失败疏忽,不断的书写,是本人对系统有了更深的认知、更规整的思路规划与感悟,都将是本人以后要用到的都将是本人的人生宝贵的财富。
    6.4 系统维护系统维护是对后期系统的修补维持运行与升级,在你系统做好能够运行了之后,并不是说就可以万事大吉了,你往往还要不停地修改增加功能使其更好用更全面更符合客户需求,在现在不断发展的互联网落实带,万事万物包括软件都在不停的更新进步并且不断淘汰落后的陈腐的旧的事物可以预见现在新奇的好看的好用的漂亮的有很大用处的很多优点的事物在随后的一段时间里必将过时落后淘汰,例如,手机产业中的华为、小米、iPhone等不停地更新他们的产品,哪怕是刚研发出来、很新的产品对他们来说研发出来了那就过时了,在市场还没流行或刚开始流行的时候他们已经开始开发下一版本的、更新的产品了,记得在本人在公司实习的那段时候有一次加班去完成任务发现组长和老员工们还在加班,回到家之后就睡了,凌晨1:00左右发现组长的QQ还在亮着,也就是说组长还在工作,真养的奉献精神值得人们钦佩与学习,刚好明天是周六,他们却要结束现在是版本,周六加班去开发新的版本,时间很是紧张,任务很是艰巨,从这里可以看出公司的产品更新是很快的,更可以看出互联网行业的东西更新淘汰的速度是多么快啊,所以软件的维护与升级是多么的重要,它已经成为各个软件行业的最重要的环节之一了,它让本人们的系统能够正常也能运行与使用,防止用户在使用中突然出现错误bug导致系统崩溃甚至用户数据泄露从而造成巨大的损失,那么本人们的系统不仅是前功尽弃、白做了,还要承担巨量的赔偿损失费,得不偿失啊,所以再次告诫各位朋友们,做系统一定不能忽略系统的后期维护。
    参考文献[1] 孙卫琴,Tomcat与web开发技术详解[M],北京:电子工业出版社,2004
    [2] 赵瑞雪,农业企业物业管理管理系统研制[J].计算机与农业,2003,30(5):80-84.
    [3] 陆惠恩,软件工程基础[M],北京:人们邮电出版社,2005:19-20
    [4] 罗辉,web商务系统的设计与实现[J],电脑与信息技术,2008,(1):165-168
    [5] 汪泉,我国农业电子商务的SWOT分析及应对策略[J].北京农业职业学院学报, 2006,20(6):19-22
    [6] 林丽蓉,论农业电子商务与农业化[J],湖北经济学院学报,2007.4
    [7] 石见,研究和建立农产品市场信息社会服务体系[J],农业信息探索,1998,(5)
    [8] Raymond Frost. 数据库设计与开发[M].北京:清华大学出版社,2007.
    [9] 福勒.UML:精髓标准对象建模语言简明指南[M].北京:电子工业出版社.2012.70-90
    [10] Steven Roman. Access Database Design &Programming[M]. USA: O. Reilly,1999-07
    [11] DENG XF,LV XN,ZHENG SY,et al. GIS-based agricultural products safety traceability system[J]. Transactions of the Chinese Society of Agricultural Engineering,2008,24: 172 -176.
    [12] YANG XT,QIAN JP,ZHANG Z,et al. Design of agricultural product trace coding based on geography coordinate and multi-encrypt [J]. Transactions of the Chinese Society of Agricultural Engineering,2009,25( 7) : 131 -135.
    [13] LING J,XIE R,HE XT. On . net-based food quality and safety tracing technique and its implementation[J]. Computer Applications and Software,2010,27( 1) : 145 -147.
    [14] MENG M,LIANG WH,SONG QD,et al. Coding research of circulation code and back yards of agricultural products[J]. Chinese Journal of Tropical Agriculture,2010,30( 1) : 82 -85.
    4 评论 136 下载 2020-08-03 19:00:05 下载需要14点积分
  • 基于Java实现的斯诺克台球小游戏

    一、引入Snooker,中文一般作:斯诺克,本意是“阻碍、障碍”,所以斯诺克台球有时也被称为障碍台球。它流行于英国、爱尔兰、加拿大、澳大利亚和印度等英联邦国家以及香港 等地,是一种高雅的双人游戏。游戏规则是两人轮流用球杆击白色主球,通过主球按一定的次序撞击球桌上的其他球入网得分,最后得分高者胜。
    二、背景斯诺克游戏的起源一般认为是在公元1875年,由驻扎在印度的一位英国军官内维尔•鲍斯•张伯伦(Neville Bowes Chamberlain)和他的战友们首先发明的。
    其实在斯诺克产生之前,台球游戏早就存在,而且有多种玩法。其中,有一种叫做“黑球入袋”(Black Pool)的玩法,在维尔•鲍斯•张伯伦所在的军队中非常流行。这种玩法用1个白球,15个红球和1个黑球。有一天,维尔•鲍斯•张伯伦和他的战友们觉得“黑球入袋”的玩法太简单、乏味,便决定增加黄色、绿色、粉色三个彩球上去。不久,他们还是嫌球不够,再加上了棕色球和蓝色球。这样,便形成了至今已风行全球的22个球的斯诺克台球。
    据说,斯诺克台球的命名也与维尔•鲍斯•张伯伦有关。有一次,维尔•鲍斯•张伯伦同一个伙伴在打这种由他们新发明的22个球的台球时,一个很容易的进球,对方没有打中。他便顺口戏谑对方是斯诺克(斯诺克是那时当地军事院里对一年级新生的流行称法)。他这么顺口一叫,提醒了大家,使大家意识到,对于这种新的台球玩法,大家都是新手,都是斯诺克。于是,斯诺克的叫法便开始流行并固定下来。
    而将斯诺克带回英国的是英国人约翰•罗伯特(John Roberts)。1885年,当时的英国英式台球冠军约翰•罗伯特在印度旅行时见到了张伯伦并从他那里知道了斯诺克的这种新玩法。于是,罗伯特就把斯诺克台球带回到英格兰。但是,当时在英国传统的BILLIARDS台球(英式台球)占据着主导地位,被认为是正统的和科学的玩法。斯诺克台球一时只能是民间的一种娱乐方式,难于登上大雅之堂。 一直到了20世纪30年代,英式台球日渐衰落,许多名手才逐渐转向斯诺克台球。其间出现了斯诺克大明星乔•戴维斯(Joe Davis),斯诺克台球才真正开始在英国流行。
    与高尔夫差不多,斯诺克要求选手在任何级别的比赛上,在任何时候都有要具备高标准的礼仪举止。无论是在地方联赛上,还是在职业联赛中的高级别赛上,这一规定均适用。

    在比赛开始和结束时,要和对手握手
    在比赛开始和结束时,要和裁判握手
    无论何时,都要将自己所有的犯规行为时行申报
    不能站在对手的击球线上
    在比赛仍在进行时,不能随意对对手的运气进行评论
    在比赛仍在进行时,不能对比赛形势表达不满
    当你的对手在台面击球时,不能划火柴或点燃打火机,别外要避免咳嗽出声
    在某盘或某场比赛中,当你击失一杆或你的对手仍在台面击球时,不能认输。等到你的对手击完球后,方可认输
    不能与裁判或你的对手进行争论

    就以上的这些礼仪,足以体现斯诺克游戏的高雅。
    在斯诺克游戏球的制作上,历史上曾使用过昂贵的象牙。二战以前改用较为轻便的微晶球,而现在的球全部是用高级合成树脂制造。
    三、逻辑抽象整个游戏其实就是对球的位置、速度、加速度等实际的物理量进行计算机模拟处理。为了较高真实度地还原整个物理过程而又不至于算法太复杂以至于作者有限的能力无法完成游戏代码的编写工作,提出以下模型及假设:

    由于斯诺克游戏球的制作材料弹性系数很高,在对球与球的碰撞处理上取弹性系数 为1,即完全弹性碰撞。对球与桌边的碰撞采用相同的处理方式
    球的位置是在以桌面为基面的二维空间上的点(以球心计),球的速度是该二维空间内的矢量
    不考虑球的绕球心的旋转运动
    不考虑球的滑动滚动,即对球滚动的处理都认为是无滑滚动
    处理碰撞时,不考虑切向的摩擦作用力

    四、目标通过对 java面向对象特性的系统地学习,运用多媒体处理、图形处理等相关技术,完成一个集竞技性、娱乐性、可移植性强的游戏。
    视觉上
    java本身自带很多功能强大的图像图形处理的类,学会熟练地使用它们,并将其有效、合理地运用到游戏的开发中去。如多使用 png 图片等来获得透明的物体。运用双缓冲 (Double-buffering)技术,来减少、消除游戏过程中的画面闪烁问题,以获得良好的动态感。另外采用多线程 (Silberschatz, Galvin, & Gagne, 2007)(Thread: A thread is a basic unit of CPU utilization; it comprises a thread ID, a program counter, a register set, and a stack. It shares with other threads belonging to the same process its code section, data section, and other operating-system resources, such as open files and signals.)技术来定时刷新画面。
    听觉上
    使用java来播放游戏过程中产生的诸如球与球相碰、球与桌相碰的声音及游戏开始和游戏整个过程的背景音乐等。
    五、算法设计作为一个球类游戏,其中最难的就是对于球的碰撞处理,包括球与球之间的碰撞和球与球桌之间的碰撞。
    5.1 球与球的碰撞基于之前的假设,我们可以认为每个台球就是平面上的一个圆,设两球的圆心分别为P1(x1,y1), P2(x2, y2),球的半径为R,当两球相碰撞时必然有:

    无论多少个球同时相碰,我们都可以分解为两两球碰撞来处理,所以这里只需考虑两个球相碰拉情况,当有三个或更多球相碰时,认为是1号球先与2号球相碰,再是1号球与3号球相碰,等等。在实际运行中,发现这种处理方式真实场景的还原度还可以,且由于每次只处理两个球的碰撞,大大减少了编程的难度。

    如图 1所示,设两两碰撞时,球1的位置为P1,速度为(V1) ⃗,球2的位置为P2,速度为(V2) ⃗。连接两球的球心,设(V1) ⃗在(P1P2) ⃗上的投影为(S1) ⃗,(V2) ⃗的投影为(S2) ⃗。先考虑在一条直线上两物体发生完全弹性碰撞时的情况,由能量守恒,可以得:

    运量守恒:

    整理得:

    即在碰撞方向上,两质量相等的球完全弹性碰撞后会交换速度。而本程序中不考虑球之间的切向作用力,所以在碰撞方向垂直的方向上,球的速度不变。由此可以推出两球碰撞后的速度公式:

    式中的(S1) ⃗,(S2) ⃗矢量可以通过(V1) ⃗,(V2) ⃗与(P1P2) ⃗的单位矢量的点乘得到:


    5.2 球与桌的碰撞总体来讲,球与桌的碰撞可以为分两类:

    球与桌边碰撞
    球与桌角碰撞

    对于第一种情形,很好处理,只需将相应方向上的球速反向即可。对于第二种情形,均认为桌角是由半径等同台球半径的圆弧构成。

    如图 2,设球心位置为P,球速为V ⃗,桌角圆心位置为O,完全弹性碰撞后球速为(V‘) ⃗,只需将原球速在(PO) ⃗垂直方向上作对称即可。
    除了球的碰撞,另外一个比较难的问题是对玩家行为的判定,即游戏规则的实现。斯诺克游戏规则本身就相当复杂,游戏过程中会出现各种各样的情况。刚开局时,白球要首先碰到红球,如果没进,换人,如果进球了,作相应加分,然后将进了的彩球还原,并且下次必须首先碰到彩球。如果白球进了,对方加分,并换人……写个判断函数,人都搞晕。后来,一同学提示我可以用有限状态机 来实现,于是就试了试,果然清晰些了。于是按大体类别,将玩家所处的状态分为四类:

    初始状态:即刚开始游戏或刚换到此玩家。如果白球进了,换人,保持当前状态。如果先碰红球,且有进球,状态2 。其他,状态1
    合法碰到一个红球状态:如果白球进了,换人,状态1。如果先碰彩球,且有进球,状态3
    合法碰到一个彩球状态:如果白球进了,换人,状态1。如果先碰红球,且有进球,如果红球没了,状态4,其他,状态2
    没有红球状态:按照黄、绿、棕、蓝、粉、黑的顺序击球

    六、类的设计对于游戏可见的每个实体这里都要单独设计类,另外一些实际存在,对外有所表现但是没有实体的一些物理量也单独设计类,所以可以得到如下类的列表:

    七、流程设计游戏的整个流程图大致如下:

    八、问题描述调BUG的过程是痛苦的,调试好BUG后的心情是愉悦的。整个开发过程中遇到过不少的BUG,而有些BUG硬是跟踪跟到死也没看出些明堂来。
    首先一个,也是最严重的一个,同时也是调试后收获最大的一个,就是两球相碰后会出现粘在一起的情况。如下图:

    碰撞判断核心代码如下:
    for (int i = 0; i < balls.size(); i++) { Ball ball1 = balls.get(i); if (ball1.isIn()) continue; for (int j = i + 1; j < balls.size(); j++) { Ball ball2 = balls.get(j); if (ball2.isIn()) continue; if (ball1.isCollision(ball2)) { ball1.collision2(ball2); } }}
    大致就是双重循环,将每一不重复对球都判断一次,如果相碰,就执行碰撞。按理说这样之后它们的速度不会再相对了,所以下次应该不会再碰。但是下次进来时,程序仍然认为它们是相碰的。原来相碰是按两球心距离小于球半径的两倍来判断的,而相碰前一帧画面中,球速度可能很大,两球心已经很近了(小于两倍半径),碰后球速可能变小,在一帧画面中,两球相互远离后,距离仍在两倍半径内。发现问题后,我将 isCollisition 函数中的判定条件改宽了,只要距离小于半径的两倍再加上一个常数就算它们撞了,但是没能实际解决问题,无论常数多大。一次偶然的情况下,突然想到,球是否相碰不仅与位置,应该还与速度方向有关。即如果两球距离小于两倍半径,且它们的速度在相互靠近的话,就算碰撞了,远离就不算。
    这样在原有的代码基础上加了几行用于判断速度方向的代码:
    if (position.distance(ball.position) < 2 * radius + 2) { Speed t = new Speed(ball.position.getX() - this.position.getX(), ball.position.getY() - this.position.getY()); double t1 = this.speed.dot(t); // 球1速度在球心连线上的投影 double t2 = ball.speed.dot(t); // 球2速度在球心连线上的投影 if (t1 - t2 > 0) retn = true;}
    这次问题得到了解决!(略过其中的一个小手误)
    用同样的思想,也解决了球与桌子碰撞的问题。之前,一旦球碰到桌子边就会来回不停地碰,产生的原因其实与球粘一起是一样的,加入速度考虑后,问题就没有了!
    九、可改善提高之处限于本人的水平和时间的不足,本程序尚有很大的提高空间:

    游戏时没有添加任何按钮、菜单等,用户可操作性较差
    游戏过程中提示信息过少,不明白玩家不知道怎么玩
    击球时,没有瞄准线,玩家很难把握击球方向
    游戏结束后,不能重新开始
    没有练习模式
    不能人机对战
    ……
    0 评论 3 下载 2021-04-08 08:17:19 下载需要10点积分
  • 基于python实现的CS通信和P2P通信

    一、实验要求
    C/S通信实现要求

    两台计算机分别模拟服务器、客户端通过编程实现服务器端、客户端程序Socket,Client。服务器端程序监听客户端向服务器端发出的请求, 并返回数据给客户端。不采用方式,自定义通信协议,传输文件要足够大(例如:一个视频文件)
    P2P通信实验要求

    为每个peer开发服务器程序、客户端程序每个peer上线后,向服务器注册自己的通信信息假设peer3要下载文件 (视频),A与peer1,peer2都拥有A,请设计方案使peer3能够同时从peer1、peer2同时下载该文件,例如:从peer1下载A的前50%、同时从peer2下载后50%比较与C/S通信方式的性能指标

    二、简介
    本次实验使用Python3语言,在Linux操作系统上完成
    C/S通信部分:使用TCP作为传输层协议,使用固定头部 + 可变数据长度的应用层通信协议,能够解决TCP的分包、黏包问题
    P2P部分:研究并实现了简化版的有tracker服务器的Bittorrent协议。采用消息循环的设计方式,两台对等主机之间建立连接后各自开启一个线程,交换bitfield并初始化自身状态,进入消息循环,根据自身状态和收到的消息决定状态的转换和执行的操作。各台对等主机,以及对等主机和服务器之间的通信基于了C/S通信部分实现的可靠二进制文件传输模块

    下面,将详细描述C/S通信、P2P通信的协议和实现,并给出运行结果。
    三、C/S通信3.1 应用层协议C/S通信中采用TCP作为传输层协议,可以保证传输的文件流是有序且无误的。然而TCP作为一种流传输协议,应用层是无法获知接收缓冲区中一个文件起始和结束的位置。因此我们采用了固定头部+可变数据长度的应用层通信协议,我们将之命名为rdt_socket。

    3.2 服务端服务端在使用该协议时,首先建立普通的socket连接:
    import socketimport utilities #实用工具库,提供get_host_ip函数SERVER_IP = utilities.get_host_ip() #获取本机ipSERVER_PORT = 6666 #服务器端口固定为6666#获取socket文件,采用tcp连接 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#设置允许重用地址,防止程序退出后提示端口仍被占用server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)#开始监听端口server_socket.bind((SERVER_IP, SERVER_PORT))#设置最大连接数为MAX_TCP_LINKserver_socket.listen(MAX_TCP_LINK)#阻塞等待客户端接入(client_socket, address) = server_socket.accept()
    然后将该server_socket传入rdt_socket类,获得rdt_socket对象,然后将要发送的二进制文件传入sendBytes方法,该方法将在在其头部加上8字节的文件长度信息。
    def sendBytes(self, f : bytearray): try: #获取文件长度 l = len(f) #设置header header = struct.pack('!1Q', l) send_data = header + f #记录日志 logger.debug('Sending raw tcp data len {}'.format(len(send_data))) #使用socket发送该message self.s.sendall(send_data) #异常处理 except socket.error as e: print(e) print(e.filename)
    3.3 客户端客户端在使用该协议时,同样首先建立普通的TCP连接连接到服务器,然后将socket传入rdt_socket类,使用rdt_socket的recvBytes方法获取文件。
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect((SERVER_IP, SERVER_PORT))rdt_s = rdt_socket.rdt_socket(sock)data = rdt_s.recvBytes()
    recvBytes的实现如下,其基本思路是:
    首先检查缓冲区是否有8个字节的header,若有则检查缓冲区的长度是否有header中指出的文件长,若有则说明有一个文件可以取出了。该函数会首先检查当前TCP缓冲区中是否已经有有一个文件,如果没有,才会阻塞读取缓冲区,之后再检查是否有一个文件。
    def recvBytes(self): if len(self.databuf) >= FILE_HEADER_SIZE: header = struct.unpack("!1Q", self.databuf[:FILE_HEADER_SIZE]) body_size = header[0] if len(self.databuf) >= FILE_HEADER_SIZE + body_size: body = self.databuf[FILE_HEADER_SIZE:FILE_HEADER_SIZE + body_size] self.databuf = self.databuf[FILE_HEADER_SIZE+body_size:] return body while True: data = self.s.recv(1024) logger.debug('Received raw tcp data len {}'.format(len(data))) if data: self.databuf += data while True: if len(self.databuf) < FILE_HEADER_SIZE: break header = struct.unpack("!1Q", self.databuf[:FILE_HEADER_SIZE]) body_size = header[0] if len(self.databuf) < FILE_HEADER_SIZE + body_size: break body = self.databuf[FILE_HEADER_SIZE:FILE_HEADER_SIZE + body_size] self.databuf = self.databuf[FILE_HEADER_SIZE+body_size:] return body
    四、P2P通信4.1 协议下面我们将从三个方面分别介绍设计的P2P通信协议:

    Torrent文件格式
    Tracker — Peer协议
    Peer — Peer 协议

    4.1.1 Torrent文件格式Torrent文件的作用是:

    声明了一个P2P网络的tracker服务器地址和端口
    声明了在该P2P网路上共享的一个文件的文件名、长度、区块数、各区块哈希值,唯一确定了一个文件

    一个Peer在获取一个Torrent文件后,便可加入该P2P网络并获取该文件。
    使用(类)Json的语法描述Torrent文件如下:
    { announce: <str>, #domain name port: <int> comment: <str> info: <dict> { piece_length: <int> piece_hash: <list<str>> file_name: <str> file_length: <int> }}
    4.1.2 Tracker — Peer协议这部分协议提供了加入和退出P2P的机制。特别是使得加入P2P的Peer能够获取目前的Peer列表。
    Peer发送的Request格式
    包含:

    Peer的IP
    port,Peer的本地监听端口
    peer_id,由peer的ip和port组成
    event,可能值包括started(用于请求加入网络),stoped(未使用),completed(用于请求退出网络)

    { port: <int> (validator: 1~65536) ip (opt): <str>, (validator: 点分十进制表示法) peer_id: <str>, (peer ip + ':' + peer port) event: <str>, [(started) | (stopped) | (completed)]}
    Traker发送的Response格式
    包含:

    error_code,收到的请求有效时为0,非法请求则为1
    message,包括started ACK和disconnect ACK两种
    num-of-peer,请求前的peer数
    请求前P2P网络中的peer的id、端口、地址

    { error_code: <int> message: <str> num-of-peer: <int> peers: <list> [ { peer-id: <str> (peer ip + ':' + peer port) peer-port: <int> <validator: 1 - 65536> peer-ip: <str> <validator: 点分十进制表示法> } ]}
    该Response仅会向刚刚发送请求的peer发送。这样已经加入的peer不会收到新peer加入的消息,然而由于我们的设计是peer1向peer2主动建立一个peer connection连接时,peer2会同样会(被动地)和peer1建立一个peer connection,因此之前已经加入网络的Peer依旧能够与新Peer建立连接。
    4.1.3 Peer — Peer 协议Peer—Peer之间的协议在PeerConnection类中实现,如上文所述,一个P2P连接的两台主机会对等地,分别建立一个PeerConnection。
    每个PeerConnection维护两组状态,这两组状态分别用两个二进制位表示:

    send_file_state

    高位:my_choke,表示我是否停止向他人发送文件低位:peer_interested,表示他人是否需要从我获取文件
    recv_file_state

    高位:peer_choke,表示对方是否停止向我发送文件低位:my_interested,表示我是否需要从对方获取文件

    每个PeerConnection在建立之时首先进行交换bitfield的操作。
    每个PeerConnection以消息循环地方式工作,收到消息时,依据消息类型,可能导致SendFile状态机或RecvFileMachine发生状态转移并执行相应动作,我们使用下图的状态机转移图进行描述。类似课本rdt协议状态机的格式,图中每条线状态转移线上有两行注释,上面一行表示收到的导致转移发生的消息,下面一行表示执行的动作和发出的消息。

    Peer — Peer间的消息有以下几种

    Choke,发送该消息者拒绝向对方发送文件
    UnChoke,发送该消息者可以向对方发送文件
    Interested,发送该消息者需要从对方获取文件
    UnInterested,发送该消息者无需从对方获取文件
    Have,一方收到一个piece后,发送该消息通知对方已经完成接收该piece
    Bitfield,一方拥有的文件区块信息
    Request,一方向另一方请求piece,消息中包含piece编号
    Piece,一方收到request后回复的文件piece,包含文件内容
    KeepAlive,保持连接,接收者收到后忽略该消息
    ServerClose,一方通知另一方自己要关闭了,另一方收到该消息后也会关闭该peer Connection

    大多数消息均有以下三个字段:
    { type: <str> length: <int> message_id: <int>}
    特别地:

    KeepAlive消息没有message_id字段,可以根据它的length为0的特点判断其类型
    Bitfield消息有一个Bitfield字段,包含了自己的bitfield
    Request消息有一个piece_index字段,表示请求的piece的序号
    Piece消息有一个piece_index字段,表示自身序号;有一个raw_data字段,用以传送文件数据

    4.2 实现4.2.1 协议的消息传输协议中消息的传递是基于C/S通信中的二进制传输代码。
    Tracker — Peer协议的消息格式为Json,我们使用Json以下两端代码将Json转换和转换为二进制。
    def objEncode(obj): """ obj,返回binary对象 """ return json.dumps(obj,indent=4, sort_keys=True,separators=(',',':')).encode('utf-8')def objDecode(binary): """ binary 返回dict对象 """ return json.loads(binary.decode('utf-8'))
    Peer — Peer 协议中协议的原始格式也为Json,但Piece中的原始文件数据在使用objEncode编码时会出错,因此使用Python的Struct类进行转换。
    4.2.2 Tracker的实现Tracker端的实现在src/backend/server.py中,与之相关的有两个类,ServerMonitor和Server,均继承于threading类,通过实现threading类的Run函数,将主逻辑运行在线程中。
    ServerMonitor类的run函数处理用户输入,在输入q时终止Tracker。
    Server类的run函数监听并Peer呼入的连接,根据消息做出回复。
    available_peers_list函数返回当前Peer列表。START_ACK/COMPLETE_ACK两个函数方便地返回了两种Response消息。

    4.2.3 Peer的实现这部分是整个实现中的重点。
    实现在src/backend/client.py、src/backend/piecemanager.py、src/backend/state.py、src/backend/message.py几个文件中。
    由Client、PeerConnection、ClientMonitor、pieceManager这几个类实现,其中Client、PeerConnection、ClientMonitor三个类同样是继承与threading类,在run函数中,以多线程方式实现主逻辑。


    整个工作原理和流程如下:

    Client类主要完成整个初始化流程,它接收一个torrent文件和配置文件,在构造函数中读取这些文件进行初始化,并启动一个pieceManager
    pieceManager类管理本地文件分块,根据本机拥有的piece设置初始bitfield。并在拥有完整的bitfield时进行文件合并
    Client使用一个全局的线程安全队列left_pieces保存缺失的piece的编号。run函数运行时,根据pieceManager设置的初始bitfield初始化left_pieces。然后执行get_peers_list向tracker请求peer列表。收到后向这些peer中的指定个(目前为4个)peer主动发起连接
    之后,Client启动ClientMonitor,该类实现的是被动接收连接功能:它监听本地端口,阻塞循环接受来自其他线程的新连接。得到新的连接new_socket后,将new_socket传入并启动一个新的PeerConnection
    Client类的工作基本结束,开始循环询问pieces_manager是否已经获取全部piece。在后台线程中运行的PeerConnections首先发送Bitfield,然后进行着协议中描述的消息循环:在一个While循环中,阻塞接收消息。然后简单地if语句进行判断

    4.3 时序图我们以实验要求中的使用场景为例,绘制了整个下载过程的时序图,让整个过程更加清晰易懂。

    假设peer3要下载文件 (视频),A与peer1,peer2都拥有A,请设计方案使peer3能够同时从peer1、peer2同时下载该文件,例如:从peer1下载A的前50%、同时从peer2下载后50%。

    注:图中三个Peer Connection是并行执行的。

    4.4 安装部署及实验结果4.4.1 运行环境
    本项目在python3.5环境下开发并测试
    服务器与客户端均运行在同一个内网中

    4.4.2 TRACKER 服务器的部署需要做两件事情。

    制作 Torrent 文件
    导入Server类,运行 Tracker 服务器

    源代码可见:
    import osimport sys# 这里是源代码的路径,可自行修改为对应的相对路径或绝对路径。SRC_PATH = '../src/backend/'sys.path.insert(0, SRC_PATH)from torrent import *# 导入 种子文件 模块full_file = './seed/test.txt'# 制作种子文件,默认存到当前目录下make_torrent_file(full_file)# 运行server端os.system("python3 "+SRC_PATH+"server.py")
    4.4.3 BITTORRENT 客户端的部署
    从源代码中代入Client类
    使用种子文件,客户端配置文件,初始化客户端,并运行之

    import syssys.path.insert(0, '../../src/backend/')from client import *from torrent import *file_name = '../test.txt'test_torrent_file = file_name+'.torrent' # 种子文件相对路径test_config_file = './client_config.json' # 客户端配置文件client = Client(test_torrent_file,test_config_file)client.start()
    4.4.4 启动TRACKER服务器在命令行下执行以下指令:
    # 在demo文件夹下python3 make_torrent_and_start_tracker.py
    使用本机IP地址更新种子文件
    启动tracker服务器
    默认监听6666端口(可在server.py中修改端口号)

    启动后的界面:

    4.4.5 启动客户端在启动客户端前,确保种子文件已经更新。
    启动客户端的时候,客户端会做两件事情:

    读取Torrent文件,并将数据初始化到客户端内部数据中
    获知文件名后,检查”文件名_data/“文件夹下是否有历史数据块,有则加载,无则不管

    由此,区分出做种的Peer与请求文件下载的Peer
    同时,下载到一半的数据也可以被Peer加载做种
    在命令行执行以下命令:(均在demo文件夹下)
    cd seedpython3 seed_client.pycd c2python3 test2_client.py可启动多个客户端,启动截图:

    4.5 实验结果说明使用该Bittorrent客户端,完成了以下测试。

    一个有完整数据的 Peer 给多个 Peer 发送文件
    一个没有数据的 Peer 向多个有完整数据的 Peer 请求文件
    多个 Peer 相互请求文件

    每一个 Peer 都有部分数据,保证全部 Peer 拥有的数据块完整通过多线程技术,每一个 Peer 在请求数据块的时候发送已有数据块每一个 Peer 都能够获得完整文件

    4.5.1 测试一:发文件客户端已有文件vid.mp4.

    启动做种Peer:



    约花费了245.59s。
    4.5.2 测试二:Peer3 同时向Peer1、Peer2请求文件在上次测试中我们发现使用约7MB的文件测试时间过长,这次我们使用大小为109kb的文件进行测试。
    如下图所示,我将终端分为4个窗口,左上角是Tracker服务器,正在运行中。右上,左下分别是Peer1、Peer2。我在这三个窗口分别执行了ls | grep vid.mp4指令,确认了这两个Peer均有完整的该文件。右下是Peer3,它没有该文件。

    接下来执行Peer3,发现Peer1和Peer2的窗口中均有响应,正在向Peer3发送文件。

    最终Peer3获得完整的文件,共耗时4.27秒。

    五、性能比较C/S模式中,我们使用7191359bytes(7.1Mb)的文件进行测试,三次测试结果分别是12.900446s、13.298574s、13.488140s。平均时间为13.2291s,平均信道容量为4.1474 mbps。
    另外由上面的P2P测试可知,对应一个做种一个接受的速度为25kbs。可见速度还慢了许多,我们初步分析,这是由于P2P由于使用了大量多线程机制,然而在Python的全局线程锁的限制下,它是交替地(并发)而非同时(并行)地向多个Peer请求数据。为了验证这一结果,我测试了6个Peer向一个Peer同时发送文件,速度没有加快。我们看到右下角窗口中,获取文件的时间仍然是4秒多,而且还有7%的增长。
    2 评论 63 下载 2019-03-07 13:37:26 下载需要13点积分
  • 基于C语言的飞机票预订系统

    1 解题思路本题需要综合使用数据结构的知识。以此,将航班数据设计成链表形式即定义结构体,其中包含飞机序号,登机口作为数据域,next作为指针域,将此结构体称为Node。将乘客信息设计成特殊的结构体,结构体中包含乘客姓名,性别,目的地,舱位,座位号和身份证,并且用数组包含每个乘客的信息。再设计一个结构体,其中包含刚刚的数组,以及乘客总人数,将此结构体称为Sqlist。而函数执行时,首先将Sqlist初始化。然后进入switch选择,通过选择来执行不同的函数。首先创建航班链表,通过判断输入的飞机序号是不是等于0来判断是否输入完毕。然后输入乘客数据,输入所在飞机号和该飞机乘客容量,使用for循环依次将数组赋值。之后可以通过飞机链表和乘客数据分别查询航班的信息和乘客的信息。并且可以删除飞机信息。最后是将所输入的信息保存成txt格式的文件,以及可以从txt格式的文件中读出数据进行处理。
    2 函数调用图
    3 各函数功能// 创建飞机链表int createPlane(Node *L); // 删除飞机节点int deleteNode(Node *L); // 容器初始化int initSqList (sqList *S); // 构造乘客容器int createSqList (Node *L, sqList *S); // 创建新乘客int createCustomer(int i); // 搜寻航班int searchPlane(Node *L); // 搜寻航班int searchPlane(Node *L); // 保存数据int reserve(Node *L, sqList *S); // 读取数据int read(Node *L, sqList*S); // 主函数,流程控制int main();
    4 测试










    4 评论 287 下载 2018-11-05 09:16:45 下载需要9点积分
  • 基于JSP和MySQL的学生信息管理系统

    1 系统概述1.1 课设目的复习、巩固JavaWeb、数据库、AJAX、JQuery、HTML的基础知识,进一步加深对JSP(Java Server Pages)层框架框架技术的理解和掌握;课程设计为学生提供了一个既动手又动脑,独立实践的机会,将课本上的理论知识和实际有机的结合起来,锻炼学生的分析解决实际问题的能力。
    培养学生在项目开发中团队合作精神、创新意识及能力。
    1.2 课设内容本系统主要用于学校学生信息管理,总体任务是实现学生信息关系的系统化、规范化和自动化,其主要任务是用计算机对学生各种信息进行日常管理,如查询、修改、增加、删除,针对这些要求设计了学生管理信息系统。本课程设计主要解决与学生信息管理相关的问题,设计一个功能齐全的学生管理信息系统。同时实现学生档案信息的添加、删除、修改和查询;学生学籍的管理;课程的添加、修改、删除;学生成绩的录入和对学生成绩的分析等主要功能。
    2 需求分析2.1 可行性分析2.1.1 经济可行性对于信息系统的初次投资都是为了以后获得更大的经济或是社会利益。本系统很小,只是一个校内的交流网站,硬件上只需要一台笔记本电脑,用于管理员管理该系统,另外,因为它是基于B/S架构的,软件开发人员一人即可完成,不需要很强的经济支持,而且师生交流网站可以给学生和老师带来很大的方便,提高了效率,所以经济上的可行性是肯定的。
    2.1.2 技术可行性本系统主要使用JAVA/JSP语言开发系统,这两种语言具有简单易学的特性,把设计人员从繁琐复杂的界面设计中解脱处理。数据库管理系统选用Mysql作为数据库管理系统,它能够处理大量数据,同时保持数据的完整性并提供许多管理功能,它的灵活性、安全性和易用性为数据库编程提供了良好的条件。而且JAVA/JSP语言与Mysql数据库管理系统对系统的软硬件环境要求并不高,因此,系统的软件开发平台已成熟可行。
    2.1.3 操作可行性用户只要使用电脑,就能进行对系统操作。本系统具有易操作、易管理、交互性好的特点,在操作上是非常简单的。逃犯信息管理员可对客户进行验证,对平台的信息进行发布,修改,管理等功能。而这些功能都是比较简单可行的,这些功能也比较简单的,任何人员经过讲解都是没有问题的。因此,从操作上来说本系统是完全可行的。
    2.2 业务需求分析2.2.1 学生需求分析学生可以看到学校信息及放假日期,可以查看考试成绩,查看班级其他同学联系方式,可以修改个人信息。
    2.2.2 教师需求分析教师可以看到学校信息及通知,添加考试及登录学生成绩,查看其它教师联系方式,修改个人信息。
    2.2.3 管理员需求分析管理员要对教师,学生资料进行管理。可以查看教师列表,学生列表,对教师及学生的信息进行,增加,删除,修改,查找。可以发布考试及统计分析成绩,可以管理年级,班级,课程,还可以修改本系统。
    3 系统开发环境与工具3.1 系统开发环境网站运用eclipse IDEA开发工具,MySQL数据库,详细信息如下:

    操作系统平台:Windows10
    数据库平台:MySQL+Navicat8.6
    开发平台:My eclipse
    运行环境:Tomcat9.0
    系统架构:MVC(Model View Controller 模型-视图-控制器)设计模式
    软件开发语言:Java+SQL

    3.2 系统开发工具开发工具:My eclipse
    MyEclipse企业级工作平台(MyEclipseEnterprise Workbench ,简称MyEclipse)是对EclipseIDE的扩展,利用它我们可以在数据库和JavaEE的开发、发布以及应用程序服务器的整合方面极大的提高工作效率。它是功能丰富的JavaEE集成开发环境,包括了完备的编码、调试、测试和发布功能,完整支持HTML,Struts,JSP,CSS,Javascript,Spring,SQL,Hibernate。
    MyEclipse 是一个十分优秀的用于开发Java, J2EE的 Eclipse 插件集合,MyEclipse的功能非常强大,支持也十分广泛,尤其是对各种开源产品的支持十分不错。MyEclipse可以支持Java Servlet,AJAX,JSP,JSF,Struts,Spring,Hibernate,EJB3,JDBC数据库链接工具等多项功能。可以说MyEclipse是几乎囊括了所有主流开源产品的专属eclipse开发工具。
    Java中间件服务器:Tomcat 9
    Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。
    JDK开发工具包:JDK1.8
    JDK 全称Java Development Kit 是Java语言的软件开发工具包,JDK是整个Java开发的核心,他包含了Java的运行环境(JVM+Java系统类库)和Java工具。个人理解:如果说JRE是客户需要安装的,那么JDK就是开发人员所必须的,Java的开发是建立在JDK的基础上的,只有安装了JDK才能实现Java代码的编译(Javac)与运行(Java)以及其他的更多对于Java代码的操作。
    数据库: MySQL和Navicat for MySQL
    MySQL是一个关系型数据库管理系统, 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件。Navicat for MySQL 是一套管理和开发 MySQL的理想解决方案,支持单一程序,可同时连接到 MySQL。这个功能齐备的前端软件为数据库管理、开发和维护提供了直观而强大的图形界面,给 MySQL新手以及专业人士提供了一组全面的工具。

    4 系统设计4.1 系统结构设计学生信息管理系统架构图如图4-1-1所示:

    4.2 E-R图学生信息管理系统E-R图如图4-2-1所示:

    4.3 数据库设计本系统将数据存储在11个表中,分别是:
    用户表
    其中Type表示身份类型,1代表学生,2代表教师,3代表管理员。



    字段
    类型
    长度
    备注




    Id
    Int
    20
    主键


    Account
    Varchar
    30
    账号


    Password
    Varchar
    30
    密码


    Name
    Varchar
    30
    姓名


    Type
    Int
    20
    身份



    教师表



    字段
    类型
    长度
    备注




    Id
    Int
    20
    主键


    Number
    Int
    20
    教师编号


    Name
    Varchar
    30
    姓名


    Sex
    Varchar
    30
    性别


    Phone
    Varchar
    30
    手机号


    qq
    Int
    20
    QQ号


    Photo
    Image
    50
    照片



    系统信息表



    字段
    类型
    长度
    备注




    Id
    Int
    20
    主键


    Schoolname
    Varchar
    30
    学校名称


    Forbidteacher
    Bool
    20
    允许教师登录


    Forbidstudent
    Bool
    20
    允许学生登录


    Noticeteacher
    Varchar
    100
    教师通知


    Noticestudent
    Varchar
    100
    学生通知



    学生表
    其中CLazzid表示学生所属班级,Gradeid表示学生所属年级。



    字段
    类型
    长度
    备注




    Id
    Int
    20
    主键


    Number
    Int
    20
    学号


    Name
    Varchar
    30
    姓名


    Sex
    Varchar
    20
    性别


    Phone
    Varchar
    30
    电话号码


    qq
    Int
    20
    QQ号


    Photo
    Image
    50
    照片


    Clazzid
    Int
    20
    班级


    Gradeid
    Int
    20
    年级



    年级表&年级课程表
    其中Gradeid表示课程所属年级,Courseid表示该年级的课程。



    字段
    类型
    长度
    备注




    Id
    Int
    20
    主键


    Name
    Varchar
    30
    年级名称


    Gradeid
    Int
    20
    年级


    Coursedid
    Int
    20
    课程



    考试表
    其中Type表示考试类型,1为统考,2为平时考试,Remark表示考试备注, Courseid表示考试科目。



    字段
    类型
    长度
    备注




    Id
    Int
    20
    主键


    Name
    Varchar
    30
    考试名称


    Time
    Datetime
    30
    考试时间


    Remark
    Varchar
    100
    备注


    Type
    Int
    20
    考试类型


    Gradeid
    Int
    20
    所属年级


    Clazzid
    Int
    20
    所属班级


    Courseid
    Int
    20
    考试科目



    考试成绩表



    字段
    类型
    长度
    备注




    Id
    Int
    20
    主键


    Examid
    Int
    20
    所属考试


    Clazzid
    Int
    20
    所属班级


    Studentid
    Int
    20
    所属学生


    Gradeid
    Int
    20
    所属年级


    Courseid
    Int
    20
    考试科目


    Socre
    Int
    20
    成绩



    课程表&任课教师表



    字段
    类型
    长度
    备注




    Id
    Int
    20
    主键


    Name
    Varchar
    30
    科目名称


    Clazzid
    Int
    20
    所属班级


    Gradeid
    Int
    20
    所属年级


    Coursed
    Int
    20
    所教科目


    Teacherid
    Int
    20
    任课老师



    班级表



    字段
    类型
    长度
    备注




    Name
    Varchar
    30
    班级


    Gradeid
    Int
    20
    所属年级



    5 详细设计5.1 登录界面设计系统通过request.getParamete方法来读取用户账号密码及验证码。通过Integer.parseInt(request.getParameter(“type”))方法获取用户登陆类型。使用VCodeGenerator.java来生成随机验证码,通过if(!sVcode.equalsIgnoreCase(vcode)语句来判断用户验证码是否一致,如果不同则返回”vcodeError”验证码错误,如果相同则将账号密码进行封装。通过User loginUser = service.getAdmin(user)语句与数据库中账号密码相匹配,如果匹配失败则返回”loginError”。并重新登录,如果匹配相同通过request.getSession().setAttribute(“user”, loginUser)语句将其存储到session中,并登录系统,登录界面如图5-1-1所示。

    5.2 功能设计5.2.1 学生功能设计学生界面分为三个区域,分别是页面上部的信息栏,左侧导航栏,以及主要显示界面,如图所示。主要显示界面通过jsp中{systemInfo.schoolName}获取数据库中学校名称,通过{systemInfo.noticeStudent}获取学校通知。如图5-2-1所示。

    页面上信息栏为系统名称及学生姓名,通过request.getRequestDispatcher方法进入学生界面,使用jsp中{user.name}语句获取数据库的学生姓名。点击退出按钮可以退出系统。通过request.getSession().removeAttribute(“user”)退出系统清除用户数据,通response.sendRedirect(contextPath+”/index.jsp”)过语句使用户跳转到登录界面index实现退出登录。
    左侧功能栏分别提供成绩查询,班级通讯录,及个人信息修改等操作。
    学生点击教学管理时如图5-2-2所示。

    学生点击成绩查询时,通过StudentDaoImpl().getStudentList方法来获取该学生在数据库中的考试列表,通过examstudent.jsp中语句调用studentExamList(request, response)方法显示考试列表。当学生点击查看成绩示使用List<Map<String, Object>> list = dao.getScoreList(exam)语句获取该学生数据库中的该科成绩,通过examstudent.jsp中语句调用columnList(request, response)将成绩显示在页面上。当学生点击班级信息时如图5-2-3所示。

    通过getStudentList(String account, Page page)方法获取本班同学的班级表,可以看到其他同学的信息及联系方式,当学生选择一个同学说时点击查看按钮通过getStudent(String account)方法查看该同学的信息。通过getPhoto(HttpServletRequest request, HttpServletResponse response)方法来查看该同学的照片,学生点击系统管理时如图5-2-4所示。

    通过使用editStudent(Student student)方法来实现修改学生姓名,性别,手机号,qq号并通过List<Object> params = new LinkedList<>()将其存入数据库中。
    学生点击close file可以从本地将图片上传,使用setPhoto(String number, String fileName)方法实现将图片上传,并通过dao.update(“UPDATE student SET photo=? WHERE number=?”, new Object[]{photo, number})存储在数据库,实现头像的修改。
    当学生点击修改密码时,学生输入原密码与新密码,通过jsp中的var validate = $(“#editPassword”).form(“validate”)来查询原密码是否正确,如果原密码正确则通过dao.update(“UPDATE user SET password=? WHERE account=?”语句将新密码存入数据库中,实现修改密码并重新登录。
    5.2.2 教师功能设计教师界面如图5-2-5所示,与学生界面类似,由上侧信息栏,左侧功能栏及主要显示界面构成。上部信息栏与主要显示界面原理与学生界面相同,不再赘述。

    左侧功能栏为教学管理,教师信息,系统管理。
    教师点击教学管理时如图5-2-6所示:

    通过teacherExamList(String number)方法中Teacher teacher = new TeacherService().getTeacher(number)语句获取该教师信息,使用List<CourseItem> itemList = teacher.getCourseList()获取该教师的考试。教师可以进行,增加考试,登记成绩,统计成绩。
    教师点击添加按钮时,通过调用addExam(Exam exam)方法实现增加考试,通过getExamClazz中Teacher list = dao.getTeacherList(sql, new Object[]{number}, grade, clazz).get(0)语句获取该教师所教课程,教师选择一门课程进行考试,输入考试名称和时间,选择考试类型,还可以添加考试备注,点击添加后通过调用dao.insertReturnKeysTransaction语句实现录入考试信息添加到数据库中。
    教师点击登记成绩按钮时,通过getScoreList(Exam exam)方法教师可以查看成绩表单,并通过setScore(String[] score)方法实现对学生成绩的添加,点击提交后通过dao.updateBatch(“UPDATE escore SET score=? WHERE id=?”, param)语句调用dao层将其添加入数据库中。
    教师可在此页面选择班级查看成绩,并点击导出,系统通过exportScore(HttpServletResponse response, Exam exam)方法会下载一份.xls格式的excel表格,方便教师后续对成绩进行分析。
    左侧功能栏中教师信息及系统管理功能如图5-2-7与5-2-8所示。教师可在教师通讯录中查看其它教师信息及照片,在个人信息中可以修改密码,性别,联系方式和修改头像。其实现原理与学生端类似,不再赘述。
    教师通讯录

    个人信息页面

    5.2.3 管理员功能设计管理员页面与学生页面,教师页面类似。也是由上侧信息栏,左侧功能栏,主要显示区域。上册信息栏与主要显示界面与学生页面,教师页面实现方式相同,但是管理员主页面里,其下方系统信息写在jsp中。其界面如图5-2-9所示。

    左侧功能栏包括五部分,分别是成绩统计分析,学生信息管理,教师信息管理,基础信息管理及系统信息。
    管理员点击成绩分析统计时,其界面如图5-2-10所示。

    管理员端通过使用getExamList(Exam exam, Page page)方法获取所有考试数据。管理员可以对考试进行增加,删除及统计成绩。其中,增加与统计成绩实现方法与教师端相同,但是在增加考试中要注意,管理员所增加的考试Type值默认是1,即管理员只能增加年级统考,与教师端不同的是,管理员多出一个删除考试按钮,通过deleteExam(int id)方法实现。同时通过jsp会发出提醒:“将删除与本次考试相关的所有成绩,确认继续?” 。
    管理员点击学生信息管理时如图5-2-11所示。

    通过getClazzList(String gradeid)方法来获取某一年级下全部班级,然后通过getStudentList(Student student, Page page)方法来获取某一班级全部学生并分页展示。管理员可对学生信息进行增加,修改,删除操作。还可以点击删除旁边的两个按钮选择指定年级与班级。
    管理员点击添加时通过addStudent(Student student)方法实现增加学生。当管理员点击修改时,通过editStudent(Student student)方法实现修改学生信息。当管理员点击删除通过deleteStudent(String[] ids, String[] numbers)方法实现删除学生信息。
    管理员点击教师信息管理时如图5-2-12所示。

    其功能实现与学生信息管理页面基本相同,但是教师信息界面多出所教年级及所教课程,通过getTeacher(String number),getExamClazz(String number, Grade grade)方法实现从数据库中读取数据。
    管理员点击基础信息管理时,左侧功能栏分别有三个选项,分别是年级列表,班级列表,课程列表。界面如图5-2-13所示。

    点击年级列表时如图5-2-14所示。
    通过getGradeList(String course)方法实现获取所有年级,通过方法中List<Object> gradeCourse = dao.getLis语句获取年级所有课程。

    点击年级列表主界面添加按钮时通过addGrade(String name, String[] clazzids)方法实现添加,并通过方法中Object[][] params = new Object[clazzids.length][2]语句实现增加年级课程。
    点击年级列表主界面删除按钮时通过使用deleteGrade(int gradeid)方法实现删除年级。
    点击班级列表时如图5-2-15所示。
    通过getClazzList(String gradeid)方法获取年级下的所有班级。

    点击班级列表主界面添加按钮时通过addClazz(String name, String gradeid)方法实现增加班级。
    点击班级列表主界面删除按钮时通过deleteClazz(int clazzid)方法实现删除班级。
    点击课程列表如图5-2-16所示。
    点击课程列表时通过getCourseList(String gradeid)方法实现获取所有课程。

    点击课程列表主界面添加按钮时通过addCourse(Course course)方法实现添加课程。
    点击课程列表删除按钮时通过deleteClazz(int courseid)方法实现删除课程。
    管理员点击系统管理时界面如图5-2-17所示。

    管理员通过editSystemInfo(String name, String value)方法实现修改学校名称,教师通知,学生通知。通知方式在学生端中已经介绍。通过adminPersonal.jsp中{systemInfo.forbidTeacher == 1 ? ‘checked’ : ‘’},{systemInfo.forbidStudent == 1 ? ‘checked’ : ‘’}语句控制是否允许教师,学生登录。
    点击管理员主要显示界面保存按钮使用editSystemInfo方法中的update(“UPDATE system SET “+name+” = ?”, new Object[]{value}语句将信息保存入数据库中
    修改密码功能实现与学生端相同,不再赘述。
    6 总结JAVA是一门优秀的编程语言,具有面向对象,与平台无关,安全、稳定和多线程等特点,是目前软件设计中极为健全的语言。
    经过一学期的JAVA学习,对JAVA编程有了一定的认识,在做这个程序设计的时期,刚开始感觉自己无从下手,不知道该怎么开始,很茫然。之后我查阅各种资料,无论是书本上的,还是网上的,只要是我认为有价值的,我都认真看,分析。接着,结合老师的教学视频,我就在一张白纸上列出了自己的思路。终于在努力完成了逃犯信息管理系统这一项目。当程序运行结果看到自己所想达的要求界面时感到很欣慰,虽然只是一个小的项目,但是却是又第一次完成的一个完整项目,我也从中学到了很多书本知识不能体现的东西,对JAVA也有了更深一步的认识与了解。
    经过这次课题的设计并实现,尽管会遇到很多难题,但是让我更加受益的是在这次课题中得到的经验、心得和锻炼。我发现做实验的过程其实就是个不断的解决问题的过程,从中也感觉到实验成功的快乐,一个人永远有学不玩的知识,就算是实验中的知识点都学了,但在实际的应用过程中仍然会遇到不少问题,遇到问题时要做到两点:一个是“查”,一个是“问”。不懂的地方就得要自己找答案,可以从书本、网络中查找解决的答案;再一个就是问周边的同学。这次课程的设计给我所学的知识做了一个总结,为我深入学习编程做了铺垫。在本课题中存在的不足之处是在所难免的,本人将在日后加于改进。

    参考文献[1] 徐传运、张杨、王森. Java高级程序设计. 北京:清华大学出版社,2014年6月.
    [2] 缪亮、陶颖. Web前端设计与开发. 北京:清华大学出版社,2018年4月.
    [3] 黄文娟. 基于Java和MySQL的图书馆信息化管理系统设计[J]. 电子设计工程,2019,27(02):20-24.
    [4] 叶春凤.“项目带动教学”模式在Java课程中的应用[J]. 福建电脑,2019,35(01):175.
    [5] https://www.w3school.com.cn/#.
    1 评论 45 下载 2020-10-23 08:55:49 下载需要14点积分
  • 基于JSP和MySQL的进销存管理系统的设计与实现

    摘 要进入21世纪以来,商业管理中需要处理的数据和信息越来越多。大量的数据和繁杂的数据使得古老的手工处理数据的方式渐渐显得力不从心。甚至有些信息处理的方式在手工处理的模式下是根本无法是实现的,只能利用计算机的高运行频率来进行迭代计算。而且最近国家正在提倡大众创业,中小型企业很多。中小企业在我国经济发展中具有重要地位,目前我国的中小企业数量多,地区分布广泛,行业分布跨度大。随着全球经济一体化的发展和电子商务的兴起,中小企业之间的竞争将越来越激烈。网络及电子商务的迅猛发展突破了时间、空间的局限性,给中小企业带来了更多的发展机会,同时也增大了企业之间的竞争强度。这就要求中小企业必须改变企业的经营管理模式,提高企业的运营效率。随着技术发展,电脑操作及管理日趋简化,电脑知识日趋普及,同时市场经济快速多变,竞争激烈,企业采用电脑管理进货、库存、销售等诸多环节也已成为必然趋势。
    关键词:进销存管理系统;B/S结构;mysql数据库;JSP;spring;springMVC;spring boot;JPA
    ABSTRACTSince twenty-first Century, more and more data and information are needed in business management. A large number of data and complex data makes the ancient way of manual processing of data gradually appear inadequate. Even some of the information processing in the manual processing mode can not be achieved at all, only the use of the computer’s high operating frequency for iterative calculation. And recently, the country is promoting public entrepreneurship, many small and medium enterprises. Small and medium-sized enterprises play an important role in China’s economic development. At present, there are a large number of small and medium-sized enterprises in china. With the development of global economic integration and the rise of e-commerce, the competition between small and medium enterprises will become more and more fierce. The rapid development of network and electronic commerce has broken through the limitation of time and space, and has brought more opportunities for the development of small and medium-sized enterprises. This requires the small and medium-sized enterprises must change the mode of operation and management of enterprises, improve the operational efficiency of enterprises. With the development of computer technology, operation and management is simplified, the growing popularity of computer knowledge, and fast changing market economy, intense competition, enterprise computer management purch asing inventory sales and many other sectors and has become an inevitable trend.
    Keywords: Purchase, sales and inventory management system; B / S structure; Mysql Database; JSP; Spring;SpringMVC;spring boot;JPA
    第一章 绪论1.1 研究背景和意义目前,许多的中小企业普遍存在一个问题:企业的决策者看到的进销存资料及相关报表都是比较繁杂,让本应该一目了然的结果因信息的分散使得产生的结果无法保持一致和完整,造成企业在进销存管理上问题很多。由此发展而来的进销存管理系统就能够很好的解决上面出现的问题,能够将数据快速转化为有效信息,为企业管理者制定生存发展决策提供了依据。
    在现今社会中,各个产品的质量都相差不大,现在顾客对个性化服务的期望值越来越高,在产品质量一样的情况下顾客更看重的是哪家的服务更好。企业的竞争已渐渐从产品的竞争这个战场转变到服务的竞争这个战场,因此企业要发展的话就必须要进一步优化业务流程来提高企业自身的竞争能力。因此,加强进销存管理是企业能适应现阶段发展的必然,通过计算机来快速准确地完成大量本来由人工手工完成的工作,这是真正达到合理和充分利用现有资源,减轻了员工的工作压力,提高了企业的生产效率。
    信息已深入到现代社会的各个行业,因此信息的管理需要有一个信息管理系统,进销存管理系统就是这样一个系统。进销存管理系统开发的市场将是非常庞大的。在这飞速发展的信息时代,这类的信息管理系统的开发为中小型企业带来了方便和有效的信息,促进了经济的发展。
    1.2 研究目标实现一个进销存管理系统,实现对企业运作过程中的进货、销售、仓储的电子化操作,可以节省大量人力物力,可以说对企业的运作带来不可限量的好处。实现一个简单实用,操作界面友好的进销存管理系统是首要解决的任务。然后一是要实现对库存数据进行分析,对接下来的进货进行一些指导;二是实现对销售数据的采集分析,对企业决策者对下一个季度或者年份的销售计划提供一个参考的功能。系统肯定要具备对进销存的一些基本的增删改查操作。
    1.3 论文结构
    第一章绪论:主要叙述了进销存管理系统开发的缘由和意义,也就是开发这个系统的背景。开发这个系统有哪些优点,开发的这个系统具备哪一些功能,或者说能开发出哪些功能,对这些功能进行了一个概述
    第二章相关技术和方法:本章节首先是概述了系统的结构,用那些技术搭建的开发环境;接下来是简单介绍了一下关键功能和是怎么实现这些关键功能;最后是介绍了用到的开发工具
    第三章系统分析:本章节的重点系统分析,主要从可行性分析和需求分析两方面入手。可行性分析从技术可行性、经济可行性、操作可行性三个方面进行综合分析,最终得出系统开发的可行;需求分析从两个方面分析:系统总体需求和用例图分析,从这两个方面确定系统是可行的
    第四章系统设计:本章节主要分为系统类设计、关键业务设计、数据库设计三个模块。系统类设计主要是用类图来呈现系统中类的一些属性和功能;关键业务设计主要是用顺序图来直观的呈现这些功能的处理流程和处理步骤;数据库设计首先是用了ER图来直观的把数据库表的一些属性表示出来,其次对涉及到的每一张表都进行了分析和介绍
    第五章系统实现:本章节主要是对核心功能介绍,首先是功能描述,然后附上实现的界面,接下来详细描述功能的实现过程并且附上实现这些功能的核心代码
    第六章系统测试:本章是说明测试目标和测试计划,对测试目标给出测试用例,并分析测试结果是否达到系统预期,如未达到提出改进的措施
    第七章总结:本章主要是对进销存系统的设计的整个过程做一个总结,说明本论文的结构组成,从绪论开始到总结结束,对每一个大的章节内容进行简单的叙述。并且阐述了自己的收获与不足,给出不足的解决方案

    1.4 本章小结本章从研究的背景开始,叙述了进销存管理系统开发的整个流程,为什么要开发这个系统,开发这个系统有啥优势。其次就是描述了本系统需要开发出什么的功能,需要具备什么样的功能,能否开发出这些功能。最后对正文的每个章节进行了一个简单的描述。
    第二章 相关技术与方法2.1 架构概述本系统设计采用的是MAVEN + SPRING BOOT+ JPA 的架构来搭建的项目。Maven是一个不错的项目管理工具,它包含了一个项目对象模型,一组标准集合,一个项目生命周期,一个依赖管理系统,和用来运行定义在生命周期阶段中插件目标的逻辑。由于 Maven 的缺省构建规则具有不错的可重用性,因此用Maven 可以快速的构建项目。Spring Boot是由Pivotal团队提供的全新框架,设计这个框架目的就是用来简化Spring应用的初始搭建以和开发过程。这个框架使用了特定的方式做配置,因此开发人员不需要和传统的Spring应用一样写大量的配置文件。Springboot具有以下优势:创建的Spring应用程序是独立的;本身嵌入了Tomcat,无需部署WAR文件;Maven配置作了简化;自动配置Spring。因此用maven加上spring boot可以让我们快速的搭建起项目来,可以省去很多繁琐的步骤。
    JPA全称为Java Persistence API,是通过注解或者XML来描述对象-关系表的映射关系,并且可以将在运行的Entity类对象存储到数据库中去。使用JPA可以打破一般简单持久化框架的局限,在我们开发企业级应用中发挥更大作用,因为JPA支持容器级事务:大数据集、事务、并发等。使用JPA创建实体非常简单,就和我们平常创建一个JAVA类一样,不存在任何的约束和限制,我们只需要在对应的实体上标注javax.persistence.Entity注解即可;开发人员很容易就可以掌握JPA,因为JPA没有特殊的规则和太多的设计模式,框架和接口都很简单。JPA采用的原则是非侵入式原则,因此对其他框架的兼容性很好,易于和其他框架集成。JPA中定义了和Hibernate HQL相似的QL:JPQL,它是EJB QL的一种拓展,操作的对象是实体,而不是关系数据库的一张表。而且能够正常的支持SQL才能够提供的高级查询特性:批量修改和更新、JOIN、GROUPBY、HAVING等,并且支持子查询功能。最重要的是JPA也支持面向对象的高级特性,这样的话开发者在开发企业级应用时能够最大化的使用面向对象的模型来设计,而不用自己来处理这些特性的持久化。
    用这三个技术搭建项目框架,可以快速完成,省去许多简单繁杂的步骤,对于我们快速开发是有非常大的优势的。
    2.2 关键技术简介作为一个进销存管理系统,其最根本的功能还是在对采购管理、销售管理和库存管理上面,其他的功能都是在这个的基础上才能够开发出来。基础功能也就是对进货、销售和库存的增删改查。其中对进货订单的添加和销售订单的添加,每个订单都含有一个或者多个商品,因此订单生成时做了跟购物车类似,我们可以把商品一个一个添加到这个购物车上,等我们商品添加完成,此时可以提交订单,这样就产生 了一个进货订单或者销售订单。跟数据库打交道肯定少不了连接数据库的技术,在本系统用到的是JPA,JPA本身有许多默认的增删改查的方法,并且不用写配置文件,而且可以自己个性化定制sql语句,只需要写一个接口继承JPARepository接口,然后在这个接口里写抽象方法,在方法上写注解就可以了,很方便。
    首先是数据分析功能,因为我们本身数据库里存有大量的销售数据库,所以我们就不用去收集数据了,直接对数据库里的数据进行分析即可。第一阶段:探索性数据分析,因为数据库里的数据是杂乱无章的,因而看不出规律。因此我们需要通过作图、表格、用各种形式的方程拟合、计算某些特征量等手段来找出某些可能的关联或某些隐含在数据中的规律。第二阶段:选定模型进行分析,接下来我们通过前面的初步操作,在探索性分析的基础上提出一种或几种可能的模型,然后通过进一步分析从里面挑选最符合当前发展的几个模型。第三阶段:推断分析,使用数理统计方法对第二阶段所定的模型做出以下判断:估计的可靠程度,精确程度作出推断。选定最终的模型。
    其次是数据备份功能,企业在运转中,系统难免会出现一些突发情况导致数据的丢失、损坏。因此当出现这些情况时,我们就需要把备份的数据恢复到数据库中去。备份数据时会占用较大的IO资源的,因此我们需要选择一个对系统影响尽可能地小的时段来进行数据的备份;对重要的数据,要保证在极端情况下的数据都可以正常恢复。在选择备份方案时要考虑到实施方案的可操作性和经济性,因此选择了逻辑备份,此方法不需要数据库运行在归档模式下,不但备份简单,而且可以不需要依赖外部存储设备。
    2.3 开发工具系统前段页面采用jsp + JavaScript + css的组合技术开发,其中JavaScript使用了jQuery和bootstrap框架,这两个前段框架让我们能更友好的使用JavaScript。省去了许多步骤,简化了我们的使用。数据库使用的是MySQL数据库,MySQL 是现阶段最流行的关系型数据库之一,因为它的体积小、运行速度快、免费,尤其是开放源码这一特点,一般中小型网站的开发都会选择MySQL作为网站数据库。考虑到系统设计的用户群体以及MySQL数据库的这些优点,于是选择了MySQL数据库作为开发数据库。开发使用的IDE工具是:Spring tool suit,这个IDE工具是Spring官网推荐的开发工具,在使用Spring体系的框架开发应用是,这个IDE工具具有很多优势。Web服务器是使用的Spring boot内置的Tomcat服务器。根据以上选择的框架、工具,选择了JDK1.8作为开发、编译环境。
    2.4 本章小结本章主要简单叙述了系统使用了的框架、用了哪些开发工具。重点介绍如何实现系统的核心功能,还有实现这些功能用到了哪些技术,对这些方面进行了阐述。
    第三章 系统分析3.1 可行性分析3.1.1 技术可行性基于本项目用到的spring boot、JPA、mysql、jQuery等技术都已经是成熟的开发技术了,完全可以满足本项目的开发需求。项目主要功能所涉及的一些技术都能是能够实现的,因此在技术上是可行的。
    3.1.2 经济可行性企业在运转过程中信息的系统化管理,运用电脑对数据进行自动化的统计,为企业在制定经营决策时提供了大量的、权威的科学数据;强大的进销存数据统计功能,大大简化了员工的日常工作,工作效率提高了很多,大大降低了人工管理过程中数据易错所带来的一系列的不良反应,提高了企业的经济效益。可以节省大量的人力物力,并且现在不会存在之前人工操作产生的人工误差的情。可以说是大大提高了企业的经济效益。因此,本系统在经济上也是可行的。
    3.1.3 操作可行性本项目因为有友好的交互界面,所以每位企业员工都能够轻松学会去操作本系统,因为操作人员只需要把数据输入进去,数据都是自动去计算的,因此可以省去以前需要手动计算的劳动,并且效率高好多。而且以前都是手动计算不仅容易出错,而且还费时费力;现在都是程序自动计算,在减小了出错的概率的同时还节省了人力物力、提高了工作效率。可以说对企业的运转是大大节省了花费,并且提高了生产效率。综合考虑本系统在操作上是可行的。
    3.2 需求分析3.2.1 系统总体需求系统需要具备以下功能:

    一般企业人员的计算机知识掌握的不多,因此要求有良好的人机交互界面,这样对操作这个系统的企业人员比较友好
    对于本系统使用对象的不同,需要给予不同的权限
    支持多条件语句查询,方便进销存数据的查询
    基础信息管理与查询(包括商品信息、客户信息、供应商信息)
    一键点击,能够直接查看仓库所有商品的库存信息
    方便、健全的账单统计功能
    图表分析年销售状况
    商品销售排行统计
    当停电、网络病毒的原因损坏本系统数据时,系统可以还原系统的数据
    各种数据的统计计算自动完成,尽可能的减少人工干预
    系统退出




    主要质量属性
    详细要求




    正确性
    按照需求正确执行任务,完成各个模块的相应要求。


    健壮性
    具有较高的容错能力和恢复能力。


    性能效率
    响应用户的请求的时间越短越好。


    易用性
    系统开发过程中应该有详细的文档,这样让别人能够更好的使用。


    安全性
    防止软件受到意外或蓄意的存取、使用、修改、毁坏或泄密导致系统的数据丢失。


    可扩展性
    能方便的进行二次开发,满足对功能的扩展或提高并能提高相应的安全机制。


    兼容性
    不易与其他软件起冲突。



    3.2.2 用例图分析系统管理用例图

    系统管理用例有配置系统、管理部门、管理员工、管理权限,这里主要介绍一下管理权限,具体说明见表3-1:

    财务用例图

    财务用例有查询应收款项、记录应收应付款项、管理发票,这里主要介绍一下记录应收应付款项,具体说明见表3-2:

    采购部分用例图

    采购部分用例有两个角色采购员和采购经理。采购员用例有采购单、管理供应商、管理商品信息;采购经理用例有审批采购单、管理商品分类。具体说明见表3-3至表3-4:
    采购单

    审批采购单

    库存部分用例图

    库存部分总共有质检员、库存管理员、仓库经理三个角色,涉及到的用例比较多,这里具体介绍一下出入库单、确认入库单、开出库单、统计库存信息、出调拨单,具体说明见表3-5至表3-9:
    出入库单

    确认入库单

    开出库单

    统计库存信息

    出调拨单

    销售部分用例图

    销售部分用例图包括销售经理和销售员两种角色,销售经理用例有统计销售信息;销售员用例有管理客户、查询商品库存、下订单、确认订单具体说明见表3-10至表3-12:
    统计销售信息

    查询商品库存

    下订单

    3.3 本章小结本章主要是进行了系统的分析,首先第一节是可行性分析,从技术可行性、经济可行性、操作可行性三个角度对系统分析是否是可行的,最终得出本系统是可行的。第二节是需求分析分析了系统所具备的一些的功能,然后重点介绍了一些特色功能。接着第二节是需求分析,第一小节阐述了系统的总需求,应该具备哪些功能;第二小节通过用例图对需求主要功能进行了具体分析。
    第四章 系统设计4.1 系统类分析经分析,该系统核心业务类见下图:

    4.1.1 MANAGER类MANAGER类用于记录系统的用户信息,并完成登陆和注销的操作。

    4.1.2 GOODS类GOODS类用于记录商品的信息,并且实现对商品的增删改查等功能。

    4.1.3 SALEORDER类SALEORDER类用于记录销售订单的信息,并且实现对销售订单的增删改查等功能。

    4.1.4 PURCHASEORDER类PURCHASEORDER类用于记录采购订单的信息,并且实现对采购订单的增删改查等功能。

    4.1.5 STOCK类STOCK类用于记录库存的信息,并且实现对库存的增删改查等功能。

    4.2 关键业务设计关键业务与用例图之间存在一定的对应关系,原则上用例图中所提出的用例应该在关键业务分析中体现,每一个用例对应一个时序图,每个时序图后面应当有一段简短的说明,时序图用WORD绘制比较难,可以借用其他工具,但复制过来时应尽量只有黑白颜色,下面以登录为例说明关键业务的说明方法。
    4.2.1 添加商品
    采购业务员通过UI界面选择添加商品菜单,此时后台controller会判断该操作用户是否有权限;权限检查通过,操作员进入到商品添加表单,输入商品信息提交,后台controller会调用service的add方法,service中的方法add在调用database中的板寸方法。成功后返回成功提示。
    4.2.2 查询商品采购业务员通过UI界面输入查询条件,此时后台controller会检查查询条件;controller会调用service里面的find方法,find方法会调用database中具体的查询方法;把查询到的结果显示到UI界面。
    4.2.3 添加库存
    库存业务员通过UI界面选择商品菜单,输入该商品的库存信息,此时后台controller检查输入商品库存信息;controller会调用service中的add方法,add方法调用database中的具体添加方法处理,添加成功返回功能提示。
    4.2.4 添加销售订单
    销售业务员通过UI界面选择添加订单菜单,输入订单信息,此时后台controller会检查订单信息;controller会调用service中的update方法,update方法会调用database中的具体更新方法,更新成功后会返回成功提示。
    4.3 数据库设计4.3.1 概念设计系统ER图

    商品ER图

    顾客ER图

    供应商ER图

    图4.10 管理员ER图

    日志用于记录用户的日常行为,通过用户编号与用户实体之间存在一对多关系。
    4.3.2 数据库表系统中使用到数据库基本如表4-1所示。
    系统数据库表



    编号
    表名
    描述




    01
    customer
    顾客表


    02
    dept
    部门表


    03
    employee
    员工表


    04
    goods
    商品表


    05
    manager
    管理员表


    06
    purchase_item
    采购单明细表


    07
    purchase_order
    采购订单表


    08
    return_item
    采购退货明细表


    09
    return_order
    采购退货表


    10
    sale_item
    销售订单明细表


    11
    sale_order
    销售订单表


    12
    sale_return_item
    退货销售明细表


    13
    sale_return_order
    销售退货表


    14
    stock
    库存表


    15
    suppliers
    供应商表



    顾客表用于记录顾客信息,顾客表的具体字段如表4-2所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    customer_id
    顾客编号
    Long
    PK



    customer_name
    顾客名称
    Varchar(20)
    NOT NULL



    address
    顾客地址
    Varchar(255)




    zip
    邮编
    Varchar(20)




    telPhone
    联系电话
    Varchar(20)




    linkMan
    联系人
    Varchar(20)




    linkTel
    联系人号码
    Varchar(20)




    bank
    开户银行
    Varchar(20)




    bankAccoount
    银行账号
    Long




    email
    邮箱
    Varchar(20)




    字段顾客编号为本表的主键,用来标识一个顾客,字段顾客名称非空字段,字段顾客地址、邮编、联系电话、联系人、联系人号码、开户银行、银行账号、邮箱是顾客的一些详细信息。
    部门表用于记录部门的信息,部门表的具体字段如表4-3所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    dept_id
    部门编号
    Long
    PK



    dept_name
    顾客名称
    Varchar(20)
    NOT NULL



    字段部门编号为本表的主键,用来标识一个部门,字段部门名称为非空字段。
    员工表
    员工表用于记录员工的信息并且用于员工登录系统,员工表的具体字段如表4-4所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    employee_id
    员工编号
    Long
    PK



    employee_name
    员工姓名
    Varchar(20)
    NOT NULL



    employee_password
    密码
    Varchar(20)
    NOT NULL
    MD5加密


    employee_gender
    性别
    Varchar(5)




    employee_age
    年龄
    Long




    employee_phonenumber
    手机号码
    Varchar(20)




    deptId
    部门ID
    Long
    FK



    字段员工编号为本表的主键,用来标识一个员工,员工名字和员工密码为非空字段,部门ID为外键,引用自部门表;字段性别、年龄和手机号码为员工的一些基本信息。
    商品表商品表用于记录商品的信息,商品表的具体字段如表4-5所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    goods_id
    商品编号
    Long
    PK



    goods_name
    商品名称
    Varchar(20)
    NOT NULL



    unit
    单位
    Varchar(20)




    space
    商品产地
    Varchar(255)




    supplierId
    供应商编号
    Varchar(20)
    FK



    approveId
    批准文号
    Varchar(20)




    batchId
    生产批号
    Varchar(20)




    字段商品编号为本表的主键,用来标识一个商品,字段商品名称不为空,字段供应商编号为外键,引用自供应商表,字段单位、商品产地、批准文号和生产批号为商品的一些属性。
    管理员表管理员表用于记录管理员的信息并且用于管理员登录系统,管理员表的具体字段如表4-6所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    manager_id
    管理员编号
    Long
    PK



    manager_name
    管理员姓名
    Varchar(20)
    NOT NULL



    manager_password
    密码
    Varchar(20)
    NOT NULL
    MD5加密


    manager_gender
    性别
    Varchar(5)




    manager_age
    年龄
    Long




    manager_phonenumber
    手机号码
    Varchar(20)




    dept_name
    部门名称
    Varchar(255)
    FK



    字段管理员编号为管理员表的主键,用来标识一个管理员,字段管理员名字和密码是不能为空的,部门编号是一个外键,引用自部门表,字段性别、年龄和手机号码是管理员的一些个人信息。
    采购单明细表用于记录采购单信息,采购单明细表的具体字段如表4-7所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    purchase_item_id
    采购单明细编号
    Long
    PK



    goods_name
    商品名称
    Varchar(20)
    FK



    purchase_order_id
    采购单编号
    Varchar(20)
    FK



    purchase_price
    单价
    Double




    purchase_count
    数量
    Long




    字段采购单明细编号为采购单明细表的主键,用来标识一个采购订单明细,其中字段采购单编号和商品名称是外键,分别引用自采购订单表和商品表,字段单价和数量是采购单明细表的属性。
    采购订单表用于记录采购单信息,采购订单细表的具体字段如表4-8所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    purchase_order_id
    采购单编号
    Long
    PK



    suppliersId
    采购商编号
    Varchar(20)
    FK



    purchase_order_pay
    支付方式
    Varchar(20)




    inDate
    采购日期
    Date




    purchase_order__total
    总金额
    Double




    字段采购单编号为采购订单表的主键,用来标识一个采购订单,其中字段采购商编号为外键,引用自采购商表,字段支付方式、采购日期和总金额为采购订单的信息。
    采购退货明细表用于记录采购退货单信息,采购退货明细表的具体字段如表4-9所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    return_item_id
    采购退货单明细编号
    Long
    PK



    returnOrderId
    采购退货单编号
    Long
    FK



    goodsName
    商品名称
    Varchar(20)
    FK



    return_item_price
    单价
    Double




    return_item_count
    数量
    Long




    字段采购退货单明细编号是采购退货明细表的主键,用来标识一个采购退货明细,其中采购退货单编号和商品名称是外键,分别引用自采购退货表和商品表。字段单价和数量为采购明细表的属性。
    采购采购退货表用于记录采购采购退货信息,采购采购退货表的具体字段如表4-10所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    return_order_id
    采购单编号
    Long
    PK



    suppliersId
    采购商编号
    Varchar(20)
    FK



    return_order_pay
    支付方式
    Varchar(20)




    return_order_outDate
    退货日期
    Date




    return_order_total
    总金额
    Double




    字段采购退货单编号是采购退货表的主键,用来标识一个采购退货,其中字段采购商编号为外键,引用自采购商表,字段支付方式、退货日期和总金额为采购退货表的属性。
    销售订单明细表用于记录销售订单明细信息,销售订单明细表的具体字段如表4-11所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    sale_item_id
    销售订单明细编号
    Long
    PK



    saleOrderId
    销售订单编号
    Long
    FK



    sale_item_name
    商品名称
    Varchar(20)
    FK



    sale_item_price
    单价
    Double




    sale_item_count
    数量
    Long




    字段销售订单明细编号是销售订单明细表的主键,用来标识一个销售明细,其中字段销售订单编号和商品名称是外键,分别引用自销售订单表和商品表,字段单价和数量是销售订单明细的属性。
    销售订单表用于记录销售订单信息,销售订单表的具体字段如表4-12所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    sale_order_id
    销售单编号
    Long
    PK



    customerId
    顾客编号
    Varchar(20)
    FK



    sale_order_pay
    支付方式
    Varchar(20)




    sale_order_saleDate
    销售日期
    Date




    sale_order_total
    总金额
    Double




    字段销售单编号是销售订单表的主键,用来标识一个销售订单,字段顾客编号是外键,引用自顾客表,字段支付方式、销售日期和总金额是销售订单表的属性。
    销售退货明细表用于记录销售退货明细信息,销售退货明细表的具体字段如表4-13所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    sale_return_item_id
    销售退货订单明细编号
    Long
    PK



    saleReturnOrderId
    销售退货订单编号
    Long
    FK



    goodsName
    商品名称
    Varchar(20)
    FK



    sale_return_item_price
    单价
    Double




    sale_return_item_count
    数量
    Long




    字段销售退货订单明细编号是销售退货明细表的主键,用哪个来标识一个销售退货明细,字段销售退货订单编号、商品名称为外键,分别引用自销售退货表和商品表,字段单价和数量为销售退货明细表的属性。
    销售退货表用于记录销售退货信息,销售退货表的具体字段如表4-14所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    sale_return_order_id
    销售退货单编号
    Long
    PK



    customerId
    顾客ID
    Varchar(20)
    FK



    sale_return_order_pay
    支付方式
    Varchar(20)




    sale_return_order_returnDate
    退货日期
    Date




    sale_return_order_total
    总金额
    Double




    库存表用于记录库存信息,库存表的具体字段如表4-15所示。



    字段名
    字段描述
    类型/长度
    约束
    备注




    stock_id
    库存编号
    Long
    PK



    goodsId
    商品编号
    Long
    FK



    stock_count
    商品库存数量
    Varchar(20)
    NOT NULL



    stock_area
    存放地方
    Varchar(255)




    字段库存编号是库存表的主键,用来标识一个库存,字段商品编号是外键,引用自商品表,字段商品库存数量不为空,字段存放地方为库存表的属性。
    供应商表用于记录供应商信息,供应商表的具体字段如表4-16所示:



    字段名
    字段描述
    类型/长度
    约束
    备注




    suppliers_id
    供应商编号
    Long
    PK



    supplier_name
    供应商名称
    Varchar(20)
    NOT NULL



    address
    顾客地址
    Varchar(255)




    zip
    邮编
    Varchar(20)




    telPhone
    联系电话
    Varchar(20)




    linkMan
    联系人
    Varchar(20)




    linkTel
    联系人号码
    Varchar(20)




    bank
    开户银行
    Varchar(20)




    bankAccoount
    银行账号
    Long




    email
    邮箱
    Varchar(20)




    字段供应商编号是供应商表的主键,用来标识一个供应商,字段供应商名称不为空,字段顾客地址、邮编、联系电话、联系人、联系人号码、开户银行、银行账号和邮箱是供应商表的属性。
    4.4 本章小结本章主要分为三个小节来介绍系统设计。第一节是系统类分析,主要是通过类图的方式来介绍系统设计到的类,介绍类里的属性和设计到的方法。第二节是关键业务设计,主要是通过顺序图的方式来介绍核心业务的设计和处理过程。第三节是数据库设计,首先是通过ER图的方式介绍设计到的模块和模块的一些字段(分为总ER图和分ER图),其次是数据库表,介绍了所设计到的表,详细的介绍了表中的字段和字段对应的关系。
    第五章 系统实现5.1 用户登录5.1.1 功能描述登录是对用户使用系统功能进行身份验证的过程,登录也是可以很好的控制用户的权限问题,登录界面要求简明易懂。每一用户都有自己的独有的账号和密码,用户在系统的每一个操作都有日志进行记载,可以有效保证数据可追溯性,做到责任到人,界面如下图。

    5.1.2 实现流程在登陆按钮添加监听事件,在用户输入账号密码点击登录后,终端先判断是否满足JS中的验证方法,此方法是防止当账号密码为空时登录的提示,如果为空跳出一个对话框来提示用户账号和密码需要填。如果不为空,后台会把接受的用户名密码与数据库数据库中用户信息比较核对,如果是一致则顺利登录到用户权限所对应的界面中,否则出现账号密码错误的提示,登录失败。登录流程如图5-12所示。实现代码如下:
    if("manager".equals(user)){ Managers managers = null; try { managers = managerService.login(name, password); } catch (ServiceException e) { e.printStackTrace(); } if(managers!=null){ logger.info(name+"登录成功!!!"); ServletContext app = req.getSession().getServletContext(); app.setAttribute("user",managers); req.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(req, resp); }else{ logger.info("登录失败,用户名或者密码错误"); HttpSession session = req.getSession(); session.setAttribute("msg","用户名或者密码错误"); resp.sendRedirect("login.html"); }}else if("employee".equals(user)){ Employee employee = null; try { employee = managerService.employeelogin(name, password); } catch (ServiceException e) { e.printStackTrace(); } if(employee!=null){ logger.info(name+"登录成功!!!"); ServletContext app = req.getSession().getServletContext(); app.setAttribute("user",employee); req.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(req, resp); }else{ logger.info("登录失败,用户名或者密码错误"); HttpSession session = req.getSession(); session.setAttribute("msg","用户名或者密码错误"); resp.sendRedirect("login.html"); }}

    5.2 采购管理5.2.1 功能描述采购管理是对需要采购的订单的综合管理,在这个模块里包含采购订单、收货入库、采购退货三个子模块。其中采购订单是员工用来生成采购单的,还有对采购单的一些处理;收货入库是对已经提交的采购单进行入库操作;采购退货是把我们已经提交的采购单进行退货处理的操作。主要界面如下图:

    5.2.2 实现流程点击采购订单按钮会跳转到采购订单首页,在首页可以看到所有已经提交的采购单信息;当我们想添加新的采购订单的时候,首先点击添加商品按钮,会跳转到商品添加页面,我们把商品信息输入进去之后点击提交,后台方法会把商品信息暂时存起来,当我们把所有商品添加完成,我们可以再点击添加订单按钮,此时会把我们添加的所有的商品都提交生成一个采购订单,并且把数据存进对应的数据库表中保存起来。对已经提交的订单当我们点击退货按钮时,后台会接收到要退货的订单ID,并且根据ID到数据库中订单表把数据删除,同时在退货表中把数据插进去。当我们点击入库按钮时,后台会接收到需要入库的订单的ID,并且把订单表中的flag字段的值修改为已入库,同时在库存表中会新加一条数据。主要实现代码如下:
    Long suppliersId = Long.parseLong(request.getParameter("suppliersId"));String name = request.getParameter("name");Double price = Double.parseDouble(request.getParameter("price"));Long count =Long.parseLong(request.getParameter("count")); String unit = request.getParameter("unit");String space = request.getParameter("space");Long supplierId = Long.parseLong(request.getParameter("supplierId"));String approveId = request.getParameter("approveId");String batchId = request.getParameter("batchId"); purchaseItem = new PurchaseItem();purchaseItem.setCount(count);purchaseItem.setPrice(price);purchaseItem.setName(name);purchaseItem.setSupplierId(suppliersId);list.add(purchaseItem);model.addAttribute("list", list);logger.info("成功添加商品");logger.info("提交采购订单");String pay = request.getParameter("pay");purchaseOrder = new PurchaseOrder();purchaseOrder.setPay(pay);purchaseOrder.setInDate(new Date());purchaseOrder.setFlag("未入库");try { int i = managerService.addPurchaseOrder(purchaseOrder, list); if(i==1){ list.removeAll(list); /*orderList.removeAll(orderList);*/ orderList = managerService.findPurchaseOrderByPage(0); count = managerService.findPurchaseOrderCount(); currentPage = 1L; totalPage = managerService.getTotalPage(); model.addAttribute("currentPage", currentPage); model.addAttribute("totalPage", totalPage); model.addAttribute("orderList", orderList); model.addAttribute("count", count); logger.info("提交采购订单成功"); }
    5.3 库存管理5.3.1 功能描述库存管理是对仓库里的商品的综合管理,包括商品入库、商品出库、某种商品的库存查询、商品移库和库存盘点。商品入库是对新的商品需要入库的管理;商品出库是根据销售订单到库存里拿出对应数量的商品并且库存进行相应的减少;库存查询是输入想查询的商品会返回该商品的库存数量;商品移库是输入商品ID和需要移动到的仓库号就可以更改商品的存放仓库;最后一个是库存盘点,该功能是返回仓库里所有商品的库存信息。主要界面如下图:
    商品出库

    库存查询

    商品移库

    5.3.2 实现流程首先是商品入库,点击商品入库按钮跳转到对应商品添加页面,填入对应商品信息,后台首先会判断该商品在商品表里是否已经存在,如果存在,则更新该商品的库存即可,如果不存在,则先在商品表里添加一条商品的信息,再到库存表里添加一条库存信息。商品出库,首先是输入需要出库的商品ID和该商品出库的数量,后台根据接收的商品ID和数量到数据库库存表去更新该商品的库存数量。库存查询,输入需要查询库存的商品ID,后台会根据商品的ID去库存表里查询该商品的库存数量,并且返回到对应的前台页面。商品移库,输入商品ID和移动到的仓库号,后台会根据商品ID号到数据库库存表中更新该商品的库存地方。库存盘点,这个功能是会显示所有商品的库存信息。主要实现代码如下:
    商品入库:
    public int stockAdd(Stock stock, Goods goods) throws ServiceException { Goods gods = goodsRepository.findGoodsByName(goods.getName()); if(gods==null){ gods = goodsRepository.save(goods); } stock.setGoodsId(gods.getId()); Stock stok = findStockByGoodsId(gods.getId()); if(stok==null){ stockRepository.save(stock); }else{stockRepository.updateStockCountByGoodsId(stok.getCounts()+stock.getCounts(),stock.getGoodsId()); } return 1;}
    商品出库:
    @RequestMapping("/update")public String UpdateStock(HttpServletRequest request,Model model){ logger.info("库存信息更新开始"); Long goodsId = Long.parseLong(request.getParameter("goodsId")); Long count = Long.parseLong(request.getParameter("count")); try { stockService.updateStock(goodsId,count); outList = stockService.findStockByPage(0); model.addAttribute("outList", outList); logger.info("库存信息更新完成"); } catch (ServiceException e) { e.printStackTrace(); } return "outStock"; }
    商品移库:
    @RequestMapping("updateArea")public String upDateArea(HttpServletRequest request,Model model){ logger.info("存放仓库信息更新开始"); Long goodsId = Long.parseLong(request.getParameter("goodsId")); String area = request.getParameter("area"); try { stockService.updateStockAreaByGoodsId(area,goodsId); List<Stock> list = stockService.findAllStock(); model.addAttribute("outList", list); logger.info("存放仓库信息更新完成"); } catch (ServiceException e) { e.printStackTrace(); } return "updateArea"; }
    5.4 销售管理5.4.1 功能描述销售管理对销售订单的综合管理,包含销售订单、发货出库和销售退货。销售订单,将销售的信息形成销售订单并且存入到数据库销售订单表中;发货出库,将提交的销售订单的flag状态改为已发货,并且对应的库存表中的库存数量也相应的减少;销售退货,对已经销售的订单进行退货处理。主要界面如下图:

    5.4.2 实现流程首先是销售订单,第一步是点击添加商品,然后输入对应的商品信息点击提交,后台接收到数据,会暂时将商品信息存储起来,当商品添加完毕,点击添加订单按钮,可以将刚才添加的所有订单信息提交到后台,后台在将这些订单信息持久化到数据库中去。发货出库,对提交销售的订单可以进行发货操作,后台会根据订单ID对订单表中的flag字段值修改为已发货,并且会到库存表中去,将该订单对应的商品的库存数作相应的改变。销售退货,对已经提交的订单可以进行退货操作,点击退货按钮,后台会根据订单ID到数据库销售订单表中把对应订单信息删除,并且在销售退货表中加入相应的退货记录,与此同时会根据flag字段,如果flag字段值是未发货,则不用去库存表跟新库存数据,如果flag字段的值为已发货,则需要到库存表中把订单对应的商品的库存数加回去。主要实现代码如下:
    @RequestMapping("/addSaleOrder")public String saveSaleOrder(HttpServletRequest request,Model model){ String pay = request.getParameter("pay"); SaleOrder saleOrder = new SaleOrder(); saleOrder.setFlag("未发货"); saleOrder.setPay(pay); saleOrder.setSaleDate(new Date()); try { int i = saleService.addSaleOrder(saleOrder,itemList); if(i==1){ itemList.clear(); saleorderList = saleService.findSaleOrderByPage(0); cunt = saleService.findSaleOrderCount(); crrentPage = 1L; ttalPage = saleService.getTotalPage(); model.addAttribute("crrentPage", crrentPage); model.addAttribute("ttalPage", ttalPage); model.addAttribute("saleorderList", saleorderList); model.addAttribute("cunt", cunt); } } catch (ServiceException e) { e.printStackTrace(); } return "sale";}
    5.5 备份与恢复5.5.1 功能描述备份与恢复,顾名思义就是对系统的重要数据进行备份,以备不时之需,备份是可以设定每天在一个固定的时间自动进行备份;当系统数据损坏时我们可以自由选择恢复哪一天的数据。主要界面如下图:

    5.5.2 实现流程备份功能,首先当系统启动的时候已经设定了一个自动备份的时间点,每天到这个时间点都会自动把数据库的数据备份一次,但是我们也可以手动备份,我们只需要点击数据备份就可以了;数据恢复,当某个时候系统数据损坏或者丢失的时候,此时我们就可以用到数据恢复功能了,我们可以选择恢复到一个时间点的数据文件。主要实现代码如下:
    public static void backup() { try { Runtime rt = Runtime.getRuntime(); // 调用 调用mysql的安装目录的命令 Process child = rt.exec(backuppath); // 设置导出编码为utf-8。这里必须是utf-8 // 把进程执行中的控制台输出信息写入.sql文件,即生成了备份文件。注:如果不对控制台信息进行读出,则会导致进程堵塞无法运行 InputStream in = child.getInputStream();// 控制台的输出信息作为输入流 InputStreamReader xx = new InputStreamReader(in, "utf-8"); // 设置输出流编码为utf-8。这里必须是utf-8,否则从流中读入的是乱码 String inStr; StringBuffer sb = new StringBuffer(""); String outStr; // 组合控制台输出信息字符串 BufferedReader br = new BufferedReader(xx); while ((inStr = br.readLine()) != null) { sb.append(inStr + "\r\n"); } outStr = sb.toString(); // 要用来做导入用的sql目标文件: SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmm"); FileOutputStream fout = new FileOutputStream("D:\\jxc\\backup\\"+sdf.format(new Date())+".sql"); OutputStreamWriter writer = new OutputStreamWriter(fout, "utf-8"); writer.write(outStr); writer.flush(); in.close(); xx.close(); br.close(); writer.close(); fout.close(); } catch (Exception e) { e.printStackTrace(); }}/** * 备份数据恢复 * @param databaseName*/public static void restore(String fileName) { try { Runtime runtime = Runtime.getRuntime(); Process process = runtime .exec(restorepath); OutputStream outputStream = process.getOutputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\jcx\\backup\\"+fileName), "utf-8")); String str = null; StringBuffer sb = new StringBuffer(); while ((str = br.readLine()) != null) { sb.append(str + "\r\n"); } str = sb.toString(); // System.out.println(str); OutputStreamWriter writer = new OutputStreamWriter(outputStream, "utf-8"); writer.write(str); writer.flush(); outputStream.close(); br.close(); writer.close(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }}
    5.6 本章小结本章主要是介绍了系统实现,重点介绍了系统的用户登录、采购管理、库存管理、销售管理、备份与恢复五个模块。这五个模块首先分别介绍了他们的功能,并且附上界面图,然后再从实现流程上对这些功能进行详细的描述,最后附上实现这些功能的主要代码。
    第六章 系统测试6.1 系统测试综述系统完成后,对系统的测试是非常重要的一环。首先在系统的每个模块完成后对这个模块做的单元测试,另外一个是在系统整体完成了后对整个系统做的综合测试。
    用户登录模块,当用户输入正确的用户名和密码时,能正常登录;当用户输入错误的用户名或者错误的密码或者不存在的用户名的时候,系统应当输出响应用户名或者密码错误;当用户没有输入用户名或者没用输入密码或者两者都没有输入的时候,系统应当响应用户名、密码项是必填项。
    采购管理模块,当天如对应的商品信息时,后台新系统能够接收到商品信息,并且在提交订单的时候能够顺利把这些信息都持久化到数据库中去,并且在出错的时候能正确返回对应的错误码;对采购订单入库时,能正常的把flag标志改为已入库,并且在库存表中更新响应的商品库存信息;销售退货,后台能根据订单ID将采购订单表中的数据删除,并且把数据插入到采购退货表中去。
    库存管理模块,商品入库功能,当用户把商品信息输入正确的时候,后台能够真确的收到数据,并且正确的持久化到数据库中去;商品出库,当用户输入出库的商品和数量时,后台能够正确到数据库库存表把对应的商品的数量相应的减少;库存查询,当输入商品的ID时,后台能根据这个ID查出该商品的库存信息,并且能正确的返回到用户界面;商品移库,当输入商品ID和移库的信息后,后台能正确地更新数据库中对应商品的库存信息。
    销售管理模块,销售模块,当前段把销售订单的信息都正确输入的时候,后台能正确的接收到订单信息,并且把订单信息正确持久化到数据库中去,在产生错误时,能够返回对应的错误码;发货出库,当销售订单的信息提交之后,我们可以对这些的订单做发货操作,点击发货后,后台要把相应商品的库存信息进行更新,并且把订单表中的flag字段的值改为已发货;销售退货,点击退货按钮,后台能正常的把销售订单表中的对应订单信息删除,并且在销售退货表中把退货信息存进去,并且要把商品的数量加回到库存表中去。
    备份与恢复模块,首先是系统每天能够在固定时间产生一个备份数据库的文件,然后在我们手动点击备份按钮的时候也能够产生一个备份数据库的文件;当点击恢复按钮时,会把我们选择的数据库文件恢复到数据库中去。
    6.2 测试用例6.2.1 用户登录模块
    6.2.2 采购管理模块
    6.2.3 库存管理模块
    6.2.4 销售管理模块
    6.2.5 备份与数据恢复模块
    6.3 测试分析经过这些测试,整个系统的大部分功能都已经能够正常的运行,达到了我们预想的结果。对于采购管理、库存管理和销售管理三个模块先阶段的功能都能达到预期效果,但是还可以加入一些其他的支持(对Excel表格的支持),能够直接导入Excel表格的数据,并且可以直接导出为Excel表格,这个功能暂时还没达到预期效果,因此需要把这个功能加上;在一个就是对权限的控制方面做的不是特别完善,因此接下来,在权限方面还应该加强。对于备份和数据恢复功能,现在和预期的结果是一致的,比较符合。实力和时间的限制,在代码的编写上面,存在许多的冗余代码,因此这方面需要改进,把重复的代码封装成方法,减少冗余度。
    6.4 本章小结本章主要是对已完成的功能做系统测试,分模块的进行测试,测试这些功能是否能达到预期的结果;为什么没有达到预期。对于每一个模块都写了相应的测试用例,通过这些测试用例的分析,整个系统的功能基本上达到了预期的效果,但是还有进一步改进的地方,让整个系统更完善。
    参考文献[1] 辛运帏等. java语言程序设计[M].北京:人民邮电出版社,2009
    [2] (美)(Nicholas C.Zakas)扎卡斯. JavaScript高级程序设计[J].人民邮电出版社2006
    [3] 姜承尧. MySQL技术内幕:InnoDB存储引擎[M].机械工业出版社 2011-1
    [4] 张海藩;吕云翔.软件工程[M]. 人民邮电出版社 2013-09-01
    [5] Roger S.Pressman, 郑人杰, 马素霞等. 软件工程:实践者的研究方法(原书第7版)[M]. 北京: 机械工业出版社, 2011
    [6] 李兴华, 王月清. 名师讲坛:Java Web开发实战经典基础篇(JSP, Servlet, Struts, Ajax)[M].北京: 清华大学出版社, 2010
    [7] 成先海.数据库基础与应用[M].北京:机械工业出版社,2008.
    [8] 张艳.基于工作过程的物流信息系统与管理课程的重构[J].辽宁高职学报,2010, 12(2):45-47.
    [9] 李小娜,董绍华.物流信息技术在现代物流中的应用[J].中国科技信息,2008,(21):140-143.
    [10] 隋英琴.供应链管理环境下的物流管理创新[J].科技创业,2008,14(03):123-125.
    [11] 陈雄华 Spring 企业级应用开发详解[M] 北京:电子工业出版社 2009
    [12] 王寅田. 基于Hadoop的交通物流大数据处理系统设计与实现[D]. 上海交通大学 2014
    [13] 李海峰. MVC模式架构的应用研究[J]. 自动化与仪器仪表. 2013(01)
    [14] 陈凤琴.基于B/S模式的中小饲料企业进销存系统设计与实现[D].南昌大学2014
    [15] 黄沙.企业物流成本管理存在问题及对策[J].物流技术与应用,2011,13(2):101-102.
    11 评论 79 下载 2020-07-31 11:34:36 下载需要14点积分
  • MFC使用ADO连接SQL SERVER数据库实现的高校教材管理系统

    摘 要随着高校规模的扩大和教学的改革的深入,高校的教学水平和管理在稳步提高,而高校的教材管理环节起着为教学和科研提供软环境的重要作用,是与高校综合能力的增强相辅而成的。而现有的高校教材管理系统大多还停留在手工管理阶段,建立一套符合高校需要的先进的高校教材管理系统是十分必要的。
    关键词:教材管理;用户管理;预定教材;财务管理;
    引 言高校教材管理系统现阶段还依旧停留在手工阶段,系统的一般流程是任课教师进修选定教材,呈交到各个院系,各个院系汇总上报教材,有教材库统一征订,入库,发放和费用结算。随着高校办学规模的扩大,开设课程的增多,教材科每个学期需要入库的教材高达几百种,数量达到几万册,涉及教师、学生几千至几万人。教材管理的涉及面广,工作量大。现有的高校教材管理系统功能比较单一,不能很好地满足实际需要,尤其在书费管理和教材征订两个方面。设计一个能对教材征订、入库、发放和费用结算实现有效的管理的系统是减轻各个院系、教材科相关人员的工作量,节约成本,提高效率的关键。因此本文采取SQL sever 2008,和VC++6.0设计并实现高校教材管理系统。
    1 需求分析1.1 处理功能及要求根据高校教材管理系统的需要,本平台实现的需求如下七个部分:用户登录模块,定数模块,教材基本信息管理,财务管理,渠道管理,用户个人中心,管理员中心。能够实现以下功能:
    1.1.1 用户登录模块登录界面的功能主要是供合法用户根据自己的用户类型进行登录。如果用户在没有登录的情况下是不能进入系统的。用户的类型分为普通用户和管理员,每一种不同的用户所拥有的权限是不一样的。
    1.1.2 订书模块网上教程预定模块可以分为根据教材号预定,根据教程名预定,分类预定和查看所有教材并预定,给用户提供了很大的空间。
    1.1.3 教材基本信息管理教材基本信息是教材入库的时候进行统计的,包括教材本身的基本信息和教材入库的库存量和教材入库的库位号方面管理和查找。在教材基本信息里卖还可以查到供应商信息和出版社信息,在教材的基本信息上还有教材的介绍,功能强大和方面。
    1.1.4 财务管理财务管理方面有按月份进行管理,按照年份进行管理,按照进货的支出,出货的收入,打印报表等,方面实用的涵盖了对财务的具体包含。
    1.1.5 渠道管理在这里进行用户,班级负责人,教师,出版社,供应商的总管理,这里可以看出每个渠道的具体信息,从而进行修改和进行进一步计划。
    1.1.6 用户个人中心在这里进行对自己的个人资料和密码的更改,退出登录,切换用户,和联系管理员。
    1.1.7 管理员中心在这里进行管理员的注册,修改管理员的密码,对用户的消息进行处理和交流,而且在这里可以对所有用户的基本信息进行修改。防止用户忘记密码等。
    1.2 高校教材管理系统业务流程
    1.3高校教材管理系统数据流图顶层数据流图如图所示:

    0层数据流图如图所示:


    第1层数据流图如图:



    1.4 高校教材管理系统数据字典1.4.1 数据项系统涉及的数据项有86项,具体如表1.1所示:



    数据项编号
    数据项名
    数据项含义
    存储结构
    别名




    DI-1
    教材ID
    教材信息ID
    int
    ID


    DI-2
    书号
    教材信息书号
    varchar(30)
    书号


    DI-3
    书名
    教材信息书名
    varchar(40)
    书名


    DI-4
    条码
    教材信息条码
    varchar(40)
    条码


    DI-5
    作者
    教材信息作者
    varchar(30)
    作者


    DI-6
    出版日期
    教材信息出版日期
    datetime
    出版日期


    DI-7
    出版社名称
    教材出版社名称
    varchar(20)
    出版社名称


    DI-8
    版次
    教材信息版次
    varchar(10)
    版次


    DI-9
    库位信息
    教材信息库位信息
    varchar(10)
    库位信息


    DI-10
    入库编号
    教材信息入库编号
    int
    入库编号


    DI-11
    库存量
    教材信息库存量
    int
    库存量


    DI-12
    供应商
    教材信息供应商
    varchar(30)
    供应商


    DI-13
    定价
    教材信息定价
    money
    定价


    DI-14
    入库编号
    入库统计入库编号
    int
    入库编号


    DI-15
    教材ID
    入库统计教材ID
    varchar(30)
    教材ID


    DI-16
    书号
    入库统计书号
    varchar(30)
    书号


    DI-17
    书名
    入库统计书名
    Varchar40)
    书名


    DI-18
    条码
    入库统计条码
    varchar(40)
    条码


    DI-19
    作者
    入库统计作者
    varchar(30)
    作者


    DI-20
    出版日期
    入库统计出版日期
    varchar(30)
    出版日期


    DI-21
    出版社名称
    入库出版社名称
    varchar(50)
    出版社名称


    DI-22
    版次
    入库统计版次
    varchar(20)
    版次


    DI-23
    库位信息
    入库统计库位信息
    varchar(10)
    库位信息


    DI-24
    供应商
    入库统计供应商
    varchar(40)
    供应商


    DI-25
    定价
    入库统计定价
    Money
    定价


    DI-26
    入库时间
    入库统计入库时间
    varchar(30)
    入库时间


    DI-27
    入库价格
    入库统计入库价格
    Money
    入库价格


    DI-28
    入库数量
    入库统计入库数量
    int
    入库数量


    DI-29
    序号
    退书统计序号
    int
    序号


    DI-30
    教材ID
    退书统计教材ID
    int
    教材ID


    DI-31
    退书时间
    退书统计退书时间
    datetime
    退书时间


    DI-32
    退书原因
    退书统计退书原因
    varchar(60)
    退书原因


    DI-33
    退书数量
    退书统计退书数量
    int
    退书数量


    DI-34
    退书单价
    退书统计退书单价
    Money
    退书单价


    DI-35
    定价
    订购统计定价
    money
    定价


    DI-36
    订购数量
    订购统计订购数量
    int
    订购数量


    DI-37
    订购时间
    订购统计订购时间
    datetime
    订购时间


    DI-38
    订购价格
    订购统计订购价格
    money
    订购价格


    DI-39
    备注
    订购统计备注
    text
    备注


    DI-40
    订购编号
    订购统计订购编号
    int
    订购编号


    DI-41
    教材ID
    订购统计教材ID
    int
    管理员编号


    DI-42
    书号
    订购统计书号
    varchar(30)
    书号


    DI-43
    书名
    订购统计书名
    Varchar(40)
    书名


    DI-44
    条码
    订购统计条码
    Varchar(40)
    条码


    DI-45
    作者
    订购统计作者
    Varchar(30)
    作者


    DI-46
    出版日期
    订购统计出版日期
    datetime
    出版日期


    DI-47
    出版社名称
    订购出版社名称
    varchar(50)
    出版社名称


    DI-48
    版次
    订购统计版次
    varchar(20)
    版次


    DI-49
    库位信息
    订购统计库位信息
    varchar(10)
    库位信息


    DI-50
    供应商
    订购统计供应商
    varchar(40)
    供应商


    DI-51
    出库编号
    出库统计出库编号
    int
    出库编号


    DI-52
    教材ID
    出库统计教材ID
    int
    教材ID


    DI-53
    收货方
    出库统计收货方
    varchar(60)
    收货方


    DI-54
    出库时间
    出库统计出库时间
    datetime
    出库时间


    DI-55
    出库数量
    出库统计出库数量
    int
    出库数量


    DI-56
    出库单价
    出库统计出库单价
    money
    出库单价


    DI-57
    取书编号
    教师取书取书编号
    int
    取书编号


    DI-58
    教材ID
    教师取书教材ID
    int
    教材ID


    DI-59
    教师姓名
    教师取书教师姓名
    varchar(10)
    教师姓名


    DI-60
    所在院校
    教师取书所在院校
    varchar(40)
    所在院校


    DI-61
    取书时间
    教师取书取书时间
    datetime
    取书时间


    DI-62
    取书数量
    教师取书取书数量
    int
    取书数量


    DI-63
    取书单价
    教师取书取书单价
    money
    取书单价


    DI-64
    取书编号
    学生取书取书编号
    int
    取书编号


    DI-65
    教材ID
    学生取书教材ID
    int
    教材ID


    DI-66
    负责人
    学生取书负责人
    varchar(10)
    负责人


    DI-67
    取书时间
    学生取书取书时间
    datetime
    取书时间


    DI-68
    取书数量
    学生取书取书数量
    int
    取书数量


    DI-69
    取书单价
    学生取书取书单价
    money
    取书单价


    DI-70
    姓名
    负责人姓名
    varchar(20)
    姓名


    DI-71
    院系名称
    负责人院系名称
    varchar(30)
    院系名称


    DI-72
    专业名称
    负责人专业名称
    varchar(30)
    专业名称


    DI-73
    班级名称
    负责人班级名称
    varchar(30)
    班级名称


    DI-74
    班级人数
    负责人班级人数
    int
    班级人数


    DI-75
    入学年份
    负责人入学年份
    datetime
    入学年份


    DI-76
    联系电话
    负责人联系电话
    varchar(20)
    联系电话


    DI-77
    供应商
    供应商姓名
    varchar(20)
    供应商


    DI-78
    联系电话
    供应商联系电话
    varchar(30)
    联系电话


    DI-79
    邮箱
    供应商邮箱
    varchar(30)
    邮箱


    DI-80
    地址
    供应商地址
    varchar(40)
    地址


    DI-81
    传真
    供应商传真
    varchar(30)
    传真


    DI-82
    出版社名称
    出版社名称
    varchar(20)
    出版社名称


    DI-83
    联系电话
    出版社联系电话
    varchar(20)
    联系电话


    DI-84
    邮箱
    出版社邮箱
    varchar(40)
    邮箱


    DI-85
    地址
    出版社地址
    varchar(40)
    地址


    DI-86
    传真
    出版社传真
    varchar(30)
    传真



    1.4.2 数据结构


    编号
    名称
    含义
    组成




    DS-1
    教材信息
    教材基本信息
    教材ID,书号,书名,条码,作者,出版日期,出版社名称,版次,库位信息,入库编号,库存量,供应商,定价


    DS-2
    入库
    入库统计信息
    入库编号,教材ID,书号,书名,条码,作者,出版日期,出版社名称,版次,库位信息,供应商,定价


    DS-3
    退书
    退书统计信息
    序号,教材ID,退书时间,退书原因,退书数量,退书单价


    DS-4
    订购
    订购统计信息
    教材ID,书号,书名,条码,作者,出版日期,出版社名称,版次库位信息,供应商出库编号,定价,订购数量,订购时间,订购价格,备注,订购编号


    DS-5
    出库
    出库统计信息
    出库编号,教材ID,收货方,出库时间,出库数量,出库单价


    DS-6
    教师取书
    教师取书信息
    取书编号,教材ID,教师姓名,所在院校,取书时间,取书数量,取书单价


    DS-7
    学生取书
    学生取书信息
    取书编号,教材ID,负责人,取书时间,取书数量,取书单价


    DS-8
    负责人
    负责人信息
    姓名,院系名称,专业名称,班级名称,班级人数,入学年份,联系电话


    DS-9
    供应商
    供应商信息
    供应商,联系电话,邮箱,地址,传真


    DS-10
    出版社
    出版社信息
    出版社名称,联系电话,邮箱,地址,传真



    1.4.3 处理逻辑描述


    编号
    处理功能
    处理过程




    PR-1
    入库进行更新功能模块
    根据入库的内容进行库存的更新


    PR-2
    订购统计插入功能模块
    根据订购的情况进行再订购表内的更新,计算总价,在教材基本信息表内进行库存更新


    PR-3
    退书更新内容功能模块
    在退书的时候进行更新库存和退书的原因


    PR-4
    负责人进行替换功能模块
    在修改负责人信息的时候,会级联更新订书表的负责人信息,减少冗余



    2 概念设计概念设计阶段主要是将需求分析阶段得到的用户需求抽象为信息结构(概念模型)的过程,它是整个数据库设计的关键。
    在本高校教材管理管理系统中,从数据流图下手。分析数据流图和数据字典,知道整个系统功能围绕“教材”、“用户”、“管理员”、“订书”、“退书”的处理,根据需求分析得出如下过程。

    一门教材只能被一个用户订阅,一个用户可以订阅多门教材;一个管理员可以管理多个用户,一个用户只能被一个管理员管理;用户决定订书,用户提出退书条件管理员接受订书条件,管理员可以同意用户退书
    根据以上需求得出基本的全局ER图如下:

    3 逻辑设计3.1 将E-R图转换为关系模型分析全局ER图,由于部门与职工的联系方式是1:n(一对多),可以将其之间的联系与n端实体部门、职工合并,,而教师与课程之间的借阅和归还联系方式则是n:m(多对多),这样要把它们之间的联系转化为独立的关系模式,职工与管理员之间的罚款联系是m:n(多对多),将其联系也转化成独立的关系模式,具体的基本E-R图向关系模型的转化如下:

    教材基本信息表:(教材ID,书号,书名,条码,作者,出版日期,出版社名称,版次,库位信息,入库编号,库存量,供应商,定价)
    入库统计信息表:(入库编号,教材ID,书号,书名,条码,作者,出版日期,出版社名称,版次,库位信息,供应商,定价)
    退书统计信息表:(序号,教材ID,退书时间,退书原因,退书数量,退书单价)
    订购统计信息表:(教材ID,书号,书名,条码,作者,出版日期,出版社名称,版次库位信息,供应商出库编号,定价,订购数量,订购时间,订购价格,备注,订购编号)
    出库统计信息表:(出库编号,教材ID,收货方,出库时间,出库数量,出库单价)
    教师取书信息表:(取书编号,教材ID,教师姓名,所在院校,取书时间,取书数量,取书单价)
    学生取书信息表:(取书编号,教材ID,负责人,取书时间,取书数量,取书单价)
    负责人信息表: (姓名,院系名称,专业名称,班级名称,班级人数,入学年份,联系电话)
    供应商信息表: (供应商,联系电话,邮箱,地址,传真)

    3.2 模型优化3.2.1 数据库模式定义教材基本信息表



    列名**
    数据类型
    可否为空
    说明




    教材ID
    int
    not null
    教材ID


    书号
    varchar(30)
    not null
    书号


    书名
    varchar(40)
    not null
    书名


    条码
    varchar(40)
    not null
    条码


    作者
    varchar(30)

    作者


    出版日期
    datetime

    出版日期


    出版社名称
    varchar(20)

    出版社名称


    版次
    varchar(10)

    版次


    库位信息
    varchar(10)

    库位信息


    入库编号
    int

    入库编号


    库存量
    int

    库存量


    供应商
    varchar(30)

    供应商


    定价
    money

    定价



    入库统计表



    列名
    数据类型
    可否为空
    说明




    入库编号
    int
    not null
    入库编号


    教材ID
    varchar(30)
    not null
    教材ID


    书号
    varchar(30)
    not null
    书号


    书名
    Varchar40)
    not null
    书名


    条码
    varchar(40)

    条码


    作者
    varchar(30)

    作者


    出版日期
    varchar(30)

    出版日期


    出版社名称
    varchar(50)

    出版社名称


    版次
    varchar(20)

    版次


    库位信息
    varchar(10)

    库位信息


    供应商
    varchar(40)

    供应商


    定价
    Money
    not null
    定价


    入库时间
    varchar(30)
    not null
    入库时间


    入库价格
    Money
    not null
    入库价格


    入库数量
    int
    not null
    入库数量



    订购统计表



    列名
    数据类型
    可否为空
    说明




    定价
    money
    not null
    订购数量


    订购数量
    int
    not null
    订购时间


    订购时间
    datetime
    not null
    订购价格


    订购价格
    money
    not null
    备注


    备注
    text

    订购编号


    订购编号
    int
    not null
    教材ID


    教材ID
    int
    not null
    书号


    书号
    varchar(30)
    not null
    书名


    书名
    Varchar(40)
    not null
    条码


    条码
    Varchar(40)

    作者


    作者
    Varchar(30)

    出版日期


    出版日期
    datetime

    出版社名称


    出版社名称
    varchar(50)

    版次


    版次
    varchar(20)

    库位信息


    库位信息
    varchar(10)

    供应商


    供应商
    varchar(40)

    订购数量



    退书统计表



    列名
    数据类型
    可否为空
    说明




    序号
    int
    not null
    序号


    教材ID
    int
    not null
    教材ID


    退书时间
    datetime
    not null
    退书时间


    退书原因
    varchar(60)
    not null
    退书原因


    退书数量
    int
    not null
    退书数量


    退书单价
    Money
    not null
    退书单价



    出库统计表



    列名
    数据类型
    可否为空
    说明




    出库编号
    int
    not null
    出库编号


    教材ID
    int
    not null
    教材ID


    收货方
    varchar(60)
    not null
    收货方


    出库时间
    datetime
    not null
    出库时间


    出库数量
    int
    not null
    出库数量


    出库单价
    money
    not null
    出库单价



    教师取书表



    列名
    数据类型
    可否为空
    说明




    取书编号
    int
    not null
    取书编号


    教材ID
    int

    教材ID


    教师姓名
    varchar(10)
    not null
    教师姓名


    所在院校
    varchar(40)

    所在院校


    取书时间
    datetime
    not null
    取书时间


    取书数量
    int
    not null
    取书数量


    取书单价
    money
    not null
    取书单价



    学生取书表



    列名
    数据类型
    可否为空
    说明




    取书编号
    int
    not null
    取书编号


    教材ID
    int
    not null
    教材ID


    负责人
    varchar(10)
    not null
    负责人


    取书时间
    datetime
    not null
    取书时间


    取书数量
    int
    not null
    取书数量


    取书单价
    money
    not null
    取书单价



    负责人信息表



    列名
    数据类型
    可否为空
    说明




    姓名
    varchar(20)
    not null
    姓名


    院系名称
    varchar(30)
    not null
    院系名称


    专业名称
    varchar(30)
    not null
    专业名称


    班级名称
    varchar(30)
    not null
    班级名称


    班级人数
    int
    not null
    班级人数


    入学年份
    datetime
    not null
    入学年份


    联系电话
    varchar(20)
    not null
    联系电话



    供应商基本信息表



    列名
    数据类型
    可否为空
    说明




    供应商
    varchar(20)
    not null
    供应商


    联系电话
    varchar(30)
    not null
    联系电话


    邮箱
    varchar(30)

    邮箱


    地址
    varchar(40)

    地址


    传真
    varchar(30)

    传真



    出版社基本信息表



    列名
    数据类型
    可否为空
    说明




    出版社名称
    varchar(20)
    not null
    出版社名称


    联系电话
    varchar(20)
    not null
    联系电话


    邮箱
    varchar(40)

    邮箱


    地址
    varchar(40)

    地址


    传真
    varchar(30)

    传真



    3.4 数据处理系统功能模块图,如图所示:

    4 物理设计4.1 数据存储数据库的物理设计就是为逻辑数据模型选取一个最合适应用要求的物理结构的过程,为数据库中各基本表建立的索引如下:

    由于基本表的主码ID,经常在查询条件和连接操作的连接条件中出现,且它们的值唯一,在两个属性上建立唯一性索引
    由于订购统计表、入库统计表和退书统计表的特殊性需要把教材基本信息表的库存进行更新
    学生取书表的负责人是负责人信息表的内容,教师取书表的负责人是教师表里面的教师ID
    供应商基本信息表和出版社基本信息表完善了教材信息表的供应商信息和出版社信息。

    4.2 系统功能模块4.2.1 登录模块登录分为用户登录和管理员登录,对于不同的登录人提供不同的功能,具体的功能模块图,如图所示:

    4.2.2 个人信息更新模块修改个人信息,在进入的时候先根据登录的用户名获取到自己的个人信息,然后进行更改,具体的功能模块图,如图所示:

    5 设计心得
    在SQL SEVER方面还是暑假前面的涉及,在vc++做系统的时候进行了一些小的更改使设计能运行,感觉在具体的权限设置方面。数据库的级联更新删除做的还不是太好。
    在VC++方面。这次设计花费了快一个月的时间,从以前的看书打代码到现在的明白了类。虽然说认识的还是不是特别深刻,但是知道了继承和关系,cpp文件和.h文件的联系。关键是暑假之前一直在做ODBC 在这次的实验过程中我用了ADO这个比较流行的接口,在网上看了一些封装ADO的接口指针的视频和教程,知道了大概改怎么使用ADO发现在vc里面使用ADO会比ODBC更加灵活,虽然说ADO更加难一点,但是理解了做发现格式都大同小异,在ado里面要经常使用try catch 语句,可以发现未知错误并且及时进行更改。前一段时间在想怎么把vc和数据库封装起来在其他的电脑上也能继续使用,但是没有成功,现在可以把数据源附加到有SQL的电脑里从新设计一个连接字符就应该可以做到封装。新的技术还是没有掌握。

    6 存在的问题及建议在这次的涉及里,我把整个的VC的框架给涉及了出来,但是因为时间有限,不能给没一个控件完善其中的代码。只做到了对数据库的插入更新删除的操作。对一些VC的高级控件还是不会使用,例如列表控件,标签控件,里面的代码缺少实践。对VC的界面没有进行更改,没有用到画刷进行高级的修饰,做出来的程序还是和市面上的程序有好大的区别,有一些bug没有进行修复。我相信,以后我会做的更好!
    参考文献[1]匡松,李强.Visual C++开发宝典[M].北京:中国铁道出版社,2009
    [2]刘锐宁,李伟明,粱水.Visual C++编程宝典[M].北京:人民邮电出版社,2011
    [3]李军.Visual C++ 实例精通[M].北京:机械工业出版社,2009
    [4]JamesR.Groff, Paul N.Weinberg, Andrew J.Oppel.SQL Server完全手册[M] .北京:电子工业出版社,2010
    附录 系统的运行界面系统的登陆界面

    主窗体

    查看本学期所需教材

    修改个人信息

    更改密码

    教材退订

    联系管理员

    教材基本信息

    教材进货

    库存管理

    用户个人管理
    2 评论 49 下载 2018-11-11 09:36:52 下载需要12点积分
  • 基于MySql和JSP的题库管理系统

    第一章 选题意义及可行性1.1 背景及意义随着电脑网络的不断普及,计算机技术已经被越来越多地应用到各个行业管理当中,担当起高效、节能的操纵主角。在日常生活中也充当着重要的角色。
    随着疫情的发生,对于大学生的课程考核成为一个问题,该需求分析报告用于WEB的课程试题库管理系统这一课题的开发过程。明确了课题开发的目的与要求,介绍了该系统的所有功能以及适用范围。
    1.2 主要研究内容本次拟通过对题库管理有关理论著作和知识的学习,主要从使用者身份以及数据和信息两个方面着手去考虑,对题库管理的整个流程,从底层开始规划设计,针对不同角色的不同管理需求,制定相应的架构模块,实时跟进使用的需求变化,尽可能提高系统的操作性和灵活性。打下一个扎实的根基是非常必要的,否则系统将变得越发难以维护,复杂度也将增加。这就要求系统要有良好的模块化设计。当系统的信息量越大,复杂度越高的时候,用户体验显得尤为重要。对当前题库管理的新需求分析,根据这些新需求设计出一套合适但相对简化的管理模式的管理系统,并且完成该系统下的各子系统功能模块的设计与开发,以实现题库管理的自动化、及时化和系统化的目的。
    第二章 需求分析及系统设计2.1 需求分析2.1.1 系统描述本选题旨在设计一个可以对题库信息进行良好管理的系统。服务器端用于部署该系统并且储存用户提交的信息数据,所有的业务逻辑均在服务器端处理,而浏览器端仅仅是一个浏览器,使用者并不需要进行维护,只是需要进行数据访问,从而实现各项功能需求的定制。
    2.1.2 系统基本要求该课题研究的目的是为提高题库管理的效率,给需要进行题库管理的人提供方便、快捷的创建、编辑题库信息;提供方便、快捷的查询,提高题库调查工作的效率。
    系统主要完成内容包括管理员管理、教师管理、题库管理、题库导入管理、题库导出管理主要功能如下:

    管理员管理:包括管理员对管理员信息的增加、删除、修改等,对各类型的查询、统计等
    教师管理:对教师信息的增加、删除、修改、查询等
    题库管理:对题库信息的增加、删除、修改、查询等
    题库导出管理:对题库信息的导出成Excel
    题库导入管理:对题库信息的Excel导入mySQL

    2.1.3 功能需求分析系统的功能包括:管理员管理、教师管理、题库管理、题库导入管理、题库导出管理等。管理员负责对各项信息的管理等,具体功能如图3.1:

    管理员用例清单表



    模块
    用例编号
    用例名称
    用例描述




    管理员登入
    Admin-001
    管理员登入
    管理员根据账户名、密码登入系统


    教师管理
    Admin-002
    教师管理
    添加、修改、删除出题教师


    试卷组建
    Admin-003
    试卷组建
    在试题库中选择需求数量的题目组成试卷


    教师名单导入
    Admin-004
    教师名单导入
    在教师库中讲Excel文件中的教师名单导入


    试题导入
    Admin-005
    试题导入
    在试题库中讲Excel文件中的试题导入



    管理员登入的用例描述表




    描述




    描述
    管理员根据账户名、密码登入系统


    基本流程
    (1)根据登入界面选择“管理员”,输入用户名、密码 (2)核对数据库账号信息 (3)信息匹配登入成功,否则返回登入界面


    返回数据
    账户名



    教师管理的用例描述表




    描述




    描述
    添加、修改、删除出题教师


    基本流程
    (1)管理员点击“教师管理”,进入教师管理界面 (2)系统根据相应信息显示已存在的教师信息 (3)管理员根据需求,单击删除、修改、添加等按钮 (4)根据选择不同的需求弹出相应的窗口 (5)完成相应需求的操作


    返回数据
    NULL



    试卷组建用例描述表




    描述




    描述
    在试题库中选择需求数量的题目组成试卷


    基本流程
    (1) 管理员点击”组卷”,进入组卷界面 (2)系统根据相应信息显示已存在的题库信息 (3) 管理员根据需求选择相应的试题组成试卷 (4) 完成相应需求的组建操作


    返回数据
    试卷集



    用户负责个人信息、个人题库的管理,具体功能如图3.2:

    教师的用例清单表



    模块
    用例编号
    用例名称
    用例描述




    管理员登入
    Admin-001
    管理员登入
    管理员根据账户名、密码登入系统


    教师管理
    Admin-002
    教师管理
    添加、修改、删除出题教师


    试卷组建
    Admin-003
    试卷组建
    在试题库中选择需求数量的题目组成试卷


    教师名单导入
    Admin-004
    教师名单导入
    在教师库中讲Excel文件中的教师名单导入


    试题导入
    Admin-005
    试题导入
    在试题库中讲Excel文件中的试题导入



    教师登入用例描述表




    描述




    描述
    教师根据账户名、密码登入系统


    基本流程
    (1)根据登入界面选择“教师”,输入用户名、密码 (2)核对数据库账号信息 (3)信息匹配登入成功,否则返回登入界面


    返回数据
    账户名



    组建试题库用例描述表




    描述




    描述
    落实课程的授课知识点,完成试题库的组建


    基本流程
    (1) 教师点击“出题”,进入出题界面 (2) 向试题库中添加试题 (3) 完成相应需求的组建题库操作


    返回数据
    试题库



    试题维护用例描述表




    描述




    描述
    修改、删除试题库


    基本流程
    (1) 教师点击”搜索”,进入题库界面 (2) 填写相应的查询添加 (3) 编辑对应试题 (4) 完成相应需求的组试题维护操作


    返回数据
    改变的试题集



    2.1.4 运行需求分析系统服务器端配置需求信息表



    类型
    配置型号




    操作系统
    Window10


    Web服务器
    Tomcat9.0.3


    数据库管理系统
    MySQL5.6


    运行库
    JDK1.8



    系统客户端配置需求信息表



    类型
    配置型号




    浏览器
    Mozilla Firefox


    操作系统
    Windows10



    第三章 系统设计3.1 系统概要设计对于本系统的各子系统功能模块初步设想如下:

    系统登录模块:分别为教师和管理员的登录,进入不同页面
    管理员管理模块:教师信息题库数据的录入、维护、查询、删除管理工作
    教师管理模块:包括题库数据的录入、维护、查询、删除管理工作
    导入导出模块:对数据库数据的导出成excel和将excel数据导入excel中

    3.2 系统功能模块图系统主要功能模块图如图3.3所示,以使用角色来分,主要包括管理员模块、用户模块两大部分。其中管理员模块主要包括管理员信息管理,教师信息管理,题库管理;教师模块主要包括个人信息管理,题库管理,导入导出题库。

    3.3 系统总体业务流程管理员通过自己的用户名和密码登录管理系统,若输入不匹配则重新输入,进入系统后可以浏览所有管理员、教师、题库信息,可以对管理员、教师、题库信息进行增加、删除、修改与查询;教师登录系统后便列出该所教课程的所有试题,可以创建新的试题,可以对试题进行录入、维护、查询、删除管理工作,教师还可以修改个人的信息;管理员和教师都可以对题库的导入导出。

    管理员登录,如果帐号密码不匹配,重新输入
    系统验证登录信息,验证通过后进入管理系统首页
    管理员对管理员、教师、题库信息的查询或修改等管理操作
    退出系统


    3.4 系统开发体系结构设计本系统采用JSP技术,通过MVC三层设计模型实现基于B/S架构的《电路原理》重点课程网。用JSP+Servlet+JavaBean实现MVC设计模式的流程。

    MVC是三个单词的缩写:M,Model(模型);V,View(视图),C,Control(控制)。MVC模式的目的就是实现Web系统的职能分工,Model层:实现系统的业务逻辑,即javaBean部分。View层:负责与用户交互,即在界面上展示数据对象给用户,即html,jsp。Control层:Model与View之间沟通的桥梁,它可以分派用户的请求并选择恰当的视图以用于显示,同时它也可以解释用户的输入并将它们映射为模型层可执行的操作,当然就是Servlet的职责了。
    3.5 系统数据库设计数据库是信息管理的常规方法,它可以处理各种各样的数据信息。数据库的优势就在于它可以将庞大而复杂的信息以有序的方式组织起来,便于修改和查询, 管理人员手工处理这些枯燥的数据。数据库一般按照数据的组织和查询方式加以区分。目前使用最多的都是基于关系代数的关系数据管理系统(RDBMS)。在关系数据库关系系统中,数据按照表存放。一个数据库可以有多个表,每个表由行和列组成,每行是一个记录,每个记录的信息分为多段,一张表的每一行的段的组成都是相同的,而不同行中相同的列就称为字段。
    设计本系统,主要包括以下数据表,E-R图如下图所示:

    使用MySQL建立起数据库表如下:

    admin表:用于存储管理员信息
    class表:用于课程信息
    teacher表:用于存储教师信息
    test表:用于存储所有题库信息

    管理员信息表(admin)



    字段
    类型
    主键
    Null
    默认
    注释




    adminNumber
    varchar(20)
    Y
    N

    用户名


    adminPassword
    varchar(20)

    N

    密码



    用户信息表(class)



    字段
    类型
    主键
    Null
    默认
    注释




    classNumber
    varchar(20)
    Y
    N

    课程号


    className
    varchar(20)

    N

    课程名


    classCredit
    varchar(20)

    N

    学分



    题库信息表(teacher)



    字段
    类型
    主键
    Null
    默认
    注释




    teacherNumber
    varchar(20)
    Y
    N

    教师编号


    teacherPassword
    varchar(20)

    N

    登入密码


    teacherName
    varchar(20)

    Y

    教师姓名


    teacherSex
    varchar(20)

    Y
    0
    教师性别


    teacherTitle
    varchar(20)

    Y

    教师头衔


    teacherPhone
    varchar(20)

    Y

    教师电话



    问题信息表(test)



    字段
    类型
    主键
    Null
    默认
    注释




    questionNumber
    int(10)
    Y
    N

    试题编号


    classNumber
    varchar(20)
    Y
    N

    所属课程


    teacherNumber
    varchar(20)
    Y
    N

    教师姓名


    questionType
    varchar(20)

    N

    试题类型


    question
    varchar(500)

    N

    试题题目


    questionSelect
    varchar(500)

    Y
    NULL
    试题选项


    questionResult
    varchar(500)

    N

    试题答案


    questionPoint
    varchar(200)

    N

    试题考点



    第四章 系统功能实现4.1 系统的开发环境与开发工具开发工具对一个系统的成败具有决定性作用。我选用了IntelliJ IDEA开发软件,并用MySQL作为系统后台数据库,开发中将用到以下主要几款开发工具:
    开发工具、程序语言



    类型
    工具




    开发环境
    IntelliJ IDEA


    后台数据库管理
    MySQL 5.6


    数据库管理软件
    SQLyog


    功能模块设计及流程图绘制
    Microsoft Visio2013


    系统界面设计
    IntelliJ IDEA


    jQuery框架
    EasyUI


    程序设计语言
    JAVA


    浏览器
    Mozilla Firefox



    4.2 系统主要功能模块实现本套题库管理系统是基于当前流行的试题管理的新需求分析而开发的一套管理系统。通过对该管理系统的研究与相关开发,已达到如下目标:

    本系统主要完成上述六大子系统功能模块的设计与开发
    从管理人员的角度出发去人性化设计系统,方便使用者使用本系统
    系统开发完成后,能够提高工作效率,使得题库管理更加高效与便捷

    4.2.1 系统登录模块实现当使用本系统时,用户需要输入用户名和密码来进行安全验证登录。用户输入用户名密码后,系统会向后台登录模块发送请求,后台会调用方法来向数据库查询用户,若没有结果则返回错误状态,在界面向用户显示输入错误的提示。
    登录界面

    登录失败界面

    4.2.2 管理员管理模块实现当管理员输入正确的账号和密码时,系统登录成功跳转至admin.jsp。页面中,管理员可以进行对管理员信息的浏览,修改,增加,删除,查询等操作。
    管理员登录界面

    管理员增加界面

    管理员增加成功界面

    管理员编辑界面

    管理员编辑成功界面

    管理员删除界面

    管理员删除成功界面

    在管理员主界面中,上方有增加、删除、修改、查询等功能,管理员的信息一目了然。
    4.2.3 教师管理模块管理员可以点击左侧菜单中的“用户管理”,切换到用户管理的页面。页面中,管理员可以进行对用户信息的浏览,修改,增加,删除,查询,上传头像等操作。
    教师信息界面

    在用户管理主界面中,上方有增加、删除、修改、查询;
    4.2.4 题库管理模块管理员可以点击左侧菜单中的“题库管理”,切换到题库管理的页面。页面中,管理员可以进行对题库信息的浏览,修改,增加,删除,查询等操作。
    题库管理界面

    题库详情界面

    题库添加界面

    题库成功界面

    题库编辑界面

    题库编辑成功界面

    题库删除界面

    题库删除成功界面

    题库导入界面

    题库导入成功界面

    第五章 总结本次作业主要是对题库管理系统中学习到了以下几点:

    数据库的结构设计,数据库结构设计是继需求分析和确定开发工具后的重要阶段,是管理型软件开发设计的核心和重要组成部分。数据库结构设计的好坏与否将对应用系统的运行效率以及实现的效果产生很大影响。科学、合理的数据库结构设计可以提高数据访问的速度,有效保持数据的完整性、一致性和共享性,因此数据库结构设计对系统设计来说至关重要
    学习尝试了使用MVC结构完成JAVA的Web开发。并初次尝试使用了session的方式储存用户。学习到了许多JSP脚本的灵活使用。当然由于使用了MVC结构,大量运用了json的技术来传递数据。同时也使用了大量的jQuery中ajax的使用
    在开发过程中,大大小小的会遇到些问题,在询问老师或上网查找资料的过程中,对这项开发技术的一些细节也有了更深的理解和掌握。对于SQL语句也有了更深的理解,以及更好的运用;从刚开始每一条语句都要在数据库中执行一遍到能熟练掌握基本的增删改查语句
    对于各个界面有更深的理解以及完成过程,但也相对的会花费了更多的时间,很好的将程序进行分层管理,将各个模型的控制器,视图均放在一个界面中,便于后期管理

    总的来说,本次的作业对我是一次很好的锻炼,让我对系统开发的需求分析阶段有了更好的理解,在实践中去领会它的优势所在无疑是最好的办法。通过本次的课程设计,提升了我在数据库设计方面的能力熟练度。
    5 评论 40 下载 2020-07-06 10:02:24 下载需要12点积分
  • 基于C#实现的TPS和B样条人脸变形系统

    1 需求分析人脸变形即,在引导图的面部 68 个关键点的引导下,将源图的面容进行扭曲变形,使得得到的图片的人脸的关键点特征与导引图的关键点特征相似。
    由于该变形过程无法用显式的数学公式进行表达,在变形上存在一定的难度。而我们的需求是将源图的关键点坐标的位置映射到导引图的关键点坐标的位置,同时也要将关键点坐标附近的像素坐标也映射过去。由于映射之后得到的坐标点不是整数,所以需要进行插值。为此,可以采用两个常见的变形函数,即 B 样条变形和 TPS 变形。
    在本报告中,规定源图为待变形图,导引图为将源图的关键点特征变换成的目标的图片,生成图即变形后的图片。如将特朗普的脸的特征换成梁静茹的儿子 Anderson 的脸,源图为特朗普,导引图为 Anderson。
    2 TPS 变形2.1 方案设计首先将导引图的关键点经平移、放大、旋转等操作进行仿射变换以变换到源图的关键点的位置,进行粗对齐。之后以导引图的关键点为控制点,源图的关键点为目标点,进行 TPS 求解即得到变形之后的图像。
    2.2 方案基本原理2.2.1 仿射变换参数拟合仿射变换是最常用的空间坐标变换之一,其形式如下。

    通过仿射变换拟合参数之后,坐标点进行了尺度、旋转、平移或偏移。对参数进行最小二乘法拟合,在进行仿射变换之后,将源图和导引图的人脸进行粗对齐,便于后续 TPS 操作。
    2.2.2 TPS 变形TPS(Thin plate spline) 是一种常见的插值模型,目标是寻找一个通过所有控制点的光滑曲面f(x, y),使得能量函数 If 最小,且该问题有解析解。

    TPS 求解,给定 n 个控制点 P1 = (x1, y1), …, Pn = (xn, yn),记矩阵 K,P,L 分别为

    假定目标点为 P′1 = (x′1, y′1), …, P′n = (x′n, y′n),记矩阵 V,Y 为

    其中 U(r) 为径向基函数,即 U(r) = r2log(r2) r ̸= 0,r 为坐标点之间的距离。任意一点的坐标为

    其中,a1, ax, ay, ω 为线性方程组 L[ω1, …, ωn, a1, ax, ay]T = Y 的解。
    2.2.3 具体实现控制点为导引图的 68 个关键点,目标点为源图的 68 个关键点,即 Pi 为导引图的关键点,P′i为源图的关键点,注意导引图的关键点要带入仿射变换之后的坐标。带入方程计算求解再进行插值即得到变形后的图片。

    3 B 样条变形3.1 方案设计首先将导引图的关键点经平移、放大、旋转等操作进行仿射变换以变换到源图的关键点位置以进行粗对齐。之后通过使用三次 B 样条扭曲进行人脸变形,即得到变换之后的结果。其中,网格点的移动受控制点影响,姑且将权重全部设为 1,之后再使用梯度下降方法以求得每一个网格点的位移权重,得到使得 Loss 较小的权重,用该组参数进行变形即得到目标图片。
    3.2 方案基本原理3.2.1 B 样条变形给定 m+n+1 个平面或空间 Pi(i = 0, 1, …, m + n),称 n 次参数曲线段:

    为第 k 段 n 次 B 样条曲线段 k = 0, 1, 2, …, m,这些曲线段的全体称为 n 次 B 样条曲线,其顶点Pi(i = 0, 1, …, n + m) 所组成的多边形称为 B 样条曲线的特征多边形。其中 Gi,n(t) 称为基函数。项目主要使用的是三次 B 样条曲线的基函数。
    三次 B 样条曲线基函数:

    其中,t ∈ [0, 1]。
    三次 B 样条扭曲 B 样条扭曲由网格点的位移影响其附近图像的变形。三次 B 样条扭曲中,任一点的位移由距其最近的 16 个网格点的位移决定。设图中某一点的的坐标为 (x, y),设网格大小为N,则有

    其中,坐标 (xi, yi) 为网格点 Pxi,xj 的坐标。根据这一原则将图片建立起网格点坐标系,则可以得到点 (x, y) 的位移为

    3.2.2 梯度下降法梯度下降的主要思想为:开始时随机选取一个参数的组合,即 (θ1, θ2, …, θn),计算代价函数,然后寻找下一个能让代价函数值下降最多的参数组合,不断迭代后得到一个局部最小值。
    这里为了得到较好的网格点位移权重,故采用梯度下降法。定义 Loss 函数为

    其中,m 为脸部关键点个数 (一般取 68),n 为网格点个数。s(·) 表示的是点的位移,θ 表示的是网格点位移权重。设学习率为 α,每次迭代进行参数的同步更新,即

    当迭代到一定次数或 Loss 函数的值小于某个阈值的时候梯度下降停止。
    要注意学习率 α 的选取:如果 α 太大,则梯度下降法可能会越过最低点,甚至可能无法收敛,即移动步数很大导致每次更新都越过最低点,离最低点越来越远;如果 α 太小,梯度下降可能会很慢。这里默认学习率为 0.001,且为了避免无法收敛的情况,在具有发散的趋势时,将当前学习率减半,以保证最终代价函数能够收敛。
    3.2.3 具体实现先定义三类点,即控制点、网格点、任一点。控制点即为脸部的 68 个关键点,网格点定义见上文,任一点即变换后的图像上的每一个点。现在所需要做的,首先建立好网格坐标,之后根据控制点的位移计算每个控制点周围的 16 个点的位移偏差。即遍历 68 个关键点,周围的每个网格点以 1 的权重进行分别求和。由于权重为 1,故每个网格点的位移的权重需要进行调整,故对所有网格点设一个位移权重,采用梯度下降法进行求解。设 X,Y 方向的学习率均为 0.001,初始化权重均为 0.05。

    4 68个关键点检测使用 C# 的 Dlib 库运用机器学习进行关键点检测1。在加载已经训练好的模型后,检测即可得到 68 个关键点。通过与附件中给定的 9 张图的关键点坐标相对比,相差较小。
    5 插值原理5.1 最近邻插值将变换后的图像中的元像素点最近邻像素的灰度值赋给原像素点的方法,是最简单的灰度值插值,即将非整点的坐标四舍五入,不够精确。
    5.2 双线性插值图像中任意一点的像素值由它周围四个点的像素值确定,具体关系为

    双线性插值相对简便,速度相对较快。但是双线性灰度插值的平滑作用可能使得图像的细节产生退化,这种现象在进行图像放大时尤其明显。
    5.3 双三次插值图像中任意一点的像素由它周围 16 个点的像素确定,具体关系为

    其中,矩阵 A、B、C 分别为

    S(·) 为

    双三次插值通常能够产生较好的效果,最精确的插补图形,能够创造出比双线性插值更平滑的图像边缘。但是它的速度几乎是最慢的。
    6 实现效果6.1 运行界面用户可以根据需要对变形方式进行选择 (TPS/BSpline),对三种插值方式进行选择。同时对于关键点信息的载入,用户可以选择读入外部数据或者选择自动识别。同时,为了防止用户操作上的失误,设置只有在用户载入图片之后才能上载关键点信息,二者均完成后才能开始进行变形。

    6.2 不同变形模式下的运行效果6.2.1 TPS 变形上图即为 TPS 变形的效果。由于 TPS 的原理,故在变形之后会出现没有信息的部分,对于该部分的处理为忽略。之前考虑用最边缘的像素值进行 padding,但是由于本身就缺乏该部分信息,进行 padding 之后图像会变得很奇怪。
    6.2.2 B 样条变形在进行 20 次梯度下降之后,得到变形后的图片。由于 B 样条只对局部进行处理,所以背景上没有缺失信息的部分。如这张图,奥巴马的眼睛变大。

    6.3 不同插值方式下的变形效果以奥巴马的脸特征换成 Anderson 为例,使用 TPS 变形方式。大图见 figure 文件夹。由于看小图无法感受到插值效果的不同,故将图片放大 5 倍对比奥巴马的右眼。
    6.3.1 最近邻插值
    6.3.2 双线性插值
    6.3.3 双三次插值
    6.3.4 三种插值方式效果对比由对比图可以看到,最近邻插值的效果最差,双线性和双三次插值的效果要好于最近邻插值。除此之外,双三次插值的图像边缘要比双线性平滑,即双线性插值可能会对图像产生稍微模糊的效果。

    6.4 自行检测关键点并进行变形在实现自行检测 68 个关键点之后,可以对想要被变形的图片进行变形。下图尝试“王校长”的变形,68 个关键点等在检测结束后自行显示在图片上。在识别关键点之后,可以得到变形后的图片。
    可以看到,变形后的“王校长”更符合图片的配字。

    识别算法可以识别这种通过人脸制作的表情包。

    7 误差分析7.1 观测误差与舍入误差对于观测误差,由于图片的 RGB 值是 uint8 类型,所以观测误差最大为 0.5。
    工程中多出使用 C# 的 double 类型,精度为 15 位有效数字,故中间过程的舍入误差相对较小,可以忽略。而在对 Bitmap 的 RGB 赋值时,将 double 类型转换为 0 255 的 uint8,舍入误差最大为 0.5。而对于这三种插值,其实质为周围 4 个或 16 个点的线性组合,且线性组合的系数为 1。
    综上,观测误差的最大值为 0.5,舍入误差的最大值为 0.5。
    7.2 方法误差 (插值)7.2.1 最近邻插值由坐标的舍入误差可以得到,|∆x| ≤ 0.5, |∆y| ≤ 0.5,所以最近邻的方法误差为

    由于数字图像为离散信号,故将微分换位差分。假定,f(x, y) 在 x 方向和 y 方向上的一阶导数存在且有界为 Mx1, My1。则显然,在物体边缘等变化较大的区域,Mx1, My1 比较大,其他区域非常小。所以,x 方向和 y 方向的方法误差最大为 0.5Mx1, 0.5My1,总方法误差为 0.5(Mx1 + My1)。
    7.2.2 双线性插值假定,f(x, y) 在 x 方向和 y 方向上的二阶导数存在且有界 Mx2, My2。先考虑 x 分量的插值,即考虑 y = j 与 y = j + 1 方向的插值。每个直线方向上的插值为一维插值,故可以得到每条直线的插值误差为

    再将得到的插值后的两点进行 y 分量的插值,即考虑 x = x0 方向的插值,且同为一维插值,故可以得到插值误差为

    综上,总的方法误差为

    7.2.3 双三次插值假定,f(x, y) 在 x 方向和 y 方向上的四阶导数存在且有界 Mx4, My4。若直接按照分析双线性插值对双三次插值误差进行分析,则很容易得到总的方法误差为

    考虑双三次插值的另一种形式。具体如下

    其中,参数矩阵可以表示为

    其中,矩阵 P 和矩阵 F 分别为

    记 Px, Py 矩阵如下

    则有

    根据这个形式可以得知,双三次插值即可以等价位,先做 y 方向的三次埃尔米特插值,再做 x 方向的三次埃尔米特插值,即与双线性插值分解方法类似。则误差为

    而在求取导数的过程中同样存在着误差。由于离散情况下,需要使用差分来代替导数,考虑使用中心差分来近似一阶导数。具体形式如下,这里 h 取 1。

    在这里,有

    不妨先考虑 x 方向,则易知存在 x∗ ∈ [x − 1, x + 1] 使得 fx(x) = f′(x∗)。假定 f(x, y) 的二阶导数存在且有界 Mx2, My2。所以有

    y 方向同理。所以由于使用差分来代替导数造成的误差为 Mx2 + My2。双三次插值总的方法误差为二者相同时考虑。
    7.3 方法误差 (变形)7.3.1 最小二乘拟合最小二乘参数拟合使用了高斯消元法进行求解,具体分析见下。
    7.3.2 TPS 变形高斯消元法 线性方程组 L[ω1, …, ωn, a1, ax, ay]T = Y 求解时应用了高斯消元法。由定理,若 A 是非奇异阵,Ax = b ̸= 0,且 A(x + δx) = b + δb,则有

    高斯消元误差的上界即为 ∥A−1∥ ∥A∥, 经过 Matlab 辅助计算,所给定的 9 份数据点 (最小二乘法拟合后) 的所构成的矩阵 L 不是病态矩阵。但是由于水平有限,无法进行更详细的分析。
    除此之外,舍入误差与观测误差没有被放大,几乎无影响。
    7.3.3 B 样条变形梯度下降法 迭代次数限制在 20 次时,根据当前实现的算法,代价函数 (均方误差) 的区间为(0,40)。
    而当参数最佳时,均方误差为 E(E ≥ 0),故梯度下降法的均方误差为 (0, 40)。
    8 其他相关说明8.1 TPS 与 B 样条的对比通过视觉效果来看,TPS 是针对全局进行变形,而 B 样条是对局部进行变形,所以论全局观赏效果的话,B 样条占优势。但是显而易见 TPS 的变形效果要比 B 样条更明显。除此之外,B 样条的计算时间要比 TPS 少一些。
    8.2 问题与解决8.2.1 关于线性方程组求解的误差分析由于自身能力有限,关于高斯消元法部分的误差分析在稍微自学课本后面的内容之后,仍是无法进行更具体的分析。我感觉可能无法去分析得更具体,即若分析误差上界,可能实际值要远小于该误差上界,故或许需要一个条件更强的分析高斯消元误差的方法。
    8.2.2 关于 LOSS 函数的选取LOSS 函数的选取本着网格点与移动点的位移关系设计,但事实证明若 LOSS 函数趋于 0 所得到的变形并不是最优的,猜测设计的 LOSS 函数的条件不够强。为了解决这种情况,将迭代次数固定。
    8.2.3 关于图片中有多个人68 个关键点检测算法是先对人脸进行识别,再载入模型进行检测关键点。如果图片中有多个人,则默认人脸为所检测的最后一个人脸。

    8.2.4 关于侧脸和歪脸的处理变换最好的效果就是正脸源图和正脸导引图。如果有歪脸,即头正,则通过仿射变换最小二乘,已经进行旋转,故效果较好。但是对于侧脸,比如梁静茹和特朗普的另一张照片,变换之后的图像为了模仿导引图的特征,脸会歪,但是这是正确的输出结果。同时由于没有露出的脸部的信息未知,所以无法对未知的信息进行填补。
    8.3 程序运行所需环境程序使用 VS2017 进行开发,使用的语言为 C#,电脑分辨率为 1366×768。
    8.4 总结与反思本次大作业,让我慢慢地了解并应用了 C# 语言,并让我体会到了它的优点所在。除此之外,对插值的理解更加深刻。而对于图像的变形上,我感受到了 TPS 变形与 B 样条变形之间的差异。TPS相对来讲实现简单,但是对全局进行操作导致背景出现黑色部分;而 B 样条可以对局部进行调整,但是调整效果并没有 TPS 那么明显,各有利弊。以及由于还有其他几个大作业,关于 B 样条还有一些升级的思路,但是由于时间关系没有付诸实践。除此之外,由于时间关系,没有对界面进行美化,保持着原始的朴素。
    此外,在逐渐完成大作业的过程中,我发现我之前将换脸和脸部变形的概念混淆。本次大作业完成的只是根据导引图关键点特征对源图进行变形,生成图片的像素值采自源图,所以无法实现换脸的效果。
    4 评论 46 下载 2019-04-17 14:50:33 下载需要13点积分
  • 基于JavaScript和MySQL的物业管理系统

    摘 要近年来,随着网络技术的迅猛发展,高速流通的时代,计算机的普及以及计算机网络技术的应用,让大量普通人能够有机会接触到比以往更多的知识。作为一个以传播知识为主要职能的机构——学校,建立一个网校管理系统是十分必要的事情,这不仅能使更多的人享用宝贵的教育资料源,同时也对于提升学校自身的知名度,提高学生自学能力,有相当大的帮助。
    随着互联网技术的飞速发展,利用网络进行辅助教学已经成为时代发展的必然趋势,建立网校管理系统,尽可能提高优质教学的利用率,对实现人才培养,促进社会经济发展都能起到十分重要的作用。也可以引导用户主动年该学习,提高学习效率,更为教学双方提供一个信息共享与信息交流的平台。
    针对以上问题,前台主要使用JavaScript作为开发语言,后台使用MySQL作为数据库管理系统,设计开发了物业管理系统。
    关键词:物业管理,WEB,数据库,vue
    一、绪论1.1 选题背景简介随着互联网技术的飞速发展,利用网络进行辅助教学已经成为时代发展的必然趋势,建立网校管理系统,尽可能提高优质教学的利用率,对实现人才培养,促进社会经济发展都能起到十分重要的作用。也可以引导用户主动年该学习,提高学习效率,更为教学双方提供一个进行写作学习和交流的平台。
    人口多而教育资源缺乏影响着我国受过高等教育的人在人口比例中所占的比重,这严重的制约了我国社会的发展与进步,这对于提高我国国民的文化科学素养十分不利。怎样才能让更多的人享有少部分人拥有的精品教育资源呢?对于这个问题,前人已经做了大量的研究。随着计算机技术以及计算机网络技术的飞速发展,人们终于找到了一条实现这种梦想的捷径,那就是寄希望于把各种教育资源移置到互联网上去,使得各地方的人都能够方便的获取到各种自己想要的知识,打破传统教育资源分配不均的限制,使得更多的人能够有机会获取到知识。
    近年来,学校学生的数量逐渐增加,人工书写教学的方式已经不能满足如此庞大的数据。为了更好的适应信息时代的高效性,一个利用计算机来实现网校管理工作的系统将必然诞生。基于这一点,设计了一个网校管理系统以便在最短的时间内,高效准确的完成整个教学过程。
    1.2 目的和意义与传统的教育相比,网校管理系统是一种全新的教育模式,它可以突破时间和空间的限制,让更多的学习者共享优秀的教育资源。网校管理系统既具有开放性、交互性、协作性和自主性等特点,有具有异步性、实时性、生动性、集成性和大容量等优势。因此在网校管理系统的建设中,单纯地构建各种功能单一的系统并不能完全满足网校管理系统建设的要求,只有那些对数据和信息进行有效组织,整合了多种业务,为用户提供个性化服务的系统才能充分地发挥网校管理系统的作用。
    建设网校管理系统的根本目的是利用现代化的教育信息技术手段将网校管理系统的相关内容上网并免费开放,以实现优质教学资源共享,提高高等学校教学质量和人才培养质量。
    二、技术简介2.1 HTML5技术简介HTML5 将成为 HTML、XHTML 以及 HTML DOM 的新标准。HTML 的上一个版本诞生于 1999 年。自从那以后,Web 世界已经经历了巨变。HTML5 仍处于完善之中。然而,大部分现代浏览器已经具备了某些 HTML5 支持。
    2.2 ES6简介ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,于2015年6月批准通过。ECMAScript6的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。让代码更加准确,更易于阅读。
    ECMAScript是JavaScript语言的国际标准,JavaScript是ECMAScript的实现(ES是规范,JS是实现)。在日常场合,这两个词是可以互换的。
    2.3 Vue-cli 3.0Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统
    2.4 Koa2Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。
    2.5 VuexVuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
    2.6 iViewiView 是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产品。
    2.7 MySQLMysql是最流行的关系型数据库管理系统,在WEB应用方面MySQL是最好的RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。
    在本文中,会让大家快速掌握Mysql的基本知识,并轻松使用Mysql数据库。
    2.8 NavicatNavicat 是一套能帮助你快速直观地构建精确模型的图形化工具,使各个层面的用户都能轻松地创建高品质的数据模型。它能为专业人士提供适合其特殊需要的复杂功能,但是对数据模型的新手来说又相当容易上手。
    创建一个优良的数据模型可以是很困难的。我们将一切保持简单方便,让你专注于你的数据库设计,而不会令得它变得更复杂。
    为了让你无需花费时间学习,便能对你的模型有一个简单而精确的了解,Navicat 拥有难以置信的迅速反应和简洁美观的设计,大大增强了其性能和可用性。
    再加上准确的字段类型预测功能和无限次的撤消或重做功能,它就能减省开发所需的时间并提供一个快捷高效的方式来创建和编辑你的表或视图结构。
    无论你是想从一个数据模型创建新的数据库,或者从现有数据库导入数据模型。Navicat Data Modeler 就是你所需要的工具。
    2.9 VScodeVisual Studio Code(以下简称vscode)是一个轻量且强大的代码编辑器,支持Windows,OS X和Linux。内置JavaScript、TypeScript和Node.js支持,而且拥有丰富的插件生态系统,可通过安装插件来支持C++、C#、Python、PHP等其他语言。
    据vscode的作者介绍,这款产品可能是微软第一款支持Linux的产品。
    微软对于vscode的定位如下图,位于编辑器与IDE之间,但是更像一个编辑器。有人说是披着编辑器外衣的IDE,我觉得是披着IDE外衣的编辑器。
    深入了解了vscode之后发现了vscode很贴心地内置了很多功能,让我觉得我可以很快适应到vscode的使用。
    三、系统概要设计系统的设计主要前台和后台两个部分:

    前台客户端是展现给用户的,包括登录注册、查看个人房间信息、查看家庭报修信息、报修故障、撤销报修、在线缴费、查看家庭成员、审核家庭成员、删除家庭成员、查看与编辑个人信息
    后台管理端是物业管理人员使用的,包括管理员登入与登出、修改个人信息、查看与筛选房间信息、新增业主

    3.1 系统需求分析
    物业管理端

    登录/登出房间管理
    为房间添加业主信息条件筛选房间
    业主管理
    编辑/删除业主信息编辑/删除家庭成员信息
    报修管理
    查看报修列表报修状态筛选查看具体报修内容更改报修进度:已联系、已派修、已维修(更改为已维修时录入维修费用)、已缴费
    零件管理
    对零件增删改查,出库对零件类型增删改查
    管理员管理
    新增/查看管理员

    业主端

    登录/登出(判断是否为业主,若为业主添加审核家庭成员权限)注册(注册成功后须业主审核后才可登录)修改个人信息业主查看家庭报修列表普通用户查看个人报修列表支付维修费用

    3.2 可行性分析这里讲的可行性分析的任务是从技术上、经济上分析需解决的问题是否存在可行性。其目的是在尽可能短的时间内用尽可能小的代价确定问题是否有解。
    3.2.1 技术可行性技术上的可行性分析主要分析技术条件能否顺利完成开发工作,硬、软件能否满足开发者的需要等。
    本系统前端设计主要由Vue.js实现,vue 的开发体验是非常令人感到愉悦的。Vue在数据交互,组件化开发方面有非常大的优势,每个组件都是一个.vue文件,可以把页面拆成很多组件,方便开发与维护,使用时只需引入组件即可,通过vue-router实现路由跳转,可以很容易地创建单页面应用程序,只需要把vue-router添加到vue工程中,将组件(components)映射到路由(routes),然后告诉 vue-router 在哪里渲染它们。
    本系统数据库使用的MySQL,MySQL是最流行的关系型数据库管理系统,在WEB应用方面MySQL是最好的关系型数据库,轻量、开源、简便易用,使用Navicat Premium 12做数据库图形化管理更高效率进行前后端开发
    3.2.2 经济可行性如今是信息化时代,信息化管理可以使物业的管理工作更加系统化、快速化、全面化。这样可以为社会带来较高的工作效益和经济效益,本系统对计算机配置的要求不高,普通私人电脑都可以完全满足需要,本系统作为一个设计,其开发目的是为巩固所学知识,无需开发经费,因此在经济上也是可行的。
    综上所述,本系统的开发目标已经明确,且在技术和经济上都是可行的,因此系统的开发是完全可行的。
    3.2.3 操作可行性该系统如投入使用,预期作到界面友好,管理方便,使用简单,管理人员经过培训,也是完全能够使用本系统管理相关信息的。
    综上所述,本系统的开发目标已经明确,且在技术和经济上都是可行的,因此系统的开发是完全可行的。
    3.3 网站模型
    3.4 Server端模型系统基本结构

    利用Koa服务器,用于连接客户端和数据库服务器。对于客户端发出的需要对数据库进行访问的请求,Koa服务器负责客户端与数据库服务器的网络通信,并将相关数据嵌入返回给客户端的页面;对于客户端发出的不需要对数据库进行访问的请求,Koa服务器将直接处理这些请求,并将最终生成的数据发往客户端浏览器。
    四、数据库设计4.1 数据概念结构设计E-R模型是数据进行第一层抽象的表示方法。它的主要成分包括:实体、联系和属性。我们可以用E-R图将内容表达出来,辅助设计的实现[6]。
    4.2 数据库关系设计该网络学校系统数据库关系图如下所示:
    数据库前端关系

    数据库后台关系图

    4.3 数据字典管理员表(admin_user)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    name
    varchar(255)





    password
    varchar(255)





    role
    int(1)


    1:超级管理员 2:管理员


    isDel
    int(1)


    默认0



    管理员token表(admin_token)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    token
    varchar(255)





    deadline
    bigint(13)


    时间戳


    admin_id
    int(11)





    用户表(user)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    name
    varchar(255)





    nick_name
    varchar(255)





    password
    varchar(255)





    sex
    int(1)


    0:男 1:女


    room_id
    int(11)





    role
    int(1)


    0:未审核 1:家庭成员 2:业主


    isDel
    int(1)


    默认0


    tel
    varchar(255)





    用户token表(user_token)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    token
    varchar(255)





    deadline
    bigint(13)


    时间戳


    user_id
    int(11)





    报修表(repair_list)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    title
    varchar(255)





    status
    int(1)


    0:已撤消 1:已报修 2:已联系 3:已派修 4:已维修 5:已缴费


    photo
    text


    JSON字符串


    price
    float(10, 2)





    user_id
    int(11)





    create_time
    varchar(13)


    创建时间的时间戳


    appointment_time
    varchar(13)


    派修时间的时间戳


    pay_time
    varchar(13)


    支付时间的时间戳



    房间表(room)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    room_num
    varchar(255)





    building
    varchar(255)





    area
    float(255, 0)





    零件表(part)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    part_name
    varchar(255)





    price
    float(10, 2)





    type_id
    int(11)





    isDel
    int(11)


    默认0


    count
    int(11)





    零件类型表(part_type)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    type_name
    varchar(255)





    isDel
    int(11)


    默认0



    零件出库表(part_order)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    repair_id
    int(11)





    part_id
    int(11)





    count
    int(11)





    五、 前端部分5.1 管理端部分5.1.1 登录页面
    用户输入用户名密码,密码使用md5加密,点击登录向后台发送,若匹配失败,返回’用户名或密码错误’并弹出提示消息;若匹配成功,向前端返回一个token令牌,前端储存在cookie中,并弹出登录成功的提示,后跳转入main路由。
    登录成功后,进入main路由,此时将cookie中的token取出并发送给后台,后台匹配token是否存在且未过期(七天),若匹配失败,则跳转回login路由;若成功,则将用户信息发送至前端,前端将信息存在vuex的state中。
    当用户点击退出登录时,清除cookie中的token并跳转回login路由。
    5.1.2 管理员个人信息
    个人信息页面显示管理员的用户名、角色、密码,点击密码显示修改密码对话框

    若要修改密码,需要在原密码处输入正确密码并点击验证,验证通过后,可在后两个输入框中输入新密码

    重置密码部分均做了正则表达式校验
    5.1.3 房间管理
    房间管理页面获取管辖内所有房间数据,可根据楼号进行筛选
    每个房间显示对应的业主和电话号码,没有业主的房间可点击新增按钮新增业主

    新增业主处也均做了正则表达式的表单校验
    5.1.4 业主管理
    业主管理可以查看辖区内所有业主信息,并做了分页处理,减少浏览器和服务器压力

    删除业主时,会联动删除此业主所在家庭的所有家庭成员
    5.1.5 家庭成员管理
    家庭成员管理中可以查看所有家庭成员,并可将某一普通家庭成员设置为业主,同时原业主将变为家庭成员
    5.1.6 报修管理

    报修管理部分,可以通过关键词检索标题搜索对应数据
    由于该部分字段过多,这里将报修编号和标题这两列固定,方便查看表格内容
    可以根据不同的状态对数据进行筛选
    可以根据创建时间、派修时间、支付时间对数据进行排序

    点击图片按钮可以查看报修照片
    点击后面操作按钮,可以将报修流程进行至下一步,状态为已撤销、已维修与已缴费时无法点击,状态为已报修时,点击变为已维修须输入报价

    当前端用户支付成功后,此处可以显示支付时间
    5.1.7 零件类型管理
    此处编辑,新增,删除零件类型

    新增与编辑时须输入类型名称

    删除类型时,会联动删除类型下所有零件
    5.1.8 零件管理
    此处显示零件列表,可根据单价与剩余量排序,可根据类型筛选。

    可编辑,新增与删除,并在获取列表时做了分页处理。

    点击出库,可对库存不为0的零件进行出库,输入标题关键字选择为哪个报修进行出库。
    由于零件的消耗量不与报修成绝对关系,在此处做手动出库处理。
    5.1.9 管理员管理
    此处可对管理员进行增删改,仅有超级管理员可进入此路由,并且只可编辑与删除普通管理员

    而普通管理员是看不到此tab页的,若在url上输入此路由地址,则跳转入401页面

    5.1.10 404当用户访问不存在的页面时,跳转入404 no found页面

    5.2 客户端部分客户端部分为H5应用通过Hbuilder打包成的APP应用。
    5.2.1 登录
    点击登录按钮匹配数据库,若匹配失败,返回用户名或密码错误,若成功,返回token令牌,将token存入cookie并跳转入main路由,之后将token发送至后台验证是否有效,若无效则跳转入login,若有效,则返回用户信息并在页面回显
    5.2.2 注册
    用户注册页面,选项均做了表单校验,用户名、密码与手机号做了正则表达式的校验,刚刚注册的用户在后台存角色为0,只有当选择房间的业主审核后才可变为1(家庭成员)
    5.2.3 房屋信息
    进入此路由页,请求当前用户所在的room信息,返回后回显到页面
    5.2.4 报修信息
    此路由页显示报修列表,做了分页处理,每页10条数据,当滚动到底部时会自动加载下一页的数据,若报修未上传照片,则会用默认照片替代。

    点击缴费,会提示是否进行缴费,点击确认,此处可添加支付宝与微信的接口,跳转入对应应用,支付成功后回调,发送支付成功的请求,完成缴费
    上部搜索框可以进行关键字检索,搜索无结果时会显示无数据页面



    点击用户可以查看用户详情,业主可删除其他家庭成员,而普通家庭成员无此权限
    业主可审核新注册的用户,通过审核的用户会变为当前家庭的家庭成员

    此处可以编辑个人信息,仅可直接修改昵称及手机号,点击右上角更改按钮提交更改

    修改密码须输入原密码,验证通过后输入新密码
    六、后台部分6.1 路由RESTful架构遵循统一接口原则,访问同一资源时均使用相同路由,根据不同请求方式进行数据操作。
    使用koa-router中间件对路由进行处理。
    6.2 数据库操作首先根据配置文件(数据库用户名、端口号、密码等)建立数据库连接池

    连接池创建好后,当请求发送至后台,为这一请求建立数据库连接成功后,进行数据库操作,再将结果返回出去,之后释放资源,断开连接。

    6.3 跨域跨域是前后端联调开发中经常会遇到的问题,由于浏览器有同源策略,用来防止CSRF攻击,当前端发出请求的时候,请求的协议名,地址,端口号与当前的有一个不同,就会引发浏览器拒绝跨域请求,解决跨域问题的方法有很多,比如jsonp,服务器代理,document.domain + iframe等等方式解决跨域问题,我选择了在服务端,允许前端跨域发出PUT, POST, GET, DELETE, OPTIONS请求,成功地解决了ajax跨域问题
    koa2中提供了cors中间件,允许接受跨域请求,直接use即可。
    6.4 图片处理首先使用nodejs中的os.networkInterfaces()获取到网络(Windows系统中为WLAN,MAC中为en0),将本机ip+3000端口号作为主机名。
    在接收到前端传的base64图片后,先将url的头过滤掉,将其转换为buffer对象,使用随机字符串算法进行重命名,保证存储中不会有重名文件,再将其写入文件,将路径发送至前端。

    七、结论7.1 系统的特点本系统是一个网校管理系统,采用ASP.NET+SQL的模式来开发。本系统从功能上来说,比较完备。系统以Web界面与用户交互,为用户提供信息并接受其操作,同时通过数据库管理系统来存储信息数据。系统实现了对信息数据的浏览、查询、编辑和管理等基本数据库操作,系统采用了模块化设计方法,根据用户的需求及程序的应用与维护的易用性,将各个部分置于不同的模块当中,方便了程序的扩展与维护,同时建立了程序功能复用的基础。
    7.2 系统的不足和改进本系统基本上满足了网校管理系统关于信息管理方面的需要。实现了网校管理系统所需的功能。在界面上力求做到美观、在操作方面尽量避免由于用户操作不当带来系统的出错现象。但由于时间仓促,本系统还存在一些不足之处,界面不够美观,需要进一步修饰和美化;对数据库操作的性能有待进一步优化,虽然本系统优化了不少,但要达到理想状态还有一段距离,如部分功能程序代码过长,如果后台数据库过大将会影响运行速度;部分数据库表的设计存在一定的冗余,有待进一步优化。根据系统的不足,继续改进和完善本系统。提高审美观点,可使用photoshop、fireworks等图片处理工具修饰图片,力求给用户提供美观友好的界面;简化程序代码,可使不同界面之间能共享一些方法、函数和变量,对于相同的功能模块可生成程序包供其它界面引用,这样就会提高系统的运行速度;使用数据库连接池技术提高数据库操作的性能;数据库的关系模式可以进一步规范化,减少冗余现象。
    1 评论 17 下载 2021-04-09 08:52:44 下载需要14点积分
  • 基于QT实现的日历程序

    1 概要1.1 简介本篇设计文档主要讲述了计52班的吴启凌根据小学期第一周李国良老师所教的内容,来实现的程序Calendar的设计思路,架构,以及一些设计细节。
    1.2 实现的功能Calendar实现了日历的基本功能以及一些附加功能,主要有

    正确地按照公历显示日历。
    能够添加、删除、修改事件序列,某个事件在设置时,能够按天,按周,按月重复发生;删除事件时,能删除可重复事件的单个或全部。
    能够设置每一天的颜色。
    能够与本地文件实现拖拽交互。当用户把文件拖到某一天上时,能够保存到Calendar所在的目录下,并在当天格子内显示文件名。双击某一天能够打开一个对话框,其中显示了该天上的所有文件,并且能够拖拽到本地保存。此外,还设计了一个按钮来打开和关闭拖拽交互。
    能够使用配置文件,包括XML和ini文件来保存信息。其中,XML用于保存事件和每天的颜色,ini用于保存语言,是否打开拖拽交互的信息。信息能够通过save按钮保存,也可在关闭程序时自动保存。支持导入,导出XML文件。
    可以对日历进行整体拖拽,并设置了一个按钮来固定、解锁界面,锁定后,日历不再响应鼠标动作,并且能将鼠标事件传递到桌面。
    国际化:支持中文、英文两种模式。

    2 系统架构2.1 文件结构Calendar的代码根据界面分组,文件如下
    Mycalendar构建了日历的样式及其交互模式,Filesdialog和Listwidget用于显示日期所储存的文件,以及提供拖拽功能,Scheduledialog用于新建及编辑事件,Schedule类用于储存事件,Schedulemanager用于管理事件,而Mainwindow则作为各组件沟通的纽带。

    2.2 组件分析Schedule类用于储存事件的描述,开始、结束日期、重复模式等信息。Schedulemanager提供了对Schedule管理的接口,包括添加、编辑、删除事件,获取某天的事件列表或单个事件,以及获取全部事件。

    Scheduledialog用于向用户显示事件的描述、重复模式信息,同时接受用户的编辑。
    Listwidget重写了QListWidget的mousePressEvent事件处理函数,在用户对列表中的文件按下鼠标时,传递文件路径的信息。
    Mycalendar则是工程中较为重要的一个类,重写了父类的dragEnterEvent和dropEvent来处理鼠标拖入事件,并在鼠标拖入文件时,将文件复制到Calendar所在目录下,并显示在日期格子中。重写了paintCell来获取每个日期的外框的位置信息,以此来判断鼠标将文件拖到了哪一天内;以及在日期中显示文件名,设置日期颜色。重写了resizeEvent来重置datepos中储存的矩形信息,以免造成拖拽的误差。

    Mainwindow则是工程中的核心类,用于收集、处理、传递几乎所有的信息。三个public slots用于在三个事件按钮按下时,弹出窗口并收集事件信息;on_calendar_clicked用于在鼠标点击calendar时,在列表框中刷新事件信息,以及在colorbox,即颜色选择框内显示该天的颜色信息;on_actionLock_triggered在lock按钮按下时,固定窗口并设置鼠标穿透;on_checkBox_toggled用于读取是否开启文件拖拽按钮的信息;on_languageBox_currentTextChanged用于设置语言;最后三个槽用于保存配置信息、导入XML、导出XML。

    3 用户界面3.1 主界面界面如下图1所示,左半边区域为日历部分,中间为功能按钮,右边为事件显示区域。此外工具栏中为lock按钮,菜单栏中Calendar可以弹出下拉菜单。
    如图2,3,点击某天后,右侧列表框中会显示当天事件,用户可以点击New按钮来新建事件,或者可以点击列表框中的条目,再点击Edit或Delete按钮来编辑或删除事件,删除时,会出现确认对话框,三个选项分别对应删除单个事件、全部事件、取消删除。
    在color标签下方的下拉框中,可以设置某天的颜色。
    Language下拉框可以设置语言,设置后需要重启才能生效。需要重新设置一下翻译文件加载的路径。
    Enable drag的复选框能够开启、关闭文件拖拽功能。
    按lock按钮能够锁定日历,由于锁定后鼠标穿透,需要用快键键Ctrl + L来解锁。
    在Calendar的下拉菜单栏中,save能够保存设置,import XML能导入事件、日期颜色设置,export XML能够导出事件、日期颜色设置。
    3 评论 121 下载 2019-06-23 18:07:10 下载需要13点积分
  • 基于Android Studio实现的论坛网站Android客户端和JAVA EE后台

    第一章 概述1.1 开发环境本安卓程序在Windows 10系统下使用Android Studio开发,后台使用MyEclipse开发,测试环境为安卓系统5.1、4.4、4.3、5.0,屏幕尺寸5.0、5.1、5.5的安卓手机。
    1.2 安装配置本安卓程序要求安卓SDK为API level 15以上,target level为23,即,android 4.0.3到android 6.0。
    1.3 需求分析本程序为安卓APP开发项目,项目内容为IT主题的论坛开发。根据需求分析,需要一下功能:

    用户的登陆与注册功能
    用户权限包括管理员、版主、普通用户和游客身份登陆
    根据不同权限登录用户可以对帖子进行不同程度的管理,管理员可以查看、删除所有帖子,版主可以查看所有帖子、删除做属板块的帖子,普通用户和游客都只能查看帖子
    除了游客外所有用户都能发帖、回帖,游客不能发帖、回帖
    用户可以查看自己发的帖子并管理自己的帖子

    第二章 程序概要设计2.1 程序功能模块本安卓程序分为登陆注册模块、查看帖子模块、删除帖子模块、回复帖子模块。

    登陆注册模块是程序的入口,如果已经登陆过了又没有退出登陆,就可以自动登陆,如果没有账号,可以游客登陆
    查看帖子模块可以根据板块选择性查看所有帖子,已注册用户可以查看自己的帖子,帖子信息包括标题、内容、时间等
    删除帖子模块包括管理员可以删除所有帖子,版主可以删除所属板块的帖子,所有用户可以删除自己的帖子,游客不能使用删除功能,程序根据登陆用户的权限自动显示是否可以使用
    回复帖子模块用于已注册用户对帖子的回复,游客不能回复帖子

    2.2 流程图
    2.3 程序文件结构分析java文件夹下MyWork包内的java文件是每个布局对应的Activity,其中Circle是自定义的一个控件;control包下是两个适配器,包括主页面的适配器MainAdapter和回复页面的适配器LookAdapter,还有联网的工具类NetWord。

    res资源文件夹下的layout布局资源文件包括各个Activity的布局和listview的自布局,其中tool_bar是ToolBar的布局。

    menu文件夹下是两个ToolBar的菜单布局,values文件夹下使用到了strings文件和colors文件,特别的是attrs文件,这个是Circle自定义控件的配置文件。

    2.4 数据库设计本程序使用javaEE后台,数据库为sql server,包括card表、section表和userTable表,分别的字段如下:

    card:id、nameId、contents、date、title、sectionId、replyId、isTop、topDate
    section:id、name、host
    userTable:id、username、password、power、pic

    第三章 程序详细设计3.1 关键代码分析联网:使用java jdk自带的HttpURLConnection进行联网,并使用json进行数据传输。图3-1包括了链接网络的方法connect()、传参的输出流ObjectOutputStream,图3-2判断了状态码是否为200然后接收后台传过来的参数并处理返回,接收参数使用InputStream输入流。


    自定义适配器:先写了继承BaseAdapter的适配器类,这个项目中使用了两个适配器,分别为MainAdapter、LookAdapter,作为主界面和回复节目的适配器。两个泪重写了getView方法,处理每个listview中每个item的布局,以显示每一个帖子。
    侧滑菜单:在布局中使用DrawerLayout如图3-3,在Activity中使用ActionBarDrawerToggle作为侧滑开关,并实现开和关的监听,如图3-4。


    界面返回刷新:使用Intent跳转时用startActivityForResult,并重写onActivityResult方法,如图3-5。

    3.2 疑难问题解决用户权限识别:在第一次登陆成功后将后台返回的用户信息存进SharedPreferences,后面根据从中取出来的权限信息进行判断,然后决定是否显示相应按钮。

    第四章 程序的发布和测试4.1 发布过程安卓端的发布,将程序运行到手机,通过android studio的Logcat查看运行信息;
    JavaEE端的发布,将程序部署到Tomcat,同样通过myeclipse的Logcat查看运行信息。
    4.2 测试过程图4-1为登陆界面,点击注册按钮到如图4-2的注册界面,注册成功后跳转回登陆界面登陆。



    登录
    注册









    图4-3为管理员登陆的界面(还有打开侧滑菜单的状态),图4-4为版主和普通用户及游客登陆后的界面。



    管理员登录
    普通用户登录









    图4-5为游客登陆的侧滑菜单界面,与其他用户是不同的,只有一个选项,当其他用户登录时,可以点击右上角的笔进入发帖节目,如图4-6。



    侧滑菜单界面
    发帖









    第五章 分析与总结5.1 优点本安卓程序的优点在于界面简洁,有与服务器后台联系,交互友好,基础功能及部分拓展功能已经实现。
    5.2 缺点本安卓程序的缺点在于界面跳转仍有部分不流畅,因为代码效率问题有待改进,还有其他计划中的拓展功能由于时间关系还没实现。
    5.3 总结通过此次安卓大作业的开发,让我对安卓开发更加熟悉,对知识点的运用更加熟练,由于运用到了javaEE后台,使我对javaEE的熟练度也增加了。因为这次大作业的制作时间比较短,所以刺激了自己的潜力,锻炼了自己赶项目的感觉。
    第六章 参考目录[1] 《疯狂安卓讲义》 电子工业出版社 李刚 2015.8
    [2] 《android应用开发学习手册》 清华大学出版社 管蕾 2015.7
    16 评论 346 下载 2018-11-06 15:32:08 下载需要12点积分
  • 基于C++实现的模拟文件系统

    1.实验要求
    设计和实现一个模拟文件系统,要求包括目录、普通文件和文件的存储
    文件系统的目录结构采用类似Linux的树状结构
    要求模拟的操作包括:

    目录的添加、删除、重命名目录的显示(列表)文件的添加、删除、重命名文件和目录的拷贝文件的读写操作
    用户进入时显示可用命令列表;用户输入help时显示所有命令的帮助文档

    输入某个命令+?时显示该条命令的使用说明
    用户输入exit时退出该系统
    实验实现基于LINUX平台。
    实验开发语言必须选用C/C++,不能选用JAVA

    2.实验环境调试环境

    操作系统:Ubuntu 16.04 TLS
    内存:3.5GiB
    处理器:AMD E-350 Processor×2
    图形:AMD PALM(DRM 2.50.0/4.15.0-45-generic,LLVM 6.6.6)
    操作系统类型:64位
    磁盘:30.4GB

    开发环境

    开发工具:Visual Studio 2017
    操作系统:Windows 10 家庭中文版
    处理器:Inter(R) Core(TM) i7-8565u CPU \@ 1.8GHz 1.99 GHz
    内存:8.00 GB
    系统类型:64位操作系统,基于x64的处理器

    3.实验设计3.1 系统流程整体系统操作模拟Ubuntu命令行,具体流程如下:

    3.2 文件结构整体系统采用属性结构组织文件,具体图示如下:

    3.3 实现的命令


    命令
    用法
    说明
    选项




    cd
    cd [dir]
    显示当前目录名或改变当前目录



    ls
    ls [dir]
    显示当前或指定路径下所有文件和目录



    mkdir
    mkdir dir
    在当前目录下建立一个新目录



    touch
    touch file
    在当前目录下新建一个新文件



    gedit
    gedit file
    读写指定的文件



    rm
    rm -d\
    -f file\
    dir
    删除指定的目录或文件
    -d:删除目录 -f:删除文件


    cp
    cp -d\
    -f\
    -cd\
    -cf SOURSE DEST
    从原路径复制一个文件或目录到目的路径下
    -d:复制目录 -f:复制文件 -cd:复制目录,但不在原路径下保留原目录 -cf:复制文件,但不在原路径下保留原文件


    rename
    rename -d\
    -f oldname newname
    更改指定文件或目录的名字
    -d:重命名目录 -f:重命名文件


    su
    su
    更改当前用户



    cls
    cls
    清屏



    exit
    exit
    退出文件系统



    help
    help
    显示帮助文档




    4.数据结构为简化代码结构,系统未采用面向对象编程的思想。将用户、文件、目录分别封装成一个struct结构体。
    4.1 用户数据结构struct user{ string name;//用户名 string password;//密码};
    用户结构体中包含用户的用户名以及密码。
    4.2 文件数据结构struct file{ string name;//文件名 vector<string> content;//文件内容 user owner;//文件所有者};
    文件结构体包含文件名、文件内容以及文件所有者。需要特别指出的是,目前系统实现的多用户权限可以概括为:文件创建者为文件所有者,非文件所有者可以知道该文件的存在,但不能对该文件执行读写、复制、删除等操作。
    4.3 目录数据结构struct dir { string name;//目录名 dir* pre;//父目录 map<string, file*> files;//所包含的文件 map<string, dir*> next;//子目录};
    目录结构体包含目录名、父目录、当前目录下的文件以及直接子目录。其中,为方便代码编写,后两个成员使用map容器包装,其中map的first为文件名(或目录名),second为对应的文件指针(或目录指针)。
    5.模块详解5.1 用户指令以下按3.3节展开。
    5.1.1 cd显示当前目录的绝对路径或改变当前目录。
    流程图

    关键代码
    //cd void cd(string name) { if (name == "") { //显示当前目录的绝对路径 } else { dir* tmp = pathTrans(name);//解析路径 if (tmp == NULL) { cout << "No Such Directory.\n"; } else { curdir = tmp;//进入用户输入的路径 } } }
    5.1.2 ls显示当前目录下或指定路径下所有文件和目录。
    流程图

    关键代码
    //ls void ls(string path) { dir *tmp = curdir; if (path != "") { curdir = pathTrans(path);//解析路径 if (curdir == NULL) { //输出错误提示 } } //遍历输出文件和目录信息 for (auto it = curdir->files.begin(); it != curdir->files.end(); it++) { } for (auto it = curdir->next.begin(); it != curdir->next.end(); it++) { } curdir = tmp; }
    5.1.3 mkdir在当前目录下建立一个新目录。mkdir dir,其中dir表示新建目录的目录名。
    流程图

    关键代码
    //创建目录 void mkdir(string name) { if (name == "") { cout << "Require Parameters" << endl; } else if (curdir->next.find(name) != curdir->next.end()) { cout << "There is a directory having same name.\n"; } else if (!judgeName(name)) { cout << "Name has at least a illegal character.\n"; } else { dir *tmp = new dir();//一定要这样创建,否则字符串后面就不能读取 tmp->name = name; tmp->pre = curdir; curdir->next[name] = tmp; } }
    5.1.4 touch在当前目录下新建一个新文件。touch file,其中file表示新建文件的文件名
    流程图

    关键代码
    //建立文件 void touch(string name) { if (name == "") { cout << "Require Parameters" << endl; } else if (curdir->files.find(name) != curdir->files.end()) { cout << "There is a same file.\n"; } else if (!judgeName(name)) { cout << "Name has at least a illegal character.\n"; } else { //建立对应的新文件 } }
    5.1.5 gedit读写指定的文件。gedit file,其中file表示需要读写的文件,可以用绝对路径或相对路径指定。
    流程图

    关键代码
    //编辑文件 void gedit(string name) { dir *t = curdir; if (name.find_last_of('/') != name.npos) { //解析路径 } //是否存在目标文件 if (curdir->files.find(name) == curdir->files.end()) {} //目标文件是否为当前用户所拥有 else if (curdir->files[name]->owner.name != curuser.name) {} else { ofstream out("tmp.dat"); //将文件当前内容输入临时文件 for (int i = 0; i < curdir->files[name]->content.size(); i++) {} out.close(); //用gedit打开临时文件 system("gedit tmp.dat"); //读取临时文件中的内容,存入文件 ifstream in("tmp.dat"); while (getline(in, t)) { //读取临时文件内容 } } curdir = t; }
    因本文件系统完全运行在内存中,创立的文件与目录并未存在实际磁盘中。因此,为提高用户读写文件的体验,在此引入了一个临时文件机制:将存储在内存中的文件暂时存储到临时文件中,然后用gedit打开这个临时文件。在用户编辑完成后,再将临时文件中的内容转存到内存中。
    Gedit是一个GNOME桌面环境下兼容UTF-8的文本编辑器。它使用GTK+编写而成,因此它十分的简单易用,有良好的语法高亮,对中文支持很好,支持包括gb2312、gbk在内的多种字符编码。
    虽然这样的操作效率不高,但是借助gedit强大的功能,能给用户带来一种编辑真实文件的体验。
    5.1.6 rm删除指定的目录或文件。
    用法:rm -d|-f

    file|dir,其中file与dir代表需要删除的文件或目录,目录(或文件)均可用绝对路径或者相对路径表示选项:
    -d:删除目录-f:删除文件

    流程图

    关键代码
    //删除 void rm(string tmp) { //选项解析,路径解析 //删除目录 if (option == "-d") { //是否存在目标目录 if (curdir->next.find(name) == curdir->next.end()) {} else { deletedir(curdir->next[name]);//递归删除 } } else if (option == "-f") { //是否存在目标目录 if (curdir->files.find(name) == curdir->files.end()) {} //是否为文件所有者 else if (curdir->files[name]->owner.name != curuser.name) {} else { delete(curdir->files[name]); } } }
    因本系统采用树形的目录结构,因此在删除目录时需要用到递归,如deletedir函数所示。
    //递归删除目录 void deletedir(dir *cur) { //先删文件 for (auto it = cur->files.begin(); it != cur->files.end(); it++) { delete(it->second); } cur->files.clear(); //再删目录,要嵌套删除 for (auto it = cur->next.begin(); it != cur->next.end(); it++) { deletedir(it->second); } cur->next.clear(); delete(cur); }
    5.1.7 cp复制一个文件或目录到指定路径下。

    用法:cp -d|-f|-cd|-cf SOURCE DEST
    其中SOURCE为需要复制的文件或目录,DEST为需要复制到的路径。SOURCE与DEST均可用绝对路径或者相对路径表示选项:
    -d:复制目录-f:复制文件-cd:复制目录,但不在原路径下保留原目录-cf:复制文件,但不在原路径下保留原文件


    流程图

    关键代码
    //复制 void cp(string tmp) { //解析选项与路径 if (option == "-f") { //是否有同名文件 if (den->files.find(name) != den->files.end()) {} //是否存在目标文件 else if (sou->files.find(name) == sou->files.end()) {} //是否为当前用户所拥有 else if (curdir->files[name]->owner.name != curuser.name) {} else { file *tmp = new file(*(sou->files[name]));//复制文件 den->files[name] = tmp;//放入目的目录下 } } else if (option == "-d") { //是否有同名目录 if (den->next.find(name) != den->next.end()) {} //是否存在目标目录 else if (sou->next.find(name) == sou->next.end()) {} else { dir *tmp = cpDir(sou->next[name]);//递归复制目录 tmp->pre = den; den->next[name] = tmp;//放入到目的目录下 } } else if (option == "-cf") { //是否有同名文件 if (den->files.find(name) != den->files.end()){} //是否存在目标文件 else if (sou->files.find(name) == sou->files.end()){} //是否为当前用户所拥有 else if (curdir->files[name]->owner.name != curuser.name){} else { den->files[name] = sou->files[name];//放入到目的目录下 sou->files.erase(name); } } else if (option == "-cd") { //是否有同名目录 if (den->next.find(name) != den->next.end()){} //是否存在目标目录 else if (sou->next.find(name) == sou->next.end()){} else { den->next[name] = sou->next[name];//放入到目的目录下 sou->next.erase(name); } } }
    跟删除类似,在复制目录时需要用到递归复制,如cpDir所示。
    //递归复制目录 dir* cpDir(dir *tmp) { dir *goal = new dir(*tmp); //清除原来的内容 goal->next.clear(); goal->files.clear(); //把文件重建 for (auto it = tmp->files.begin(); it != tmp->files.end(); it++) { file *f = new file(*(it->second)); goal->files[it->first] = f; } //重建目录 for (auto it = tmp->next.begin(); it != tmp->next.end(); it++) { dir *d = cpDir(it->second); d->pre = goal; goal->next[it->first] = d; } return goal; }
    5.1.8 rename更改指定文件或目录的名字。

    用法:rename -d|-f oldname newname
    oldname代表需要重命名的目录或文件,newname代表重命名后的名字。oldname可以使用绝对路径或相对路径选项:
    -d:重命名目录-f:重命名文件


    流程图

    关键代码
    void rename(string tmp) { //解析路径与选项 if (!judgeName(newname)) {}//新名字中是否有非法字符 if (option == "-d") { if (curdir->next.find(old) == curdir->next.end()) {}//是否存在目标目录 else if (curdir->next.find(newname) != curdir->next.end()) {}//是否存在与新名字重名的目录 else { //重命名 } } else if (option == "-f") { if (curdir->files.find(old) == curdir->files.end()) {}//是否存在对应文件 else if (curdir->files.find(newname) != curdir->files.end()) {}//是否存在与新名字重名的文件 else if (curdir->files[old]->owner.name != curuser.name) {}//需重命名文件是否为当前用户拥有 else { //重命名 } } }
    5.1.9 su更改当前用户(调用login函数,详见下文)。
    5.1.10 cls清屏。
    5.1.11 exit退出文件系统(主要调用save函数,详见下文)。
    5.1.12 help显示帮助文档。
    5.2 其他系统操作5.2.1 登录流程图

    关键代码
    void login() { bool flag = 1; map<string, string> users;//所有注册用户 //打印欢迎语 ifstream in("user.dat"); string tname, tpass; while (in >> tname >> tpass) {}//读入所有注册用户的信息 //输入用户名 while (flag) { if (users.find(tname) == users.end()) {}//注册用户中是否有输入用户 else { if (users[tname] == tpass) { //核对用户名与密码是否匹配 } else { printf("password is incorrect!\n"); } } } if (!flag) { printf("This user is not exist.\nDo you want to creat a new user?(y/n):"); char choice; cin >> choice; if (choice == 'Y' || choice == 'y') { //注册 } else { login(); } } //重新存回 ofstream out("user.dat"); for (auto it = users.begin(); it != users.end(); it++) {} return; }
    5.2.2 保存系统状态为提高用户体验,每次用户使用exit命令退出系统时,系统会保存退出前的系统状态。
    保存系统状态的主要实现思想是:通过递归遍历系统的目录结构,以字符串向量的形式存储包括目录名、文件名、文件内容在内的所有信息。最后将字符串向量存入record.dat文件。字符串向量内部的结构类似xml文件。具体流程图与代码如下:
    exit函数

    save函数

    具体代码
    //退出系统 void exit() { records.clear(); save(root); ofstream outr("record.dat"); for (int i = 0; i < records.size(); i++) { outr << records[i] << endl; } }
    //存储目前情况 void save(dir *tmp) { records.push_back(tmp->name);//目录名 records.push_back(to_string(tmp->files.size()));//文件数 for (auto it = tmp->files.begin(); it != tmp->files.end(); it++) { records.push_back(it->second->name);//文件名 for (int i = 0; i < it->second->content.size(); i++) { records.push_back( it->second->content[i]);//文件内容 } records.push_back("content");//文件内容结束符 records.push_back(it->second->owner.name);//所有者用户名 records.push_back(it->second->owner.password);//所有者密码 } records.push_back(to_string(tmp->next.size()));//子目录数 for (auto it = tmp->next.begin(); it != tmp->next.end(); it++) { records.push_back(it->second->name);//子目录名 save(it->second);//递归子目录 } }
    为方便调试,record.dat文件以明文存储,文件内容如下:

    5.2.3 恢复系统状态为提高用户体验,每次打开系统时,系统会根据record.dat文件存储的系统状态恢复上一次退出前的系统状态。
    恢复系统状态的实现思想与保存系统状态(5.2.2)类似,根据record.dat的数据重建目录结构。具体流程图与代码如下:
    init函数

    creat函数

    具体代码
    void init() { ifstream inr("record.dat"); string tmp; if (!inr) { initDir(); } while (inr >> tmp) records.push_back(tmp); if (records.size() >= 1) { root = curdir = creat(NULL); } else { initDir(); } }
    //还原上一次系统关闭状态 dir* creat(dir *last) { dir *tmp = new dir();//新建目录 tmp->name=records[reco++];//读取目录名 tmp->pre = last;//设置父指针 string t; t= records[reco++];//读取文件数 for (int i = 0; i < stoi(t); i++) { file *tfile = new file();//新建文件 tfile->name= records[reco++];//读取文件名 while (1) { string ts; ts= records[reco++];//读取文件内容 if (ts != "content") {//不是关键字就持续读入内容 tfile->content.push_back(ts); } else { break; } } user a; a.name = records[reco++];//读取用户名 a.password= records[reco++];//密码 tfile->owner = a; tmp->files[tfile->name] = tfile;//将新建的文件加入目录 } t= records[reco++];//子目录数 for (int i = 0; i < stoi(t); i++) { string name; name= records[reco++];//子目录名 tmp->next[name] = creat(tmp);//递归新建子目录 } return tmp; }
    5.2.4 路径解析为提高用户体验,系统引入了路径解析的机制,可以让包括cd、ls、gedit在内的多种操作同时支持相对路径与绝对路径。绝对路径与相对路径的表示方式与Ubuntu系统相同。
    路径解析输入的参数为绝对路径或相对路径,返回的结果是目标目录的指针。具体流程图与代码如下:
    流程图

    关键代码
    dir* pathTrans(string path) { string tmp = path; //绝对路径 if (path[0] == '~' || path[0] == '/') { dir *cur = root; if (path[0] == '/')path = "~" + path; vector<string> tmp = split(path);//按照/分割路径 for (int i = 1; i < tmp.size(); i++) { if (cur->next.find(tmp[i]) == cur->next.end()) { return NULL; } cur = cur->next[tmp[i]]; } return cur; } //相对路径 else { dir *cur = curdir; vector<string> tmp = split(path);//按照/分割路径 for (int i = 0; i < tmp.size(); i++) { if (tmp[i] == ".") { } else if (tmp[i] == "..") { if (cur == root) {//不能再往上走了 return NULL; } else { cur = cur->pre; } } else if (cur->next.find(tmp[i]) == cur->next.end()) { return NULL; } else if (cur->next.find(tmp[i]) != cur->next.end()) { cur = cur->next[tmp[i]]; } } return cur; } return NULL; }
    6.实验演示6.1 登录欢迎界面

    当用户名与密码不匹配,系统会让用户反复输入密码,直到正确为止:

    当输入用户名与不在已注册用户中,若用户同意创建用户,系统会根据先前输入的用户名与密码创建用户:

    6.2帮助文档与使用说明用户输入help时显示所有命令的帮助文档:

    输入某个命令+?时显示该条命令的使用说明:

    6.3 cd命令
    红框为目前根节点下拥有的目录;黄框展示使用相对路径、绝对路径更改目录,以及回到上一级目录的情况;蓝框展示遇到错误路径的情况。
    6.4 ls命令
    黄框展示有参及无参ls命令的使用情况;蓝框展示遇到错误路径的情况。
    6.5 mkdir命令


    红框展示目前根节点下拥有的目录;黄框展示新建一个paly目录的情况;蓝框展示遇到重名目录的情况;第三张图展示新建目录名中存在非法字符的情况。
    6.6 touch命令
    红框展示~/study/college目录下拥有的文件;黄框展示新建一个test2.txt文件的情况;蓝框展示遇到重名文件的情况;展示新建文件名中存在非法字符的情况。
    6.7 gedit命令
    红框展示~/study/college目录下拥有的文件;黄框展示读写test2.txt文件的情况,截图下半部为gedit打开临时文件;蓝框展示遇到缺少文件名及文件非当前用户拥有的情况。
    6.8 rm命令
    红框展示根目录下拥有的文件与目录;黄框展示删除work目录的情况;绿框展示删除test.txt文件的情况;蓝框展示遇到不存在目录或文件的情况。
    6.9 cp命令
    红框展示~/study目录与~/work目录下拥有的文件与目录;黄框展示复制college目录到~/work目录的情况。

    红框展示~/work与~/study/college目录下拥有的文件与目录;黄框展示复制test2.txt文件到~/work目录的情况。

    红框展示~/work与~/study/college目录下拥有的文件与目录;黄框展示剪贴test2.txt文件到~/work目录的情况。

    红框展示~/work与~/study目录下拥有的文件与目录;黄框展示剪贴college目录到~/work目录的情况。
    6.10 用户权限系统实现的多用户权限可以概括为:文件创建者为文件所有者,非文件所有者可以知道该文件的存在,但不能对该文件执行读写、复制、删除等操作。下图展示了非文件所有者不能对文件执行gedit、rm、rename、cp命令的情况:
    0 评论 3 下载 2021-04-04 14:44:56 下载需要8点积分
  • 基于JSP和Sql Server实现的飞机票售票管理系统

    1.系统背景随着现代生活水平提高,人类逐渐对精神文化享受重视,追求不同的生活,而其中旅游成为大众的喜爱,于是到年到节的时候需要一种交通 工具来达到目的地,这也成为这系统开发的动力,系统的进步也是应客户的需求而生,为了能够在更早的出售机票,不影响客户的行程,机票售票系统也做出相应的决策,那就是通过无人管理机票预定,然后在快到期的那天,管理员可以通过订单管理来处理客户订单。所以管理员的模块也极其重要,本系统通过后台界面为管理员和数据库与服务器进行交互提供环境。客户只要通过浏览器来进行订票,订票的数据存储在数据里面,然后管理员通过打开后台浏览器来进行信息汇总,然后下单确定发票,整一个信息传递过程是订票信息→订票查询→核实机票。
    2.功能简介
    顾客上网通过浏览器来登入系统首页,系统提供客户注册、机票查询和机票预定功能,当然也包括已预定机票取消
    用户通过窗口选取机票,订单信息保存在数据库上,等待管理员审核
    管理员处理用户信息,确定用户购买
    用户可以根据己购买的字眼可以到代理取票,也可以再登机那天取票
    管理员随时更新航班信息
    客户可以随时登入系统获取航班信息

    3.系统分析系统通过数据库的连接,通过接受客户数据来响应WEB服务器处理,来进行数据管理。整个分为两大部分,第一部分就是客户模块,第二部分就是管理员模块。客户模块包括客户注册、查询、购票、换票、取消机票。管理员模块包括自动处理客户订单、管理员处理订单、机票班次更新、管理系统用户。通过计算机网络来贯穿两大模块,从而实现客户和服务器的交互。
    3.1 功能需求在客户端系统的功能实现上,可以分为以下几个部分:

    用户通过支持web容器的浏览器来进行信息的输入,客户端根据用户输入将数据流输入和数据流的统计。这部分的要求是一个人性化的界面,让用户通过浏览器来进行页面访问。所谓人性化界面包括,浏览功能,预定功能,多种进行人机交互按钮,比如html页面信息和提交、重置等
    把用户信息存储到客户端系统中,经过系统自动审核后存储到数据库当中,已备以后登录查询
    服务器通过数据库出来从客户端传输的信息加以确定,然后返回给客户端,客户端通过信息来提醒用户,用户可以根据信息到柜台拿票

    在服务器端系统的功能实现上,可以分为以下几个部分:

    服务器通过网络接受用户从客户端输入所需要的信息,然后根据用户所需要的信息来判断是否通过WEB容器进行管理,如果纯粹是看票的话,直接调用数据库已经存储好的机票信息通过静态服务反馈用户,如果有购票需要数据通过WEB服务器来进行管理
    在服务器段提供了航班输入功能,管理员根据现实情况来对航班进行管理
    把航班信息通过网络来传递到客户端来与用户进行交互

    3.2 数据流图根据数据流图的特点可以从大到小逐渐深入系统处理过程,图3-1是飞机票售票管理系统的最顶层的数据流图。

    从顶层数据流图,可以得到整个数据流图过程,如图3-2,图3-3。
    系统数据流图

    订票数据流图

    3.3 业务流图飞机票售票管理系统的业务流图如图3-4。

    3.4 数据库表说明在一个B/S系统中数据无疑是非常重要的,数据的安全性、稳定性、可恢复性对使用者起着极其重要的作用。选择一个健全稳定的数据库无疑也是系统实现的首要步骤,本系统选用的是SQL 2005,它能提供大型系统所需的数据库服务。下面将介绍系统的数据库结构。本系统的最主要的功能在与数据库的分配,对不同的用户采用不同的数据库,和不同的查询方式。
    用户表common_user
    CREATE TABLE IF NOT EXISTS `common_user` ( `user_name` varchar(16) NOT NULL, `user_pwd` varchar(32) NOT NULL, `avatar_img` varchar(50) DEFAULT NULL, PRIMARY KEY (`user_name`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='用户表' AUTO_INCREMENT=1 ;
    管理员用户表admin_user
    CREATE TABLE IF NOT EXISTS `admin_user` ( `user` varchar(16) NOT NULL COMMENT '管理员用户名', `pwd` varchar(32) NOT NULL COMMENT '管理员密码', PRIMARY KEY (`user`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='管理员用户表' AUTO_INCREMENT=1 ;
    航班信息表flight
    CREATE TABLE IF NOT EXISTS `flight` ( `f_n` varchar(6) NOT NULL COMMENT '航班号', `f_s_p` varchar(4) NOT NULL COMMENT '航班起点', `f_e_p` varchar(4) NOT NULL COMMENT '航班终点', `f_s_a` varchar(12) NOT NULL COMMENT '航班起飞机场', `f_a_a` varchar(12) NOT NULL COMMENT '航班到达机场', `f_d_t` varchar(5) NOT NULL COMMENT '起飞(departure)时间', `f_a_t` varchar(5) NOT NULL COMMENT '到达时间', `f_f_c_p` int(11) NOT NULL COMMENT '头等舱价格First class price', `f_s_c_p` int(11) NOT NULL COMMENT '商务舱价格', `f_t_c_p` int(11) NOT NULL COMMENT '经济舱价格', PRIMARY KEY (`f_n`), UNIQUE KEY `f_n` (`f_n`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='航班信息' AUTO_INCREMENT=1 ;
    航班订单信息表t_order
    CREATE TABLE IF NOT EXISTS `t_order` ( `id` int(12) NOT NULL AUTO_INCREMENT, `order_user` varchar(16) NOT NULL COMMENT '下单用户', `f_n` varchar(6) NOT NULL COMMENT '航班号', `p_name` varchar(6) NOT NULL COMMENT '乘客姓名', `date` varchar(12) NOT NULL COMMENT '订单日期', `grade` varchar(3) NOT NULL COMMENT '舱别', `p_id` varchar(18) NOT NULL COMMENT '乘客身份证号', `contact` varchar(6) NOT NULL COMMENT '联系人', `c_p` varchar(11) NOT NULL COMMENT '联系人电话', PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci AUTO_INCREMENT=8 ;
    用户留言信息表user_message
    CREATE TABLE IF NOT EXISTS `user_message` ( `id` int(11) NOT NULL AUTO_INCREMENT, `time` varchar(10) NOT NULL, `user_name` varchar(32) NOT NULL, `message_content` text NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=30 ;
    4.程序结构功能结构4.1 用户注册系统对于用户来说只能查询,不能诺命购票,因为不提供真实身份,无法判断用户,购票也极为麻烦,所以只能依靠登录来进行用户识别和购票。
    用户注册的关键代码,主要利用request这个接口的getParameter0方法来接受用户所输入的数据,通过getRemoteAddr()方法来获取用户的ID,每一个以用户都只有唯一—个ID标识,然后通过flag来判断输入是否符合,为真的话就通过request的setAtribute方法来保存信息。
    1. public void doPost(HttpServletRequest req, HttpServletResponse resp) 2. throws ServletException, IOException { 3. String log_name = req.getParameter("log_name"); 4. String log_pwd = req.getParameter("log_pwd"); 5. String reg_name = req.getParameter("reg_name"); 6. String reg_pwd1 = req.getParameter("reg_pwd1"); 7. String reg_pwd2 = req.getParameter("reg_pwd2"); 8. 9. if(log_name!=null&&log_pwd!=null&®_name==null&®_pwd1==null&®_pwd2==null) { 10. //调用登录方法处理登录 11. go_login(log_name, log_pwd, req, resp); 12. 13. } 14. else if(log_name==null&&log_pwd==null&®_name!=null&®_pwd1!=null&®_pwd2!=null&®_pwd1.equals(reg_pwd2)) { 15. //调用注册方法处理注册 16. go_reg(reg_name, reg_pwd1, req, resp); 17. 18. }//为什么不再写一个判断注册时reg_pwd1和reg_pwd2是否相等的语句呢?因为,前端页面中已经用js去做判断了, 19. //如果用户两次输入的密码不一致根本不可能提交数据到此servlet,除非用户限制js或者修改了js,也就是做了非法操作 20. //因此,直接输出提示非法操作的提示信息即可 21. else { 22. 23. resp.setContentType("text/html;charset=utf-8"); 24. PrintWriter out = resp.getWriter(); 25. out.println("请不要尝试非法操作"); 26. /*****测试数据 27. out.println("登录账号:"+log_name+"\n登录密码:"+log_pwd+"\n注册账号:" 28. +reg_name+"\n注册密码1:"+reg_pwd1+"\n注册密码2:"+reg_pwd2); 29. out.print("---log_name==null:"+(log_name==null)); 30. out.print("---log_pwd==null:"+(log_pwd==null)); 31. out.print("---reg_name==null:"+(reg_name==null)); 32. out.print("---reg_pwd1==null:"+(reg_pwd1==null)); 33. out.print("---reg_pwd2==null:"+(reg_pwd2==null)); 34. */ 35. 36. resp.setHeader("refresh", "2;url=index/login_reg.jsp"); 37. //除了登录和注册操作,提交其它数据均为非法操作,不做处理,仅给出提示非法信息 38. } 39. }
    4.2 机票查询在该系统当中,因为运行外面的旅客访问系统并查询系统,以供是否注册为本系统用户,所以两者都可以查询机票航班,旅客通过session来访问,但访问数据随着页面刷新而消除。
    这部的关键步骤也是调用request这个接口的获取信息方法,同样也是调用geParameter()方法就可以把信息获取出来。同时用SQL语言来查询表的信息,附值给定义的属性,可以通过方法来调用数据库。
    1. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 2. req.setCharacterEncoding("utf-8"); 3. //HttpSession session = req.getSession(); 4. String url=null; 5. /* 6. * if(session.getAttribute("url")!=null) { 7. * url=session.getAttribute("url").toString(); }else { 8. */ 9. url="default/index.jsp"; 10. 11. String departure=null; 12. String destination=null; 13. departure=req.getParameter("departure"); 14. destination=req.getParameter("destination"); 15. String sql=null; 16. if(departure==""&&destination=="") { 17. //如果始发地和目的地都为空则跳转回原页面 18. resp.sendRedirect(url); 19. }else if (departure!=""&&destination=="") { 20. sql="select * from flight where f_s_p='"+departure+"'"; 21. }else if (departure==""&&destination!="") { 22. sql="select * from flight where f_e_p='"+destination+"'"; 23. }else if (departure!=""&&destination!="") { 24. sql="select * from flight where f_s_p='"+departure+"' and f_e_p='"+destination+"'"; 25. } 26. if(departure==""&&destination=="") { 27. //如果都为空,执行不到这一步,所以就不用做处理了,否则,执行else 28. }else { 29. db_conn conn=new db_conn(); 30. //System.out.println(sql); 31. ArrayList<flight> flightlist = new ArrayList<flight>(); 32. flight flight_info=new flight(); 33. 34. ResultSet res=conn.executeQuery(sql); 35. try { 36. while (res.next()) { 37. flight_info.setF_n(res.getString(1)); 38. flight_info.setF_s_a(res.getString(4)); 39. flight_info.setF_a_a(res.getString(5)); 40. flight_info.setF_d_t(res.getString(6)); 41. flight_info.setF_a_t(res.getString(7)); 42. flight_info.setF_f_c_p(res.getString(8)); 43. flight_info.setF_s_c_p(res.getString(9)); 44. flight_info.setF_t_c_p(res.getString(10)); 45. flightlist.add(flight_info); 46. } 47. req.setAttribute("flightlist", flightlist); 48. } catch (SQLException e) { 49. System.out.println("错误信息:"+e); 50. }finally { 51. conn.closeDB(); 52. } 53. //resp.sendRedirect("default/search.jsp"); 54. req.getRequestDispatcher("default/search.jsp").forward(req, resp); 55. } 56. }
    4.3 机票预定为了整个流程更为简单,易用,该系统就只设定只用验证的用户才可以购买飞机票,同时用户可以通过登录查询自己的航班。
    下面代码是预定机票的代码,通过判断机票剩余数和预定机票的关系,确定用户购买成功,成功的话,设置成功信息,失败的设只失败提示信息。
    1. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 2. //开始获取各种参数 3. req.setCharacterEncoding("utf-8"); 4. String flight_id=req.getParameter("flight_id"); 5. String start_place=req.getParameter("start_place"); 6. String end_place=req.getParameter("end_place"); 7. String start_airport=req.getParameter("start_airport"); 8. String end_airport=req.getParameter("end_airport"); 9. String take_off_time=req.getParameter("take_off_time"); 10. String landing_time=req.getParameter("landing_time"); 11. String first_class_price_str=req.getParameter("first_class_price"); 12. Integer first_class_price=Integer.parseInt(first_class_price_str); 13. String business_class_price_str=req.getParameter("business_class_price"); 14. Integer business_class_price=Integer.parseInt(business_class_price_str); 15. String economy_class_price_str=req.getParameter("economy_class_price"); 16. Integer economy_class_price=Integer.parseInt(economy_class_price_str); 17. //参数获取结束 18. db_conn conn=new db_conn(); 19. String sql="select * from flight where f_n='"+flight_id+"'"; 20. ResultSet res=conn.executeQuery(sql); 21. try { 22. if(res.next()) { 23. resp.setContentType("text/html;charset=utf-8"); 24. PrintWriter out=resp.getWriter(); 25. out.println("您输入的航班号重复了,请选择其他航班号添加,5s后返回"); 26. resp.setHeader("refresh", "5;url=admin/flight_add.jsp"); 27. }else { 28. sql="insert into flight values('"+flight_id+"','"+start_place+"','"+end_place+"','"+start_airport+"','"+end_airport+"','"+take_off_time+"','"+landing_time+"','"+first_class_price+"','"+business_class_price+"','"+economy_class_price+"')"; 29. //Integer res= 30. conn.executeInsert(sql); 31. //System.out.println(res); 32. //System.out.println(sql); 33. resp.sendRedirect("admin/flight_list.jsp"); 34. } 35. } catch (SQLException e) { 36. // TODO Auto-generated catch block 37. e.printStackTrace(); 38. } 39. }
    4.4 订单管理订单管理模块主要是对用户订票进行管理,管理员通过登录进行访问系统后台页面,然后选取订单管理模块,对客户进行处理。通过数据库对用户订单信息组进行管理,通过定义ArrayList()数据组来获得订票所以信息。
    1. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 2. req.setCharacterEncoding("utf-8"); 3. HttpSession session = req.getSession(); 4. if(session.getAttribute("user_id")!=null) { 5. String user_id=session.getAttribute("user_id").toString(); 6. String f_i=req.getParameter("flight_id"); 7. String passenger_name=req.getParameter("passenger_name"); 8. String date=req.getParameter("date"); 9. String grade=req.getParameter("grade"); 10. String passenger_id=req.getParameter("passenger_id"); 11. String contact=req.getParameter("contact"); 12. String contact_phone=req.getParameter("contact_phone"); 13. 14. 15. /* 16. * System.out.println(f_i); System.out.println(passenger_name); 17. * System.out.println(date); System.out.println(grade); 18. * System.out.println(passenger_id); System.out.println(contact); 19. * System.out.println(contact_phone); 20. */ 21. 22. if(f_i!=""&&passenger_name!=""&&date!=""&&grade!=""&&passenger_id!=""&&contact!=""&&contact_phone!="") { 23. db_conn conn=new db_conn(); 24. String sql="insert into t_order (f_n,order_user,p_name,date,grade,p_id,contact,c_p) values('"+f_i+"','"+user_id+"','"+passenger_name+"','"+date+"','"+grade+"','"+passenger_id+"','"+contact+"','"+contact_phone+"')"; 25. Integer res=conn.executeInsert(sql); 26. System.out.println(res); 27. if(res.equals(1)) { 28. resp.sendRedirect("default/order_list.jsp"); 29. }else { 30. resp.sendRedirect("default/order.jsp"); 31. } 32. 33. }else { 34. resp.sendRedirect("default/order.jsp"); 35. } 36. 37. }else { 38. resp.sendRedirect("default/order.jsp"); 39. } 40. 41. }
    5.操作方法用户访问首页

    用户进行登录

    用户进行注册

    登录或注册成功,进入用户个人首页

    用户修改个人资料

    用户订购航班

    用户查询航班

    用户查看航班订单

    用户查看留言

    管理员登录界面

    管理员添加航班信息

    管理员查看航班列表信息

    管理员查看航班订单

    管理员查看用户列表信息

    管理员查看留言列表

    6.测试结果用户能成功订购航班,并且查看订单



    管理员查看航班并成功添加航班


    7.心得体会通过JavaEE的综合课程设计感触很深,在数据库的课设的基础上,又一次用JSP做相关项目,这不仅又一次加强了自己对JSP这门课程的理解也很好的锻炼了自己的动手能力。这一技术是需要有一定基础、而且动手能力强的学科。书上也强调一点是:要想真正地掌握JSP技术,必须有较好的java语言基础,以及HTML语言方面的知识。
    JSP是一门新技术,他基于Java Servlet以及整个java体系的Web开发技术。通过这个大作业,使我初步掌握和了解了JSP的基本运行原理、各个对象的结构和功能、怎样连接数据库、能自己手动写code 开发一些小网页。并且,自己能够组建一台JSP服务器,而且还了解了安装过程中,所要注意的事项。对于一些简单的小问题,能够自己动手排除。
    8 评论 107 下载 2020-08-04 12:31:18 下载需要12点积分
  • 基于C语言实现的仓库管理系统

    1 题目要求该系统用于实现仓库管理,系统应支持入库、出库、库存查询以及打印。用户可自定库存警戒值,库存低于警戒值时以红字显示。仓库信息需要用文件存储。
    2 需求分析根据题目要求,由于货品信息存放在文件中,所以应该提供文件的读入、输出等操作;在程序中要浏览货品信息,应提供显示、查找、排序等操作;实现货物入库功能,要提供结构体的输入操作;实现统计功能,要提供相应的统计操作;实现修改功能,要提供修改操作;另外,还要提供键盘式菜单实现功能选择。
    3 总体设计根据上面的需求分析,可以将该系统的系统的设计分为大模块,即入库模块、出库模块、查询模块、排序模块、修改模块和统计模块等。

    4 详细设计4.1 主函数
    #include<stdio.h>#include<windows.h>#include<string.h>#include<conio.h>void main(){ int sele; Re_file(); //读取货品信息 sele=1; while(sele) { system("cls"); printf("\n\n"); printf("*********************************************\n"); printf("* *\n"); printf("* 1.入库 2.出库 *\n"); printf("* *\n"); printf("* 3.查询 4.排序 *\n"); printf("* *\n"); printf("* 5.修改 6.统计 *\n"); printf("* *\n"); printf("* 7.退出 *\n"); printf("* *\n"); printf("*********************************************\n"); printf("请选择功能序号:"); scanf("%d",&sele); switch(sele) { case 1:Stock_in();Display();break; case 2:Stock_out();Display();break; case 3:Query();break; case 4:Sort();Display();break; case 5:Modify();Display();break; case 6:Statistics();break; case 7:exit(0);sele=0;break; } printf("\n\n按任意键继续...\n"); getch(); } Wr_file();}
    4.2 各功能模块设计4.2.1 数据读入模块单独看各组数据信息,货品名称是字符串,可以采用字符型数组;其他数据均可用整数存放。数据信息存放在文件中,一条记录对应一种货品的信息,既符合习惯也方便信息管理。把一种货品的相关信息作为结构体成员,如果要存放若干种货品的信息就要用结构体数组。
    typedef struct{ int num; //货品编号 char name[20]; //货品名称 int stock; //原始库存 int in; //入库数目 int out; //出库数目 int amount; //最终库存 int warning_value; //警戒值 int state; //库存状态(是否低于警戒值)}goods;goods s[M]; //用于存放货品信息 goods r[M]; //用于存放入库货品信息 goods t[M]; //用于存放出库货品信息
    s[M]、r[M]、t[M]的M为货品种类数,程序中采用宏定义的方式,可以随时在源程序宏定义中修改。本程序中宏定义为:#define M 50。
    void Re_file() //读入原始库存文件{ FILE*fp; N=0; fp=fopen("goods.txt","r"); while(fscanf(fp,"%d%s%d%d%d%d%d",&s[N].num,&s[N].name,&s[N].stock,&s[N].in,&s[N].out,&s[N].amount,&s[N].warning_value)!=EOF) N++; fclose(fp); P=N;}
    4.2.2 入库模块
    该模块的功能是根据题目要求读入货品的入库数据。注意在主函数中已经读入了原始数据。
    void Stock_in() //读入入库文件{ FILE*fp; int i,j; N=0; fp=fopen("stockin.txt","r"); while(fscanf(fp,"%d%d",&r[N].num,&r[N].in)!=EOF) N++; fclose(fp); for(i=0;i<P;i++) { for(j=0;j<N;j++) { if(r[i].num==s[j].num) s[j].in=r[j].in; } } for(i=0;i<P;i++) s[i].amount=s[i].stock+s[i].in;}
    4.2.3 出库模块该模块的功能是根据题目要求读入货品的出库数据。注意在主函数中已经读入了原始数据。
    void Stock_out() //读入出库文件{ FILE*fp; int i,j; N=0; fp=fopen("stockout.txt","r"); while(fscanf(fp,"%d%d",&t[N].num,&t[N].out)!=EOF) N++; fclose(fp); for(i=0;i<P;i++) { for(j=0;j<N;j++) { if(t[i].num==s[j].num) s[j].out=t[j].out; } } for(i=0;i<P;i++) s[i].amount=s[i].stock+s[i].in-s[i].out;}
    4.2.4 浏览模块
    该模块的功能是显示所有货品的记录信息。根据货品库存数目是否低于警戒值,分别按红字显示和白字显示。采用SetConsoleTextAttribute函数改变输出字体颜色。
    void Display() //显示库存情况{ int i,j; system("cls"); Estimate(); printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n"); for(i=0,j=1;i<P;i++,j++) { if(s[i].state==1) //库存值小于警戒值红字显示 { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED); printf("%-9d %-10s%-10d%-10d%-10d%-10d%-10d\n", s[i].num, s[i].name, s[i].stock, s[i].in, s[i].out, s[i].amount, s[i].warning_value); if(j%10==0&&j!=P) //控制每次显示十行 { printf("按任意键继续..."); getch(); puts("\n"); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE); printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n"); } } else if(s[i].state==0) //库存值不小于警戒值白字显示 { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE); printf("%-9d %-10s%-10d%-10d%-10d%-10d%-10d\n", s[i].num, s[i].name, s[i].stock, s[i].in, s[i].out, s[i].amount, s[i].warning_value); if(j%10==0&&j<P) { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE); printf("按任意键继续..."); getch(); puts("\n"); printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n"); } } }}
    4.4.5 判断模块该模块用于判断货品库存数目是否小于警戒值并记录,多次在其他被模块调用。
    // 判断库存值是否小于警戒值void Estimate(){ int i; for(i=0;i<P;i++) { if(s[i].amount>=s[i].warning_value) s[i].state=0; else if(s[i].amount<s[i].warning_value) s[i].state=1; }}
    4.4.6 查询模块
    该模块的功能是根据输入的货品名称或货号查找对应的记录,找到以后,显示货品记录。同时,库存数目小于警戒值以红字显示。
    // 查询货品void Query(){ int k,m,i,j=-1; char n[20]; system("cls"); printf("\n\n"); printf("*********************************************\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* 1.货品编号 2.货品名称 *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("*********************************************\n"); printf("\n\n请输入查询选项:"); scanf("%d",&k); if(k==1) { printf("请输入货品编号:"); scanf("%d",&m); for(i=0;i<P;i++) { if(m==i) j=m-1; } } else if(k=2) { printf("请输入货品名称:"); scanf("%s",&n); for(i=0;i<P;i++) { if(strcmp(n,s[i].name)==0) j=i; } } Estimate(); if(j==-1) { printf("\n没有找到!\n"); Printf_back(); } else { if(s[j].state==1) { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED); printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n");printf("%-9d %-10s%-10d%-10d%-10d%-10d%-10d\n",s[j].num,s[j].name, s[j].stock,s[j].in,s[j].out,s[j].amount,s[j].warning_value); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE); Printf_back(); } else { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE); printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n"); printf("%-9d %-10s%-10d%-10d%-10d%-10d%-10d\n",s[j].num,s[j].name, s[j].stock, s[j].in, s[j].out,s[j].amount,s[j].warning_value); Printf_back(); } }}
    4.4.7 排序模块该模块的功能是将货品记录按照最终库存升序排列。这里按照冒泡法排序。排序完成后显示货品记录,显示完成后返回主菜单
    // 商品库存总量从小到大排序void Sort() { int i,j; goods t; for(i=0;i<P-1;i++) for(j=i+1;j<P;j++) { if(s[i].amount>s[j].amount) { t=s[i]; s[i]=s[j]; s[j]=t; } } Display(); Printf_back();}
    4.4.8 修改模块
    该模块的功能是根据货品编号或货品名称找到要修改的记录,并提示用户修改该记录的哪部分信息(原始库存、入库数目、出库数目、警戒值),然后根据用户的选择修改相应的位置。最后显示货品信息供用户确认。
    // 修改货品信息void Modify() { int k,m,i,j=-1,t,h; char n[20]; system("cls"); printf("\n\n"); printf("*********************************************\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* 1.货品编号 2.货品名称 *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("*********************************************\n"); printf("\n\n请输入修改选项:"); scanf("%d",&k); if(k==1) { printf("请输入货品编号:"); scanf("%d",&m); for(i=0;i<P;i++) { if(m==i) j=m-1; } } else if(k==2) { printf("请输入货品名称:"); scanf("%s",&n); for(i=0;i<P;i++) { if(strcmp(n,s[i].name)==0) j=i; } } if(j==-1) { printf("\n没有找到!\n"); Printf_back(); } else { printf("\n\n"); printf("*********************************************\n"); printf("* *\n"); printf("* 1.原始库存 2.入库数目 *\n"); printf("* *\n"); printf("* 3.出库数目 4.警戒值 *\n"); printf("* *\n"); printf("*********************************************\n"); printf("请选择修改选项:"); scanf("%d",&t); if(t==1) { scanf("%d",&h); s[j].stock=h; } else if(t==2) { scanf("%d",&h); s[j].in=h; } else if(t==3) { scanf("%d",&h); s[j].out=h; } else if(t==4) { scanf("%d",&h); s[j].warning_value=h; } s[j].amount=s[j].stock+s[j].in-s[j].out; } printf("请确认核对货品信息:\n"); Display();}
    4.4.9 统计模块
    该模块的功能是根据用户的选择统计货品总数或最终库存低于警戒值的货品种数。统计结束后将所有货品信息以文件形式输出。
    // 统计数目void Statistics() { int k,i,j,m=0,n=0; system("cls"); printf("\n\n"); printf("*********************************************\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* 1.库存总数 2.库存状态 *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("*********************************************\n"); printf("\n\n请输入查询选项:"); scanf("%d",&k); if(k==1) { for(i=0;i<P;i++) m=m+s[i].amount; printf("库存总数为:%d",m); } else if(k==2) { Estimate(); for(j=0;j<P;j++) if(s[j].state==1) n=n+1; printf("低于库存警戒值的商品种数为:%d",n); } Wr_file();}
    4.4.10 数据输出模块该模块的功能是将货品信息写入文件。
    // 写输出文件int Wr_file() { FILE*fp; int i; fp=fopen("amount.txt","w"); for(i=0;i<P;i++) fprintf(fp,"%-9d %-10s%-10d%-10d%-10d%-10d%-10d\n",s[i].num,s[i].name, s[i].stock,s[i].in,s[i].out,s[i].amount,s[i].warning_value); fclose(fp); return 1;}
    5 上机操作5.1 数据源该程序的运行需要四个文件,三个用于读取货品信息,一个用于存储货品息。goods.txt文件的格式如下:
    货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值1 A1 456 0 0 456 4002 A2 23 0 0 23 1003 A3 67 0 0 67 1004 A4 104 0 0 104 1005 A5 78 0 0 78 100
    用于读取货品编号、货品名称、原始库存、警戒值等货品信息。
    stockin.txt文件的格式如下:
    货品编号 入库数目1 573 784 805 236 10
    用于读取入库信息。
    stockout.txt文件的格式如下:
    货品信息 出库数目1 102 53 234 125 3
    用于读取出库信息。
    amount.txt文件用于存储货品信息。
    5.2 编译、链接和运行5.3 结果主函数界面

    入库模块

    出库模块

    查询模块

    排序模块

    修改模块

    统计模块

    6 总结通过这次课程设计,我进一步理解和运用了结构化程序设计的思想方法,初步掌握了开发小型实用系统的基本方法,学会了调试较长的程序,能够利用流程图描述算法,进一步掌握和提高利用C语言进行程序设计的能力。
    在程序的编写中,我们首先要构架好整体结构,然后再将各个模块的函数写出来。在写函数的过程中,我们要选择性地利用到所学的知识,如排序法、while循环、if语句等,实现相应的功能。一个较大的程序主要调试方法有分模块调试和分步调试。文件的数据格式很重要,要与程序读取的数据类型保持一致。程序调试通了以后,在修改其中的细节问题。
    学习好C语言这门课,能为我们以后开发出更多实用的程序打下坚实的基础。要学好C语言这门课,我们平时就要勤于实践,锻炼自己的逻辑思维能力与整体构架能力。
    12 评论 719 下载 2018-11-05 10:24:37 下载需要8点积分
显示 75 到 90 ,共 15 条
eject